]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Merge branch_anisotropic to trunk: Extension of isotropic to
authorhartmann <hartmann@0785d39b-7218-0410-832d-ea1e28bc413d>
Tue, 8 Jul 2008 15:25:01 +0000 (15:25 +0000)
committerhartmann <hartmann@0785d39b-7218-0410-832d-ea1e28bc413d>
Tue, 8 Jul 2008 15:25:01 +0000 (15:25 +0000)
anisotropic refinement.

git-svn-id: https://svn.dealii.org/trunk@16430 0785d39b-7218-0410-832d-ea1e28bc413d

81 files changed:
deal.II/base/include/base/geometry_info.h
deal.II/base/include/base/qprojector.h
deal.II/base/source/geometry_info.cc
deal.II/base/source/quadrature.cc
deal.II/deal.II/include/fe/fe.h
deal.II/deal.II/include/fe/fe_dgp.h
deal.II/deal.II/include/fe/fe_dgp_nonparametric.h
deal.II/deal.II/include/fe/fe_nedelec.h
deal.II/deal.II/include/fe/fe_poly.templates.h
deal.II/deal.II/include/fe/fe_tools.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_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/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_levels.h
deal.II/deal.II/include/grid/tria_object.h
deal.II/deal.II/include/grid/tria_objects.h
deal.II/deal.II/include/multigrid/mg_transfer.templates.h
deal.II/deal.II/include/numerics/derivative_approximation.h
deal.II/deal.II/source/dofs/dof_accessor.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_abf.cc
deal.II/deal.II/source/fe/fe_dgp.cc
deal.II/deal.II/source/fe/fe_dgp_monomial.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_nedelec_1d.cc
deal.II/deal.II/source/fe/fe_nedelec_2d.cc
deal.II/deal.II/source/fe/fe_nedelec_3d.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_q_hierarchical.cc
deal.II/deal.II/source/fe/fe_raviart_thomas.cc
deal.II/deal.II/source/fe/fe_raviart_thomas_nodal.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/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/grid/grid_refinement.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_levels.cc
deal.II/deal.II/source/grid/tria_objects.all_dimensions.cc [new file with mode: 0644]
deal.II/deal.II/source/grid/tria_objects.cc
deal.II/deal.II/source/hp/dof_handler.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/derivative_approximation.cc
deal.II/deal.II/source/numerics/error_estimator.cc
deal.II/deal.II/source/numerics/solution_transfer.cc
deal.II/deal.II/source/numerics/time_dependent.cc
deal.II/doc/doxygen/deal.dox
deal.II/doc/doxygen/tutorial/toc.html
deal.II/doc/news/anisotropic.html
deal.II/doc/news/changes.h
deal.II/examples/step-12/step-12.cc
deal.II/examples/step-28/step-28.cc
deal.II/examples/step-30/Makefile [new file with mode: 0644]
deal.II/examples/step-30/doc/intro.dox [new file with mode: 0644]
deal.II/examples/step-30/doc/results.dox [new file with mode: 0644]
deal.II/examples/step-30/doc/step-30.grid-3.aniso.png [new file with mode: 0644]
deal.II/examples/step-30/doc/step-30.sol-1.aniso.png [new file with mode: 0644]
deal.II/examples/step-30/doc/step-30.sol-1.iso.png [new file with mode: 0644]
deal.II/examples/step-30/doc/step-30.sol-5.aniso.png [new file with mode: 0644]
deal.II/examples/step-30/doc/step-30.sol-5.iso.png [new file with mode: 0644]
deal.II/examples/step-30/step-30.cc [new file with mode: 0644]
deal.II/examples/step-31/step-31.cc
deal.II/examples/step-9/step-9.cc
deal.II/todo [new file with mode: 0644]

index ea280e6b0d96afb5886a5b375fee6372fda36911..79ca912a7ccdf43a13c046a0993c35dbb0e17629 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
 
+
+
+/**
+ * A class that provides possible choices for isotropic and
+ * anisotropic refinement flags in the current space dimension.
+ *
+ * This general template is unused except in some weird template
+ * constructs. Actual is made, however, of the specializations
+ * <code>RefinementPossibilities@<1@></code>,
+ * <code>RefinementPossibilities@<2@></code>, and
+ * <code>RefinementPossibilities@<3@></code>.
+ *
+ * @ingroup aniso
+ * @author Ralf Hartmann, 2005, Wolfgang Bangerth, 2007
+ */
+template <int dim>
+struct RefinementPossibilities
+{
+                                    /**
+                                     * Possible values for refinement
+                                     * cases in the current
+                                     * dimension.
+                                     *
+                                     * Note the construction of the
+                                     * values: the lowest bit
+                                     * describes a cut of the x-axis,
+                                     * the second to lowest bit
+                                     * corresponds to a cut of the
+                                     * y-axis and the third to lowest
+                                     * bit corresponds to a cut of
+                                     * the z-axis. Thus, the
+                                     * following relations hold
+                                     * (among others):
+                                     *
+                                     * @code
+                                     * cut_xy  == cut_x  | cut_y
+                                     * cut_xyz == cut_xy | cut_xz
+                                     * cut_x   == cut_xy & cut_xz
+                                     * @endcode
+                                     *
+                                     * Only those cuts that are
+                                     * reasonable in a given space
+                                     * dimension are offered, of
+                                     * course.
+                                     *
+                                     * In addition, the tag
+                                     * <code>isotropic_refinement</code>
+                                     * denotes isotropic refinement
+                                     * in the space dimension
+                                     * selected by the template
+                                     * argument of this class.
+                                     */
+    enum Possibilities
+    {
+         no_refinement= 0,
+
+         isotropic_refinement = static_cast<unsigned char>(-1)
+    };
+};
+
+
+
+/**
+ * A class that provides possible choices for isotropic and
+ * anisotropic refinement flags in the current space dimension.
+ *
+ * This specialization is used for <code>dim=1</code>, where it offers
+ * refinement in x-direction.
+ *
+ * @ingroup aniso
+ * @author Ralf Hartmann, 2005, Wolfgang Bangerth, 2007
+ */
+template <>
+struct RefinementPossibilities<1>
+{
+                                    /**
+                                     * Possible values for refinement
+                                     * cases in the current
+                                     * dimension.
+                                     *
+                                     * Note the construction of the
+                                     * values: the lowest bit
+                                     * describes a cut of the x-axis,
+                                     * the second to lowest bit
+                                     * corresponds to a cut of the
+                                     * y-axis and the third to lowest
+                                     * bit corresponds to a cut of
+                                     * the z-axis. Thus, the
+                                     * following relations hold
+                                     * (among others):
+                                     *
+                                     * @code
+                                     * cut_xy  == cut_x  | cut_y
+                                     * cut_xyz == cut_xy | cut_xz
+                                     * cut_x   == cut_xy & cut_xz
+                                     * @endcode
+                                     *
+                                     * Only those cuts that are
+                                     * reasonable in a given space
+                                     * dimension are offered, of
+                                     * course.
+                                     *
+                                     * In addition, the tag
+                                     * <code>isotropic_refinement</code>
+                                     * denotes isotropic refinement
+                                     * in the space dimension
+                                     * selected by the template
+                                     * argument of this class.
+                                     */
+    enum Possibilities
+    {
+         no_refinement= 0,
+         cut_x        = 1,
+
+         isotropic_refinement = cut_x
+    };
+};
+
+
+
+/**
+ * A class that provides possible choices for isotropic and
+ * anisotropic refinement flags in the current space dimension.
+ *
+ * This specialization is used for <code>dim=2</code>, where it offers
+ * refinement in x- and y-direction separately, as well as isotropic
+ * refinement in both directions at the same time.
+ *
+ * @ingroup aniso
+ * @author Ralf Hartmann, 2005, Wolfgang Bangerth, 2007
+ */
+template <>
+struct RefinementPossibilities<2>
+{
+                                    /**
+                                     * Possible values for refinement
+                                     * cases in the current
+                                     * dimension.
+                                     *
+                                     * Note the construction of the
+                                     * values: the lowest bit
+                                     * describes a cut of the x-axis,
+                                     * the second to lowest bit
+                                     * corresponds to a cut of the
+                                     * y-axis and the third to lowest
+                                     * bit corresponds to a cut of
+                                     * the z-axis. Thus, the
+                                     * following relations hold
+                                     * (among others):
+                                     *
+                                     * @code
+                                     * cut_xy  == cut_x  | cut_y
+                                     * cut_xyz == cut_xy | cut_xz
+                                     * cut_x   == cut_xy & cut_xz
+                                     * @endcode
+                                     *
+                                     * Only those cuts that are
+                                     * reasonable in a given space
+                                     * dimension are offered, of
+                                     * course.
+                                     *
+                                     * In addition, the tag
+                                     * <code>isotropic_refinement</code>
+                                     * denotes isotropic refinement
+                                     * in the space dimension
+                                     * selected by the template
+                                     * argument of this class.
+                                     */
+    enum Possibilities
+    {
+         no_refinement= 0,
+         cut_x        = 1,
+         cut_y        = 2,
+         cut_xy       = cut_x | cut_y,
+
+         isotropic_refinement = cut_xy
+    };
+};
+
+
+
+/**
+ * A class that provides possible choices for isotropic and
+ * anisotropic refinement flags in the current space dimension.
+ *
+ * This specialization is used for <code>dim=3</code>, where it offers
+ * refinement in x-, y- and z-direction separately, as well as
+ * combinations of these and isotropic refinement in all directions at
+ * the same time.
+ *
+ * @ingroup aniso
+ * @author Ralf Hartmann, 2005, Wolfgang Bangerth, 2007
+ */
+template <>
+struct RefinementPossibilities<3>
+{
+                                    /**
+                                     * Possible values for refinement
+                                     * cases in the current
+                                     * dimension.
+                                     *
+                                     * Note the construction of the
+                                     * values: the lowest bit
+                                     * describes a cut of the x-axis,
+                                     * the second to lowest bit
+                                     * corresponds to a cut of the
+                                     * y-axis and the third to lowest
+                                     * bit corresponds to a cut of
+                                     * the z-axis. Thus, the
+                                     * following relations hold
+                                     * (among others):
+                                     *
+                                     * @code
+                                     * cut_xy  == cut_x  | cut_y
+                                     * cut_xyz == cut_xy | cut_xz
+                                     * cut_x   == cut_xy & cut_xz
+                                     * @endcode
+                                     *
+                                     * Only those cuts that are
+                                     * reasonable in a given space
+                                     * dimension are offered, of
+                                     * course.
+                                     *
+                                     * In addition, the tag
+                                     * <code>isotropic_refinement</code>
+                                     * denotes isotropic refinement
+                                     * in the space dimension
+                                     * selected by the template
+                                     * argument of this class.
+                                     */
+    enum Possibilities
+    {
+         no_refinement= 0,
+         cut_x        = 1,
+         cut_y        = 2,
+         cut_xy       = cut_x | cut_y,
+         cut_z        = 4,
+         cut_xz       = cut_x | cut_z,
+         cut_yz       = cut_y | cut_z,
+         cut_xyz      = cut_x | cut_y | cut_z,
+
+         isotropic_refinement = cut_xyz
+    };
+};
+
+
+
+/**
+ * A class storing the possible anisotropic and isotropic refinement
+ * cases of an object with <code>dim</code> dimensions (for example,
+ * for a line <code>dim=1</code> in whatever space dimension we are,
+ * for a quad <code>dim=2</code>, etc.). Possible values of this class
+ * are the ones listed in the enumeration declared within the class.
+ *
+ * @ingroup aniso
+ * @author Ralf Hartmann, 2005, Wolfgang Bangerth, 2007
+ */
+template <int dim>
+class RefinementCase : public RefinementPossibilities<dim>
+{
+  public:
+                                    /**
+                                     * Constructor. Take and store a
+                                     * value indicating a particular
+                                     * refinement from the list of
+                                     * possible refinements specified
+                                     * in the base class.
+                                     */
+   RefinementCase (const typename RefinementPossibilities<dim>::Possibilities refinement_case);
+
+                                    /**
+                                     * Constructor. Take and store a
+                                     * value indicating a particular
+                                     * refinement as a bit field. To
+                                     * avoid implicit conversions to
+                                     * and from integral values, this
+                                     * constructor is marked as
+                                     * explicit.
+                                     */
+   explicit RefinementCase (const unsigned char refinement_case);
+    
+                                    /**
+                                     * Return the numeric value
+                                     * stored by this class. While
+                                     * the presence of this operator
+                                     * might seem dangerous, it is
+                                     * useful in cases where one
+                                     * would like to have code like
+                                     * <tt>switch
+                                     * (refinement_flag)... case
+                                     * RefinementCase<dim>::cut_x:
+                                     * ... </tt>, which can be
+                                     * written as <code>switch
+                                     * (static_cast@<unsigned
+                                     * char@>(refinement_flag)</code>. Another
+                                     * application is to use an
+                                     * object of the current type as
+                                     * an index into an array;
+                                     * however, this use is
+                                     * deprecated as it assumes a
+                                     * certain mapping from the
+                                     * symbolic flags defined in the
+                                     * RefinementPossibilities base
+                                     * class to actual numerical
+                                     * values (the array indices).
+                                     */
+    operator unsigned char () const;
+
+                                    /**
+                                     * Return the union of the
+                                     * refinement flags represented
+                                     * by the current object and the
+                                     * one given as argument.
+                                     */
+    RefinementCase operator | (const RefinementCase &r) const;
+    
+                                    /**
+                                     * Return the intersection of the
+                                     * refinement flags represented
+                                     * by the current object and the
+                                     * one given as argument.
+                                     */
+    RefinementCase operator & (const RefinementCase &r) const;
+
+                                    /**
+                                     * Return the negation of the
+                                     * refinement flags represented
+                                     * by the current object. For
+                                     * example, in 2d, if the current
+                                     * object holds the flag
+                                     * <code>cut_x</code>, then the
+                                     * returned value will be
+                                     * <code>cut_y</code>; if the
+                                     * current value is
+                                     * <code>isotropic_refinement</code>
+                                     * then the result will be
+                                     * <code>no_refinement</code>;
+                                     * etc.
+                                     */
+    RefinementCase operator ~ () const;
+
+
+                                    /**
+                                     * Return the flag that
+                                     * corresponds to cutting a cell
+                                     * along the axis given as
+                                     * argument. For example, if
+                                     * <code>i=0</code> then the
+                                     * returned value is
+                                     * <tt>RefinementPossibilities<dim>::cut_x</tt>.
+                                     */
+    static
+    RefinementCase cut_axis (const unsigned int i);
+    
+                                    /**
+                                     * Return the amount of memory
+                                     * occupied by an object of this
+                                     * type.
+                                     */
+    static unsigned int memory_consumption ();
+
+                                    /**
+                                     * Exception.
+                                     */
+    DeclException1 (ExcInvalidRefinementCase,
+                   int,
+                   << "The refinement flags given (" << arg1 << ") contain set bits that do not "
+                   << "make sense for the space dimension of the object to which they are applied.");
+    
+  private:
+                                    /**
+                                     * Store the refinement case as a
+                                     * bit field with as many bits as
+                                     * are necessary in any given
+                                     * dimension.
+                                     */
+    unsigned char value : (dim > 0 ? dim : 1);
+};
+
+
+
+namespace internal
+{
+
+
+/**
+ * A class that provides all possible situations a face (in the
+ * current space dimension @p dim) might be subdivided into
+ * subfaces. For <code>dim=1</code> and <code>dim=2</code> they
+ * correspond to the cases given in
+ * <code>RefinementPossibilities@<dim-1@></code>. However,
+ * <code>SubfacePossibilities@<3@></code> includes the refinement
+ * cases of <code>RefinementPossibilities@<2@></code>, but
+ * additionally some subface possibilities a face might be subdivided
+ * into which occur through repeated anisotropic refinement steps
+ * performed on one of two neighboring cells.
+ *
+ * This general template is unused except in some weird template
+ * constructs. Actual is made, however, of the specializations
+ * <code>SubfacePossibilities@<1@></code>,
+ * <code>SubfacePossibilities@<2@></code> and
+ * <code>SubfacePossibilities@<3@></code>.
+ *
+ * @ingroup aniso
+ * @author Tobias Leicht 2007, Ralf Hartmann, 2008
+ */
+  template <int dim>
+  struct SubfacePossibilities
+  {
+                                      /**
+                                       * Possible cases of faces
+                                       * being subdivided into
+                                       * subface.
+                                       */
+      enum Possibilities
+      {
+           case_none = 0,
+
+           case_isotropic = static_cast<unsigned char>(-1)
+      };
+  };
+
+
+/**
+ * A class that provides all possible situations a face (in the
+ * current space dimension @p dim) might be subdivided into
+ * subfaces.
+ *
+ * For <code>dim=0</code> we provide a dummy implementation only.
+ *
+ * @ingroup aniso
+ * @author Ralf Hartmann, 2008
+ */
+  template <>
+  struct SubfacePossibilities<0>
+  {
+                                      /**
+                                       * Possible cases of faces
+                                       * being subdivided into
+                                       * subface.
+                                       *
+                                       * Dummy implementation.
+                                       */
+      enum Possibilities
+      {
+           case_none = 0,
+
+           case_isotropic = case_none
+      };
+  };
+
+
+
+/**
+ * A class that provides all possible situations a face (in the
+ * current space dimension @p dim) might be subdivided into
+ * subfaces.
+ *
+ * For <code>dim=1</code> there are no faces. Thereby, there are no
+ * subface possibilities.
+ *
+ * @ingroup aniso
+ * @author Ralf Hartmann, 2008
+ */
+  template <>
+  struct SubfacePossibilities<1>
+  {
+                                      /**
+                                       * Possible cases of faces
+                                       * being subdivided into
+                                       * subface.
+                                       *
+                                       * In 1d there are no faces,
+                                       * thus no subface
+                                       * possibilities.
+                                       */
+      enum Possibilities
+      {
+           case_none = 0,
+
+           case_isotropic = case_none
+      };
+  };
+
+
+
+/**
+ * A class that provides all possible situations a face (in the
+ * current space dimension @p dim) might be subdivided into
+ * subfaces.
+ *
+ * This specialization is used for <code>dim=2</code>, where it offers
+ * the following possibilities: a face (line) being refined
+ * (<code>case_x</code>) or not refined (<code>case_no</code>).
+ *
+ * @ingroup aniso
+ * @author Ralf Hartmann, 2008
+ */
+  template <>
+  struct SubfacePossibilities<2>
+  {
+                                      /**
+                                       * Possible cases of faces
+                                       * being subdivided into
+                                       * subface.
+                                       *
+                                       * In 2d there are following
+                                       * possibilities: a face (line)
+                                       * being refined *
+                                       * (<code>case_x</code>) or not
+                                       * refined
+                                       * (<code>case_no</code>).
+                                      */
+      enum Possibilities
+      {
+           case_none = 0,
+           case_x    = 1,
+
+           case_isotropic = case_x
+      };
+  };
+
+
+
+/**
+ * A class that provides all possible situations a face (in the
+ * current space dimension @p dim) might be subdivided into
+ * subfaces.
+ *
+ * This specialization is used for dim=3, where it offers following
+ * possibilities: a face (quad) being refined in x- or y-direction (in
+ * the face-intern coordinate system) separately, (<code>case_x</code>
+ * or (<code>case_y</code>), and in both directions
+ * (<code>case_x</code> which corresponds to
+ * (<code>case_isotropic</code>). Additionally, it offers the
+ * possibilities a face can have through repeated anisotropic
+ * refinement steps performed on one of the two neighboring cells.  It
+ * might be possible for example, that a face (quad) is refined with
+ * <code>cut_x</code> and afterwards the left child is again refined
+ * with <code>cut_y</code>, so that there are three active
+ * subfaces. Note, however, that only refinement cases are allowed
+ * such that each line on a face between two hexes has not more than
+ * one hanging node. Furthermore, it is not allowed that two
+ * neighboring hexes are refined such that one of the hexes refines
+ * the common face with <code>cut_x</code> and the other hex refines
+ * that face with <code>cut_y</code>. In fact,
+ * Triangulation::prepare_coarsening_and_refinement takes care of this
+ * situation and ensures that each face of a refined cell is
+ * completely contained in a single face of neighboring cells.
+ *
+ * The following drawings explain the SubfacePossibilities and give
+ * the corresponding subface numbers:
+ * @code
+
+ *-------*
+ |       |
+ |   0   |    case_none
+ |       |
+ *-------*
+ *---*---*
+ |   |   |
+ | 0 | 1 |    case_x
+ |   |   |
+ *---*---*
+ *---*---*
+ | 1 |   |
+ *---* 2 |    case_x1y
+ | 0 |   |
+ *---*---*
+ *---*---*
+ |   | 2 |
+ | 0 *---*    case_x2y
+ |   | 1 |
+ *---*---*
+ *---*---*
+ | 1 | 3 |
+ *---*---*    case_x1y2y   (successive refinement: first cut_x, then cut_y for both children)
+ | 0 | 2 |
+ *---*---*
+ *-------*
+ |   1   |
+ *-------*    case_y
+ |   0   |
+ *-------*
+ *-------*
+ |   2   |
+ *---*---*    case_y1x
+ | 0 | 1 |
+ *---*---*
+ *---*---*
+ | 1 | 2 |
+ *---*---*    case_y2x
+ |   0   |
+ *-------*
+ *---*---*
+ | 2 | 3 |
+ *---*---*    case_y1x2x   (successive refinement: first cut_y, then cut_x for both children)
+ | 0 | 1 |
+ *---+---*
+ *---*---*
+ | 2 | 3 |
+ *---*---*    case_xy      (one isotropic refinement step)
+ | 0 | 1 |
+ *---*---*
+
+ * @endcode
+ *
+ * @ingroup aniso
+ * @author Tobias Leicht 2007, Ralf Hartmann, 2008
+ */
+  template <>
+  struct SubfacePossibilities<3>
+  {
+                                      /**
+                                       * Possible cases of faces
+                                       * being subdivided into
+                                       * subface.
+                                       *
+                                       * See documentation to the
+                                       * SubfacePossibilities<3> for
+                                       * more details on the subface
+                                       * possibilities.
+                                       */
+      enum Possibilities
+      {
+           case_none  = 0,
+           case_x     = 1,
+           case_x1y   = 2,
+           case_x2y   = 3,
+           case_x1y2y = 4,
+           case_y     = 5,
+           case_y1x   = 6,
+           case_y2x   = 7,
+           case_y1x2x = 8,
+           case_xy    = 9,
+
+           case_isotropic = case_xy
+      };
+  };
+
+
+
+
+/**
+ * A class that provides all possible cases a face (in the
+ * current space dimension @p dim) might be subdivided into
+ * subfaces.
+ *
+ * @ingroup aniso
+ * @author Ralf Hartmann, 2008
+ */
+  template <int dim>
+  class SubfaceCase : public SubfacePossibilities<dim>
+  {
+    public:
+                                      /**
+                                       * Constructor. Take and store
+                                       * a value indicating a
+                                       * particular subface
+                                       * possibility in the list of
+                                       * possible situations
+                                       * specified in the base class.
+                                       */
+      SubfaceCase (const typename SubfacePossibilities<dim>::Possibilities subface_possibility);
+    
+                                      /**
+                                       * Return the numeric value
+                                       * stored by this class. While
+                                       * the presence of this operator
+                                       * might seem dangerous, it is
+                                       * useful in cases where one
+                                       * would like to have code like
+                                       * <code>switch
+                                       * (subface_case)... case
+                                       * SubfaceCase@<dim@>::case_x:
+                                       * ... </code>, which can be
+                                       * written as <code>switch
+                                       * (static_cast@<unsigned
+                                       * char@>(subface_case)</code>. Another
+                                       * application is to use an
+                                       * object of the current type as
+                                       * an index into an array;
+                                       * however, this use is
+                                       * deprecated as it assumes a
+                                       * certain mapping from the
+                                       * symbolic flags defined in the
+                                       * SubfacePossibilities
+                                       * base class to actual numerical
+                                       * values (the array indices).
+                                       */
+      operator unsigned char () const;
+    
+                                      /**
+                                       * Return the amount of memory
+                                       * occupied by an object of this
+                                       * type.
+                                       */
+      static unsigned int memory_consumption ();
+
+                                      /**
+                                       * Exception.
+                                       */
+      DeclException1 (ExcInvalidSubfaceCase,
+                     int,
+                     << "The subface case given (" << arg1 << ") does not make sense "
+                     << "for the space dimension of the object to which they are applied.");
+    
+    private:
+                                      /**
+                                       * Store the refinement case as a
+                                       * bit field with as many bits as
+                                       * are necessary in any given
+                                       * dimension.
+                                       */
+      unsigned char value : (dim == 3 ? 4 : 1);
+  };
+  
+} // namespace internal
+
+
+
 template <int dim> class GeometryInfo;
 
 
@@ -35,35 +765,50 @@ template <int dim> class GeometryInfo;
  * This class contains as static members information on vertices and
  * faces of a @p dim-dimensional grid cell. The interface is the same
  * for all dimensions. If a value is of no use in a low dimensional
- * cell, it is (correctly) set to zero, e.g. #subfaces_per_face in
+ * cell, it is (correctly) set to zero, e.g. #max_children_per_face in
  * 1d.
  *
  * This information should always replace hard-coded numbers of
  * vertices, neighbors and so on, since it can be used dimension
  * independently.
  *
- * @ingroup grid geomprimitives
+ * @ingroup grid geomprimitives aniso
  * @author Wolfgang Bangerth, 1998
  */
 template <>
 struct GeometryInfo<0> 
 {
 
-                                    /**
-                                     * Number of children a cell has.
-                                     */
-    static const unsigned int children_per_cell = 1;
+                                     /**
+                                      * Maximum number of children of
+                                      * a cell, i.e. the number of
+                                      * children of an isotropically
+                                      * refined cell.
+                                     *
+                                     * If a cell is refined
+                                     * anisotropically, the actual
+                                     * number of children may be less
+                                     * than the value given here.
+                                      */
+    static const unsigned int max_children_per_cell = 1;
 
                                     /**
                                      * Number of faces a cell has.
                                      */
     static const unsigned int faces_per_cell    = 0;
 
-                                    /**
-                                     * Number of children each face has
-                                     * when the adjacent cell is refined.
-                                     */
-    static const unsigned int subfaces_per_face = 0;
+                                     /**
+                                      * Maximum number of children of
+                                      * a refined face, i.e. the
+                                      * number of children of an
+                                      * isotropically refined face.
+                                     *
+                                     * If a cell is refined
+                                     * anisotropically, the actual
+                                     * number of children may be less
+                                     * than the value given here.
+                                      */
+    static const unsigned int max_children_per_face = 0;
 
                                     /**
                                      * Number of vertices a cell has.
@@ -451,19 +1196,20 @@ struct GeometryInfo<0>
  *
  * <h4>Children</h4>
  *
- * The eight children of a cell are numbered according to the vertices they
- * are adjacent to:
+ * The eight children of an isotropically refined cell are numbered according to
+ * the vertices they are adjacent to:
  * @verbatim
- *       *-------*        *-------*
- *      /| 6   7 |       / 6   7 /|
- *     /6|       |      /       /7|
- *    /  |       |     / 4   5 /  |
- *   *   | 2   3 |    *-------*5 3|
- *   |4 2*-------*    | 4   5 |   *
- *   |  / 2   3 /     |       |  /
- *   |0/       /      |       |1/
- *   |/0    1 /       | 0   1 |/
- *   *-------*        *-------*
+ *       *----*----*        *----*----*
+ *      /| 6  |  7 |       / 6  /  7 /|
+ *     *6|    |    |      *----*----*7|
+ *    /| *----*----*     / 4  /  5 /| *
+ *   * |/|    |    |    *----*----* |/|
+ *   |4* | 2  |  3 |    | 4  |  5 |5*3|
+ *   |/|2*----*----*    |    |    |/| *
+ *   * |/ 2  /  3 /     *----*----* |/
+ *   |0*----*----*      |    |    |1*
+ *   |/0   /  1 /       | 0  |  1 |/
+ *   *----*----*        *----*----*
  * @endverbatim
  *
  * Taking into account the orientation of the faces, the following
@@ -503,6 +1249,107 @@ struct GeometryInfo<0>
  * orientation as additional argument to
  * <tt>GeometryInfo<3>::child_cell_on_face</tt>).
  *
+ * For anisotropic refinement, the child cells can not be numbered according to
+ * adjacent vertices, thus the following conventions are used:
+ * @verbatim
+ *            RefinementCase<3>::cut_x
+ *
+ *       *----*----*        *----*----*
+ *      /|    |    |       /    /    /|
+ *     / |    |    |      / 0  /  1 / |
+ *    /  | 0  |  1 |     /    /    /  |
+ *   *   |    |    |    *----*----*   |
+ *   | 0 |    |    |    |    |    | 1 |
+ *   |   *----*----*    |    |    |   *
+ *   |  /    /    /     | 0  | 1  |  /
+ *   | / 0  /  1 /      |    |    | /
+ *   |/    /    /       |    |    |/
+ *   *----*----*        *----*----*
+ * @endverbatim
+ *
+ * @verbatim
+ *            RefinementCase<3>::cut_y
+ *
+ *       *---------*        *---------*
+ *      /|         |       /    1    /|
+ *     * |         |      *---------* |
+ *    /| |    1    |     /    0    /| |
+ *   * |1|         |    *---------* |1|
+ *   | | |         |    |         | | |
+ *   |0| *---------*    |         |0| *
+ *   | |/    1    /     |    0    | |/
+ *   | *---------*      |         | *
+ *   |/    0    /       |         |/
+ *   *---------*        *---------*
+ * @endverbatim
+ *
+ * @verbatim
+ *            RefinementCase<3>::cut_z
+ *
+ *       *---------*        *---------*
+ *      /|    1    |       /         /|
+ *     / |         |      /    1    / |
+ *    /  *---------*     /         /  *
+ *   * 1/|         |    *---------* 1/|
+ *   | / |    0    |    |    1    | / |
+ *   |/  *---------*    |         |/  *
+ *   * 0/         /     *---------* 0/
+ *   | /    0    /      |         | /
+ *   |/         /       |    0    |/
+ *   *---------*        *---------*
+ * @endverbatim
+ *
+ * @verbatim
+ *            RefinementCase<3>::cut_xy
+ *
+ *       *----*----*        *----*----*
+ *      /|    |    |       / 2  /  3 /|
+ *     * |    |    |      *----*----* |
+ *    /| | 2  |  3 |     / 0  /  1 /| |
+ *   * |2|    |    |    *----*----* |3|
+ *   | | |    |    |    |    |    | | |
+ *   |0| *----*----*    |    |    |1| *
+ *   | |/ 2  /  3 /     | 0  |  1 | |/
+ *   | *----*----*      |    |    | *
+ *   |/ 0  /  1 /       |    |    |/
+ *   *----*----*        *----*----*
+ * @endverbatim
+ *
+ * @verbatim
+ *            RefinementCase<3>::cut_xz
+ *
+ *       *----*----*        *----*----*
+ *      /| 1  |  3 |       /    /    /|
+ *     / |    |    |      / 1  /  3 / |
+ *    /  *----*----*     /    /    /  *
+ *   * 1/|    |    |    *----*----* 3/|
+ *   | / | 0  |  2 |    | 1  |  3 | / |
+ *   |/  *----*----*    |    |    |/  *
+ *   * 0/    /    /     *----*----* 2/
+ *   | / 0  /  2 /      |    |    | /
+ *   |/    /    /       | 0  |  2 |/
+ *   *----*----*        *----*----*
+ * @endverbatim
+ *
+ * @verbatim
+ *            RefinementCase<3>::cut_yz
+ *
+ *       *---------*        *---------*
+ *      /|    3    |       /    3    /|
+ *     * |         |      *---------* |
+ *    /|3*---------*     /    2    /|3*
+ *   * |/|         |    *---------* |/|
+ *   |2* |    1    |    |    2    |2* |
+ *   |/|1*---------*    |         |/|1*
+ *   * |/    1    /     *---------* |/
+ *   |0*---------*      |         |0*
+ *   |/    0    /       |    0    |/
+ *   *---------*        *---------*
+ * @endverbatim
+ *
+ * This information can also be obtained by the
+ * <tt>GeometryInfo<3>::child_cell_on_face</tt> function.
+ *
  * <h4>Coordinate systems</h4>
  *
  * We define the following coordinate system for the explicit coordinates of
@@ -539,28 +1386,43 @@ struct GeometryInfo<0>
  * and there is a specialization for dim=0 (see the section on @ref
  * Instantiations in the manual).
  *
- * @ingroup grid geomprimitives
+ * @ingroup grid geomprimitives aniso
  * @author Wolfgang Bangerth, 1998, Ralf Hartmann, 2005, Tobias Leicht, 2007
  */
 template <int dim>
 struct GeometryInfo
 {
     
-                                    /**
-                                     * Number of children of a refined cell.
-                                     */
-    static const unsigned int children_per_cell = 1 << dim;
+                                     /**
+                                      * Maximum number of children of
+                                      * a refined cell, i.e. the
+                                      * number of children of an
+                                      * isotropically refined cell.
+                                     *
+                                     * If a cell is refined
+                                     * anisotropically, the actual
+                                     * number of children may be less
+                                     * than the value given here.
+                                      */
+    static const unsigned int max_children_per_cell = 1 << dim;
 
                                     /**
                                      * Number of faces of a cell.
                                      */
     static const unsigned int faces_per_cell = 2 * dim;
 
-                                    /**
-                                     * Number of children each face has
-                                     * when the adjacent cell is refined.
-                                     */
-    static const unsigned int subfaces_per_face = GeometryInfo<dim-1>::children_per_cell;
+                                     /**
+                                      * Maximum number of children of
+                                      * a refined face, i.e. the
+                                      * number of children of an
+                                      * isotropically refined face.
+                                     *
+                                     * If a cell is refined
+                                     * anisotropically, the actual
+                                     * number of children may be less
+                                     * than the value given here.
+                                      */
+    static const unsigned int max_children_per_face = GeometryInfo<dim-1>::max_children_per_cell;
 
                                     /**
                                      * Number of vertices of a cell.
@@ -672,7 +1534,6 @@ struct GeometryInfo
                                      */
     static const unsigned int dx_to_deal[vertices_per_cell];
 
-
                                      /**
                                      * This field stores for each vertex
                                       * to which faces it belongs. In any
@@ -684,7 +1545,88 @@ struct GeometryInfo
                                       * the vertex belongs
                                       */
     static const unsigned int vertex_to_face[vertices_per_cell][dim];
-   
+                                    /**
+                                     * Return the number of children
+                                     * of a cell (or face) refined
+                                     * with <tt>ref_case</tt>.
+                                     */
+    static unsigned int n_children(const RefinementCase<dim> &refinement_case);
+
+                                    /**
+                                     * Return the number of subfaces
+                                     * of a face refined according to
+                                     * internal::SubfaceCase
+                                     * @p face_ref_case.
+                                     */
+    static unsigned int n_subfaces(const internal::SubfaceCase<dim> &subface_case);
+
+                                    /**
+                                     * Given a face on the reference
+                                     * element with a
+                                     * <code>internal::SubfaceCase@<dim@></code>
+                                     * @p face_refinement_case this
+                                     * function returns the ratio
+                                     * between the area of the @p
+                                     * subface_no th subface and the
+                                     * area(=1) of the face.
+                                     *
+                                     * E.g. for
+                                     * <code>internal::SubfaceCase@<3@>::cut_xy</code>
+                                     * the ratio is 1/4 for each of
+                                     * the subfaces.
+                                     */
+    static double subface_ratio(const internal::SubfaceCase<dim> &subface_case,
+                               const unsigned int subface_no);
+
+                                    /**
+                                     * Given a cell refined with the
+                                     * <code>RefinementCase</code>
+                                     * @p cell_refinement_case
+                                     * return the
+                                     * <code>SubfaceCase</code> of
+                                     * the @p face_no th face.
+                                     */
+    static RefinementCase<dim-1> face_refinement_case(
+      const RefinementCase<dim> &cell_refinement_case,
+      const unsigned int face_no,
+      const bool face_orientation = true,
+      const bool face_flip        = false,
+      const bool face_rotation    = false);
+
+                                    /**
+                                     * Given the SubfaceCase @p
+                                     * face_refinement_case of the @p
+                                     * face_no th face, return the
+                                     * smallest RefinementCase of the
+                                     * cell, which corresponds to
+                                     * that refinement of the face.
+                                     */
+    static RefinementCase<dim> min_cell_refinement_case_for_face_refinement(
+      const RefinementCase<dim-1> &face_refinement_case,
+      const unsigned int face_no,
+      const bool face_orientation = true,
+      const bool face_flip        = false,
+      const bool face_rotation    = false);
+
+                                    /**
+                                     * Given a cell refined with the
+                                     * RefinementCase @p
+                                     * cell_refinement_case return
+                                     * the RefinementCase of the @p
+                                     * line_no th face.
+                                     */
+    static RefinementCase<1> line_refinement_case(const RefinementCase<dim> &cell_refinement_case,
+                                                 const unsigned int line_no);
+
+                                    /**
+                                     * Return the minimal / smallest
+                                     * RefinementCase of the cell, which
+                                     * ensures refinement of line
+                                     * @p line_no.
+                                     */
+    static RefinementCase<dim> min_cell_refinement_case_for_line_refinement(const unsigned int line_no);
+
                                      /**
                                      * This field stores which child
                                      * cells are adjacent to a
@@ -740,12 +1682,23 @@ struct GeometryInfo
                                      * face orientations is explained in this
                                      * @ref GlossFaceOrientation "glossary"
                                      * entry.
+                                     *
+                                     * In the case of anisotropically refined
+                                     * cells and faces, the @p RefineCase of
+                                     * the face, <tt>face_ref_case</tt>,
+                                     * might have an influence on 
+                                     * which child is behind which given
+                                     * subface, thus this is an additional
+                                     * argument, defaulting to isotropic
+                                     * refinement of the face.
                                      */
-    static unsigned int child_cell_on_face (const unsigned int face,
+    static unsigned int child_cell_on_face (const RefinementCase<dim> &ref_case,
+                                           const unsigned int face,
                                            const unsigned int subface,
                                            const bool face_orientation = true,
                                            const bool face_flip        = false,
-                                           const bool face_rotation    = false);
+                                           const bool face_rotation    = false,
+                                           const RefinementCase<dim-1> &face_refinement_case = RefinementCase<dim-1>::isotropic_refinement);
     
                                     /**
                                      * Map line vertex number to cell
@@ -921,7 +1874,7 @@ struct GeometryInfo
                                      * children, return any one of
                                      * their indices. The result is
                                      * always less than
-                                     * GeometryInfo<dimension>::children_per_cell.
+                                     * GeometryInfo<dimension>::max_children_per_cell.
                                      *
                                      * The order of child cells is described
                                      * the general documentation of this
@@ -944,7 +1897,7 @@ struct GeometryInfo
                                      * child.
                                      */
     static Point<dim> cell_to_child_coordinates (const Point<dim>    &p,
-                                                const unsigned int child_index);
+                                                const unsigned int   child_index);
 
                                     /**
                                      * The reverse function to the
@@ -1076,6 +2029,14 @@ struct GeometryInfo
                    double,
                    << "The coordinates must satisfy 0 <= x_i <= 1, "
                    << "but here we have x_i=" << arg1);
+            
+                                     /**
+                                      * Exception
+                                      */
+    DeclException3 (ExcInvalidSubface,
+                    int, int, int,
+                    << "RefinementCase<dim> " << arg1 << ": face " << arg2
+                    << " has no subface " << arg3);
 };
 
 
@@ -1116,6 +2077,165 @@ const unsigned int GeometryInfo<4>::opposite_face[faces_per_cell];
 
 /* -------------- inline functions ------------- */
 
+namespace internal
+{
+
+  template <int dim>
+  inline
+  SubfaceCase<dim>::SubfaceCase (const typename SubfacePossibilities<dim>::Possibilities subface_possibility)
+                 :
+                 value (subface_possibility)
+  {}
+  
+  
+  template <int dim>
+  inline
+  SubfaceCase<dim>::operator unsigned char () const
+  {
+    return value;
+  }
+  
+  
+} // namespace internal
+  
+
+template <int dim>
+inline
+RefinementCase<dim>
+RefinementCase<dim>::cut_axis (const unsigned int)
+{
+  Assert (false, ExcInternalError());
+  return static_cast<unsigned char>(-1);
+}
+
+
+template <>
+inline
+RefinementCase<1>
+RefinementCase<1>::cut_axis (const unsigned int i)
+{
+  const unsigned int dim = 1;
+  Assert (i < dim, ExcIndexRange(i, 0, dim));
+
+  static const RefinementCase options[dim] = { cut_x };
+  return options[i];
+}
+
+
+
+template <>
+inline
+RefinementCase<2>
+RefinementCase<2>::cut_axis (const unsigned int i)
+{
+  const unsigned int dim = 2;
+  Assert (i < dim, ExcIndexRange(i, 0, dim));
+
+  static const RefinementCase options[dim] = { cut_x, cut_y };
+  return options[i];
+}
+
+
+
+template <>
+inline
+RefinementCase<3>
+RefinementCase<3>::cut_axis (const unsigned int i)
+{
+  const unsigned int dim = 3;
+  Assert (i < dim, ExcIndexRange(i, 0, dim));
+
+  static const RefinementCase options[dim] = { cut_x, cut_y, cut_z };
+  return options[i];
+}
+
+
+
+template <int dim>
+inline
+RefinementCase<dim>::RefinementCase (const typename RefinementPossibilities<dim>::Possibilities refinement_case)
+               :
+               value (refinement_case)
+{
+                                  // check that only those bits of
+                                  // the given argument are set that
+                                  // make sense for a given space
+                                  // dimension
+  Assert ((refinement_case & RefinementPossibilities<dim>::isotropic_refinement) ==
+         refinement_case,
+         ExcInvalidRefinementCase (refinement_case));
+}
+
+
+
+template <int dim>
+inline
+RefinementCase<dim>::RefinementCase (const unsigned char refinement_case)
+               :
+               value (refinement_case)
+{
+                                  // check that only those bits of
+                                  // the given argument are set that
+                                  // make sense for a given space
+                                  // dimension
+  Assert ((refinement_case & RefinementPossibilities<dim>::isotropic_refinement) ==
+         refinement_case,
+         ExcInvalidRefinementCase (refinement_case));
+}
+
+
+
+template <int dim>
+inline
+RefinementCase<dim>::operator unsigned char () const
+{
+  return value;
+}
+
+
+
+template <int dim>
+inline
+RefinementCase<dim>
+RefinementCase<dim>::operator | (const RefinementCase<dim> &r) const
+{
+  return RefinementCase<dim>(value | r.value);
+}
+
+
+
+template <int dim>
+inline
+RefinementCase<dim>
+RefinementCase<dim>::operator & (const RefinementCase<dim> &r) const
+{
+  return RefinementCase<dim>(value & r.value);
+}
+
+
+
+template <int dim>
+inline
+RefinementCase<dim>
+RefinementCase<dim>::operator ~ () const
+{
+  return RefinementCase<dim>((~value) & RefinementPossibilities<dim>::isotropic_refinement);
+}
+
+
+
+
+template <int dim>
+inline
+unsigned int
+RefinementCase<dim>::memory_consumption ()
+{
+  return sizeof(RefinementCase<dim>);
+}
+
+
+
+
 
 template <>
 inline
@@ -1232,8 +2352,8 @@ Point<dim>
 GeometryInfo<dim>::cell_to_child_coordinates (const Point<dim>    &p,
                                              const unsigned int child_index)
 {
-  Assert (child_index < GeometryInfo<dim>::children_per_cell,
-         ExcIndexRange (child_index, 0, GeometryInfo<dim>::children_per_cell));
+  Assert (child_index < GeometryInfo<dim>::max_children_per_cell,
+         ExcIndexRange (child_index, 0, GeometryInfo<dim>::max_children_per_cell));
 
   return 2*p - unit_cell_vertex(child_index);
 }
@@ -1246,8 +2366,8 @@ Point<dim>
 GeometryInfo<dim>::child_to_cell_coordinates (const Point<dim>    &p,
                                              const unsigned int child_index)
 {
-  Assert (child_index < GeometryInfo<dim>::children_per_cell,
-         ExcIndexRange (child_index, 0, GeometryInfo<dim>::children_per_cell));
+  Assert (child_index < GeometryInfo<dim>::max_children_per_cell,
+         ExcIndexRange (child_index, 0, GeometryInfo<dim>::max_children_per_cell));
 
   return (p + unit_cell_vertex(child_index))/2;
 }
@@ -1320,6 +2440,7 @@ GeometryInfo<3>::is_inside_unit_cell (const Point<3> &p,
         (p[2] >= l) && (p[2] <= u);
 }
 
+
 #endif // DOXYGEN
 DEAL_II_NAMESPACE_CLOSE
 
index df3fdb3c72c9612c88e55c7ed2dcfb5fbd971a6e..16339e32d3df9899e3abc0b1ab4519f93396b109 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 2005, 2006 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
@@ -15,6 +15,7 @@
 
 
 #include <base/quadrature.h>
+#include <base/geometry_info.h>
 
 DEAL_II_NAMESPACE_OPEN
 /*!@addtogroup Quadrature */
@@ -107,28 +108,34 @@ class QProjector
                     const unsigned int      face_no);
 
                                     /**
-                                     * Compute the quadrature points
-                                     * on the cell if the given
-                                     * quadrature formula is used on
-                                     * face <tt>face_no</tt>, subface
-                                     * number <tt>subface_no</tt>.
+                                     * Compute the quadrature points on the
+                                     * cell if the given quadrature formula is
+                                     * used on face <tt>face_no</tt>, subface
+                                     * number <tt>subface_no</tt> corresponding
+                                     * to RefineCase::Type
+                                     * <tt>ref_case</tt>. The last argument is
+                                     * only used in 3D.
                                      *
                                      * @note Only the points are
                                      * transformed. The quadrature
                                      * weights are the same as those
                                      * of the original rule.
                                      */
-    static void project_to_subface (const SubQuadrature &quadrature,
-                                   const unsigned int   face_no,
-                                   const unsigned int   subface_no,
-                                   std::vector<Point<dim> > &q_points);
+    static void project_to_subface (const SubQuadrature       &quadrature,
+                                   const unsigned int         face_no,
+                                   const unsigned int         subface_no,
+                                   std::vector<Point<dim> >  &q_points,
+                                   const RefinementCase<dim-1> &ref_case=RefinementCase<dim-1>::isotropic_refinement);
 
                                     /**
-                                     * Compute the cell quadrature
-                                     * formula corresponding to using
+                                     * Compute the cell quadrature formula
+                                     * corresponding to using
                                      * <tt>quadrature</tt> on subface
                                      * <tt>subface_no</tt> of face
-                                     * <tt>face_no</tt>.
+                                     * <tt>face_no</tt> with
+                                     * RefinementCase<dim-1>
+                                     * <tt>ref_case</tt>. The last argument is
+                                     * only used in 3D.
                                      *
                                      * @note Only the points are
                                      * transformed. The quadrature
@@ -136,9 +143,10 @@ class QProjector
                                      * of the original rule.
                                      */
     static Quadrature<dim>
-    project_to_subface (const SubQuadrature &quadrature,
-                       const unsigned int      face_no,
-                       const unsigned int   subface_no);
+    project_to_subface (const SubQuadrature       &quadrature,
+                       const unsigned int         face_no,
+                       const unsigned int         subface_no,
+                       const RefinementCase<dim-1> &ref_case=RefinementCase<dim-1>::isotropic_refinement);
 
                                     /**
                                      * Take a face quadrature formula
@@ -317,7 +325,7 @@ class QProjector
                                           * ignored if the space dimension
                                           * equals 2.
                                           *
-                                          * The last argument denotes
+                                          * The last but one argument denotes
                                           * the number of quadrature
                                           * points the
                                           * lower-dimensional face
@@ -325,6 +333,10 @@ class QProjector
                                           * one that has been
                                           * projected onto the faces)
                                           * has.
+                                         *
+                                         * Through the last argument
+                                         * anisotropic refinement can be
+                                         * respected.
                                           */
         static
         DataSetDescriptor
@@ -333,7 +345,8 @@ class QProjector
                  const bool         face_orientation,
                  const bool         face_flip,
                  const bool         face_rotation,
-                 const unsigned int n_quadrature_points);
+                 const unsigned int n_quadrature_points,
+                const internal::SubfaceCase<dim> ref_case=internal::SubfaceCase<dim>::case_isotropic);
 
                                          /**
                                           * Conversion operator to an
@@ -438,19 +451,22 @@ void
 QProjector<1>::project_to_subface (const Quadrature<0> &,
                                    const unsigned int,
                                    const unsigned int,
-                                   std::vector<Point<1> > &);
+                                   std::vector<Point<1> > &,
+                                  const RefinementCase<0> &);
 template <>
 void
 QProjector<2>::project_to_subface (const Quadrature<1>    &quadrature,
                                    const unsigned int      face_no,
                                    const unsigned int      subface_no,
-                                   std::vector<Point<2> > &q_points);
+                                   std::vector<Point<2> > &q_points,
+                                  const RefinementCase<1> &);
 template <>
 void
-QProjector<3>::project_to_subface (const Quadrature<2>    &quadrature,
-                                   const unsigned int      face_no,
-                                   const unsigned int      subface_no,
-                                   std::vector<Point<3> > &q_points);
+QProjector<3>::project_to_subface (const Quadrature<2>       &quadrature,
+                                   const unsigned int         face_no,
+                                   const unsigned int         subface_no,
+                                   std::vector<Point<3> >    &q_points,
+                                  const RefinementCase<2> &face_ref_case);
 
 template <>
 Quadrature<1>
index 0e006ca5c4d3ad8c45b75716fa2297810d6e1997..2b5ffb638d3f1ac8f23acc2502791b88ee82e028 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 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
@@ -17,9 +17,9 @@
 DEAL_II_NAMESPACE_OPEN
 
 
-template <int dim> const unsigned int GeometryInfo<dim>::children_per_cell;
+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>::subfaces_per_face;
+template <int dim> const unsigned int GeometryInfo<dim>::max_children_per_face;
 template <int dim> const unsigned int GeometryInfo<dim>::vertices_per_cell;
 template <int dim> const unsigned int GeometryInfo<dim>::vertices_per_face;
 template <int dim> const unsigned int GeometryInfo<dim>::lines_per_face;
@@ -131,21 +131,21 @@ const unsigned int GeometryInfo<3>::ucd_to_deal[GeometryInfo<3>::vertices_per_ce
 template <>
 const unsigned int GeometryInfo<4>::ucd_to_deal[GeometryInfo<4>::vertices_per_cell]
 = {  invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int};
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int};
 
 
 template <>
@@ -163,21 +163,21 @@ const unsigned int GeometryInfo<3>::dx_to_deal[GeometryInfo<3>::vertices_per_cel
 template <>
 const unsigned int GeometryInfo<4>::dx_to_deal[GeometryInfo<4>::vertices_per_cell]
 = {  invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int,
-       invalid_unsigned_int};
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int,
+     invalid_unsigned_int};
 
 template <>
 const unsigned int GeometryInfo<1>::vertex_to_face
@@ -226,6 +226,473 @@ const unsigned int GeometryInfo<4>::vertex_to_face
     { invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int }};
 
 
+template<int dim>
+unsigned int
+GeometryInfo<dim>::n_children(const RefinementCase<dim> &ref_case)
+{
+  static const unsigned int n_children[RefinementCase<3>::cut_xyz+1]=
+    {0, 2, 2, 4, 2, 4, 4, 8};
+
+  return n_children[ref_case];
+}
+
+
+template<>
+unsigned int
+GeometryInfo<1>::n_subfaces(const internal::SubfaceCase<1> &)
+{
+  Assert(false, ExcImpossibleInDim(1));
+  return 0;
+}
+
+
+
+template<>
+unsigned int
+GeometryInfo<2>::n_subfaces(const internal::SubfaceCase<2> &subface_case)
+{
+  return (subface_case == internal::SubfaceCase<2>::case_x) ? 2 : 0;
+}
+
+
+
+template<>
+unsigned int
+GeometryInfo<3>::n_subfaces(const internal::SubfaceCase<3> &subface_case)
+{
+  static const unsigned int nsubs[internal::SubfaceCase<3>::case_isotropic+1]=
+    {0, 2, 3, 3, 4, 2, 3, 3, 4, 4};
+  return nsubs[subface_case];
+}
+
+
+template<>
+double
+GeometryInfo<1>::subface_ratio(const internal::SubfaceCase<1> &,
+                              const unsigned int)
+{
+  Assert(false, ExcImpossibleInDim(1));
+  return 1;
+}
+
+  
+template<>
+double
+GeometryInfo<2>::subface_ratio(const internal::SubfaceCase<2> &subface_case,
+                              const unsigned int)
+{
+  const unsigned int dim=2;
+
+  double ratio=1;
+  switch (subface_case)
+    {
+      case internal::SubfaceCase<dim>::case_none:
+                                            // Here, an
+                                            // Assert(false,ExcInternalError())
+                                            // would be the right
+                                            // choice, but
+                                            // unfortunately the
+                                            // current function is
+                                            // also called for faces
+                                            // without children (see
+                                            // tests/fe/mapping.cc).
+//         Assert(false, ExcMessage("Face has no subfaces."));
+                                            // Furthermore, assign
+                                            // following value as
+                                            // otherwise the
+                                            // bits/volume_x tests
+                                            // break
+           ratio=1./GeometryInfo<dim>::max_children_per_face;
+           break;
+      case internal::SubfaceCase<dim>::case_x:
+           ratio=0.5;
+           break;
+      default:
+                                            // there should be no
+                                            // cases left
+           Assert(false, ExcInternalError());
+           break;
+    }
+  
+  return ratio;
+}
+
+
+template<>
+double
+GeometryInfo<3>::subface_ratio(const internal::SubfaceCase<3> &subface_case,
+                              const unsigned int subface_no)
+{
+  const unsigned int dim=3;
+
+  double ratio=1;
+  switch (subface_case)
+    {
+      case internal::SubfaceCase<dim>::case_none:
+                                            // Here, an
+                                            // Assert(false,ExcInternalError())
+                                            // would be the right
+                                            // choice, but
+                                            // unfortunately the
+                                            // current function is
+                                            // also called for faces
+                                            // without children (see
+                                            // tests/bits/mesh_3d_16.cc). Add
+                                            // following switch to
+                                            // avoid diffs in
+                                            // tests/bits/mesh_3d_16
+           ratio=1./GeometryInfo<dim>::max_children_per_face;
+           break;
+      case internal::SubfaceCase<dim>::case_x:
+      case internal::SubfaceCase<dim>::case_y:
+           ratio=0.5;
+           break;
+      case internal::SubfaceCase<dim>::case_xy:
+      case internal::SubfaceCase<dim>::case_x1y2y:
+      case internal::SubfaceCase<dim>::case_y1x2x:
+           ratio=0.25;
+           break;
+      case internal::SubfaceCase<dim>::case_x1y:
+      case internal::SubfaceCase<dim>::case_y1x:
+           if (subface_no<2)
+             ratio=0.25;
+           else
+             ratio=0.5;
+           break;
+      case internal::SubfaceCase<dim>::case_x2y:
+      case internal::SubfaceCase<dim>::case_y2x:
+           if (subface_no==0)
+             ratio=0.5;
+           else
+             ratio=0.25;
+           break;
+      default:
+                                            // there should be no
+                                            // cases left
+           Assert(false, ExcInternalError());
+           break;
+    }
+  
+  return ratio;
+}
+
+
+
+template<>
+RefinementCase<0>
+GeometryInfo<1>::face_refinement_case(const RefinementCase<1> &,
+                                     const unsigned int,
+                                     const bool,
+                                     const bool,
+                                     const bool)
+{
+  Assert(false, ExcImpossibleInDim(1));
+
+  return RefinementCase<0>::no_refinement;
+}
+
+
+template<>
+RefinementCase<1>
+GeometryInfo<2>::face_refinement_case(const RefinementCase<2> &cell_refinement_case,
+                                     const unsigned int face_no,
+                                     const bool,
+                                     const bool,
+                                     const bool)
+{
+  const unsigned int dim=2;
+  Assert(cell_refinement_case<RefinementCase<dim>::isotropic_refinement+1,
+        ExcIndexRange(cell_refinement_case, 0, RefinementCase<dim>::isotropic_refinement+1));
+  Assert(face_no<GeometryInfo<dim>::faces_per_cell,
+        ExcIndexRange(face_no, 0, GeometryInfo<dim>::faces_per_cell));
+
+  static const RefinementCase<dim-1>
+    ref_cases[RefinementCase<dim>::isotropic_refinement+1][GeometryInfo<dim>::faces_per_cell/2]=
+    {{RefinementCase<dim-1>::no_refinement,  // no_refinement
+      RefinementCase<dim-1>::no_refinement},
+     
+     {RefinementCase<dim-1>::no_refinement,
+      RefinementCase<dim-1>::cut_x},
+     
+     {RefinementCase<dim-1>::cut_x,
+      RefinementCase<dim-1>::no_refinement},
+     
+     {RefinementCase<dim-1>::cut_x,          // cut_xy
+      RefinementCase<dim-1>::cut_x}     
+    };
+  
+  return ref_cases[cell_refinement_case][face_no/2];
+}
+
+
+template<>
+RefinementCase<2>
+GeometryInfo<3>::face_refinement_case(const RefinementCase<3> &cell_refinement_case,
+                                     const unsigned int face_no,
+                                     const bool face_orientation,
+                                     const bool /*face_flip*/,
+                                     const bool face_rotation)
+{
+  const unsigned int dim=3;
+  Assert(cell_refinement_case<RefinementCase<dim>::isotropic_refinement+1,
+        ExcIndexRange(cell_refinement_case, 0, RefinementCase<dim>::isotropic_refinement+1));
+  Assert(face_no<GeometryInfo<dim>::faces_per_cell,
+        ExcIndexRange(face_no, 0, GeometryInfo<dim>::faces_per_cell));
+
+  static const RefinementCase<dim-1>
+    ref_cases[RefinementCase<dim>::isotropic_refinement+1][GeometryInfo<dim>::faces_per_cell/2]=
+    {{RefinementCase<dim-1>::no_refinement,  // no_refinement
+      RefinementCase<dim-1>::no_refinement,
+      RefinementCase<dim-1>::no_refinement},
+     
+     {RefinementCase<dim-1>::no_refinement,  // cut_x
+      RefinementCase<dim-1>::cut_y,
+      RefinementCase<dim-1>::cut_x},
+     
+     {RefinementCase<dim-1>::cut_x,          // cut_y
+      RefinementCase<dim-1>::no_refinement,
+      RefinementCase<dim-1>::cut_y},
+     
+     {RefinementCase<dim-1>::cut_x,          // cut_xy
+      RefinementCase<dim-1>::cut_y,
+      RefinementCase<dim-1>::cut_xy},
+     
+     {RefinementCase<dim-1>::cut_y,          // cut_z
+      RefinementCase<dim-1>::cut_x,
+      RefinementCase<dim-1>::no_refinement},
+     
+     {RefinementCase<dim-1>::cut_y,          // cut_xz
+      RefinementCase<dim-1>::cut_xy,
+      RefinementCase<dim-1>::cut_x},
+
+     {RefinementCase<dim-1>::cut_xy,         // cut_yz
+      RefinementCase<dim-1>::cut_x,
+      RefinementCase<dim-1>::cut_y},
+
+     {RefinementCase<dim-1>::cut_xy,         // cut_xyz
+      RefinementCase<dim-1>::cut_xy,
+      RefinementCase<dim-1>::cut_xy},     
+    };
+
+  const RefinementCase<dim-1> ref_case=ref_cases[cell_refinement_case][face_no/2];
+  
+  static const RefinementCase<dim-1> flip[4]=
+    {RefinementCase<dim-1>::no_refinement,
+     RefinementCase<dim-1>::cut_y,
+     RefinementCase<dim-1>::cut_x,
+     RefinementCase<dim-1>::cut_xy};
+  
+                                  // correct the ref_case for face_orientation
+                                  // and face_rotation. for face_orientation,
+                                  // 'true' is the default value whereas for
+                                  // face_rotation, 'false' is standard. If
+                                  // <tt>face_rotation==face_orientation</tt>,
+                                  // then one of them is non-standard and we
+                                  // have to swap cut_x and cut_y, otherwise no
+                                  // change is necessary.  face_flip has no
+                                  // influence. however, in order to keep the
+                                  // interface consistent with other functions,
+                                  // we still include it as an argument to this
+                                  // function
+  return (face_orientation==face_rotation) ? flip[ref_case] : ref_case;
+}
+
+
+
+template<>
+RefinementCase<1>
+GeometryInfo<1>::line_refinement_case(const RefinementCase<1> &cell_refinement_case,
+                                     const unsigned int line_no)
+{
+  const unsigned int dim = 1;
+  Assert(cell_refinement_case<RefinementCase<dim>::isotropic_refinement+1,
+        ExcIndexRange(cell_refinement_case, 0, RefinementCase<dim>::isotropic_refinement+1));
+  Assert(line_no<GeometryInfo<dim>::lines_per_cell,
+        ExcIndexRange(line_no, 0, GeometryInfo<dim>::lines_per_cell));
+  
+  return cell_refinement_case;
+}
+
+
+template<>
+RefinementCase<1>
+GeometryInfo<2>::line_refinement_case(const RefinementCase<2> &cell_refinement_case,
+                                     const unsigned int line_no)
+{
+                                  // Assertions are in face_refinement_case() 
+  return face_refinement_case(cell_refinement_case, line_no);
+}
+
+
+template<>
+RefinementCase<1>
+GeometryInfo<3>::line_refinement_case(const RefinementCase<3> &cell_refinement_case,
+                                     const unsigned int line_no)
+{
+  const unsigned int dim=3;
+  Assert(cell_refinement_case<RefinementCase<dim>::isotropic_refinement+1,
+        ExcIndexRange(cell_refinement_case, 0, RefinementCase<dim>::isotropic_refinement+1));
+  Assert(line_no<GeometryInfo<dim>::lines_per_cell,
+        ExcIndexRange(line_no, 0, GeometryInfo<dim>::lines_per_cell));
+
+                                  // array indicating, which simple refine
+                                  // case cuts a line in dirextion x, y or
+                                  // z. For example, cut_y and everything
+                                  // containing cut_y (cut_xy, cut_yz,
+                                  // cut_xyz) cuts lines, which are in y
+                                  // direction.
+  static const RefinementCase<dim>
+    cut_one[dim] =
+    {RefinementCase<dim>::cut_x,
+     RefinementCase<dim>::cut_y,
+     RefinementCase<dim>::cut_z};
+
+                                  // order the direction of lines
+                                  // 0->x, 1->y, 2->z
+  static const unsigned int direction[lines_per_cell]=
+    {1,1,0,0,1,1,0,0,2,2,2,2};
+  
+  return ((cell_refinement_case & cut_one[direction[line_no]]) ?
+    RefinementCase<1>::cut_x : RefinementCase<1>::no_refinement);
+}
+
+
+
+template<>
+RefinementCase<1>
+GeometryInfo<1>::min_cell_refinement_case_for_face_refinement(const RefinementCase<0> &,
+                                                             const unsigned int,
+                                                             const bool,
+                                                             const bool,
+                                                             const bool)
+{
+  const unsigned int dim = 1;
+  Assert(false, ExcImpossibleInDim(dim));
+  
+  return RefinementCase<dim>::no_refinement;
+}
+
+
+template<>
+RefinementCase<2>
+GeometryInfo<2>::min_cell_refinement_case_for_face_refinement(const RefinementCase<1> &face_refinement_case,
+                                                             const unsigned int face_no,
+                                                             const bool,
+                                                             const bool,
+                                                             const bool)
+{
+  const unsigned int dim = 2;
+  Assert(face_refinement_case<RefinementCase<dim-1>::isotropic_refinement+1,
+        ExcIndexRange(face_refinement_case, 0, RefinementCase<dim-1>::isotropic_refinement+1));
+  Assert(face_no<GeometryInfo<dim>::faces_per_cell,
+        ExcIndexRange(face_no, 0, GeometryInfo<dim>::faces_per_cell));
+
+  if (face_refinement_case==RefinementCase<dim>::cut_x)
+    return (face_no/2) ? RefinementCase<dim>::cut_x : RefinementCase<dim>::cut_y;
+  else
+    return RefinementCase<dim>::no_refinement;
+}
+
+
+template<>
+RefinementCase<3>
+GeometryInfo<3>::min_cell_refinement_case_for_face_refinement(const RefinementCase<2> &face_refinement_case,
+                                                             const unsigned int face_no,
+                                                             const bool face_orientation,
+                                                             const bool /*face_flip*/,
+                                                             const bool face_rotation)
+{
+  const unsigned int dim=3;
+  Assert(face_refinement_case<RefinementCase<dim-1>::isotropic_refinement+1,
+        ExcIndexRange(face_refinement_case, 0, RefinementCase<dim-1>::isotropic_refinement+1));
+  Assert(face_no<GeometryInfo<dim>::faces_per_cell,
+        ExcIndexRange(face_no, 0, GeometryInfo<dim>::faces_per_cell));
+
+  static const RefinementCase<2> flip[4]=
+    {RefinementCase<2>::no_refinement,
+     RefinementCase<2>::cut_y,
+     RefinementCase<2>::cut_x,
+     RefinementCase<2>::cut_xy};
+
+                                  // correct the face_refinement_case for
+                                  // face_orientation and face_rotation. for
+                                  // face_orientation, 'true' is the default
+                                  // value whereas for face_rotation, 'false'
+                                  // is standard. If
+                                  // <tt>face_rotation==face_orientation</tt>,
+                                  // then one of them is non-standard and we
+                                  // have to swap cut_x and cut_y, otherwise no
+                                  // change is necessary.  face_flip has no
+                                  // influence. however, in order to keep the
+                                  // interface consistent with other functions,
+                                  // we still include it as an argument to this
+                                  // function
+  const RefinementCase<dim-1> std_face_ref = (face_orientation==face_rotation) ? flip[face_refinement_case] : face_refinement_case;
+
+  static const RefinementCase<dim> face_to_cell[3][4]=
+    {{RefinementCase<dim>::no_refinement,  // faces 0 and 1
+      RefinementCase<dim>::cut_y,          // cut_x in face 0 means cut_y for the cell
+      RefinementCase<dim>::cut_z,
+      RefinementCase<dim>::cut_yz},
+     
+     {RefinementCase<dim>::no_refinement,  // faces 2 and 3 (note that x and y are "exchanged on faces 2 and 3")
+      RefinementCase<dim>::cut_z,
+      RefinementCase<dim>::cut_x,
+      RefinementCase<dim>::cut_xz},
+     
+     {RefinementCase<dim>::no_refinement,  // faces 4 and 5
+      RefinementCase<dim>::cut_x,
+      RefinementCase<dim>::cut_y,
+      RefinementCase<dim>::cut_xy}};
+
+  return face_to_cell[face_no/2][std_face_ref];
+}
+
+
+
+template<>
+RefinementCase<1>
+GeometryInfo<1>::min_cell_refinement_case_for_line_refinement(const unsigned int line_no)
+{
+  Assert(line_no==0, ExcIndexRange(line_no,0,1));
+  
+  return RefinementCase<1>::cut_x;
+}
+
+
+template<>
+RefinementCase<2>
+GeometryInfo<2>::min_cell_refinement_case_for_line_refinement(const unsigned int line_no)
+{
+  const unsigned int dim = 2;
+  Assert(line_no<GeometryInfo<dim>::lines_per_cell,
+        ExcIndexRange(line_no, 0, GeometryInfo<dim>::lines_per_cell));
+
+  return (line_no/2) ? RefinementCase<2>::cut_x : RefinementCase<2>::cut_y;
+}
+
+
+template<>
+RefinementCase<3>
+GeometryInfo<3>::min_cell_refinement_case_for_line_refinement(const unsigned int line_no)
+{
+  const unsigned int dim=3;
+  Assert(line_no<GeometryInfo<dim>::lines_per_cell,
+        ExcIndexRange(line_no, 0, GeometryInfo<dim>::lines_per_cell));
+
+  static const RefinementCase<dim> ref_cases[6]=
+    {RefinementCase<dim>::cut_y,  // lines  0 and  1
+     RefinementCase<dim>::cut_x,  // lines  2 and  3
+     RefinementCase<dim>::cut_y,  // lines  4 and  5
+     RefinementCase<dim>::cut_x,  // lines  6 and  7
+     RefinementCase<dim>::cut_z,  // lines  8 and  9
+     RefinementCase<dim>::cut_z}; // lines 10 and 11
+
+  return ref_cases[line_no/2];
+}
+
+
+
 template <>
 unsigned int
 GeometryInfo<3>::standard_to_real_face_vertex(const unsigned int vertex,
@@ -500,13 +967,15 @@ GeometryInfo<dim>::real_to_standard_face_line(const unsigned int line,
 
 template <>
 unsigned int
-GeometryInfo<1>::child_cell_on_face (const unsigned int face,
+GeometryInfo<1>::child_cell_on_face (const RefinementCase<1> &,
+                                    const unsigned int face,
                                      const unsigned int subface,
-                                    const bool, const bool, const bool)
+                                    const bool, const bool, const bool,
+                                    const RefinementCase<0> &)
 {
   Assert (face<faces_per_cell, ExcIndexRange(face, 0, faces_per_cell));
-  Assert (subface<subfaces_per_face,
-         ExcIndexRange(subface, 0, subfaces_per_face));
+  Assert (subface<max_children_per_face,
+         ExcIndexRange(subface, 0, max_children_per_face));
 
   return face;
 }
@@ -515,55 +984,272 @@ GeometryInfo<1>::child_cell_on_face (const unsigned int face,
 
 template <>
 unsigned int
-GeometryInfo<2>::child_cell_on_face (const unsigned int face,
+GeometryInfo<2>::child_cell_on_face (const RefinementCase<2> &ref_case,
+                                    const unsigned int face,
                                      const unsigned int subface,
-                                    const bool, const bool, const bool)
+                                    const bool, const bool, const bool,
+                                    const RefinementCase<1> &)
 {
   Assert (face<faces_per_cell, ExcIndexRange(face, 0, faces_per_cell));
-  Assert (subface<subfaces_per_face, ExcIndexRange(subface, 0, subfaces_per_face));
+  Assert (subface<max_children_per_face,
+         ExcIndexRange(subface, 0, max_children_per_face));
+
+                                    // always return the child adjacent to the specified
+                                    // subface. if the face of a cell is not refined, don't
+                                    // throw an assertion but deliver the child adjacent to
+                                    // the face nevertheless, i.e. deliver the child of
+                                    // this cell adjacent to the subface of a possibly
+                                    // refined neighbor. this simplifies setting neighbor
+                                    // information in execute_refinement.
+  static const unsigned int
+    subcells[RefinementCase<2>::isotropic_refinement][faces_per_cell][max_children_per_face] =
+  {{{0,0},{1,1},{0,1},{0,1}},          // cut_x
+   {{0,1},{0,1},{0,0},{1,1}},          // cut_y
+   {{0,2},{1,3},{0,1},{2,3}}};         // cut_xy
   
-  static const unsigned
-    subcells[faces_per_cell][subfaces_per_face] = {{0,2},
-                                                   {1,3},
-                                                   {0,1},
-                                                   {2,3}};
-
-  return subcells[face][subface];
+  return subcells[ref_case-1][face][subface];
 }
 
 
 
 template <>
 unsigned int
-GeometryInfo<3>::child_cell_on_face (const unsigned int face,
+GeometryInfo<3>::child_cell_on_face (const RefinementCase<3> &ref_case,
+                                    const unsigned int face,
                                     const unsigned int subface,
                                     const bool face_orientation,
                                     const bool face_flip,
-                                    const bool face_rotation)
+                                    const bool face_rotation,
+                                    const RefinementCase<2> &face_ref_case)
 {
-  Assert (face<faces_per_cell, ExcIndexRange(face, 0, faces_per_cell));
-  Assert (subface<subfaces_per_face, ExcIndexRange(subface, 0, subfaces_per_face));
+  const unsigned int dim = 3;
 
-  static const unsigned
-    subcells[faces_per_cell][subfaces_per_face] = {{0, 2, 4, 6},
-                                                   {1, 3, 5, 7},
-                                                   {0, 4, 1, 5},
-                                                   {2, 6, 3, 7},
-                                                   {0, 1, 2, 3},
-                                                   {4, 5, 6, 7}};
-  return subcells[face][real_to_standard_face_vertex(subface,
-                                                    face_orientation,
-                                                    face_flip,
-                                                    face_rotation)];
+  Assert (ref_case>RefinementCase<dim-1>::no_refinement, ExcMessage("Cell has no children."));
+  Assert (face<faces_per_cell, ExcIndexRange(face, 0, faces_per_cell));
+  Assert (subface<GeometryInfo<dim-1>::n_children(face_ref_case) ||
+         (subface==0 && face_ref_case==RefinementCase<dim-1>::no_refinement),
+         ExcIndexRange(subface, 0, GeometryInfo<2>::n_children(face_ref_case)));
+
+                                  // invalid number used for invalid cases,
+                                  // e.g. when the children are more refined at
+                                  // a given face than the face itself
+  static const unsigned int e=invalid_unsigned_int;
+
+                                  // the whole process of finding a child cell
+                                  // at a given subface considering the
+                                  // possibly anisotropic refinement cases of
+                                  // the cell and the face as well as
+                                  // orientation, flip and rotation of the face
+                                  // is quite complicated. thus, we break it
+                                  // down into several steps.
+  
+                                  // first step: convert the given face refine
+                                  // case to a face refine case concerning the
+                                  // face in standard orientation (, flip and
+                                  // rotation). This only affects cut_x and
+                                  // cut_y
+  static const RefinementCase<dim-1> flip[4]=
+    {RefinementCase<dim-1>::no_refinement,
+     RefinementCase<dim-1>::cut_y,
+     RefinementCase<dim-1>::cut_x,
+     RefinementCase<dim-1>::cut_xy};
+                                  // for face_orientation, 'true' is the
+                                  // default value whereas for face_rotation,
+                                  // 'false' is standard. If
+                                  // <tt>face_rotation==face_orientation</tt>,
+                                  // then one of them is non-standard and we
+                                  // have to swap cut_x and cut_y, otherwise no
+                                  // change is necessary.
+  const RefinementCase<dim-1> std_face_ref = (face_orientation==face_rotation) ? flip[face_ref_case] : face_ref_case;
+
+                                  // second step: convert the given subface
+                                  // index to the one for a standard face
+                                  // respecting face_orientation, face_flip and
+                                  // face_rotation
+
+                                  // first index:  face_ref_case
+                                  // second index: face_orientation
+                                  // third index:  face_flip
+                                  // forth index:  face_rotation
+                                  // fifth index:  subface index
+  static const unsigned int subface_exchange[4][2][2][2][4]=
+    {
+                                          // no_refinement (subface 0 stays 0,
+                                          // all others are invalid)
+         {{{{0,e,e,e},
+            {0,e,e,e}}, 
+           {{0,e,e,e},
+            {0,e,e,e}}},
+          {{{0,e,e,e},
+            {0,e,e,e}},
+           {{0,e,e,e},
+            {0,e,e,e}}}},
+                                          // cut_x (here, if the face is only
+                                          // rotated OR only falsely oriented,
+                                          // then subface 0 of the non-standard
+                                          // face does NOT correspond to one of
+                                          // the subfaces of a standard
+                                          // face. Thus we indicate the subface
+                                          // which is located at the lower left
+                                          // corner (the origin of the face's
+                                          // local coordinate system) with
+                                          // '0'. The rest of this issue is
+                                          // taken care of using the above
+                                          // conversion to a 'standard face
+                                          // refine case')
+         {{{{0,1,e,e},
+            {0,1,e,e}}, 
+           {{1,0,e,e},
+            {1,0,e,e}}},
+          {{{0,1,e,e},
+            {0,1,e,e}},
+           {{1,0,e,e},
+            {1,0,e,e}}}},
+                                          // cut_y (the same applies as for
+                                          // cut_x)
+         {{{{0,1,e,e},
+            {1,0,e,e}}, 
+           {{1,0,e,e},
+            {0,1,e,e}}},
+          {{{0,1,e,e},
+            {1,0,e,e}},
+           {{1,0,e,e},
+            {0,1,e,e}}}},
+                                          // cut_xyz: this information is
+                                          // identical to the information
+                                          // returned by
+                                          // GeometryInfo<3>::real_to_standard_face_vertex()
+         {{{{0,2,1,3},    // face_orientation=false, face_flip=false, face_rotation=false, subfaces 0,1,2,3
+            {2,3,0,1}},   // face_orientation=false, face_flip=false, face_rotation=true,  subfaces 0,1,2,3
+           {{3,1,2,0},    // face_orientation=false, face_flip=true,  face_rotation=false, subfaces 0,1,2,3
+            {1,0,3,2}}},  // face_orientation=false, face_flip=true,  face_rotation=true,  subfaces 0,1,2,3
+          {{{0,1,2,3},    // face_orientation=true,  face_flip=false, face_rotation=false, subfaces 0,1,2,3
+            {1,3,0,2}},   // face_orientation=true,  face_flip=false, face_rotation=true,  subfaces 0,1,2,3
+           {{3,2,1,0},    // face_orientation=true,  face_flip=true,  face_rotation=false, subfaces 0,1,2,3
+            {2,0,3,1}}}}};// face_orientation=true,  face_flip=true,  face_rotation=true,  subfaces 0,1,2,3
+
+  const unsigned int std_subface=subface_exchange
+                                [face_ref_case]
+                                [face_orientation]
+                                [face_flip]
+                                [face_rotation]
+                                [subface];
+  Assert (std_subface!=e, ExcInternalError());
+
+                                  // third step: these are the children, which
+                                  // can be found at the given subfaces of an
+                                  // isotropically refined (standard) face
+                                  //
+                                  // first index:  (refinement_case-1)
+                                  // second index: face_index
+                                  // third index:  subface_index (isotropic refinement)
+  static const unsigned int
+    iso_children[RefinementCase<dim>::cut_xyz][faces_per_cell][max_children_per_face] =
+  {
+                                        // cut_x
+       {{0, 0, 0, 0},  // face 0, subfaces 0,1,2,3
+        {1, 1, 1, 1},  // face 1, subfaces 0,1,2,3
+        {0, 0, 1, 1},  // face 2, subfaces 0,1,2,3
+        {0, 0, 1, 1},  // face 3, subfaces 0,1,2,3
+        {0, 1, 0, 1},  // face 4, subfaces 0,1,2,3
+        {0, 1, 0, 1}}, // face 5, subfaces 0,1,2,3
+                                        // cut_y
+       {{0, 1, 0, 1},  
+        {0, 1, 0, 1},
+        {0, 0, 0, 0},
+        {1, 1, 1, 1},
+        {0, 0, 1, 1},
+        {0, 0, 1, 1}},
+                                        // cut_xy      
+       {{0, 2, 0, 2},
+        {1, 3, 1, 3},
+        {0, 0, 1, 1},
+        {2, 2, 3, 3},
+        {0, 1, 2, 3},
+        {0, 1, 2, 3}},
+                                        // cut_z
+       {{0, 0, 1, 1},
+        {0, 0, 1, 1},
+        {0, 1, 0, 1},
+        {0, 1, 0, 1},
+        {0, 0, 0, 0},
+        {1, 1, 1, 1}},
+                                        // cut_xz
+       {{0, 0, 1, 1},
+        {2, 2, 3, 3},
+        {0, 1, 2, 3},
+        {0, 1, 2, 3},
+        {0, 2, 0, 2},
+        {1, 3, 1, 3}},
+                                        // cut_yz
+       {{0, 1, 2, 3},
+        {0, 1, 2, 3},
+        {0, 2, 0, 2},
+        {1, 3, 1, 3},
+        {0, 0, 1, 1},
+        {2, 2, 3, 3}},
+                                        // cut_xyz
+       {{0, 2, 4, 6},
+        {1, 3, 5, 7},
+        {0, 4, 1, 5},
+        {2, 6, 3, 7},
+        {0, 1, 2, 3},
+        {4, 5, 6, 7}}};
+
+                                  // forth step: check, whether the given face
+                                  // refine case is valid for the given cell
+                                  // refine case. this is the case, if the
+                                  // given face refine case is at least as
+                                  // refined as the face is for the given cell
+                                  // refine case
+
+                                  // note, that we are considering standard
+                                  // face refinement cases here and thus must
+                                  // not pass the given orientation, flip and
+                                  // rotation flags
+  if ((std_face_ref & face_refinement_case(ref_case, face))
+      == face_refinement_case(ref_case, face))
+    {
+                                      // all is fine. for anisotropic face
+                                      // refine cases, select one of the
+                                      // isotropic subfaces which neighbors the
+                                      // same child
+
+                                      // first index: (standard) face refine case
+                                      // second index: subface index
+      static const unsigned int equivalent_iso_subface[4][4]=
+       {{0,e,e,e},                    // no_refinement
+        {0,3,e,e},                    // cut_x
+        {0,3,e,e},                    // cut_y
+        {0,1,2,3}};                   // cut_xy
+
+      const unsigned int equ_std_subface
+       =equivalent_iso_subface[std_face_ref][std_subface];
+      Assert (equ_std_subface!=e, ExcInternalError());
+
+      return iso_children[ref_case-1][face][equ_std_subface];
+    }
+  else
+    {
+                                      // the face_ref_case was too coarse,
+                                      // throw an error
+      Assert(false,
+            ExcMessage("The face RefineCase is too coarse "
+                       "for the given cell RefineCase."));
+    }
+                                  // we only get here in case of an error
+  return e;
 }
 
 
 
 template <>
 unsigned int
-GeometryInfo<4>::child_cell_on_face (const unsigned int,
+GeometryInfo<4>::child_cell_on_face (const RefinementCase<4> &,
                                     const unsigned int,
-                                    const bool, const bool, const bool)
+                                    const unsigned int,
+                                    const bool, const bool, const bool,
+                                    const RefinementCase<3> &)
 {
   Assert(false, ExcNotImplemented());
   return invalid_unsigned_int;
@@ -588,7 +1274,7 @@ unsigned int
 GeometryInfo<2>::line_to_cell_vertices (const unsigned int line,
                                        const unsigned int vertex)
 {
-  return child_cell_on_face(line, vertex);
+  return child_cell_on_face(RefinementCase<2>::isotropic_refinement, line, vertex);
 }
 
 
@@ -705,7 +1391,7 @@ GeometryInfo<dim>::face_to_cell_vertices (const unsigned int face,
                                          const bool face_flip,
                                          const bool face_rotation)
 {
-  return child_cell_on_face(face, vertex,
+  return child_cell_on_face(RefinementCase<dim>::isotropic_refinement, face, vertex,
                            face_orientation, face_flip, face_rotation);
 }
 
@@ -740,6 +1426,7 @@ GeometryInfo<dim>::distance_to_unit_cell (const Point<dim> &p)
    return result;
 }
 
+
 template class GeometryInfo<1>;
 template class GeometryInfo<2>;
 template class GeometryInfo<3>;
index 319043f9010534eed022dc7065501483236de453..ea0443553894d8c27210bc3e7158809b82756c11 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007 by the deal.II authors
+//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 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
@@ -522,7 +522,8 @@ void
 QProjector<1>::project_to_subface (const Quadrature<0> &,
                                    const unsigned int,
                                    const unsigned int,
-                                   std::vector<Point<1> > &)
+                                   std::vector<Point<1> > &,
+                                  const RefinementCase<0> &)
 {
   Assert(false, ExcNotImplemented());
 }
@@ -534,7 +535,8 @@ void
 QProjector<2>::project_to_subface (const Quadrature<1>    &quadrature,
                                    const unsigned int      face_no,
                                    const unsigned int      subface_no,
-                                   std::vector<Point<2> > &q_points)
+                                   std::vector<Point<2> > &q_points,
+                                  const RefinementCase<1> &)
 {
   const unsigned int dim=2;
   Assert (face_no<2*dim, ExcIndexRange (face_no, 0, 2*dim));
@@ -612,7 +614,8 @@ void
 QProjector<3>::project_to_subface (const Quadrature<2>    &quadrature,
                                    const unsigned int      face_no,
                                    const unsigned int      subface_no,
-                                   std::vector<Point<3> > &q_points)
+                                   std::vector<Point<3> > &q_points,
+                                  const RefinementCase<2> &ref_case)
 {
   const unsigned int dim=3;
   Assert (face_no<2*dim, ExcIndexRange (face_no, 0, 2*dim));
@@ -620,153 +623,78 @@ QProjector<3>::project_to_subface (const Quadrature<2>    &quadrature,
   Assert (q_points.size() == quadrature.size(),
          ExcDimensionMismatch (q_points.size(), quadrature.size()));
 
-
-                                  // for all faces and subfaces:
-                                  // first project onto the first
-                                  // subface of each face, then move
-                                  // it to the right place
+                                  // one coordinate is at a const value. for
+                                  // faces 0, 2 and 4 this value is 0.0, for
+                                  // faces 1, 3 and 5 it is 1.0
+  double const_value=face_no%2;
+                                  // local 2d coordinates are xi and eta,
+                                  // global 3d coordinates are x, y and
+                                  // z. those have to be mapped. the following
+                                  // indices tell, which global coordinate
+                                  // (0->x, 1->y, 2->z) corresponds to which
+                                  // local one
+  unsigned int xi_index   = deal_II_numbers::invalid_unsigned_int,
+             eta_index   = deal_II_numbers::invalid_unsigned_int,
+             const_index = face_no/2;
+                                  // the xi and eta values have to be scaled
+                                  // (by factor 0.5 or factor 1.0) depending on
+                                  // the refinement case and translated (by 0.0
+                                  // or 0.5) depending on the refinement case
+                                  // and subface_no.
+  double xi_scale=1.0,
+    eta_scale=1.0,
+    xi_translation=0.0,
+    eta_translation=0.0;
+                                  // set the index mapping between local and
+                                  // global coordinates
+  switch(face_no/2)
+    {
+      case 0:
+           xi_index=1;
+           eta_index=2;
+           break;
+      case 1:
+           xi_index=2;
+           eta_index=0;
+           break;
+      case 2:
+           xi_index=0;
+           eta_index=1;
+           break;
+    }
+                                  // set the scale and translation parameter
+                                  // for individual subfaces
+  switch((unsigned char)ref_case)
+    {
+      case RefinementCase<dim-1>::cut_x:
+           xi_scale=0.5;
+           xi_translation=subface_no%2 * 0.5;
+           break;
+      case RefinementCase<dim-1>::cut_y:
+           eta_scale=0.5;
+           eta_translation=subface_no%2 * 0.5;
+           break;
+      case RefinementCase<dim-1>::cut_xy:
+           xi_scale= 0.5;
+           eta_scale=0.5;
+           xi_translation =subface_no%2 * 0.5;
+           eta_translation=subface_no/2 * 0.5;
+           break;
+      default:
+           Assert(false,ExcInternalError());
+           break;
+    }
+                                  // finally, compute the scaled, translated,
+                                  // projected quadrature points
   for (unsigned int p=0; p<quadrature.size(); ++p)
-    switch (face_no)
-      {
-       case 0:
-             q_points[p] = Point<dim>(0,
-                                      quadrature.point(p)(0)/2,
-                                      quadrature.point(p)(1)/2);
-             switch (subface_no) 
-               {
-                 case 0:
-                       break;
-                 case 1:
-                       q_points[p][1] += 1./2.;
-                       break;
-                 case 2:
-                       q_points[p][2] += 1./2.;
-                       break;
-                 case 3:
-                       q_points[p][1] += 1./2.;
-                       q_points[p][2] += 1./2.;
-                       break;
-                 default:
-                       Assert (false, ExcInternalError());
-               };
-             break;       
-       case 1:
-             q_points[p] = Point<dim>(1,
-                                      quadrature.point(p)(0)/2,
-                                      quadrature.point(p)(1)/2);
-             switch (subface_no) 
-               {
-                 case 0:
-                       break;
-                 case 1:
-                       q_points[p][1] += 1./2.;
-                       break;
-                 case 2:
-                       q_points[p][2] += 1./2.;
-                       break;
-                 case 3:
-                       q_points[p][1] += 1./2.;
-                       q_points[p][2] += 1./2.;
-                       break;
-                 default:
-                       Assert (false, ExcInternalError());
-               };
-             break;       
-       case 2:
-             q_points[p] = Point<dim>(quadrature.point(p)(1)/2,
-                                      0,
-                                      quadrature.point(p)(0)/2);
-             switch (subface_no) 
-               {
-                 case 0:
-                       break;
-                 case 1:
-                       q_points[p][2] += 1./2.;
-                       break;
-                 case 2:
-                       q_points[p][0] += 1./2.;
-                       break;
-                 case 3:
-                       q_points[p][0] += 1./2.;
-                       q_points[p][2] += 1./2.;
-                       break;
-                 default:
-                       Assert (false, ExcInternalError());
-               };
-             break;
-       case 3:
-             q_points[p] = Point<dim>(quadrature.point(p)(1)/2,
-                                      1,
-                                      quadrature.point(p)(0)/2);
-             switch (subface_no) 
-               {
-                 case 0:
-                       break;
-                 case 1:
-                       q_points[p][2] += 1./2.;
-                       break;
-                 case 2:
-                       q_points[p][0] += 1./2.;
-                       break;
-                 case 3:
-                       q_points[p][0] += 1./2.;
-                       q_points[p][2] += 1./2.;
-                       break;
-                 default:
-                       Assert (false, ExcInternalError());
-               };
-             break;
-       case 4:
-             q_points[p] = Point<dim>(quadrature.point(p)(0)/2,
-                                      quadrature.point(p)(1)/2,
-                                      0);
-             switch (subface_no) 
-               {
-                 case 0:
-                       break;
-                 case 1:
-                       q_points[p][0] += 1./2.;
-                       break;
-                 case 2:
-                       q_points[p][1] += 1./2.;
-                       break;
-                 case 3:
-                       q_points[p][0] += 1./2.;
-                       q_points[p][1] += 1./2.;
-                       break;
-                 default:
-                       Assert (false, ExcInternalError());
-               };
-             break;
-       case 5:
-             q_points[p] = Point<dim>(quadrature.point(p)(0)/2,
-                                      quadrature.point(p)(1)/2,
-                                      1);
-             switch (subface_no) 
-               {
-                 case 0:
-                       break;
-                 case 1:
-                       q_points[p][0] += 1./2.;
-                       break;
-                 case 2:
-                       q_points[p][1] += 1./2.;
-                       break;
-                 case 3:
-                       q_points[p][0] += 1./2.;
-                       q_points[p][1] += 1./2.;
-                       break;
-                 default:
-                       Assert (false, ExcInternalError());
-               };
-             break;
-       default:
-             Assert (false, ExcInternalError());
-      };
+    {
+      q_points[p][xi_index]    = xi_scale  * quadrature.point(p)(0) + xi_translation;
+      q_points[p][eta_index]   = eta_scale * quadrature.point(p)(1) + eta_translation;
+      q_points[p][const_index] = const_value;
+    }
 }
 
 
-
 template <>
 Quadrature<1>
 QProjector<1>::project_to_all_faces (const Quadrature<0> &)
@@ -899,7 +827,7 @@ QProjector<2>::project_to_all_subfaces (const SubQuadrature &quadrature)
   
   const unsigned int n_points          = quadrature.size(),
                     n_faces           = GeometryInfo<dim>::faces_per_cell,
-                    subfaces_per_face = GeometryInfo<dim>::subfaces_per_face;
+                    subfaces_per_face = GeometryInfo<dim>::max_children_per_face;
   
                                   // first fix quadrature points
   std::vector<Point<dim> > q_points;
@@ -940,7 +868,6 @@ Quadrature<3>
 QProjector<3>::project_to_all_subfaces (const SubQuadrature &quadrature)
 {
   const unsigned int dim = 3;
-  
   SubQuadrature q_reflected=reflect (quadrature);
   SubQuadrature q[8]=
     {quadrature,
@@ -954,15 +881,15 @@ QProjector<3>::project_to_all_subfaces (const SubQuadrature &quadrature)
 
   const unsigned int n_points          = quadrature.size(),
                     n_faces           = GeometryInfo<dim>::faces_per_cell,
-                    subfaces_per_face = GeometryInfo<dim>::subfaces_per_face;
+              total_subfaces_per_face = 2 + 2 + 4;
   
                                   // first fix quadrature points
   std::vector<Point<dim> > q_points;
-  q_points.reserve (n_points * n_faces * subfaces_per_face * 8);
+  q_points.reserve (n_points * n_faces * total_subfaces_per_face * 8);
   std::vector <Point<dim> > help(n_points);
   
   std::vector<double> weights;
-  weights.reserve (n_points * n_faces * subfaces_per_face * 8);
+  weights.reserve (n_points * n_faces * total_subfaces_per_face * 8);
 
                                   // do the following for all possible
                                   // mutations of a face (mutation==0
@@ -973,24 +900,31 @@ QProjector<3>::project_to_all_subfaces (const SubQuadrature &quadrature)
                                       // project to each face and copy
                                       // results
       for (unsigned int face=0; face<n_faces; ++face)
-       for (unsigned int subface=0; subface<subfaces_per_face; ++subface)
-         {
-           project_to_subface(q[mutation], face, subface, help);
-           std::copy (help.begin(), help.end(),
-                      std::back_inserter (q_points));
-         }
+       for (unsigned int ref_case=RefinementCase<dim-1>::cut_xy;
+            ref_case>=RefinementCase<dim-1>::cut_x;
+            --ref_case)
+         for (unsigned int subface=0; subface<GeometryInfo<dim-1>::n_children(RefinementCase<dim-1>(ref_case)); ++subface)
+           {
+             project_to_subface(q[mutation], face, subface, help,
+                                RefinementCase<dim-1>(ref_case));
+             std::copy (help.begin(), help.end(),
+                        std::back_inserter (q_points));
+           }
 
                                       // next copy over weights
       for (unsigned int face=0; face<n_faces; ++face)
-       for (unsigned int subface=0; subface<subfaces_per_face; ++subface)
-         std::copy (q[mutation].get_weights().begin(),
-                    q[mutation].get_weights().end(),
-                    std::back_inserter (weights));
+       for (unsigned int ref_case=RefinementCase<dim-1>::cut_xy;
+            ref_case>=RefinementCase<dim-1>::cut_x;
+            --ref_case)
+         for (unsigned int subface=0; subface<GeometryInfo<dim-1>::n_children(RefinementCase<dim-1>(ref_case)); ++subface)
+           std::copy (q[mutation].get_weights().begin(),
+                      q[mutation].get_weights().end(),
+                      std::back_inserter (weights));
     }
   
-  Assert (q_points.size() == n_points * n_faces * subfaces_per_face * 8,
+  Assert (q_points.size() == n_points * n_faces * total_subfaces_per_face * 8,
           ExcInternalError());
-  Assert (weights.size() == n_points * n_faces * subfaces_per_face * 8,
+  Assert (weights.size() == n_points * n_faces * total_subfaces_per_face * 8,
           ExcInternalError());  
   
   return Quadrature<dim>(q_points, weights);
@@ -998,13 +932,14 @@ QProjector<3>::project_to_all_subfaces (const SubQuadrature &quadrature)
 
 
 
+// This function is not used in the library
 template <int dim>
 Quadrature<dim>
 QProjector<dim>::project_to_child (const Quadrature<dim>    &quadrature,
                                   const unsigned int        child_no)
 {
-  Assert (child_no < GeometryInfo<dim>::children_per_cell,
-         ExcIndexRange (child_no, 0, GeometryInfo<dim>::children_per_cell));
+  Assert (child_no < GeometryInfo<dim>::max_children_per_cell,
+         ExcIndexRange (child_no, 0, GeometryInfo<dim>::max_children_per_cell));
   
   const unsigned int n_q_points = quadrature.size();
 
@@ -1018,7 +953,7 @@ QProjector<dim>::project_to_child (const Quadrature<dim>    &quadrature,
                                   // scale them
   std::vector<double> weights = quadrature.get_weights ();
   for (unsigned int i=0; i<n_q_points; ++i)
-    weights[i] *= (1./GeometryInfo<dim>::children_per_cell);
+    weights[i] *= (1./GeometryInfo<dim>::max_children_per_cell);
 
   return Quadrature<dim> (q_points, weights);
 }
@@ -1115,28 +1050,88 @@ face (const unsigned int face_no,
 
 
 
-template <int dim>
-typename QProjector<dim>::DataSetDescriptor
-QProjector<dim>::DataSetDescriptor::
+template <>
+QProjector<1>::DataSetDescriptor
+QProjector<1>::DataSetDescriptor::
+subface (const unsigned int,
+         const unsigned int,
+         const bool,
+         const bool,
+         const bool,
+         const unsigned int,
+        const internal::SubfaceCase<1>)
+{
+  Assert (false, ExcInternalError());
+  return deal_II_numbers::invalid_unsigned_int;
+}
+
+
+
+template <>
+QProjector<2>::DataSetDescriptor
+QProjector<2>::DataSetDescriptor::
+subface (const unsigned int face_no,
+         const unsigned int subface_no,
+         const bool,
+         const bool,
+         const bool,
+         const unsigned int n_quadrature_points,
+        const internal::SubfaceCase<2>)
+{
+  Assert (face_no < GeometryInfo<2>::faces_per_cell,
+          ExcInternalError());
+  Assert (subface_no < GeometryInfo<2>::max_children_per_face,
+          ExcInternalError());  
+
+  return ((face_no * GeometryInfo<2>::max_children_per_face +
+          subface_no)
+         * n_quadrature_points);
+}
+
+
+template <>
+QProjector<3>::DataSetDescriptor
+QProjector<3>::DataSetDescriptor::
 subface (const unsigned int face_no,
          const unsigned int subface_no,
          const bool         face_orientation,
          const bool         face_flip,
          const bool         face_rotation,
-         const unsigned int n_quadrature_points)
+         const unsigned int n_quadrature_points,
+        const internal::SubfaceCase<3> ref_case)
 {
-  Assert (dim != 1, ExcInternalError());
+  const unsigned int dim = 3;
+  
   Assert (face_no < GeometryInfo<dim>::faces_per_cell,
           ExcInternalError());
-                                   // the trick with +1 prevents that we get a
-                                   // warning in 1d
-  Assert (subface_no+1 < GeometryInfo<dim>::subfaces_per_face+1,
-          ExcInternalError());
+  Assert (subface_no < GeometryInfo<dim>::max_children_per_face,
+          ExcInternalError());  
+
+                                  // As the quadrature points created by
+                                  // QProjector are on subfaces in their
+                                  // "standard location" we have to use a
+                                  // permutation of the equivalent subface
+                                  // number in order to respect face
+                                  // orientation, flip and rotation. The
+                                  // information we need here is exactly the
+                                  // same as the
+                                  // GeometryInfo<3>::child_cell_on_face info
+                                  // for the bottom face (face 4) of a hex, as
+                                  // on this the RefineCase of the cell matches
+                                  // that of the face and the subfaces are
+                                  // numbered in the same way as the child
+                                  // cells.
   
                                   // in 3d, we have to account for faces that
                                   // have non-standard face orientation, flip
                                   // and rotation. thus, we have to store
                                   // _eight_ data sets per face or subface
+                                  // already for the isotropic
+                                  // case. Additionally, we have three
+                                  // different refinement cases, resulting in
+                                  // <tt>4 + 2 + 2 = 8</tt> differnt subfaces
+                                  // for each face.
+  const unsigned int total_subfaces_per_face=8;
   
                                   // set up a table with the according offsets
                                   // for non-standard orientation, first index:
@@ -1153,39 +1148,207 @@ subface (const unsigned int face_no,
                                   // a face in standard orientation. therefore
                                   // we use the offsets 4,5,6,7,0,1,2,3 here to
                                   // stick to that (implicit) convention
-  static const unsigned int offset[2][2][2]=
+  static const unsigned int orientation_offset[2][2][2]=
     {{
                                           // face_orientation=false; face_flip=false; face_rotation=false and true
-         {4*GeometryInfo<dim>::faces_per_cell*GeometryInfo<dim>::subfaces_per_face,
-          5*GeometryInfo<dim>::faces_per_cell*GeometryInfo<dim>::subfaces_per_face},
+         {4*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face,
+          5*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face},
                                           // face_orientation=false; face_flip=true;  face_rotation=false and true
-         {6*GeometryInfo<dim>::faces_per_cell*GeometryInfo<dim>::subfaces_per_face,
-          7*GeometryInfo<dim>::faces_per_cell*GeometryInfo<dim>::subfaces_per_face}},   
+         {6*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face,
+          7*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face}},   
      {
                                            // face_orientation=true;  face_flip=false; face_rotation=false and true
-          {0*GeometryInfo<dim>::faces_per_cell*GeometryInfo<dim>::subfaces_per_face,
-           1*GeometryInfo<dim>::faces_per_cell*GeometryInfo<dim>::subfaces_per_face},
+          {0*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face,
+           1*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face},
                                            // face_orientation=true;  face_flip=true;  face_rotation=false and true
-          {2*GeometryInfo<dim>::faces_per_cell*GeometryInfo<dim>::subfaces_per_face,
-           3*GeometryInfo<dim>::faces_per_cell*GeometryInfo<dim>::subfaces_per_face}}};
+          {2*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face,
+           3*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face}}};
+
+                                  // set up a table with the offsets for a
+                                  // given refinement case respecting the
+                                  // corresponding number of subfaces. the
+                                  // index corresponds to (RefineCase::Type - 1)
+
+                                  // note, that normally we should use the
+                                  // obvious offsets 0,2,6. However, prior to
+                                  // the implementation of anisotropic
+                                  // refinement, in many places of the library
+                                  // the convention was used, that the first
+                                  // dataset with offset 0 corresponds to a
+                                  // standard (isotropic) face
+                                  // refinement. therefore we use the offsets
+                                  // 6,4,0 here to stick to that (implicit)
+                                  // convention
+  static const unsigned int ref_case_offset[3]=
+    {
+         6,  //cut_x
+         4,  //cut_y
+         0   //cut_xy
+    };
+
+
+                                  // for each subface of a given FaceRefineCase
+                                  // there is a corresponding equivalent
+                                  // subface number of one of the "standard"
+                                  // RefineCases (cut_x, cut_y, cut_xy). Map
+                                  // the given values to those equivalent
+                                  // ones.
+
+                                  // first, define an invalid number
+  static const unsigned int e = deal_II_numbers::invalid_unsigned_int;
   
-  switch (dim)
+  static const RefinementCase<dim-1>
+    equivalent_refine_case[internal::SubfaceCase<dim>::case_isotropic+1][GeometryInfo<3>::max_children_per_face]
+    =
     {
-      case 1:
-      case 2:
-            return ((face_no * GeometryInfo<dim>::subfaces_per_face +
-                     subface_no)
-                    * n_quadrature_points);
-      case 3:
-            return (((face_no * GeometryInfo<dim>::subfaces_per_face +
-                      subface_no)
-                     + offset[face_orientation][face_flip][face_rotation]
-                     )
-                    * n_quadrature_points);
-      default:
-            Assert (false, ExcInternalError());
-    }
-  return numbers::invalid_unsigned_int;              
+                                          // case_none. there should be only
+                                          // invalid values here. However, as
+                                          // this function is also called (in
+                                          // tests) for cells which have no
+                                          // refined faces, use isotropic
+                                          // refinement instead
+         {RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::cut_xy},
+                                          // case_x
+         {RefinementCase<dim-1>::cut_x,
+          RefinementCase<dim-1>::cut_x,
+          RefinementCase<dim-1>::no_refinement,
+          RefinementCase<dim-1>::no_refinement},
+                                          // case_x1y
+         {RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::cut_x,
+          RefinementCase<dim-1>::no_refinement},
+                                          // case_x2y
+         {RefinementCase<dim-1>::cut_x,
+          RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::no_refinement},
+                                          // case_x1y2y
+         {RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::cut_xy},
+                                          // case_y
+         {RefinementCase<dim-1>::cut_y,
+          RefinementCase<dim-1>::cut_y,
+          RefinementCase<dim-1>::no_refinement,
+          RefinementCase<dim-1>::no_refinement},
+                                          // case_y1x
+         {RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::cut_y,
+          RefinementCase<dim-1>::no_refinement},
+                                          // case_y2x
+         {RefinementCase<dim-1>::cut_y,
+          RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::no_refinement},
+                                          // case_y1x2x
+         {RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::cut_xy},
+                                          // case_xy (case_isotropic)
+         {RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::cut_xy,
+          RefinementCase<dim-1>::cut_xy}
+    };
+
+  static const unsigned int
+    equivalent_subface_number[internal::SubfaceCase<dim>::case_isotropic+1][GeometryInfo<3>::max_children_per_face]
+    =
+    {
+                                          // case_none, see above
+         {0,1,2,3},
+                                          // case_x
+         {0,1,e,e},
+                                          // case_x1y
+         {0,2,1,e},
+                                          // case_x2y
+         {0,1,3,e},
+                                          // case_x1y2y
+         {0,2,1,3},
+                                          // case_y
+         {0,1,e,e},
+                                          // case_y1x
+         {0,1,1,e},
+                                          // case_y2x
+         {0,2,3,e},
+                                          // case_y1x2x
+         {0,1,2,3},
+                                          // case_xy (case_isotropic)
+         {0,1,2,3}
+    };
+  
+                                  // If face-orientation or face_rotation are
+                                  // non-standard, cut_x and cut_y have to be
+                                  // exchanged.
+  static const RefinementCase<dim-1> ref_case_permutation[4]
+    ={RefinementCase<dim-1>::no_refinement,
+      RefinementCase<dim-1>::cut_y,
+      RefinementCase<dim-1>::cut_x,
+      RefinementCase<dim-1>::cut_xy};
+
+                                  // set a corresponding (equivalent)
+                                  // RefineCase and subface number
+  const RefinementCase<dim-1> equ_ref_case=equivalent_refine_case[ref_case][subface_no];
+  const unsigned int equ_subface_no=equivalent_subface_number[ref_case][subface_no];
+                                  // make sure, that we got a valid subface and RefineCase 
+  Assert(equ_ref_case!=RefinementCase<dim>::no_refinement, ExcInternalError());
+  Assert(equ_subface_no!=e, ExcInternalError());
+                                  // now, finally respect non-standard faces
+  const RefinementCase<dim-1>
+    final_ref_case = (face_orientation==face_rotation
+                     ?
+                     ref_case_permutation[equ_ref_case]
+                     :
+                     equ_ref_case);
+       
+                                  // what we have now is the number of
+                                  // the subface in the natural
+                                  // orientation of the *face*. what we
+                                  // need to know is the number of the
+                                  // subface concerning the standard face
+                                  // orientation as seen from the *cell*.
+
+                                  // this mapping is not trivial, but we
+                                  // have done exactly this stuff in the
+                                  // child_cell_on_face function. in
+                                  // order to reduce the amount of code
+                                  // as well as to make maintaining the
+                                  // functionality easier we want to
+                                  // reuse that information. So we note
+                                  // that on the bottom face (face 4) of
+                                  // a hex cell the local x and y
+                                  // coordinates of the face and the cell
+                                  // coincide, thus also the refinement
+                                  // case of the face corresponds to the
+                                  // refinement case of the cell
+                                  // (ignoring cell refinement along the
+                                  // z direction). Using this knowledge
+                                  // we can (ab)use the
+                                  // child_cell_on_face function to do
+                                  // exactly the transformation we are in
+                                  // need of now
+  const unsigned int
+    final_subface_no = GeometryInfo<dim>::child_cell_on_face(RefinementCase<dim>(final_ref_case),
+                                                            4,
+                                                            equ_subface_no,
+                                                            face_orientation,
+                                                            face_flip,
+                                                            face_rotation,
+                                                            equ_ref_case);
+       
+  return (((face_no * total_subfaces_per_face
+           + ref_case_offset[final_ref_case-1]
+           + final_subface_no)
+          + orientation_offset[face_orientation][face_flip][face_rotation]
+         )
+         * n_quadrature_points);
 }
 
 
@@ -1227,12 +1390,13 @@ QProjector<dim>::project_to_face(const SubQuadrature &quadrature,
 
 template <int dim>
 Quadrature<dim>
-QProjector<dim>::project_to_subface(const SubQuadrature &quadrature,
-                                   const unsigned int face_no,
-                                   const unsigned int subface_no)
+QProjector<dim>::project_to_subface(const SubQuadrature       &quadrature,
+                                   const unsigned int         face_no,
+                                   const unsigned int         subface_no,
+                                   const RefinementCase<dim-1> &ref_case)
 {
   std::vector<Point<dim> > points(quadrature.size());
-  project_to_subface(quadrature, face_no, subface_no, points);
+  project_to_subface(quadrature, face_no, subface_no, points, ref_case);
   return Quadrature<dim>(points, quadrature.get_weights());
 }
 
index 328f89fe10514a3d5cd31392733e1784a8bcaa0a..5af016f8916bdc381841e1ebd683301a60c28772 100644 (file)
 #define __deal2__fe_h
 
 #include <base/config.h>
+#include <base/geometry_info.h>
 #include <fe/fe_base.h>
 
+
 DEAL_II_NAMESPACE_OPEN
 
 template <int dim> class FEValuesData;
@@ -303,7 +305,7 @@ namespace hp
   for (unsigned int i=0; i<GeometryInfo<dim>::children_per_cell; ++i)
     this->prolongation[i].reinit (this->dofs_per_cell,
                                  this->dofs_per_cell);
-  FETools::compute_embedding_matrices (*this, &this->prolongation[0]);
+  FETools::compute_embedding_matrices (*this, this->prolongation);
  * @endcode
  *
  * <h5>Computing the #restriction matrices for error estimators</h5>
@@ -672,11 +674,18 @@ class FiniteElement : public Subscriptor,
                                      * If projection matrices are not
                                      * implemented in the derived
                                      * finite element class, this
-                                     * function aborts with
-                                     * ExcProjectionVoid.
+                                     * function aborts with 
+                                     * ExcProjectionVoid. You can
+                                     * check whether this is the case
+                                     * by calling the
+                                     * restriction_is_implemented()
+                                     * or the
+                                     * isotropic_restriction_is_implemented()
+                                     * function.
                                      */
     const FullMatrix<double> &
-    get_restriction_matrix (const unsigned int child) const;
+    get_restriction_matrix (const unsigned int child,
+                           const RefinementCase<dim> &refinement_case=RefinementCase<dim>::isotropic_refinement) const;
 
                                     /**
                                      * Embedding matrix between grids.
@@ -725,10 +734,14 @@ class FiniteElement : public Subscriptor,
                                      * ExcEmbeddingVoid. You can
                                      * check whether this is the case
                                      * by calling the
-                                     * prolongation_is_implemented().
+                                     * prolongation_is_implemented()
+                                     * or the
+                                     * isotropic_prolongation_is_implemented()
+                                     * function.
                                      */
     const FullMatrix<double> &
-    get_prolongation_matrix (const unsigned int child) const;
+    get_prolongation_matrix (const unsigned int child,
+                            const RefinementCase<dim> &refinement_case=RefinementCase<dim>::isotropic_refinement) const;
 
                                      /**
                                       * Return whether this element implements
@@ -737,6 +750,18 @@ class FiniteElement : public Subscriptor,
                                       * the get_prolongation_matrix()
                                       * function will generate an error or
                                       * not.
+                                     *
+                                     * Note, that this function
+                                     * returns <code>true</code> only
+                                     * if the prolongation matrices of
+                                     * the isotropic and all
+                                     * anisotropic refinement cases
+                                     * are implemented. If you are
+                                     * interested in the prolongation
+                                     * matrices for isotropic
+                                     * refinement only, use the
+                                     * isotropic_prolongation_is_implemented
+                                     * function instead.
                                       *
                                       * This function is mostly here in order
                                       * to allow us to write more efficient
@@ -758,6 +783,34 @@ class FiniteElement : public Subscriptor,
                                       */
     bool prolongation_is_implemented () const;
 
+                                     /**
+                                      * Return whether this element implements
+                                      * its prolongation matrices for isotropic
+                                      * children. The return value also
+                                      * indicates whether a call to the @p
+                                      * get_prolongation_matrix function will
+                                      * generate an error or not.
+                                      *
+                                      * This function is mostly here in order
+                                      * to allow us to write more efficient
+                                      * test programs which we run on all
+                                      * kinds of weird elements, and for which
+                                      * we simply need to exclude certain
+                                      * tests in case something is not
+                                      * implemented. It will in general
+                                      * probably not be a great help in
+                                      * applications, since there is not much
+                                      * one can do if one needs these features
+                                      * and they are not implemented. This
+                                      * function could be used to check
+                                      * whether a call to
+                                      * <tt>get_prolongation_matrix()</tt> will
+                                      * succeed; however, one then still needs
+                                      * to cope with the lack of information
+                                      * this just expresses.
+                                      */
+    bool isotropic_prolongation_is_implemented () const;
+
                                      /**
                                       * Return whether this element implements
                                       * its restriction matrices. The return
@@ -765,6 +818,18 @@ class FiniteElement : public Subscriptor,
                                       * the get_restriction_matrix()
                                       * function will generate an error or
                                       * not.
+                                     *
+                                     * Note, that this function
+                                     * returns <code>true</code> only
+                                     * if the restriction matrices of
+                                     * the isotropic and all
+                                     * anisotropic refinement cases
+                                     * are implemented. If you are
+                                     * interested in the restriction
+                                     * matrices for isotropic
+                                     * refinement only, use the
+                                     * isotropic_restriction_is_implemented
+                                     * function instead.
                                       *
                                       * This function is mostly here in order
                                       * to allow us to write more efficient
@@ -786,6 +851,35 @@ class FiniteElement : public Subscriptor,
                                       */
     bool restriction_is_implemented () const;
 
+                                     /**
+                                      * Return whether this element implements
+                                      * its restriction matrices for isotropic
+                                      * children. The return value also
+                                      * indicates whether a call to the @p
+                                      * get_restriction_matrix function will
+                                      * generate an error or not.
+                                      *
+                                      * This function is mostly here in order
+                                      * to allow us to write more efficient
+                                      * test programs which we run on all
+                                      * kinds of weird elements, and for which
+                                      * we simply need to exclude certain
+                                      * tests in case something is not
+                                      * implemented. It will in general
+                                      * probably not be a great help in
+                                      * applications, since there is not much
+                                      * one can do if one needs these features
+                                      * and they are not implemented. This
+                                      * function could be used to check
+                                      * whether a call to
+                                      * <tt>get_restriction_matrix()</tt> will
+                                      * succeed; however, one then still needs
+                                      * to cope with the lack of information
+                                      * this just expresses.
+                                      */
+    bool isotropic_restriction_is_implemented () const;
+    
+
                                     /**
                                      * Access the
                                      * #restriction_is_additive_flags
@@ -826,7 +920,7 @@ class FiniteElement : public Subscriptor,
                                      * succeed or generate the
                                      * exception.
                                      */
-    const FullMatrix<double> & constraints () const;
+    const FullMatrix<double> & constraints (const internal::SubfaceCase<dim> &subface_case=internal::SubfaceCase<dim>::case_isotropic) const;
 
                                      /**
                                       * Return whether this element
@@ -858,7 +952,7 @@ class FiniteElement : public Subscriptor,
                                       * the lack of information this
                                       * just expresses.
                                       */
-    bool constraints_are_implemented () const;
+    bool constraints_are_implemented (const internal::SubfaceCase<dim> &subface_case=internal::SubfaceCase<dim>::case_isotropic) const;
 
 
                                      /**
@@ -1866,6 +1960,41 @@ class FiniteElement : public Subscriptor,
     DeclException0 (ExcJacobiDeterminantHasWrongSign);
     
   protected:
+
+                                    /**
+                                     * Reinit the vectors of
+                                     * restriction and prolongation
+                                     * matrices to the right sizes:
+                                     * For every refinement case,
+                                     * except for
+                                     * RefinementCase::no_refinement,
+                                     * and for every child of that
+                                     * refinement case the space of
+                                     * one restriction and
+                                     * prolongation matrix is
+                                     * allocated, see the
+                                     * documentation of the
+                                     * restriction and prolongation
+                                     * vectors for more detail on the
+                                     * actual vector sizes.
+                                     *
+                                     * @param
+                                     * isotropic_restriction_only:
+                                     * only the restriction matrices
+                                     * required for isotropic
+                                     * refinement are reinited to the
+                                     * right size.
+                                     * @param
+                                     * isotropic_prolongation_only:
+                                     * only the prolongation matrices
+                                     * required for isotropic
+                                     * refinement are reinited to the
+                                     * right size.
+                                     */
+    void reinit_restriction_and_prolongation_matrices(const bool isotropic_restriction_only=false,
+                                                     const bool isotropic_prolongation_only=false);
+    
+    
                                     /**
                                      * Store whether all shape
                                      * functions are primitive. Since
@@ -1878,7 +2007,7 @@ class FiniteElement : public Subscriptor,
     const bool cached_primitivity;
 
                                     /**
-                                     * Array of projection
+                                     * Vector of projection
                                      * matrices. See
                                      * get_restriction_matrix()
                                      * above. The constructor
@@ -1886,11 +2015,27 @@ class FiniteElement : public Subscriptor,
                                      * zero dimensions, which can be
                                      * changed by derived classes
                                      * implementing them.
-                                     */
-    FullMatrix<double> restriction[GeometryInfo<dim>::children_per_cell];
+                                     *
+                                     * Note, that
+                                     * <code>restriction[refinement_case-1][child]</code>
+                                     * includes the restriction
+                                     * matrix of child
+                                     * <code>child</code> for the
+                                     * RefinementCase
+                                     * <code>refinement_case</code>. Here,
+                                     * we use
+                                     * <code>refinement_case-1</code>
+                                     * instead of
+                                     * <code>refinement_case</code>
+                                     * as for
+                                     * RefinementCase::no_refinement(=0)
+                                     * there are no restriction
+                                     * matrices available.
+                                     */
+    std::vector<std::vector<FullMatrix<double> > > restriction;
 
                                     /**
-                                     * Array of embedding
+                                     * Vector of embedding
                                      * matrices. See
                                      * <tt>get_prolongation_matrix()</tt>
                                      * above. The constructor
@@ -1898,8 +2043,24 @@ class FiniteElement : public Subscriptor,
                                      * zero dimensions, which can be
                                      * changed by derived classes
                                      * implementing them.
-                                     */
-    FullMatrix<double> prolongation[GeometryInfo<dim>::children_per_cell];
+                                     *
+                                     * Note, that
+                                     * <code>prolongation[refinement_case-1][child]</code>
+                                     * includes the prolongation
+                                     * matrix of child
+                                     * <code>child</code> for the
+                                     * RefinementCase
+                                     * <code>refinement_case</code>. Here,
+                                     * we use
+                                     * <code>refinement_case-1</code>
+                                     * instead of
+                                     * <code>refinement_case</code>
+                                     * as for
+                                     * RefinementCase::no_refinement(=0)
+                                     * there are no prolongation
+                                     * matrices available.
+                                     */
+    std::vector<std::vector<FullMatrix<double> > > prolongation;
 
                                     /**
                                      * Specify the constraints which
index ad6df6474f9c2eea10eecf1e03e6987c383707d4..c1775e82b1cb540fb58cc14c02c775a9d4c8024c 100644 (file)
@@ -311,7 +311,7 @@ class FE_DGP : public FE_Poly<PolynomialSpace<dim>,dim>
                                          * As @p embedding but for
                                          * projection matrices.
                                          */
-       static const double * const projection_matrices[][GeometryInfo<dim>::children_per_cell];
+       static const double * const projection_matrices[][GeometryInfo<dim>::max_children_per_cell];
 
                                         /**
                                          * As
@@ -356,19 +356,19 @@ class FE_DGP : public FE_Poly<PolynomialSpace<dim>,dim>
 // compiler allows us to do that (the standard says we must)
 #ifndef DEAL_II_MEMBER_VAR_SPECIALIZATION_BUG
 template <>
-const double * const FE_DGP<1>::Matrices::projection_matrices[][GeometryInfo<1>::children_per_cell];
+const double * const FE_DGP<1>::Matrices::projection_matrices[][GeometryInfo<1>::max_children_per_cell];
 
 template <>
 const unsigned int FE_DGP<1>::Matrices::n_projection_matrices;
 
 template <>
-const double * const FE_DGP<2>::Matrices::projection_matrices[][GeometryInfo<2>::children_per_cell];
+const double * const FE_DGP<2>::Matrices::projection_matrices[][GeometryInfo<2>::max_children_per_cell];
 
 template <>
 const unsigned int FE_DGP<2>::Matrices::n_projection_matrices;
 
 template <>
-const double * const FE_DGP<3>::Matrices::projection_matrices[][GeometryInfo<3>::children_per_cell];
+const double * const FE_DGP<3>::Matrices::projection_matrices[][GeometryInfo<3>::max_children_per_cell];
 
 template <>
 const unsigned int FE_DGP<3>::Matrices::n_projection_matrices;
index df034ede792eaf5719e108742ec083465089ea7a..3f3e94928a9e129e8e0b8a528bc12e704f65f373 100644 (file)
@@ -419,7 +419,7 @@ class FE_DGPNonparametric : public FiniteElement<dim>
                                          * polynomial degree starting
                                          * from constant elements
                                          */
-       static const double * const embedding[][GeometryInfo<dim>::children_per_cell];
+       static const double * const embedding[][GeometryInfo<dim>::max_children_per_cell];
 
                                         /**
                                          * Number of elements (first
@@ -436,7 +436,7 @@ class FE_DGPNonparametric : public FiniteElement<dim>
                                          * As @p embedding but for
                                          * projection matrices.
                                          */
-       static const double * const projection_matrices[][GeometryInfo<dim>::children_per_cell];
+       static const double * const projection_matrices[][GeometryInfo<dim>::max_children_per_cell];
 
                                         /**
                                          * As
@@ -614,37 +614,37 @@ 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>::children_per_cell];
+const double * const FE_DGPNonparametric<1>::Matrices::embedding[][GeometryInfo<1>::max_children_per_cell];
 
 template <>
 const unsigned int FE_DGPNonparametric<1>::Matrices::n_embedding_matrices;
 
 template <>
-const double * const FE_DGPNonparametric<1>::Matrices::projection_matrices[][GeometryInfo<1>::children_per_cell];
+const double * const FE_DGPNonparametric<1>::Matrices::projection_matrices[][GeometryInfo<1>::max_children_per_cell];
 
 template <>
 const unsigned int FE_DGPNonparametric<1>::Matrices::n_projection_matrices;
 
 template <> 
-const double * const FE_DGPNonparametric<2>::Matrices::embedding[][GeometryInfo<2>::children_per_cell];
+const double * const FE_DGPNonparametric<2>::Matrices::embedding[][GeometryInfo<2>::max_children_per_cell];
 
 template <>
 const unsigned int FE_DGPNonparametric<2>::Matrices::n_embedding_matrices;
 
 template <>
-const double * const FE_DGPNonparametric<2>::Matrices::projection_matrices[][GeometryInfo<2>::children_per_cell];
+const double * const FE_DGPNonparametric<2>::Matrices::projection_matrices[][GeometryInfo<2>::max_children_per_cell];
 
 template <>
 const unsigned int FE_DGPNonparametric<2>::Matrices::n_projection_matrices;
 
 template <> 
-const double * const FE_DGPNonparametric<3>::Matrices::embedding[][GeometryInfo<3>::children_per_cell];
+const double * const FE_DGPNonparametric<3>::Matrices::embedding[][GeometryInfo<3>::max_children_per_cell];
 
 template <>
 const unsigned int FE_DGPNonparametric<3>::Matrices::n_embedding_matrices;
 
 template <>
-const double * const FE_DGPNonparametric<3>::Matrices::projection_matrices[][GeometryInfo<3>::children_per_cell];
+const double * const FE_DGPNonparametric<3>::Matrices::projection_matrices[][GeometryInfo<3>::max_children_per_cell];
 
 template <>
 const unsigned int FE_DGPNonparametric<3>::Matrices::n_projection_matrices;
index 2b65530bf3eb2e895efbf173ce5aca8d4e7789b1..6568e5cfa635d9bcdc5937f52d396558a8e25654 100644 (file)
@@ -350,7 +350,7 @@ class FE_Nedelec : public FiniteElement<dim>
                                          * fields.
                                          */
        static const double * const
-       embedding[][GeometryInfo<dim>::children_per_cell];
+       embedding[][GeometryInfo<dim>::max_children_per_cell];
 
                                         /**
                                          * Number of elements (first
@@ -678,7 +678,7 @@ 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>::children_per_cell];
+FE_Nedelec<1>::Matrices::embedding[][GeometryInfo<1>::max_children_per_cell];
 
 template <>
 const unsigned int FE_Nedelec<1>::Matrices::n_embedding_matrices;
@@ -691,7 +691,7 @@ const unsigned int FE_Nedelec<1>::Matrices::n_constraint_matrices;
 
 template <> 
 const double * const 
-FE_Nedelec<2>::Matrices::embedding[][GeometryInfo<2>::children_per_cell];
+FE_Nedelec<2>::Matrices::embedding[][GeometryInfo<2>::max_children_per_cell];
 
 template <>
 const unsigned int FE_Nedelec<2>::Matrices::n_embedding_matrices;
@@ -704,7 +704,7 @@ const unsigned int FE_Nedelec<2>::Matrices::n_constraint_matrices;
 
 template <> 
 const double * const 
-FE_Nedelec<3>::Matrices::embedding[][GeometryInfo<3>::children_per_cell];
+FE_Nedelec<3>::Matrices::embedding[][GeometryInfo<3>::max_children_per_cell];
 
 template <>
 const unsigned int FE_Nedelec<3>::Matrices::n_embedding_matrices;
index 91353175ef3bdbf3126bccf1a1ca7e069fb5e105..e9a71d18e3e142eb8a15c25f9edfe64b4ee7c9ca 100644 (file)
@@ -352,7 +352,8 @@ FE_Poly<POLY,dim>::fill_fe_subface_values (const Mapping<dim>
                   cell->face_orientation(face),
                   cell->face_flip(face),
                   cell->face_rotation(face),
-                  quadrature.size());
+                  quadrature.size(),
+                  cell->subface_case(face));
 
   const UpdateFlags flags(fe_data.update_once | fe_data.update_each);
 
index e636a0d4d1af9c259b837fc7afe094eefbee0489..05754070aea429b9ec11baed951544df0ead3346 100644 (file)
@@ -305,16 +305,18 @@ class FETools
                                    const FiniteElement<dim>& fe);
     
                                     /**
-                                     * Compute the embedding matrices
-                                     * from a coarse cell to
-                                     * 2<sup>dim</sup> child
-                                     * cells. Each column of the
-                                     * resulting matrices contains
-                                     * the representation of a coarse
-                                     * grid basis functon by the fine
-                                     * grid basis; the matrices are
-                                     * split such that there is one
-                                     * matrix for every child.
+                                     * For all possible (isotropic
+                                     * and anisotropic) refinement
+                                     * cases compute the embedding
+                                     * matrices from a coarse cell to
+                                     * the child cells. Each column
+                                     * of the resulting matrices
+                                     * contains the representation of
+                                     * a coarse grid basis functon by
+                                     * the fine grid basis; the
+                                     * matrices are split such that
+                                     * there is one matrix for every
+                                     * child.
                                      *
                                      * This function computes the
                                      * coarse grid function in a
@@ -328,20 +330,49 @@ class FETools
                                      * the finite element spaces are
                                      * actually nested.
                                      *
+                                     * Note, that
+                                     * <code>matrices[refinement_case-1][child]</code>
+                                     * includes the embedding (or prolongation)
+                                     * matrix of child
+                                     * <code>child</code> for the
+                                     * RefinementCase
+                                     * <code>refinement_case</code>. Here,
+                                     * we use
+                                     * <code>refinement_case-1</code>
+                                     * instead of
+                                     * <code>refinement_case</code>
+                                     * as for
+                                     * RefinementCase::no_refinement(=0)
+                                     * there are no prolongation
+                                     * matrices available.
+                                     *
+                                     * Typically this function is
+                                     * called by the various
+                                     * implementations of
+                                     * FiniteElement classes in order
+                                     * to fill the respective
+                                     * FiniteElement::prolongation
+                                     * matrices.
+                                     *
                                      * @param fe The finite element
                                      * class for which we compute the
-                                     * embedding matrices.
-                                     * @param matrices A pointer to
-                                     * <i>GeometryInfo::children_per_cell=2<sup>dim</sup></i> FullMatrix
-                                     * objects. This is the format
-                                     * used in FiniteElement,
-                                     * where we want to use ths
-                                     * function mostly.
+                                     * embedding matrices.  @param
+                                     * matrices A reference to
+                                     * <tt>RefinementCase<dim>::isotropic_refinement</tt>
+                                     * vectors of FullMatrix
+                                     * objects. Each vector
+                                     * corresponds to one
+                                     * RefinementCase @p
+                                     * refinement_case and is of the
+                                     * vector size
+                                     * <tt>GeometryInfo<dim>::n_children(refinement_case)</tt>. This
+                                     * is the format used in
+                                     * FiniteElement, where we want
+                                     * to use this function mostly.
                                      */
     template <int dim, typename number>
-    static void
-    compute_embedding_matrices(const FiniteElement<dim> &fe,
-                              FullMatrix<number> (&matrices)[GeometryInfo<dim>::children_per_cell]);
+    static void compute_embedding_matrices(const FiniteElement<dim> &fe,
+                                          std::vector<std::vector<FullMatrix<number> > >& matrices);
 
                                     /**
                                      * Compute the embedding matrices
@@ -373,28 +404,61 @@ class FETools
     template<int dim, typename number>
     static void
     compute_face_embedding_matrices(const FiniteElement<dim>& fe,
-                                   FullMatrix<number> (&matrices)[GeometryInfo<dim>::subfaces_per_face],
+                                   FullMatrix<number> (&matrices)[GeometryInfo<dim>::max_children_per_face],
                                    const unsigned int face_coarse,
                                    const unsigned int face_fine);
 
                                     /**
-                                     * Compute the
+                                     * For all possible (isotropic
+                                     * and anisotropic) refinement
+                                     * cases compute the
                                      * <i>L<sup>2</sup></i>-projection
                                      * matrices from the children to
                                      * a coarse cell.
                                      *
-                                     * @arg fe The finite element class for
-                                     * which we compute the projection
-                                     * matrices.  @arg matrices A pointer to
-                                     * <tt>GeometryInfo::children_per_cell</tt>=2<sup>dim</sup>
-                                     * FullMatrix objects. This is the format
-                                     * used in FiniteElement, where we
-                                     * want to use this function mostly.
+                                     * Note, that
+                                     * <code>matrices[refinement_case-1][child]</code>
+                                     * includes the projection (or restriction)
+                                     * matrix of child
+                                     * <code>child</code> for the
+                                     * RefinementCase
+                                     * <code>refinement_case</code>. Here,
+                                     * we use
+                                     * <code>refinement_case-1</code>
+                                     * instead of
+                                     * <code>refinement_case</code>
+                                     * as for
+                                     * RefinementCase::no_refinement(=0)
+                                     * there are no projection
+                                     * matrices available.
+                                     *
+                                     * Typically this function is
+                                     * called by the various
+                                     * implementations of
+                                     * FiniteElement classes in order
+                                     * to fill the respective
+                                     * FiniteElement::restriction
+                                     * matrices.
+                                     *
+                                     * @arg fe The finite element
+                                     * class for which we compute the
+                                     * projection matrices.  @arg
+                                     * matrices A reference to
+                                     * <tt>RefinementCase<dim>::isotropic_refinement</tt>
+                                     * vectors of FullMatrix
+                                     * objects. Each vector
+                                     * corresponds to one
+                                     * RefinementCase @p
+                                     * refinement_case and is of the
+                                     * vector size
+                                     * <tt>GeometryInfo<dim>::n_children(refinement_case)</tt>. This
+                                     * is the format used in
+                                     * FiniteElement, where we want
+                                     * to use this function mostly.
                                      */
     template <int dim, typename number>
-    static void
-    compute_projection_matrices(const FiniteElement<dim> &fe,
-                               FullMatrix<number> (&matrices)[GeometryInfo<dim>::children_per_cell]);
+    static void compute_projection_matrices(const FiniteElement<dim> &fe,
+                                           std::vector<std::vector<FullMatrix<number> > >& matrices);
 
 //TODO:[WB] Replace this documentation by something comprehensible
     
index b14128ebfa7c8bf9dd519a5eb1748b53e0bd481b..54edbc94e98c798b9330da057559a95d016c5a5b 100644 (file)
@@ -35,6 +35,7 @@
 #include <fe/fe.h>
 #include <fe/fe_update_flags.h>
 #include <fe/mapping.h>
+#include <fe/mapping_q.h>
 #include <multigrid/mg_dof_handler.h>
 #include <multigrid/mg_dof_accessor.h>
 
@@ -556,6 +557,18 @@ class FEValuesData
                                      */
     std::vector<double>       JxW_values;
 
+                                    /**
+                                     * Array of the Jacobian matrices at the
+                                     * quadrature points.
+                                     */
+    std::vector<Tensor<2,dim> > jacobians;
+    
+                                    /**
+                                     * Array of the derivatives of the Jacobian
+                                     * matrices at the quadrature points.
+                                     */
+    std::vector<Tensor<3,dim> > jacobian_grads;
+    
                                     /**
                                      * Store an array of weights
                                      * times the Jacobi determinant
@@ -1591,6 +1604,36 @@ class FEValuesBase : protected FEValuesData<dim>,
                                      */
     const std::vector<double> & get_JxW_values () const;
     
+                                    /**
+                                     * Return the Jacobian of the
+                                     * transformation at the specified
+                                     * quadrature point, i.e.
+                                     * $J_{ij}=dx_i/d\hat x_j$
+                                     */
+    const Tensor<2,dim> & 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;
+
+                                    /**
+                                     * Return the second derivative of the
+                                     * transformation from unit to real cell,
+                                     * i.e. the first derivative of the
+                                     * 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;
+
+                                    /**
+                                     * Pointer to the array holding
+                                     * the values returned by
+                                     * jacobian_grads().
+                                     */
+    const std::vector<Tensor<3,dim> > & get_jacobian_grads () const;
+    
                                     /**
                                      * Constant reference to the
                                      * selected mapping object.
@@ -3973,6 +4016,28 @@ FEValuesBase<dim>::get_JxW_values () const
 
 
 
+template <int dim>
+inline
+const std::vector<Tensor<2,dim> >&
+FEValuesBase<dim>::get_jacobians () const
+{
+  Assert (this->update_flags & update_jacobians, ExcAccessToUninitializedField());
+  return this->jacobians;
+}
+
+
+
+template <int dim>
+inline
+const std::vector<Tensor<3,dim> >&
+FEValuesBase<dim>::get_jacobian_grads () const
+{
+  Assert (this->update_flags & update_jacobian_grads, ExcAccessToUninitializedField());
+  return this->jacobian_grads;
+}
+
+
+
 template <int dim>
 inline
 const Point<dim> &
@@ -4000,6 +4065,32 @@ FEValuesBase<dim>::JxW (const unsigned int i) const
 
 
 
+template <int dim>
+inline
+const Tensor<2,dim> &
+FEValuesBase<dim>::jacobian (const unsigned int i) const
+{
+  Assert (this->update_flags & update_jacobians, ExcAccessToUninitializedField());
+  Assert (i<this->jacobians.size(), ExcIndexRange(i, 0, this->jacobians.size()));
+  
+  return this->jacobians[i];
+}
+
+
+
+template <int dim>
+inline
+const Tensor<3,dim> &
+FEValuesBase<dim>::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()));
+  
+  return this->jacobian_grads[i];
+}
+
+
+
 template <int dim>
 template <class InputVector>
 inline
index 5dd92c7553ba59f57109e03516e9dd798ec5df1f..88c3992a00c6b69cbdb400e7a059e0a14f54365c 100644 (file)
@@ -472,7 +472,7 @@ class Mapping : public Subscriptor
                                      * filled have to have the
                                      * correct size.
                                      *
-                                     * Values are split into three
+                                     * Values are split into two
                                      * groups: first,
                                      * @p quadrature_points and
                                      * @p JxW_values are
@@ -484,18 +484,18 @@ class Mapping : public Subscriptor
                                      * matrices needed to transform
                                      * vector-valued functions,
                                      * namely
-                                     * @p covariant_transformation,
-                                     * @p contravariant_transformation and the 
-                                     * derivatives
-                                     * @p covariant_grads.
-                                     *
+                                     * @p jacobians
+                                     * and the derivatives
+                                     * @p jacobian_grads.
                                      */
     virtual void
     fill_fe_values (const typename Triangulation<dim>::cell_iterator &cell,
                    const Quadrature<dim>                         &quadrature,
                    InternalDataBase                              &internal,
                    std::vector<Point<dim> >                      &quadrature_points,
-                   std::vector<double>                           &JxW_values) const = 0;
+                   std::vector<double>                           &JxW_values,
+                   std::vector<Tensor<2,dim> >                   &jacobians,
+                   std::vector<Tensor<3,dim> >                   &jacobian_grads) const = 0;
 
                                     /**
                                      * Performs the same as @p fill_fe_values
index 826b7ee88c81efe1340b4e5440efdecb15192d8b..d9bf66f544ed614244cd2ca4951eda2bf8be45c7 100644 (file)
@@ -59,7 +59,9 @@ class MappingCartesian : public Mapping<dim>
                    const Quadrature<dim>& quadrature,
                    typename Mapping<dim>::InternalDataBase &mapping_data,
                    std::vector<Point<dim> >        &quadrature_points,
-                   std::vector<double>             &JxW_values) const ;
+                   std::vector<double>             &JxW_values,
+                   std::vector<Tensor<2,dim> >     &jacobians,
+                   std::vector<Tensor<3,dim> >     &jacobian_grads) const ;
 
     virtual void
     fill_fe_face_values (const typename Triangulation<dim>::cell_iterator &cell,
index 2b19721dace7a830ee2bd195393d5f5c2d257a77..2f903a3e4f34b98e931e476beda9f9105f442d96 100644 (file)
@@ -231,7 +231,9 @@ class MappingQ : public MappingQ1<dim>
                    const Quadrature<dim>                &quadrature,
                    typename Mapping<dim>::InternalDataBase &mapping_data,
                    typename std::vector<Point<dim> >             &quadrature_points,
-                   std::vector<double>                  &JxW_values) const ;
+                   std::vector<double>                  &JxW_values,
+                   std::vector<Tensor<2,dim> >          &jacobians,
+                   std::vector<Tensor<3,dim> >          &jacobian_grads) const ;
 
                                     /**
                                      * Implementation of the interface in
index 9a75ebf402dfbf3f49972f14364474caa34ebc92..c600375b5eb937cddbdddf0ef43aa544ef401cf5 100644 (file)
@@ -151,6 +151,22 @@ class MappingQ1 : public Mapping<dim>
        Tensor<1,dim> &derivative (const unsigned int qpoint,
                                   const unsigned int shape_nr);
 
+                                        /**
+                                         * Second derivative of shape
+                                         * function in quadrature
+                                         * point. See above.
+                                         */
+       Tensor<2,dim> second_derivative (const unsigned int qpoint,
+                                        const unsigned int shape_nr) const;
+
+                                        /**
+                                         * Second derivative of shape
+                                         * function in quadrature
+                                         * point. See above.
+                                         */
+       Tensor<2,dim> &second_derivative (const unsigned int qpoint,
+                                         const unsigned int shape_nr);
+
                                         /**
                                          * Return an estimate (in
                                          * bytes) or the memory
@@ -177,6 +193,16 @@ class MappingQ1 : public Mapping<dim>
                                          */
        std::vector<Tensor<1,dim> > shape_derivatives;
        
+                                        /**
+                                         * Values of shape function
+                                         * second derivatives. Access
+                                         * by function
+                                         * @p second_derivative.
+                                         *
+                                         * Computed once.
+                                         */
+       std::vector<Tensor<2,dim> > shape_second_derivatives;
+       
                                         /**
                                          * Tensors of covariant
                                          * transformation at each of
@@ -199,7 +225,7 @@ class MappingQ1 : public Mapping<dim>
                                          * contravariant matrix is
                                          * the Jacobian of the
                                          * transformation,
-                                         * i.e. $J_ij=dx_i/d\hat x_j$.
+                                         * i.e. $J_{ij}=dx_i/d\hat x_j$.
                                          *
                                          * Computed on each cell.
                                          */
@@ -281,7 +307,9 @@ class MappingQ1 : public Mapping<dim>
                    const Quadrature<dim>& quadrature,
                    typename Mapping<dim>::InternalDataBase &mapping_data,
                    typename std::vector<Point<dim> >       &quadrature_points,
-                   std::vector<double>             &JxW_values) const ;
+                   std::vector<double>             &JxW_values,
+                   std::vector<Tensor<2,dim> >     &jacobians,
+                   std::vector<Tensor<3,dim> >     &jacobian_grads) const ;
 
                                     /**
                                      * Implementation of the interface in
@@ -375,7 +403,7 @@ class MappingQ1 : public Mapping<dim>
                                      */
     void compute_fill_face (const typename Triangulation<dim>::cell_iterator &cell,
                            const unsigned int      face_no,
-                           const bool              is_subface,
+                           const unsigned int      subface_no,
                            const unsigned int      npts,
                            const DataSetDescriptor data_set,
                            const std::vector<double>   &weights,
@@ -652,6 +680,32 @@ MappingQ1<dim>::InternalData::derivative (const unsigned int qpoint,
 }
 
 
+template <int dim>
+inline
+Tensor<2,dim>
+MappingQ1<dim>::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,
+                      shape_second_derivatives.size()));
+  return shape_second_derivatives [qpoint*n_shape_functions + shape_nr];
+}
+
+
+
+template <int dim>
+inline
+Tensor<2,dim> &
+MappingQ1<dim>::InternalData::second_derivative (const unsigned int qpoint,
+                                                const unsigned int shape_nr)
+{
+  Assert(qpoint*n_shape_functions + shape_nr < shape_second_derivatives.size(),
+        ExcIndexRange(qpoint*n_shape_functions + shape_nr, 0,
+                      shape_second_derivatives.size()));
+  return shape_second_derivatives [qpoint*n_shape_functions + shape_nr];
+}
+
 
 
 
@@ -679,7 +733,7 @@ MappingQ1<1>::compute_face_data (const UpdateFlags,
 template <> void MappingQ1<1>::compute_fill_face (
   const Triangulation<1>::cell_iterator &,
   const unsigned int,
-  const bool,
+  const unsigned int,
   const unsigned int,
   const DataSetDescriptor,
   const std::vector<double> &,
index 84e1bd7d903c85f1cf8d2a65e684751ff670c848..a4bce05c5d906049134ea3f8b7458a3a4b4d51ea 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 by the deal.II authors
+//    Copyright (C) 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
@@ -426,7 +426,16 @@ class GridTools
     static
     std::vector<typename Container::active_cell_iterator>
     get_active_child_cells (const typename Container::cell_iterator &cell);
-    
+
+                                    /**
+                                     * Extract the active cells around a given
+                                     * cell @p cell and return them in the
+                                     * vector @p active_neighbors.
+                                     */
+    template <class Container>
+    static void
+    get_active_neighbors (const typename Container::active_cell_iterator        &cell,
+                         std::vector<typename Container::active_cell_iterator> &active_neighbors);    
     
                                      /**
                                       * Use the METIS partitioner to generate
@@ -734,7 +743,7 @@ GridTools::get_active_child_cells (const typename DH::cell_iterator& cell)
   if (cell->has_children())
     {
       for (unsigned int child=0;
-          child<GeometryInfo<DH::dimension>::children_per_cell; ++child)
+          child<cell->n_children(); ++child)
        if (cell->child (child)->has_children())
          {
            const std::vector<typename DH::active_cell_iterator>
@@ -750,6 +759,70 @@ GridTools::get_active_child_cells (const typename DH::cell_iterator& cell)
 }
 
 
+  
+#if deal_II_dimension == 1
+
+template <class Container>
+void
+GridTools::get_active_neighbors(const typename Container::active_cell_iterator        &cell,
+                               std::vector<typename Container::active_cell_iterator> &active_neighbors)
+{
+  active_neighbors.clear ();
+  for (unsigned int n=0; n<GeometryInfo<1>::faces_per_cell; ++n)
+    if (! cell->at_boundary(n))
+      {
+                                        // check children of neighbor. note
+                                        // that in 1d children of the neighbor
+                                        // may be further refined. In 1d the
+                                        // case is simple since we know what
+                                        // children bound to the present cell
+       typename Container::cell_iterator
+         neighbor_child = cell->neighbor(n);
+       if (!neighbor_child->active())
+         {
+           while (neighbor_child->has_children())
+             neighbor_child = neighbor_child->child (n==0 ? 1 : 0);
+       
+           Assert (neighbor_child->neighbor(n==0 ? 1 : 0)==cell,
+                   ExcInternalError());
+         }
+       active_neighbors.push_back (neighbor_child);
+      }
+}
+
+#else
+
+template <class Container>
+void
+GridTools::get_active_neighbors(const typename Container::active_cell_iterator        &cell,
+                               std::vector<typename Container::active_cell_iterator> &active_neighbors)
+{
+  active_neighbors.clear ();
+  for (unsigned int n=0; n<GeometryInfo<Container::dimension>::faces_per_cell; ++n)
+    if (! cell->at_boundary(n))
+      {
+       if (cell->face(n)->has_children())
+                                          // this neighbor has children. find
+                                          // out which border to the present
+                                          // cell
+         for (unsigned int c=0; c<cell->face(n)->number_of_children(); ++c)
+           active_neighbors.push_back (cell->neighbor_child_on_subface(n,c));
+       else
+         {
+                                            // the neighbor must be active
+                                            // himself
+           Assert(cell->neighbor(n)->active(), ExcInternalError());
+           active_neighbors.push_back(cell->neighbor(n));
+         }
+      }
+}
+
+
+#endif
+
+
+
+
 // declaration of explicit specializations
 template <>
 double
index 329b64587366de90834baad6ef1c297789763108..45fcc6da0cff612502bef2a4adf86ae1ba5c191c 100644 (file)
@@ -724,6 +724,14 @@ namespace internal
  *     @p limit_level_difference_at_vertices, situations as the above one are
  *     eliminated by also marking the lower left cell for refinement.
  *
+ *     In case of anisotropic refinement, the level of a cell is not linked to
+ *     the refinement of a cell as directly as in case of isotropic
+ *     refinement. Furthermore, a cell can be strongly refined in one direction
+ *     and not or at least much less refined in another. Therefore, it is very
+ *     difficult to decide, which cases should be excluded from the refinement
+ *     process. As a consequence, when using anisotropic refinement, the @p
+ *     limit_level_difference_at_vertices flag must not be set.
+ *
  *   <li> @p eliminate_unrefined_islands:
  *     Single cells which are not refined and are surrounded by cells which are
  *     refined usually also lead to a sharp decline in approximation properties
@@ -820,6 +828,32 @@ namespace internal
  *     This flag includes all the above ones and therefore combines all
  *     smoothing algorithms implemented.
  *
+ *   <li> @p allow_anisotropic_smoothing: 
+ *     This flag is not included in @p maximum_smoothing. The flag is
+ *     concerned with the following case: consider the case that an
+ *     unrefined and a refined cell share a common face and that one
+ *     of the children of the refined cell along the common face is
+ *     flagged for further refinement. In that case, the resulting
+ *     mesh would have more than one hanging node along one or more of
+ *     the edges of the triangulation, a situation that is not
+ *     allowed. Consequently, in order to perform the refinement, the
+ *     coarser of the two original cells is also going to be refined.
+ *
+ *     However, in many cases it is sufficient to refine the coarser
+ *     of the two original cells in an anisotropic way to avoid the
+ *     case of multiple hanging vertices on a single edge. Doing only
+ *     the minimal anisotropic refinement can save cells and degrees
+ *     of freedom. By specifying this flag, the library can produce
+ *     these anisotropic refinements.
+ *
+ *     The flag is not included by default since it may lead to
+ *     anisotropically refined meshes even though no cell has ever
+ *     been refined anisotropically explicitly by a user command. This
+ *     surprising fact may lead to programs that do the wrong thing
+ *     since they are not written for the additional cases that can
+ *     happen with anisotropic meshes, see the discussion in the
+ *     introduction to @ref step_30 "step-30".
+ *
  *   <li> @p none:
  *     Select no smoothing at all.
  *   </ul>
@@ -1134,7 +1168,7 @@ namespace internal
  *   object, you should be well aware that you might involuntarily alter the
  *   data stored in the triangulation.
  *
- * @ingroup grid
+ * @ingroup grid aniso
  * @author Wolfgang Bangerth, 1998; Ralf Hartmann, 2005
  */
 template <int dim>
@@ -1172,6 +1206,8 @@ class Triangulation : public Subscriptor
          eliminate_unrefined_islands        = 0x2,
          patch_level_1                      = 0x4,
          coarsest_level_1                   = 0x8,
+
+         allow_anisotropic_smoothing        = 0x10,
          
          eliminate_refined_inner_islands    = 0x100,
          eliminate_refined_boundary_islands = 0x200,
@@ -1183,7 +1219,7 @@ class Triangulation : public Subscriptor
                                                eliminate_refined_boundary_islands |
                                                do_not_produce_unrefined_islands),
          
-         maximum_smoothing                  = 0xffff
+         maximum_smoothing                  = 0xffff ^ allow_anisotropic_smoothing
     };
     
 
@@ -1735,6 +1771,12 @@ class Triangulation : public Subscriptor
                                      */
     void load_coarsen_flags (const std::vector<bool> &v);
 
+                                    /**
+                                     * Return whether this triangulation has
+                                     * ever undergone anisotropic (as opposed
+                                     * to only isotropic) refinement.
+                                     */
+    bool get_anisotropic_refinement_flag() const;
                                     /*@}*/
 
 
@@ -3052,6 +3094,23 @@ 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
@@ -3064,20 +3123,53 @@ class Triangulation : public Subscriptor
                                      * decide whether a refined line may be
                                      * coarsened or not in 3D. In 1D and 2D
                                      * this argument is not needed and thus
-                                     * ignored.
+                                     * ignored. The same applies for the last
+                                     * argument and quads instead of lines.
                                      */
     void delete_children (cell_iterator &cell,
-                         std::vector<unsigned int> &cell_count);
+                         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 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
+                                     * 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_line (std::vector<unsigned int> &cell_count);
+    void count_cells_at_quad (std::vector<unsigned int> &quad_cell_count);
 
                                     /**
                                      * Some dimension dependent stuff for
@@ -3098,12 +3190,36 @@ class Triangulation : public Subscriptor
                                      */
     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
@@ -3177,6 +3293,13 @@ class Triangulation : public Subscriptor
                                      */
     SmartPointer<const Boundary<dim> > boundary[255];
 
+                                    /**
+                                     * Flag indicating whether
+                                     * anisotropic refinement took
+                                     * place.
+                                     */
+    bool                             anisotropic_refinement;
+
                                     /**
                                      *  Do some smoothing in the process
                                      *  of refining the triangulation. See
@@ -3276,6 +3399,7 @@ 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;
@@ -3286,11 +3410,14 @@ 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;
@@ -3385,10 +3512,25 @@ 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> &);
-template <> void Triangulation<2>::delete_children (cell_iterator &cell, std::vector<unsigned int> &);
-template <> void Triangulation<3>::delete_children (cell_iterator &cell, std::vector<unsigned int> &cell_count);
-template <> void Triangulation<3>::count_cells_at_line (std::vector<unsigned int> &cell_count);
+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 ();
index 0f59aedefcf9f5a12cf1bf6b993ec9351b6ac4bc..83bb7515cadb965012c843d7243f885d7865bfb0 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <base/config.h>
 #include <base/exceptions.h>
+#include <base/geometry_info.h>
 #include <grid/tria_iterator_base.h>
 
 
@@ -68,6 +69,10 @@ namespace TriaAccessorExceptions
                                   /**
                                    * @ingroup Exceptions
                                    */
+  DeclException0 (ExcCellNotActive);
+                                  /**
+                                   * @ingroup Exceptions
+                                   */
   DeclException1 (ExcInvalidNeighbor,
                  int,
                  << "Neighbor indices must be between 0 and 2^dim-1, but "
@@ -116,6 +121,13 @@ namespace TriaAccessorExceptions
                                    * @ingroup Exceptions
                                    */
   DeclException0 (ExcFacesHaveNoLevel);
+                                  /**
+                                   * @ingroup Exceptions
+                                   */
+  DeclException1 (ExcSetOnlyEvenChildren,
+                 int,
+                 << "You can only set the child index of an even numbered child."
+                 << "The number of the child given was " << arg1 << ".");    
 }
 
 
@@ -771,6 +783,42 @@ class TriaObjectAccessor :  public TriaAccessor<celldim,dim>
                                      * function.
                                      */
     void recursively_clear_user_index () const;
+
+                                    /**
+                                     * Return the @p RefinementCase<dim>
+                                     * of this cell.
+                                     */
+    RefinementCase<celldim> refinement_case() 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).
+                                     *
+                                     * 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<celldim> &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;
                                     /*@}*/
     
                                     /**
@@ -780,6 +828,17 @@ class TriaObjectAccessor :  public TriaAccessor<celldim,dim>
     TriaIterator<dim,TriaObjectAccessor<celldim,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<celldim,dim> >
+    isotropic_child (const unsigned int i) const;
+
                                     /**
                                      *  Index of the @p ith child.
                                      *  The level of the child is one
@@ -793,17 +852,31 @@ class TriaObjectAccessor :  public TriaAccessor<celldim,dim>
     int child_index (const unsigned int i) const;
 
                                     /**
-                                     *  Set the child field. Since we
-                                     *  only store the index of the
-                                     *  first child (the others
-                                     *  follow directly) only one
-                                     *  child index is to be
-                                     *  given. The level of the child
-                                     *  is one level up of the level
-                                     *  of the cell to which this
-                                     *  iterator points.
+                                     *  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 int index) const;
+    void set_children (const unsigned int i, const int index) const;
        
                                     /**
                                      *  Clear the child field,
@@ -829,6 +902,22 @@ class TriaObjectAccessor :  public TriaAccessor<celldim,dim>
                                      * <tt>has_children()==true</tt>.
                                      */
     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
@@ -985,9 +1074,9 @@ class TriaObjectAccessor :  public TriaAccessor<celldim,dim>
                                      * which are not further
                                      * refined. Thus, if all of the
                                      * eight children of a hex are
-                                     * further refined exactly once,
-                                     * the returned number will be
-                                     * 64, not 80.
+                                     * further refined isotropically
+                                     * exactly once, the returned
+                                     * number will be 64, not 80.
                                      *
                                      * If the present cell is not refined,
                                      * one is returned.
@@ -1423,6 +1512,12 @@ class TriaObjectAccessor<1, dim> :  public TriaAccessor<1,dim>
                                      * <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
@@ -1478,6 +1573,16 @@ class TriaObjectAccessor<1, dim> :  public TriaAccessor<1,dim>
     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
@@ -1492,12 +1597,30 @@ class TriaObjectAccessor<1, dim> :  public TriaAccessor<1,dim>
     int child_index (const unsigned int i) const;
 
                                     /**
-                                     *  Set the child field. Since we
-                                     *  only store the index of the
-                                     *  first child (the others
-                                     *  follow directly) only one
-                                     *  child index is to be
-                                     *  given. The level of the child
+                                     *  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
@@ -1505,7 +1628,7 @@ class TriaObjectAccessor<1, dim> :  public TriaAccessor<1,dim>
                                      *  Otherwise the line and its children
                                      *  have no level.
                                      */
-    void set_children (const int index) const;
+    void set_children (const unsigned int i, const int index) const;
        
                                     /**
                                      *  Clear the child field,
@@ -1532,6 +1655,22 @@ class TriaObjectAccessor<1, dim> :  public TriaAccessor<1,dim>
                                      */
     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
@@ -2127,12 +2266,55 @@ class TriaObjectAccessor<2, dim> :  public TriaAccessor<2,dim>
                                      * 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
@@ -2147,17 +2329,31 @@ class TriaObjectAccessor<2, dim> :  public TriaAccessor<2,dim>
     int child_index (const unsigned int i) const;
 
                                     /**
-                                     *  Set the child field. Since we
-                                     *  only store the index of the
-                                     *  first child (the others
-                                     *  follow directly) only one
-                                     *  child index is to be
-                                     *  given. The level of the child
-                                     *  is one level up of the level
-                                     *  of the cell to which this
-                                     *  iterator points.
+                                     *  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 int index) const;
+    void set_children (const unsigned int i, const int index) const;
        
                                     /**
                                      *  Clear the child field,
@@ -2184,6 +2380,22 @@ class TriaObjectAccessor<2, dim> :  public TriaAccessor<2,dim>
                                      */
     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
@@ -2379,9 +2591,10 @@ class TriaObjectAccessor<2, dim> :  public TriaAccessor<2,dim>
                                      * number if quads which are not
                                      * further refined. Thus, if all
                                      * of the four children of a quad
-                                     * are further refined exactly
-                                     * once, the returned number will
-                                     * be 16, not 20.
+                                     * are further refined
+                                     * isotropically exactly once,
+                                     * the returned number will be
+                                     * 16, not 20.
                                      *
                                      * If the present cell is not
                                      * refined, one is returned.
@@ -2836,6 +3049,37 @@ class TriaObjectAccessor<3, dim> :  public TriaAccessor<3,dim>
                                      */
     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.
@@ -2843,6 +3087,17 @@ class TriaObjectAccessor<3, dim> :  public TriaAccessor<3,dim>
     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
@@ -2854,17 +3109,31 @@ class TriaObjectAccessor<3, dim> :  public TriaAccessor<3,dim>
     int child_index (const unsigned int i) const;
 
                                     /**
-                                     *  Set the child field. Since we
-                                     *  only store the index of the
-                                     *  first child (the others
-                                     *  follow directly) only one
-                                     *  child index is to be
-                                     *  given. The level of the child
-                                     *  is one level up of the level
-                                     *  of the cell to which this
-                                     *  iterator points.
+                                     *  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 int index) const;
+    void set_children (const unsigned int i, const int index) const;
        
                                     /**
                                      *  Clear the child field,
@@ -2891,6 +3160,22 @@ class TriaObjectAccessor<3, dim> :  public TriaAccessor<3,dim>
                                      */
     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
@@ -3068,9 +3353,10 @@ class TriaObjectAccessor<3, dim> :  public TriaAccessor<3,dim>
                                      * number if hexs which are not
                                      * further refined. Thus, if all
                                      * of the eight children of a hex
-                                     * are further refined exactly
-                                     * once, the returned number will
-                                     * be 64, not 80.
+                                     * are further refined
+                                     * isotropically exactly once,
+                                     * the returned number will be
+                                     * 64, not 80.
                                      *
                                      * If the present cell is not
                                      * refined, one is returned.
@@ -3345,9 +3631,9 @@ class CellAccessor :  public TriaObjectAccessor<dim,dim>
                                      * Return the how-many'th
                                      * neighbor this cell is of
                                      * <tt>cell->neighbor(neighbor)</tt>,
-                                     * i.e. return the number @p n
+                                     * i.e. return the @p face_no
                                      * such that
-                                     * <tt>cell->neighbor(neighbor)->neighbor(n)==cell</tt>. This
+                                     * <tt>cell->neighbor(neighbor)->neighbor(face_no)==cell</tt>. This
                                      * function is the right one if
                                      * you want to know how to get
                                      * back from a neighbor to the
@@ -3355,26 +3641,52 @@ class CellAccessor :  public TriaObjectAccessor<dim,dim>
                                      *
                                      * Note that this operation is
                                      * only useful if the neighbor is
-                                     * not on a coarser level than
-                                     * the present cell
-                                     * (i.e. <tt>cell->neighbor(neighbor)->level()</tt>
-                                     * needs to be equal to
-                                     * <tt>cell->level()</tt>. Use the
-                                     * @p neighbor_of_coarser_neighbor
+                                     * not coarser than the present
+                                     * cell. If the neighbor is
+                                     * coarser this function throws
+                                     * an exception. Use the @p
+                                     * neighbor_of_coarser_neighbor
                                      * function in that case.
                                      */
     unsigned int neighbor_of_neighbor (const unsigned int neighbor) const;
+
+                                    /**
+                                     * Return, whether the neighbor
+                                     * is coarser then the present
+                                     * cell. This is important in
+                                     * case of ansiotropic
+                                     * refinement where this
+                                     * information does not depend on
+                                     * the levels of the cells.
+                                     *
+                                     * Note, that in an anisotropic
+                                     * setting, a cell can only be
+                                     * coarser than another one at a
+                                     * given face, not on a general
+                                     * basis. The face of the finer
+                                     * cell is contained in the
+                                     * corresponding face of the
+                                     * coarser cell, the finer face
+                                     * is either a child or a
+                                     * grandchild of the coarser
+                                     * face.
+                                     */
+    bool neighbor_is_coarser (const unsigned int neighbor) const;
     
                                     /**
-                                     * This function is a
-                                     * generalization of the
-                                     * @p neighbor_of_neighbor
-                                     * function for the case of a
-                                     * coarser neighbor. It returns a
-                                     * pair of numbers, face_no and
-                                     * subface_no, with the following
-                                     * property:
+                                     * This function is a generalization of the
+                                     * @p neighbor_of_neighbor function for the
+                                     * case of a coarser neighbor. It returns a
+                                     * pair of numbers, face_no and subface_no,
+                                     * with the following property, if the
+                                     * neighbor is not refined:
                                      * <tt>cell->neighbor(neighbor)->neighbor_child_on_subface(face_no,subface_no)==cell</tt>.
+                                     * In 3D, a coarser neighbor can still be
+                                     * refined. In that case subface_no denotes the child index of the neighbors face that relates to our face:
+                                     * <tt>cell->neighbor(neighbor)->face(face_no)->child(subface_no)==cell->face(neighbor)</tt>.
+                                     * This case in 3d and how it can happen
+                                     * is discussed in the introduction of the
+                                     * @ref step_30 "step-30" tutorial program.
                                      *
                                      * This function is impossible
                                      * for <tt>dim==1</tt>.
@@ -3382,6 +3694,17 @@ class CellAccessor :  public TriaObjectAccessor<dim,dim>
     std::pair<unsigned int, unsigned int>
     neighbor_of_coarser_neighbor (const unsigned int neighbor) const;
     
+                                    /**
+                                     * This function is a generalization of the
+                                     * @p neighbor_of_neighbor and the @p
+                                     * neighbor_of_coarser_neighbor
+                                     * functions. It checks whether the
+                                     * neighbor is coarser or not and calls the
+                                     * respective function. In both cases, only
+                                     * the face_no is returned.
+                                     */
+    unsigned int neighbor_face_no (const unsigned int neighbor) const;
+    
                                     /**
                                      *  Return whether the @p ith
                                      *  vertex or face (depending on
@@ -3428,24 +3751,66 @@ class CellAccessor :  public TriaObjectAccessor<dim,dim>
     bool has_boundary_lines () const;
 
                                     /**
-                                     *  Return whether the refinement
-                                     *  flag is set or not.
+                                     *  Return the @p
+                                     *  RefinementCase<dim> this cell
+                                     *  was flagged to be refined
+                                     *  with.
                                      */
-    bool refine_flag_set () const;
+    RefinementCase<dim> refine_flag_set () const;
 
                                     /**
-                                     *  Flag the cell pointed to fo
+                                     *  Flag the cell pointed to for
                                      *  refinement. This function is
                                      *  only allowed for active
                                      *  cells.
                                      */
-    void set_refine_flag () const;
+    void set_refine_flag (const RefinementCase<dim> ref_case = RefinementCase<dim>::isotropic_refinement) const;
 
                                     /**
                                      *  Clear the refinement flag.
                                      */
     void clear_refine_flag () const;
 
+                                    /**
+                                     *  Modify the refinement flag of the cell
+                                     *  to ensure (at least) the given
+                                     *  refinement case @p face_refinement_case at
+                                     *  face <tt>face_no</tt>, taking into
+                                     *  account orientation, flip and rotation
+                                     *  of the face. Return, whether the
+                                     *  refinement flag had to be
+                                     *  modified. This function is only allowed
+                                     *  for active cells.
+                                     */
+    bool flag_for_face_refinement (const unsigned int face_no,
+                                  const RefinementCase<dim-1> &face_refinement_case=RefinementCase<dim-1>::isotropic_refinement) const;
+
+                                    /**
+                                     *  Modify the refinement flag of the cell
+                                     *  to ensure that line <tt>face_no</tt>
+                                     *  will be refined. Return, whether the
+                                     *  refinement flag had to be
+                                     *  modified. This function is only allowed
+                                     *  for active cells.
+                                     */
+    bool flag_for_line_refinement (const unsigned int line_no) const;
+
+                                    /**
+                                     * Return the SubfaceCase of face
+                                     * <tt>face_no</tt>. Note that this is not
+                                     * identical to asking
+                                     * <tt>cell->face(face_no)->refinement_case()</tt>
+                                     * since the latter returns a RefinementCase<dim-1>
+                                     * and thus only considers one
+                                     * (anisotropic) refinement, whereas this
+                                     * function considers the complete
+                                     * refinement situation including possible
+                                     * refinement of the face's children. This
+                                     * function may only be called for active
+                                     * cells in 2d and 3d.
+                                     */
+    internal::SubfaceCase<dim> subface_case(const unsigned int face_no) const;
+    
                                     /**
                                      *  Return whether the coarsen flag
                                      *  is set or not.
@@ -3527,7 +3892,7 @@ class CellAccessor :  public TriaObjectAccessor<dim,dim>
                                       * for the index of the
                                       * child.
                                       *
-                                      * However, the function is more
+                                      * 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
@@ -3554,8 +3919,7 @@ class CellAccessor :  public TriaObjectAccessor<dim,dim>
                                       * necessarily the @p sf-th child
                                       * of the face of this cell. This
                                       * is so because the @p
-                                      * subface_no parameter to this
-                                      * function corresponds to the
+                                      * subface_no on a cell corresponds to the
                                       * subface with respect to the
                                       * intrinsic ordering of the
                                       * present cell, whereas children
@@ -3572,12 +3936,22 @@ class CellAccessor :  public TriaObjectAccessor<dim,dim>
                                      * of which indicate a non-standard face
                                      * have to be considered.
                                       *
-                                      * Fortunately, this is only very rarely
-                                      * of concern, since one is usually only
-                                      * concerned either in the exact number
-                                      * of a subface, or in the cell that is
-                                      * behind it, not in both at the same
-                                      * time.
+                                      * 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,
@@ -3664,6 +4038,42 @@ class CellAccessor :  public TriaObjectAccessor<dim,dim>
                                      */
     DeclException0 (ExcCellFlaggedForCoarsening);
     
+  protected:
+                                    /**
+                                     * This function assumes that the
+                                     * neighbor is not coarser than
+                                     * the current cell. In this case
+                                     * it returns the
+                                     * neighbor_of_neighbor() value.
+                                     * If, however, the neighbor is
+                                     * coarser this function returns
+                                     * an
+                                     * <code>invalid_unsigned_int</code>.
+                                     *
+                                     * This function is not for
+                                     * public use. Use the function
+                                     * neighbor_of_neighbor() instead
+                                     * which throws an exception if
+                                     * called for a coarser
+                                     * neighbor. If neighbor is
+                                     * indeed coarser (you get to
+                                     * know this by e.g. the
+                                     * neighbor_is_coarser()
+                                     * function) then the
+                                     * neighbor_of_coarser_neighbor()
+                                     * function should be call. If
+                                     * you'd like to know only the
+                                     * <code>face_no</code> which is
+                                     * required to get back from the
+                                     * neighbor to the present cell
+                                     * then simply use the
+                                     * neighbor_face_no() function
+                                     * which can be used for coarser
+                                     * as well as noncoarser
+                                     * neighbors.
+                                     */
+    unsigned int neighbor_of_neighbor_internal (const unsigned int neighbor) const;
+    
   private:
     
                                     /**
index 548d0c4b8e68711dc29d73724854fb1a03973917..87326b5840f69b5c61c628da8263cfa2793935b0 100644 (file)
@@ -311,6 +311,19 @@ TriaObjectAccessor<1,dim>::clear_user_flag () const
 }
 
 
+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 dim>
 inline
@@ -336,6 +349,16 @@ TriaObjectAccessor<1,dim>::child_index (const unsigned int i) const
 
 
 
+template <int dim>
+inline
+int
+TriaObjectAccessor<1,dim>::isotropic_child_index (const unsigned int i) const
+{
+  return child_index(i);
+}
+
+
+
 template <int dim>
 inline
 TriaIterator<dim,TriaObjectAccessor<1,dim> >
@@ -356,13 +379,36 @@ TriaObjectAccessor<1,dim>::child (const unsigned int i) 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);
+}
+
+
+
 template <int dim>
 inline
 unsigned int
 TriaObjectAccessor<1,dim>::n_children () const
 {
   Assert (has_children()==true, TriaAccessorExceptions::ExcCellHasNoChildren());
-  return GeometryInfo<1>::children_per_cell;
+  return GeometryInfo<1>::max_children_per_cell;
+}
+
+
+
+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;
 }
 
 
@@ -432,7 +478,7 @@ TriaObjectAccessor<1,dim>::operator ++ ()
                                   // has no level)
   if (this->present_index
       >=
-      static_cast<int>(this->tria->faces->lines.cells.size()))
+      static_cast<int>(objects().cells.size()))
     this->present_index = -1;
 }
 
@@ -621,6 +667,55 @@ TriaObjectAccessor<2,dim>::line_index (const unsigned int i) const
 
 
 
+template <int dim>
+inline
+RefinementCase<2>
+TriaObjectAccessor<2, dim>::refinement_case () 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];
+}
+
+
+
+template <int dim>
+inline
+void
+TriaObjectAccessor<2, dim>::set_refinement_case (const RefinementCase<2> &refinement_case) 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;
+}
+
+
+template <int dim>
+inline
+void
+TriaObjectAccessor<2, dim>::clear_refinement_case () 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;
+}
+
+
 template <int dim>
 inline
 bool
@@ -628,7 +723,7 @@ TriaObjectAccessor<2,dim>::has_children () const
 {
   Assert (this->state() == IteratorState::valid,
          TriaAccessorExceptions::ExcDereferenceInvalidObject());
-  return (objects().children[this->present_index] != -1);
+  return (objects().children[2*this->present_index] != -1);
 }
 
 
@@ -639,7 +734,43 @@ int TriaObjectAccessor<2,dim>::child_index (const unsigned int i) const
 {
   Assert (i<4, ExcIndexRange(i,0,4));
   Assert (has_children(), TriaAccessorExceptions::ExcCellHasNoChildren());
-  return objects().children[this->present_index]+i;
+  return objects().children[2*this->present_index+i/2]+i%2;
+}
+
+
+
+template <int dim>
+inline
+int TriaObjectAccessor<2,dim>::isotropic_child_index (const unsigned int i) 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;
 }
 
 
@@ -664,13 +795,75 @@ TriaObjectAccessor<2,dim>::child (const unsigned int i) const
 
 
 
+template <int dim>
+inline
+TriaIterator<dim,TriaObjectAccessor<2,dim> >
+TriaObjectAccessor<2,dim>::isotropic_child (const unsigned int i) 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);
+}
+
+
+
 template <int dim>
 inline
 unsigned int
 TriaObjectAccessor<2,dim>::n_children () const
 {
   Assert (has_children()==true, TriaAccessorExceptions::ExcCellHasNoChildren());
-  return GeometryInfo<2>::children_per_cell;
+  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());
+}
+
+
+
+template <int dim>
+inline
+unsigned int
+TriaObjectAccessor<2,dim>::middle_vertex_index () 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;
 }
 
 
@@ -990,12 +1183,65 @@ TriaObjectAccessor<3,3>::quad_index (const unsigned int i) const
 
 template <>
 inline
+RefinementCase<3>
+TriaObjectAccessor<3, 3>::refinement_case () 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()));
+
+  return this->tria->levels[this->present_level]->cells.refinement_cases[this->present_index];
+}
+
+
+
+template <>
+inline
+void
+TriaObjectAccessor<3, 3>::set_refinement_case (const RefinementCase<3> &refinement_case) 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()));
+
+  this->tria->levels[this->present_level]->
+    cells.refinement_cases[this->present_index] = refinement_case;
+}
+
+
+template <>
+inline
+void
+TriaObjectAccessor<3, 3>::clear_refinement_case () 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()));
+
+  this->tria->levels[this->present_level]->
+    cells.refinement_cases[this->present_index] = RefinementCase<3>::no_refinement;
+}
+
+
+
+template<>
+inline
 bool
 TriaObjectAccessor<3,3>::has_children () const
 {
   Assert (this->state() == IteratorState::valid,
          TriaAccessorExceptions::ExcDereferenceInvalidObject());
-    return (this->tria->levels[this->present_level]->cells.children[this->present_index] != -1);
+    return (this->tria->levels[this->present_level]->cells.children[4*this->present_index] != -1);
 }
 
 
@@ -1005,7 +1251,17 @@ int TriaObjectAccessor<3,3>::child_index (const unsigned int i) const
 {
   Assert (i<8, ExcIndexRange(i,0,8));
   Assert (has_children(), TriaAccessorExceptions::ExcCellHasNoChildren());
-    return this->tria->levels[this->present_level]->cells.children[this->present_index]+i;
+  return this->tria->levels[this->present_level]->cells.children[4*this->present_index+i/2]+i%2;
+}
+
+
+
+template <>
+inline
+int TriaObjectAccessor<3,3>::isotropic_child_index (const unsigned int i) const
+{
+  AssertThrow(false, ExcNotImplemented());
+  return child_index(i);
 }
 
 
@@ -1029,16 +1285,70 @@ TriaObjectAccessor<3,3>::child (const unsigned int i) const
 
 
 
-template <int dim>
+template <>
+inline
+TriaIterator<3,TriaObjectAccessor<3,3> >
+TriaObjectAccessor<3,3>::isotropic_child (const unsigned int i) const
+{
+  AssertThrow(false, ExcNotImplemented());
+  return child(i);
+}
+
+
+
+template <>
 inline
 unsigned int
-TriaObjectAccessor<3,dim>::n_children () const
+TriaObjectAccessor<3,3>::n_children () const
 {
   Assert (has_children()==true, TriaAccessorExceptions::ExcCellHasNoChildren());
-  return GeometryInfo<3>::children_per_cell;
+  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()));
+
+  return GeometryInfo<3>::n_children(refinement_case());
 }
 
 
+
+template <int dim>
+inline
+unsigned int
+TriaObjectAccessor<3,dim>::middle_vertex_index () const
+{
+  switch (static_cast<unsigned char> (refinement_case()))
+    {
+      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;
+    }
+  return numbers::invalid_unsigned_int;
+}
+
+
+
 template <int dim>
 inline
 unsigned int
@@ -1360,7 +1670,7 @@ CellAccessor<dim>::neighbor_level (const unsigned int i) const
 
 template <int dim>
 inline
-bool
+RefinementCase<dim>
 CellAccessor<dim>::refine_flag_set () const
 {
   Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
@@ -1371,7 +1681,7 @@ CellAccessor<dim>::refine_flag_set () const
                                   // flag is not cleared).
   Assert (this->active() ||  !this->tria->levels[this->present_level]->refine_flags[this->present_index],
          ExcRefineCellNotActive());
-  return this->tria->levels[this->present_level]->refine_flags[this->present_index];
+  return RefinementCase<dim>(this->tria->levels[this->present_level]->refine_flags[this->present_index]);
 }
 
 
@@ -1379,13 +1689,13 @@ CellAccessor<dim>::refine_flag_set () const
 template <int dim>
 inline
 void
-CellAccessor<dim>::set_refine_flag () const
+CellAccessor<dim>::set_refine_flag (const RefinementCase<dim> refinement_case) const
 {
   Assert (this->used() && this->active(), ExcRefineCellNotActive());
   Assert (!coarsen_flag_set(),
          ExcCellFlaggedForCoarsening());
   
-  this->tria->levels[this->present_level]->refine_flags[this->present_index] = true;
+  this->tria->levels[this->present_level]->refine_flags[this->present_index] = refinement_case;
 }
 
 
@@ -1396,7 +1706,165 @@ void
 CellAccessor<dim>::clear_refine_flag () const
 {
   Assert (this->used() && this->active(), ExcRefineCellNotActive());
-  this->tria->levels[this->present_level]->refine_flags[this->present_index] = false;
+  this->tria->levels[this->present_level]->refine_flags[this->present_index] =
+    RefinementCase<dim>::no_refinement;
+}
+
+
+
+template <int dim>
+inline
+bool
+CellAccessor<dim>::flag_for_face_refinement (const unsigned int face_no,
+                                            const RefinementCase<dim-1> &face_refinement_case) const
+{
+  Assert (dim>1, ExcImpossibleInDim(dim));
+  Assert (face_no<GeometryInfo<dim>::faces_per_cell,
+         ExcIndexRange(face_no,0,GeometryInfo<dim>::faces_per_cell));
+  Assert (face_refinement_case < RefinementCase<dim>::isotropic_refinement+1,
+         ExcIndexRange(face_refinement_case,0,RefinementCase<dim>::isotropic_refinement+1));
+                           
+                                   // the new refinement case is a combination
+                                  // of the minimum required one for the given
+                                  // face refinement and the already existing
+                                  // flagged refinement case
+  RefinementCase<dim> old_ref_case = refine_flag_set();
+  RefinementCase<dim>              
+    new_ref_case = (old_ref_case
+                   | GeometryInfo<dim>::min_cell_refinement_case_for_face_refinement(face_refinement_case,
+                                                                                     face_no,
+                                                                                     this->face_orientation(face_no),
+                                                                                     this->face_flip(face_no),
+                                                                                     this->face_rotation(face_no)));
+  set_refine_flag(new_ref_case);
+                                  // return, whether we had to change the
+                                  // refinement flag
+  return new_ref_case != old_ref_case;
+}
+
+
+
+template <int dim>
+inline
+bool
+CellAccessor<dim>::flag_for_line_refinement (const unsigned int line_no) const
+{
+  Assert (dim>1, ExcImpossibleInDim(dim));
+  Assert (line_no<GeometryInfo<dim>::lines_per_cell,
+         ExcIndexRange(line_no,0,GeometryInfo<dim>::lines_per_cell));
+
+                                  // the new refinement case is a combination
+                                  // of the minimum required one for the given
+                                  // line refinement and the already existing
+                                  // flagged refinement case
+  RefinementCase<dim> old_ref_case=refine_flag_set(),
+                  new_ref_case=old_ref_case
+                               | GeometryInfo<dim>::min_cell_refinement_case_for_line_refinement(line_no);
+  set_refine_flag(new_ref_case);
+                                  // return, whether we had to change the
+                                  // refinement flag
+  return new_ref_case != old_ref_case;
+}
+
+
+
+template <>
+inline
+internal::SubfaceCase<1>
+CellAccessor<1>::subface_case(const unsigned int) const
+{
+  Assert(false, ExcImpossibleInDim(1));
+  return internal::SubfaceCase<1>::case_none;
+}
+
+
+
+template <>
+inline
+internal::SubfaceCase<2>
+CellAccessor<2>::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 <>
+inline
+internal::SubfaceCase<3>
+CellAccessor<3>::subface_case(const unsigned int face_no) const
+{
+  Assert(active(), TriaAccessorExceptions::ExcCellNotActive());
+  Assert(face_no<GeometryInfo<3>::faces_per_cell,
+        ExcIndexRange(face_no,0,GeometryInfo<3>::faces_per_cell));
+  switch (static_cast<unsigned char> (face(face_no)->refinement_case()))
+    {
+      case RefinementCase<3>::no_refinement:
+           return internal::SubfaceCase<3>::case_none;
+           break;
+      case RefinementCase<3>::cut_x:
+           if (face(face_no)->child(0)->has_children())
+             {
+               Assert(face(face_no)->child(0)->refinement_case()==RefinementCase<3>::cut_y,
+                      ExcInternalError());
+               if (face(face_no)->child(1)->has_children())
+                 {
+                   Assert(face(face_no)->child(1)->refinement_case()==RefinementCase<3>::cut_y,
+                          ExcInternalError());
+                   return internal::SubfaceCase<3>::case_x1y2y;                                                                 
+                 }
+               else
+                 return internal::SubfaceCase<3>::case_x1y;
+             }
+           else
+             {
+               if (face(face_no)->child(1)->has_children())
+                 {
+                   Assert(face(face_no)->child(1)->refinement_case()==RefinementCase<3>::cut_y,
+                          ExcInternalError());
+                   return internal::SubfaceCase<3>::case_x2y;
+                 }
+               else
+                 return internal::SubfaceCase<3>::case_x;
+             }
+           break;
+      case RefinementCase<3>::cut_y:
+           if (face(face_no)->child(0)->has_children())
+             {
+               Assert(face(face_no)->child(0)->refinement_case()==RefinementCase<3>::cut_x,
+                      ExcInternalError());
+               if (face(face_no)->child(1)->has_children())
+                 {
+                   Assert(face(face_no)->child(1)->refinement_case()==RefinementCase<3>::cut_x,
+                          ExcInternalError());
+                   return internal::SubfaceCase<3>::case_y1x2x;                                                                 
+                 }
+               else
+                 return internal::SubfaceCase<3>::case_y1x;
+             }
+           else
+             {
+               if (face(face_no)->child(1)->has_children())
+                 {
+                   Assert(face(face_no)->child(1)->refinement_case()==RefinementCase<3>::cut_x,
+                          ExcInternalError());
+                   return internal::SubfaceCase<3>::case_y2x;
+                 }
+               else
+                 return internal::SubfaceCase<3>::case_y;
+             }
+           break;
+      case RefinementCase<3>::cut_xy:
+           return internal::SubfaceCase<3>::case_xy;
+           break;
+      default:
+           Assert(false, ExcInternalError());
+    }
+                                  // we should never get here
+  return internal::SubfaceCase<3>::case_none;
 }
 
 
@@ -1483,6 +1951,28 @@ CellAccessor<dim>::active () const
   return !this->has_children();
 }
 
+
+
+template <int dim>
+inline
+unsigned int
+CellAccessor<dim>::neighbor_face_no (const unsigned int neighbor) const
+{
+  if (dim==1)
+    return neighbor_of_neighbor(neighbor);
+  else
+    {
+      const unsigned int n2=neighbor_of_neighbor_internal(neighbor);
+      if (n2!=numbers::invalid_unsigned_int)
+                                        // return this value as the
+                                        // neighbor is not coarser
+       return n2;
+      else     
+                                        // the neighbor is coarser
+       return neighbor_of_coarser_neighbor(neighbor).first;
+    }
+}
+
 DEAL_II_NAMESPACE_CLOSE
 
 #endif
index 68acb12e98a97ed024716e90a704429704da4ec3..1b3275815d021397d424630bb4c6915a098e1310 100644 (file)
@@ -51,18 +51,24 @@ namespace internal
     class TriaLevel
     {
       public:
-                                         /**
-                                          *  Flags for the cells whether they are
-                                          *  to be refined or not. The meaning
-                                          *  what a cell is, is dimension specific,
-                                          *  therefore also the length of this
-                                          *  vector depends on the dimension: in
-                                          *  one dimension, the length of this
-                                          *  vector equals the length of the
-                                          *  @p lines vector, in two dimensions
-                                          *  that of the @p quads vector, etc.
-                                          */
-        std::vector<bool> refine_flags;
+                                        /**
+                                         *  @p RefinementCase<dim>::Type flags
+                                         *  for the cells to be
+                                         *  refined with or not
+                                         *  (RefinementCase<dim>::no_refinement). The
+                                         *  meaning what a cell is,
+                                         *  is dimension specific,
+                                         *  therefore also the length
+                                         *  of this vector depends on
+                                         *  the dimension: in one
+                                         *  dimension, the length of
+                                         *  this vector equals the
+                                         *  length of the @p lines
+                                         *  vector, in two dimensions
+                                         *  that of the @p quads
+                                         *  vector, etc.
+                                         */
+       std::vector<unsigned char> refine_flags;
 
                                          /**
                                           * Same meaning as the one above, but
@@ -204,7 +210,7 @@ namespace internal
     class TriaLevel<3>
     {
       public:
-        std::vector<bool> refine_flags;
+        std::vector<unsigned char> refine_flags;
         std::vector<bool> coarsen_flags;
         std::vector<std::pair<int,int> > neighbors;
         std::vector<unsigned int> subdomain_ids;
index 657738423f82406a7a1655db199a4be4b12859e5..355fe2653d83ec39d50696673cc0dd410b568a52 100644 (file)
@@ -38,6 +38,8 @@ namespace internal
     class TriaObject
     {
       public:
+       static const unsigned int dimension = structdim;
+       
                                         /**
                                          * Default constructor,
                                          * setting all face indices
index 1211625a54a300b52ccabb8a33e51c1b916dcce9..31a591e48d0b92b20457b27090258e3b766cca1e 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 2006, 2007 by the deal.II authors
+//    Copyright (C) 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
@@ -29,6 +29,9 @@ 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;
+
+
 namespace internal
 {
   namespace Triangulation
@@ -40,7 +43,7 @@ namespace internal
  * objects additional information is included, namely vectors indicating the
  * children, the used-status, user-flags, material-ids..
  *
- * Objects of these classes are include in the TriaLevel and TriaFaces
+ * Objects of these classes are included in the TriaLevel and TriaFaces
  * classes.
  *
  * @ingroup grid
@@ -63,13 +66,13 @@ namespace internal
                                          */
        std::vector<G> cells;
                                         /**
-                                         *  Index of the first child of an object.
+                                         *  Index of the even children of an object.
                                          *  Since when objects are refined, all
                                          *  children are created at the same
                                          *  time, they are appended to the list
-                                         *  after each other.
+                                         *  at least in pairs after each other.
                                          *  We therefore only store the index
-                                         *  of the first child, the others
+                                         *  of the even children, the uneven
                                          *  follow immediately afterwards.
                                          *
                                          *  If an object has no children, -1 is
@@ -81,6 +84,19 @@ namespace internal
                                          */
        std::vector<int>  children;
        
+                                        /**
+                                         * Store the refinement
+                                         * case each of the
+                                         * cells is refined
+                                         * with. This vector
+                                         * might be replaced by
+                                         * vector<vector<bool> >
+                                         * (dim, vector<bool>
+                                         * (n_cells)) which is
+                                         * more memory efficient.
+                                         */
+       std::vector<RefinementCase<G::dimension> > refinement_cases;
+       
                                         /**
                                          *  Vector storing whether an object is
                                          *  used in the @p cells vector.
@@ -132,15 +148,80 @@ namespace internal
        std::vector<unsigned char> material_id;
        
                                          /**
-                                          *  Assert that enough space is
-                                          *  allocated to accomodate
-                                          *  <tt>new_objs</tt> new objects.
-                                          *  This function does not only call
-                                          *  <tt>vector::reserve()</tt>, but
-                                          *  does really append the needed
-                                          *  elements.
+                                          *  Assert that enough space
+                                          *  is allocated to
+                                          *  accomodate
+                                          *  <code>new_objs_in_pairs</code>
+                                          *  new objects, stored in
+                                          *  pairs, plus
+                                          *  <code>new_obj_single</code>
+                                          *  stored individually.
+                                          *  This function does not
+                                          *  only call
+                                          *  <code>vector::reserve()</code>,
+                                          *  but does really append
+                                          *  the needed elements.
+                                         *
+                                         *  In 2D e.g. refined lines have to be
+                                         *  stored in pairs, whereas new lines in the
+                                         *  interior of refined cells can be stored as
+                                         *  single lines.
                                           */
-        void reserve_space (const unsigned int new_objs);
+        void reserve_space (const unsigned int new_objs_in_pairs,
+                           const unsigned int new_objs_single = 0);
+
+                                        /**
+                                         * Return an iterator to the
+                                         * next free slot for a
+                                         * single line. Only
+                                         * implemented for
+                                         * <code>G=TriaObject<1>
+                                         * </code>.
+                                         */
+       template <int dim>
+       typename dealii::Triangulation<dim>::raw_line_iterator next_free_single_line (const dealii::Triangulation<dim> &tria);
+
+                                        /**
+                                         * Return an iterator to the
+                                         * next free slot for a pair
+                                         * of lines. Only implemented
+                                         * 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);
+       
+                                        /**
+                                         * Return an iterator to the
+                                         * next free slot for a
+                                         * single quad. Only
+                                         * implemented for
+                                         * <code>G=TriaObject@<2@>
+                                         * </code>.
+                                         */
+       template <int dim>
+       typename dealii::Triangulation<dim>::raw_quad_iterator next_free_single_quad (const dealii::Triangulation<dim> &tria);
+
+                                        /**
+                                         * Return an iterator to the
+                                         * next free slot for a pair
+                                         * of quads. Only implemented
+                                         * 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);
+       
+                                        /**
+                                         * Return an iterator to the
+                                         * next free slot for a pair
+                                         * of hexes. Only implemented
+                                         * for
+                                         * <code>G=Hexahedron</code>.
+                                         */
+       template <int dim>
+       typename dealii::Triangulation<dim>::raw_hex_iterator next_free_hex (const dealii::Triangulation<dim> &tria,
+                                                                            const unsigned int               level);
 
                                         /**
                                          *  Clear all the data contained in this object.
@@ -149,17 +230,17 @@ namespace internal
        
                                         /**
                                          * The orientation of the
-                                         * face number <tt>face</tt>
+                                         * face number <code>face</code>
                                          * of the cell with number
-                                         * <tt>cell</tt>. The return
-                                         * value is <tt>true</tt>, if
+                                         * <code>cell</code>. The return
+                                         * value is <code>true</code>, if
                                          * the normal vector points
                                          * the usual way
                                          * (GeometryInfo::unit_normal_orientation)
-                                         * and <tt>false</tt> else.
+                                         * and <code>false</code> else.
                                          *
                                          * The result is always
-                                         * <tt>true</tt> in this
+                                         * <code>true</code> in this
                                          * class, but derived classes
                                          * will reimplement this.
                                          *
@@ -211,6 +292,11 @@ namespace internal
                                          */
        void clear_user_data();
        
+                                        /**
+                                         * Clear all user flags.
+                                         */
+       void clear_user_flags();
+       
                                          /**
                                           *  Check the memory consistency of the
                                           *  different containers. Should only be
@@ -245,6 +331,14 @@ namespace internal
                         << "The containers have sizes " << arg1 << " and "
                         << arg2 << ", which is not as expected.");
 
+                                         /**
+                                          *  Exception
+                                          */
+        DeclException2 (ExcWrongIterator,
+                        char*, char*,
+                        << "You asked for the next free " << arg1 << "_iterator, "
+                        "but you can only ask for " << arg2 <<"_iterators.");
+
                                         /**
                                          * Triangulation objacts can
                                          * either access a user
@@ -259,6 +353,21 @@ namespace internal
        DeclException0 (ExcPointerIndexClash);
        
       protected:
+                                        /**
+                                         * Counter for next_free_single_* functions
+                                         */
+       unsigned int next_free_single;
+
+                                        /**
+                                         * Counter for next_free_pair_* functions
+                                         */
+       unsigned int next_free_pair;
+
+                                        /**
+                                         * Bool flag for next_free_single_* functions
+                                         */
+       bool reverse_order_next_free_single;
+       
                                         /**
                                          * The data type storing user
                                          * pointers or user indices.
@@ -324,14 +433,14 @@ namespace internal
       public:
                                         /**
                                          * The orientation of the
-                                         * face number <tt>face</tt>
+                                         * face number <code>face</code>
                                          * of the cell with number
-                                         * <tt>cell</tt>. The return
-                                         * value is <tt>true</tt>, if
+                                         * <code>cell</code>. The return
+                                         * value is <code>true</code>, if
                                          * the normal vector points
                                          * the usual way
                                          * (GeometryInfo::unit_normal_orientation)
-                                         * and <tt>false</tt> if they
+                                         * and <code>false</code> if they
                                          * point in opposite
                                          * direction.
                                          */
@@ -378,7 +487,7 @@ namespace internal
                                          * a @p false value.
                                          *
                                          * In effect, this field has
-                                         * <tt>6*n_cells</tt> elements,
+                                         * <code>6*n_cells</code> elements,
                                          * being the number of cells
                                          * times the six faces each
                                          * has.
@@ -396,9 +505,9 @@ namespace internal
                                          /**
                                           *  Assert that enough space is
                                           *  allocated to accomodate
-                                          *  <tt>new_objs</tt> new objects.
+                                          *  <code>new_objs</code> new objects.
                                           *  This function does not only call
-                                          *  <tt>vector::reserve()</tt>, but
+                                          *  <code>vector::reserve()</code>, but
                                           *  does really append the needed
                                           *  elements.
                                           */
@@ -441,14 +550,14 @@ namespace internal
       public:
                                         /**
                                          * The orientation of the
-                                         * face number <tt>face</tt>
+                                         * face number <code>face</code>
                                          * of the cell with number
-                                         * <tt>cell</tt>. The return
-                                         * value is <tt>true</tt>, if
+                                         * <code>cell</code>. The return
+                                         * value is <code>true</code>, if
                                          * the normal vector points
                                          * the usual way
                                          * (GeometryInfo::unit_normal_orientation)
-                                         * and <tt>false</tt> if they
+                                         * and <code>false</code> if they
                                          * point in opposite
                                          * direction.
                                          */
@@ -457,7 +566,7 @@ namespace internal
 
                                         /**
                                          * In effect, this field has
-                                         * <tt>4*n_quads</tt> elements,
+                                         * <code>4*n_quads</code> elements,
                                          * being the number of quads
                                          * times the four lines each
                                          * has.
@@ -465,15 +574,22 @@ namespace internal
        std::vector<bool> line_orientations;
 
                                          /**
-                                          *  Assert that enough space is
-                                          *  allocated to accomodate
-                                          *  <tt>new_objs</tt> new objects.
-                                          *  This function does not only call
-                                          *  <tt>vector::reserve()</tt>, but
-                                          *  does really append the needed
-                                          *  elements.
+                                          *  Assert that enough space
+                                          *  is allocated to
+                                          *  accomodate
+                                          *  <code>new_quads_in_pairs</code>
+                                          *  new quads, stored in
+                                          *  pairs, plus
+                                          *  <code>new_quads_single</code>
+                                          *  stored individually.
+                                          *  This function does not
+                                          *  only call
+                                          *  <code>vector::reserve()</code>,
+                                          *  but does really append
+                                          *  the needed elements.
                                           */
-        void reserve_space (const unsigned int new_objs);
+        void reserve_space (const unsigned int new_quads_in_pairs,
+                           const unsigned int new_quads_single = 0);
 
                                         /**
                                          *  Clear all the data contained in this object.
@@ -595,6 +711,14 @@ namespace internal
        user_data[i].p = 0;
     }
 
+
+    template<typename G>
+    inline
+    void TriaObjects<G>::clear_user_flags ()
+    {
+      user_flags.assign(user_flags.size(),false);
+    }
+    
 //----------------------------------------------------------------------//
 
     inline
@@ -626,11 +750,13 @@ namespace internal
 
     template<>
     void
-    TriaObjects<TriaObject<1> >::reserve_space (const unsigned int new_lines);
+    TriaObjects<TriaObject<1> >::reserve_space (const unsigned int new_lines_in_pairs,
+                                     const unsigned int new_lines_single);
 
     template<>
     void
-    TriaObjects<TriaObject<2> >::reserve_space (const unsigned int new_quads);
+    TriaObjects<TriaObject<2> >::reserve_space (const unsigned int new_quads_in_pairs,
+                                     const unsigned int new_quads_single);
 
     template<>
     void
index a09d83816645e17a28efa145a9c4bb83596364ea..750a69bbca462891a219491b95719ebc45020ef8 100644 (file)
@@ -1,6 +1,6 @@
 //---------------------------------------------------------------------------
-//    mg_transfer.templates.h,v 1.22 2006/01/29 15:03:55 guido Exp
-//    Version: 
+//    $Id$
+//    Version: $Name$
 //
 //    Copyright (C) 2003, 2004, 2005, 2006, 2007 by the deal.II authors
 //
index 431afbd25fc89d3e54ecdb37268d62af5abae670..dc16c01855d432ea1b84aa8d793528dca540b5b9 100644 (file)
@@ -3,7 +3,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 by the deal.II authors
+//    Copyright (C) 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
index 400ee6b74dc41b5e1b7de4cb338c5a9a51bcd8b9..ab2ad3ed282fce04263ed94243d877f5b8161dfb 100644 (file)
@@ -451,8 +451,7 @@ get_interpolated_dof_values (const InputVector &values,
       for (unsigned int i=0; i<dofs_per_cell; ++i)
         restriction_is_additive[i] = fe.restriction_is_additive(i);
       
-      for (unsigned int child=0; child<GeometryInfo<dim>::children_per_cell;
-          ++child)
+      for (unsigned int child=0; child<this->n_children(); ++child)
        {
                                           // get the values from the present
                                           // child, if necessary by
@@ -461,7 +460,7 @@ get_interpolated_dof_values (const InputVector &values,
                                                           tmp1);
                                           // interpolate these to the mother
                                           // cell
-         fe.get_restriction_matrix(child).vmult (tmp2, tmp1);
+         fe.get_restriction_matrix(child, this->refinement_case()).vmult (tmp2, tmp1);
 
                                            // and add up or set them
                                            // in the output vector
@@ -504,13 +503,13 @@ set_dof_values_by_interpolation (const Vector<number> &local_values,
     {
       Vector<number> tmp(dofs_per_cell);
       
-      for (unsigned int child=0; child<GeometryInfo<dim>::children_per_cell;
-          ++child)
+      for (unsigned int child=0; child<this->n_children(); ++child)
        {
                                           // prolong the given data
                                           // to the present cell
-         this->get_fe().get_prolongation_matrix(child)
+         this->get_fe().get_prolongation_matrix(child, this->refinement_case())
             .vmult (tmp, local_values);
+           
          this->child(child)->set_dof_values_by_interpolation (tmp, values);
        }
     }
index 1dce1176d44f88df4c893d61246a1590975af062..0cfb89c377ca41096885878bb79833fbc8cc4001 100644 (file)
@@ -518,19 +518,14 @@ DoFTools::make_flux_sparsity_pattern (
          if (! cell_face->at_boundary() )
            {
              typename DH::cell_iterator neighbor = cell->neighbor(face);
-                                              // Refinement edges are
-                                              // taken care of by
-                                              // coarser cells
-             if (neighbor->level() < cell->level())
-               continue;
 
              const unsigned int neighbor_face
-                = cell->neighbor_of_neighbor(face);
+                = cell->neighbor_face_no(face);
 
              if (cell_face->has_children())
                {
                  for (unsigned int sub_nr = 0;
-                      sub_nr != cell_face->n_children();
+                      sub_nr != cell_face->number_of_children();
                       ++sub_nr)
                    {
                      const typename DH::cell_iterator
@@ -555,7 +550,13 @@ DoFTools::make_flux_sparsity_pattern (
                }
               else
                 {
-                  const unsigned int n_dofs_on_neighbor
+                                                  // Refinement edges are
+                                                  // taken care of by
+                                                  // coarser cells
+                 if (cell->neighbor_is_coarser(face))
+                   continue;
+                 
+                 const unsigned int n_dofs_on_neighbor
                     = neighbor->get_fe().dofs_per_cell;
                   dofs_on_other_cell.resize (n_dofs_on_neighbor);
 
@@ -736,7 +737,7 @@ DoFTools::make_flux_sparsity_pattern (
                neighbor = cell->neighbor(face);
                                               // Refinement edges are taken care of
                                               // by coarser cells
-             if (neighbor->level() < cell->level())
+             if (cell->neighbor_is_coarser(face))
                continue;
              
              typename DH::face_iterator cell_face = cell->face(face);
@@ -1426,7 +1427,7 @@ namespace internal
       get_most_dominating_subface_fe_index (const face_iterator &face)
       {
         unsigned int dominating_subface_no = 0;
-        for (; dominating_subface_no<GeometryInfo<dim>::subfaces_per_face;
+        for (; dominating_subface_no<face->n_children();
              ++dominating_subface_no)
           {
                                              // each of the subfaces
@@ -1447,7 +1448,7 @@ namespace internal
                        
             FiniteElementDomination::Domination
               domination = FiniteElementDomination::either_element_can_dominate;
-            for (unsigned int sf=0; sf<GeometryInfo<dim>::subfaces_per_face; ++sf)
+            for (unsigned int sf=0; sf<face->n_children(); ++sf)
               if (sf != dominating_subface_no)
                 {
                   const FiniteElement<dim> &
@@ -1473,7 +1474,7 @@ namespace internal
 
                                          // check that we have
                                          // found one such subface
-        Assert (dominating_subface_no != GeometryInfo<dim>::subfaces_per_face,
+        Assert (dominating_subface_no < face->n_children(),
                 ExcNotImplemented());
 
                                          // return the finite element
@@ -1721,7 +1722,7 @@ namespace internal
              Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
                      == true,
                      ExcInternalError());
-             for (unsigned int c=0; c<GeometryInfo<dim>::subfaces_per_face; ++c)
+             for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
                Assert (cell->face(face)->child(c)->n_active_fe_indices() == 1,
                        ExcInternalError());
 
@@ -1730,7 +1731,7 @@ namespace internal
                                               // the case that both
                                               // sides use the same
                                               // fe
-             for (unsigned int c=0; c<GeometryInfo<dim>::subfaces_per_face; ++c)
+             for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
                Assert (cell->face(face)->child(c)
                        ->fe_index_is_active(cell->active_fe_index()) == true,
                        ExcNotImplemented());
@@ -1843,6 +1844,17 @@ namespace internal
        for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
          if (cell->face(face)->has_children()) 
            {
+                                              // first of all, make sure that
+                                              // we treat a case which is
+                                              // possible, i.e. either no dofs
+                                              // on the face at all or no
+                                              // anisotropic refinement
+             if (cell->get_fe().dofs_per_face == 0)
+               continue;
+             
+             Assert(cell->face(face)->refinement_case()==RefinementCase<dim-1>::isotropic_refinement,
+                    ExcNotImplemented());
+
                                               // so now we've found a
                                               // face of an active
                                               // cell that has
@@ -1867,7 +1879,7 @@ namespace internal
              Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
                      == true,
                      ExcInternalError());
-             for (unsigned int c=0; c<GeometryInfo<dim>::subfaces_per_face; ++c)
+             for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
                Assert (cell->face(face)->child(c)->n_active_fe_indices() == 1,
                        ExcInternalError());
 
@@ -1881,7 +1893,7 @@ namespace internal
                                               // this face and the
                                               // children have the
                                               // same fe
-             for (unsigned int c=0; c<GeometryInfo<dim>::subfaces_per_face; ++c)
+             for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
                {
                  Assert (cell->face(face)->child(c)
                          ->fe_index_is_active(cell->active_fe_index()) == true,
@@ -1916,7 +1928,8 @@ namespace internal
                                      fe.dofs_per_quad),
                n_dofs_on_children = (5*fe.dofs_per_vertex+
                                      12*fe.dofs_per_line+
-                                     4*fe.dofs_per_quad);            
+                                     4*fe.dofs_per_quad);
+                                              //TODO[TL]: think about this and the following in case of anisotropic refinement
              
              dofs_on_mother.resize (n_dofs_on_mother);
              dofs_on_children.resize (n_dofs_on_children);
@@ -1951,7 +1964,9 @@ namespace internal
 
                                               // assert some consistency
                                               // assumptions
-             Assert ((this_face->child(0)->vertex_index(3) ==
+                                              //TODO[TL]: think about this in case of anisotropic refinement
+             Assert (dof_handler.get_tria().get_anisotropic_refinement_flag() ||
+                     (this_face->child(0)->vertex_index(3) ==
                       this_face->child(1)->vertex_index(2)) &&
                      (this_face->child(0)->vertex_index(3) ==
                       this_face->child(2)->vertex_index(1)) &&
@@ -2078,7 +2093,7 @@ namespace internal
       Table<3,boost::shared_ptr<FullMatrix<double> > >
         subface_interpolation_matrices (n_finite_elements (dof_handler),
                                         n_finite_elements (dof_handler),
-                                        GeometryInfo<dim>::subfaces_per_face);
+                                        GeometryInfo<dim>::max_children_per_face);
 
                                       // similarly have a cache for
                                       // the matrices that are split
@@ -2115,6 +2130,17 @@ namespace internal
        for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
          if (cell->face(face)->has_children()) 
            {
+                                              // first of all, make sure that
+                                              // we treat a case which is
+                                              // possible, i.e. either no dofs
+                                              // on the face at all or no
+                                              // anisotropic refinement
+             if (cell->get_fe().dofs_per_face == 0)
+               continue;
+             
+             Assert(cell->face(face)->refinement_case()==RefinementCase<dim-1>::isotropic_refinement,
+                    ExcNotImplemented());
+             
                                               // so now we've found a
                                               // face of an active
                                               // cell that has
@@ -2139,7 +2165,7 @@ namespace internal
              Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
                      == true,
                      ExcInternalError());
-             for (unsigned int c=0; c<GeometryInfo<dim>::subfaces_per_face; ++c)
+             for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
                Assert (cell->face(face)->child(c)->n_active_fe_indices() == 1,
                        ExcInternalError());
 
@@ -2160,7 +2186,7 @@ namespace internal
                mother_face_dominates = FiniteElementDomination::either_element_can_dominate;
 
               if (DoFHandlerSupportsDifferentP<DH>::value == true)
-                for (unsigned int c=0; c<GeometryInfo<dim>::subfaces_per_face; ++c)
+                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
                                            (cell->neighbor_child_on_subface (face, c)->get_fe()));
@@ -2191,7 +2217,7 @@ namespace internal
                  
                                                     // Now create constraint matrix for
                                                     // the subfaces and assemble it.
-                   for (unsigned int c=0; c<GeometryInfo<dim>::subfaces_per_face; ++c)
+                   for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
                      {
                        const typename DH::active_face_iterator
                          subface = cell->face(face)->child(c);
@@ -2456,7 +2482,7 @@ namespace internal
                                                     // discussed in the
                                                     // paper
                    for (unsigned int sf=0;
-                        sf<GeometryInfo<dim>::subfaces_per_face; ++sf)
+                        sf<cell->face(face)->n_children(); ++sf)
                      {
                        Assert (cell->face(face)->child(sf)
                                ->n_active_fe_indices() == 1,
@@ -2544,8 +2570,8 @@ namespace internal
                   (cell->neighbor(face)->active_fe_index () !=
                    cell->active_fe_index ())
                  &&
-                 (cell->neighbor(face)->level () ==
-                  cell->level ()))
+                 (!cell->face(face)->has_children() &&
+                  !cell->neighbor_is_coarser(face) ))
                {                 
                  const typename DH::cell_iterator neighbor = cell->neighbor (face);
 
index b16f24bddf76665346da8bc2176076d03028707c..6ee95da79914be225718435a9fd1563e8a3c5135 100644 (file)
@@ -208,6 +208,24 @@ FiniteElement<dim>::FiniteElement (
                                   // changed by constructor of
                                   // derived class.
   first_block_of_base_table.resize(1,0);
+
+                                  // initialize the restriction and
+                                  // prolongation matrices. the default
+                                  // contructur of FullMatrix<dim> initializes
+                                  // them with size zero
+  prolongation.resize(RefinementCase<dim>::isotropic_refinement);
+  restriction.resize(RefinementCase<dim>::isotropic_refinement);
+  for (unsigned int ref=RefinementCase<dim>::cut_x;
+       ref<RefinementCase<dim>::isotropic_refinement+1; ++ref)
+    {
+      prolongation[ref-1].resize (GeometryInfo<dim>::
+                                 n_children(RefinementCase<dim>(ref)),
+                                 FullMatrix<double>());
+      restriction[ref-1].resize (GeometryInfo<dim>::
+                                 n_children(RefinementCase<dim>(ref)),
+                                 FullMatrix<double>());
+    }
+
   adjust_quad_dof_index_for_face_orientation_table.fill(0);
 }
 
@@ -288,26 +306,71 @@ FiniteElement<dim>::shape_grad_grad_component (const unsigned int,
 }
 
 
+
+template <int dim>
+void
+FiniteElement<dim>::reinit_restriction_and_prolongation_matrices (
+  const bool isotropic_restriction_only,
+  const bool isotropic_prolongation_only)
+{
+  for (unsigned int ref_case=RefinementCase<dim>::cut_x;
+       ref_case<RefinementCase<dim>::isotropic_refinement+1; ++ref_case)
+    {
+      const unsigned int nc = GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));
+      
+      for (unsigned int i=0; i<nc; ++i)
+       {
+         if (!isotropic_restriction_only || ref_case==RefinementCase<dim>::isotropic_refinement)
+           this->restriction[ref_case-1][i].reinit (this->dofs_per_cell,
+                                                    this->dofs_per_cell);
+         if (!isotropic_prolongation_only || ref_case==RefinementCase<dim>::isotropic_refinement)
+           this->prolongation[ref_case-1][i].reinit (this->dofs_per_cell,
+                                                     this->dofs_per_cell);
+       }
+    }
+}
+
+
 template <int dim>
 const FullMatrix<double> &
-FiniteElement<dim>::get_restriction_matrix (const unsigned int child) const
+FiniteElement<dim>::get_restriction_matrix (const unsigned int child,
+                                           const RefinementCase<dim> &refinement_case) const
 {
-  Assert (child<GeometryInfo<dim>::children_per_cell,
-         ExcIndexRange(child, 0, GeometryInfo<dim>::children_per_cell));
-  Assert (restriction[child].n() != 0, ExcProjectionVoid());
-  return restriction[child];
+  Assert (refinement_case<RefinementCase<dim>::isotropic_refinement+1,
+         ExcIndexRange(refinement_case,0,RefinementCase<dim>::isotropic_refinement+1));
+  Assert (refinement_case!=RefinementCase<dim>::no_refinement,
+         ExcMessage("Restriction matrices are only available for refined cells!"));
+  Assert (child<GeometryInfo<dim>::n_children(RefinementCase<dim>(refinement_case)),
+         ExcIndexRange(child,0,GeometryInfo<dim>::n_children(RefinementCase<dim>(refinement_case))));
+                                  // we use refinement_case-1 here. the -1 takes care
+                                  // of the origin of the vector, as for
+                                  // RefinementCase<dim>::no_refinement (=0) there is no
+                                  // data available and so the vector indices
+                                  // are shifted
+  Assert (restriction[refinement_case-1][child].n() != 0, ExcProjectionVoid());
+  return restriction[refinement_case-1][child];
 }
 
 
 
 template <int dim>
 const FullMatrix<double> &
-FiniteElement<dim>::get_prolongation_matrix (const unsigned int child) const
+FiniteElement<dim>::get_prolongation_matrix (const unsigned int child,
+                                            const RefinementCase<dim> &refinement_case) const
 {
-  Assert (child<GeometryInfo<dim>::children_per_cell,
-         ExcIndexRange(child, 0, GeometryInfo<dim>::children_per_cell));
-  Assert (prolongation[child].n() != 0, ExcEmbeddingVoid());
-  return prolongation[child];
+  Assert (refinement_case<RefinementCase<dim>::isotropic_refinement+1,
+         ExcIndexRange(refinement_case,0,RefinementCase<dim>::isotropic_refinement+1));
+  Assert (refinement_case!=RefinementCase<dim>::no_refinement,
+         ExcMessage("Prolongation matrices are only available for refined cells!"));
+  Assert (child<GeometryInfo<dim>::n_children(RefinementCase<dim>(refinement_case)),
+         ExcIndexRange(child,0,GeometryInfo<dim>::n_children(RefinementCase<dim>(refinement_case))));
+                                  // we use refinement_case-1 here. the -1 takes care
+                                  // of the origin of the vector, as for
+                                  // RefinementCase::no_refinement (=0) there is no
+                                  // data available and so the vector indices
+                                  // are shifted
+  Assert (prolongation[refinement_case-1][child].n() != 0, ExcEmbeddingVoid());
+  return prolongation[refinement_case-1][child];
 }
 
 
@@ -403,17 +466,68 @@ template <int dim>
 bool
 FiniteElement<dim>::prolongation_is_implemented () const
 {
-  for (unsigned int c=0; c<GeometryInfo<dim>::children_per_cell; ++c)
+  for (unsigned int ref_case=RefinementCase<dim>::cut_x;
+       ref_case<RefinementCase<dim>::isotropic_refinement+1; ++ref_case)
+    for (unsigned int c=0;
+        c<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case)); ++c)
+      {
+       Assert ((prolongation[ref_case-1][c].m() == this->dofs_per_cell) ||
+               (prolongation[ref_case-1][c].m() == 0),
+               ExcInternalError());
+       Assert ((prolongation[ref_case-1][c].n() == this->dofs_per_cell) ||
+               (prolongation[ref_case-1][c].n() == 0),
+               ExcInternalError());
+       if ((prolongation[ref_case-1][c].m() == 0) ||
+           (prolongation[ref_case-1][c].n() == 0))
+         return false;
+       }
+  return true;
+}
+
+
+
+template <int dim>
+bool
+FiniteElement<dim>::restriction_is_implemented () const
+{
+  for (unsigned int ref_case=RefinementCase<dim>::cut_x;
+       ref_case<RefinementCase<dim>::isotropic_refinement+1; ++ref_case)
+    for (unsigned int c=0;
+        c<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case)); ++c)
+      {
+       Assert ((restriction[ref_case-1][c].m() == this->dofs_per_cell) ||
+               (restriction[ref_case-1][c].m() == 0),
+               ExcInternalError());
+       Assert ((restriction[ref_case-1][c].n() == this->dofs_per_cell) ||
+               (restriction[ref_case-1][c].n() == 0),
+               ExcInternalError());
+       if ((restriction[ref_case-1][c].m() == 0) ||
+           (restriction[ref_case-1][c].n() == 0))
+         return false;
+       }
+  return true;
+}
+
+
+
+template <int dim>
+bool
+FiniteElement<dim>::isotropic_prolongation_is_implemented () const
+{
+  const RefinementCase<dim> ref_case=RefinementCase<dim>::isotropic_refinement;
+  
+  for (unsigned int c=0;
+       c<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case)); ++c)
     {
-      Assert ((prolongation[c].m() == this->dofs_per_cell) ||
-              (prolongation[c].m() == 0),
-              ExcInternalError());
-      Assert ((prolongation[c].n() == this->dofs_per_cell) ||
-              (prolongation[c].n() == 0),
-              ExcInternalError());
-      if ((prolongation[c].m() == 0) ||
-          (prolongation[c].n() == 0))
-        return false;
+      Assert ((prolongation[ref_case-1][c].m() == this->dofs_per_cell) ||
+             (prolongation[ref_case-1][c].m() == 0),
+             ExcInternalError());
+      Assert ((prolongation[ref_case-1][c].n() == this->dofs_per_cell) ||
+             (prolongation[ref_case-1][c].n() == 0),
+             ExcInternalError());
+      if ((prolongation[ref_case-1][c].m() == 0) ||
+         (prolongation[ref_case-1][c].n() == 0))
+       return false;
     }
   return true;
 }
@@ -422,19 +536,22 @@ FiniteElement<dim>::prolongation_is_implemented () const
 
 template <int dim>
 bool
-FiniteElement<dim>::restriction_is_implemented () const
+FiniteElement<dim>::isotropic_restriction_is_implemented () const
 {
-  for (unsigned int c=0; c<GeometryInfo<dim>::children_per_cell; ++c)
+  const RefinementCase<dim> ref_case = RefinementCase<dim>::isotropic_refinement;
+
+  for (unsigned int c=0;
+       c<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case)); ++c)
     {
-      Assert ((restriction[c].m() == this->dofs_per_cell) ||
-              (restriction[c].m() == 0),
-              ExcInternalError());
-      Assert ((restriction[c].n() == this->dofs_per_cell) ||
-              (restriction[c].n() == 0),
-              ExcInternalError());
-      if ((restriction[c].m() == 0) ||
-          (restriction[c].n() == 0))
-        return false;
+      Assert ((restriction[ref_case-1][c].m() == this->dofs_per_cell) ||
+             (restriction[ref_case-1][c].m() == 0),
+             ExcInternalError());
+      Assert ((restriction[ref_case-1][c].n() == this->dofs_per_cell) ||
+             (restriction[ref_case-1][c].n() == 0),
+             ExcInternalError());
+      if ((restriction[ref_case-1][c].m() == 0) ||
+         (restriction[ref_case-1][c].n() == 0))
+       return false;
     }
   return true;
 }
@@ -443,9 +560,12 @@ FiniteElement<dim>::restriction_is_implemented () const
 
 template <int dim>
 bool
-FiniteElement<dim>::constraints_are_implemented () const
+FiniteElement<dim>::constraints_are_implemented (const internal::SubfaceCase<dim> &subface_case) const
 {
-  return (this->dofs_per_face  == 0) || (interface_constraints.m() != 0);
+  if (subface_case==internal::SubfaceCase<dim>::case_isotropic)
+    return (this->dofs_per_face  == 0) || (interface_constraints.m() != 0);
+  else
+    return false;
 }
 
 
@@ -461,8 +581,9 @@ FiniteElement<dim>::hp_constraints_are_implemented () const
 
 template <int dim>
 const FullMatrix<double> &
-FiniteElement<dim>::constraints () const
+FiniteElement<dim>::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),
           ExcConstraintsVoid());
   
@@ -815,12 +936,8 @@ unsigned int
 FiniteElement<dim>::memory_consumption () const
 {
   return (sizeof(FiniteElementData<dim>) +
-         MemoryConsumption::
-         memory_consumption<FullMatrix<double>, sizeof(restriction)/sizeof(restriction[0])>
-         (restriction)+
-         MemoryConsumption::memory_consumption
-         <FullMatrix<double>, sizeof(prolongation)/sizeof(prolongation[0])>
-         (prolongation) +
+         MemoryConsumption::memory_consumption (restriction)+
+         MemoryConsumption::memory_consumption (prolongation) +
          MemoryConsumption::memory_consumption (interface_constraints) +
          MemoryConsumption::memory_consumption (system_to_component_table) +
          MemoryConsumption::memory_consumption (face_system_to_component_table) +
index ad07723a6c8f128d1621b5c47c840cefa5089246..ce017586d3fbae1aad6a36aea969f9cf82e49d94 100644 (file)
@@ -75,17 +75,18 @@ FE_ABF<dim>::FE_ABF (const unsigned int deg)
                                   // will be the correct ones, not
                                   // the raw shape functions anymore.
   
-
-                                  // initialize the various matrices
-  for (unsigned int i=0; i<GeometryInfo<dim>::children_per_cell; ++i)
-    {
-      this->prolongation[i].reinit (n_dofs, n_dofs);
-      this->restriction[i].reinit (n_dofs, n_dofs);
-    }
-
+                                  // Reinit the vectors of
+                                  // restriction and prolongation
+                                  // matrices to the right sizes.
+                                  // Restriction only for isotropic
+                                  // refinement
+  this->reinit_restriction_and_prolongation_matrices(true);
+                                  // Fill prolongation matrices with embedding operators
   FETools::compute_embedding_matrices (*this, this->prolongation);
+
   initialize_restriction ();
 
+                                  // TODO[TL]: for anisotropic refinement we will probably need a table of submatrices with an array for each refine case
   std::vector<FullMatrix<double> >
     face_embeddings(1<<(dim-1), FullMatrix<double>(this->dofs_per_face,
                                                   this->dofs_per_face));
@@ -338,8 +339,9 @@ template <int dim>
 void
 FE_ABF<dim>::initialize_restriction()
 {
-  for (unsigned int i=0;i<GeometryInfo<dim>::children_per_cell;++i)
-    this->restriction[i].reinit(0,0);
+  unsigned int iso=RefinementCase<dim>::isotropic_refinement-1;
+  for (unsigned int i=0;i<GeometryInfo<dim>::max_children_per_cell;++i)
+    this->restriction[iso][i].reinit(0,0);
 }
 
 #else
@@ -358,6 +360,7 @@ template <int dim>
 void
 FE_ABF<dim>::initialize_restriction()
 {
+  unsigned int iso=RefinementCase<dim>::isotropic_refinement-1;
   QGauss<dim-1> q_base (rt_order+1);
   const unsigned int n_face_points = q_base.size();
                                   // First, compute interpolation on
@@ -380,7 +383,7 @@ FE_ABF<dim>::initialize_restriction()
            = this->shape_value_component(i, q_face.point(k),
                                          GeometryInfo<dim>::unit_normal_direction[face]);
 
-      for (unsigned int sub=0;sub<GeometryInfo<dim>::subfaces_per_face;++sub)
+      for (unsigned int sub=0;sub<GeometryInfo<dim>::max_children_per_face;++sub)
        {
                                           // The weight fuctions for
                                           // the coarse face are
@@ -389,7 +392,8 @@ FE_ABF<dim>::initialize_restriction()
          Quadrature<dim> q_sub
            = QProjector<dim>::project_to_subface(q_base, face, sub);
          const unsigned int child
-           = GeometryInfo<dim>::child_cell_on_face(face, sub);
+           = GeometryInfo<dim>::child_cell_on_face(
+             RefinementCase<dim>::isotropic_refinement, face, sub);
          
                                           // On a certain face, we must
                                           // compute the moments of ALL
@@ -412,7 +416,7 @@ FE_ABF<dim>::initialize_restriction()
                                                   // subcell are NOT
                                                   // transformed, so we
                                                   // have to do it here.
-                 this->restriction[child](face*this->dofs_per_face+i_face,
+                 this->restriction[iso][child](face*this->dofs_per_face+i_face,
                                     i_child)
                    += Utilities::fixed_power<dim-1>(.5) * q_sub.weight(k)
                    * cached_values(i_child, k)
@@ -452,7 +456,7 @@ FE_ABF<dim>::initialize_restriction()
       for (unsigned int d=0;d<dim;++d)
        cached_values(i,k,d) = this->shape_value_component(i, q_cell.point(k), d);
   
-  for (unsigned int child=0;child<GeometryInfo<dim>::children_per_cell;++child)
+  for (unsigned int child=0;child<GeometryInfo<dim>::max_children_per_cell;++child)
     {
       Quadrature<dim> q_sub = QProjector<dim>::project_to_child(q_cell, child);
       
@@ -461,7 +465,7 @@ FE_ABF<dim>::initialize_restriction()
          for (unsigned int d=0;d<dim;++d)
            for (unsigned int i_weight=0;i_weight<polynomials[d]->n();++i_weight)
              {
-               this->restriction[child](start_cell_dofs+i_weight*dim+d,
+               this->restriction[iso][child](start_cell_dofs+i_weight*dim+d,
                                   i_child)
                  += q_sub.weight(k)
                  * cached_values(i_child, k, d)
index d7c119fbc36cbd9da6a2193d8c9941784805eb1a..ed3e0b7802f1a91373bc578892d062d3fd7a7ed5 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 by the deal.II authors
+//    Copyright (C) 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
@@ -28,14 +28,13 @@ FE_DGP<dim>::FE_DGP (const unsigned int degree)
                  std::vector<std::vector<bool> >(FiniteElementData<dim>(
                    get_dpo_vector(degree), 1, degree).dofs_per_cell, std::vector<bool>(1,true)))
 {
-  for (unsigned int i=0; i<GeometryInfo<dim>::children_per_cell; ++i)
-    this->prolongation[i].reinit (this->dofs_per_cell,
-                                 this->dofs_per_cell);
+                                  // Reinit the vectors of
+                                  // restriction and prolongation
+                                  // matrices to the right sizes
+  this->reinit_restriction_and_prolongation_matrices();
+                                  // Fill prolongation matrices with embedding operators
   FETools::compute_embedding_matrices (*this, this->prolongation);
                                   // Fill restriction matrices with L2-projection
-  for (unsigned int i=0; i<GeometryInfo<dim>::children_per_cell; ++i)
-    this->restriction[i].reinit (this->dofs_per_cell,
-                                 this->dofs_per_cell);
   FETools::compute_projection_matrices (*this, this->restriction);
 }
 
index 0a3fcd2f12471136217222154df73fa33f1164d2..03c88b2729653f98da04ac458b857f57e3640adf 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 2004, 2005, 2006, 2007 by the deal.II authors
+//    Copyright (C) 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
@@ -129,16 +129,13 @@ FE_DGPMonomial<dim>::FE_DGPMonomial (const unsigned int degree)
                                   // DG doesn't have constraints, so
                                   // leave them empty
 
-                                  // initialize the interpolation
-                                  // matrices
-  for (unsigned int i=0; i<GeometryInfo<dim>::children_per_cell; ++i)
-    this->prolongation[i].reinit (this->dofs_per_cell,
-                                 this->dofs_per_cell);
+                                  // Reinit the vectors of
+                                  // restriction and prolongation
+                                  // matrices to the right sizes
+  this->reinit_restriction_and_prolongation_matrices();
+                                  // Fill prolongation matrices with embedding operators
   FETools::compute_embedding_matrices (*this, this->prolongation);
                                   // Fill restriction matrices with L2-projection
-  for (unsigned int i=0; i<GeometryInfo<dim>::children_per_cell; ++i)
-    this->restriction[i].reinit (this->dofs_per_cell,
-                                 this->dofs_per_cell);
   FETools::compute_projection_matrices (*this, this->restriction);
 }
 
index f36d8ae49094c1ee7c4716ac1903805a35080431..5c27e698a21402d62be8a74b0ff4614b277a1373 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 by the deal.II authors
+//    Copyright (C) 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
@@ -39,12 +39,26 @@ FE_DGPNonparametric<dim>::FE_DGPNonparametric (const unsigned int degree)
                 polynomial_space (Polynomials::Legendre::generate_complete_basis(degree))
 {
   const unsigned int n_dofs = this->dofs_per_cell;
-  for (unsigned int i=0;i<GeometryInfo<dim>::children_per_cell;++i)
+  for (unsigned int ref_case = RefinementCase<dim>::cut_x;
+       ref_case<RefinementCase<dim>::isotropic_refinement+1; ++ref_case)
     {
-      this->prolongation[i].reinit(n_dofs, n_dofs);
-      for (unsigned int j=0;j<n_dofs;++j)
-       this->prolongation[i](j,j) = 1.;
+      if (dim!=2 && ref_case!=RefinementCase<dim>::isotropic_refinement)
+                                        // do nothing, as anisotropic
+                                        // refinement is not
+                                        // implemented so far
+       continue;
+      
+      const unsigned int nc = GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));
+      for (unsigned int i=0;i<nc;++i)
+       {
+         this->prolongation[ref_case-1][i].reinit (n_dofs, n_dofs);
+                                          // Fill prolongation matrices with
+                                          // embedding operators
+         for (unsigned int j=0;j<n_dofs;++j)
+           this->prolongation[ref_case-1][i](j,j) = 1.;
+       }
     }
+
                                    // restriction can be defined
                                    // through projection for
                                    // discontinuous elements, but is
@@ -60,12 +74,13 @@ FE_DGPNonparametric<dim>::FE_DGPNonparametric (const unsigned int degree)
 //      }
 //    else
 //                                  // matrix undefined, set size to zero
-//      for (unsigned int i=0;i<GeometryInfo<dim>::children_per_cell;++i)
+//      for (unsigned int i=0;i<GeometryInfo<dim>::max_children_per_cell;++i)
 //        restriction[i].reinit(0, 0);
                                    // since not implemented, set to
-                                   // "empty"
-  for (unsigned int i=0;i<GeometryInfo<dim>::children_per_cell;++i)
-    this->restriction[i].reinit(0, 0);
+                                   // "empty". however, that is done in the
+                                   // default constructor already, so do nothing
+//  for (unsigned int i=0;i<GeometryInfo<dim>::max_children_per_cell;++i)
+//    this->restriction[i].reinit(0, 0);
 
                                    // note further, that these
                                    // elements have neither support
index 3e7326db4f132930c5dce061bacf850717186c00..4b06ab478684b1abc7167f5ff73ce39872f8debc 100644 (file)
@@ -137,17 +137,15 @@ FE_DGQ<dim>::FE_DGQ (const unsigned int degree)
                  std::vector<std::vector<bool> >(FiniteElementData<dim>(
                    get_dpo_vector(degree),1, degree).dofs_per_cell, std::vector<bool>(1,true)))
 {
+                                  // Reinit the vectors of
+                                  // restriction and prolongation
+                                  // matrices to the right sizes
+  this->reinit_restriction_and_prolongation_matrices();
                                   // Fill prolongation matrices with embedding operators
-  for (unsigned int i=0; i<GeometryInfo<dim>::children_per_cell; ++i)
-    this->prolongation[i].reinit (this->dofs_per_cell,
-                                 this->dofs_per_cell);
   FETools::compute_embedding_matrices (*this, this->prolongation);
                                   // Fill restriction matrices with L2-projection
-  for (unsigned int i=0; i<GeometryInfo<dim>::children_per_cell; ++i)
-    this->restriction[i].reinit (this->dofs_per_cell,
-                                 this->dofs_per_cell);
   FETools::compute_projection_matrices (*this, this->restriction);
-  
+                             
   
                                   // finally fill in support points
   if (degree == 0)
@@ -201,17 +199,16 @@ FE_DGQ<dim>::FE_DGQ (const Quadrature<1>& points)
                  std::vector<std::vector<bool> >(FiniteElementData<dim>(
                    get_dpo_vector(points.size()-1),1, points.size()-1).dofs_per_cell, std::vector<bool>(1,true)))
 {
-  for (unsigned int i=0; i<GeometryInfo<dim>::children_per_cell; ++i)
-    this->prolongation[i].reinit (this->dofs_per_cell,
-                                 this->dofs_per_cell);
+                                  // Reinit the vectors of
+                                  // restriction and prolongation
+                                  // matrices to the right sizes
+  this->reinit_restriction_and_prolongation_matrices();
+                                  // Fill prolongation matrices with embedding operators
   FETools::compute_embedding_matrices (*this, this->prolongation);
                                   // Fill restriction matrices with L2-projection
-  for (unsigned int i=0; i<GeometryInfo<dim>::children_per_cell; ++i)
-    this->restriction[i].reinit (this->dofs_per_cell,
-                                 this->dofs_per_cell);
   FETools::compute_projection_matrices (*this, this->restriction);
   
-                                  // Compute support points, whivh
+                                  // Compute support points, which
                                   // are the tensor product of the
                                   // Lagrange interpolation points in
                                   // the constructor.
index 34df091c8a5f6dc9fb29d6de08565e4dcc1bc2f7..122a0d42ef2e7e3e33430ac5794559c40d8f1baf 100644 (file)
@@ -566,14 +566,15 @@ template <int dim>
 void
 FE_Nedelec<dim>::initialize_embedding ()
 {
+  unsigned int iso=RefinementCase<dim>::isotropic_refinement-1;
   if ((degree < Matrices::n_embedding_matrices+1) &&
       (Matrices::embedding[degree-1][0] != 0))
-    for (unsigned int c=0; c<GeometryInfo<dim>::children_per_cell; ++c)
+    for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
       {
                                          // copy
-        this->prolongation[c].reinit (this->dofs_per_cell,
+        this->prolongation[iso][c].reinit (this->dofs_per_cell,
                                       this->dofs_per_cell);
-        this->prolongation[c].fill (Matrices::embedding[degree-1][c]);
+        this->prolongation[iso][c].fill (Matrices::embedding[degree-1][c]);
                                          // and make sure that the row
                                          // sum is 0.5 (for usual
                                          // elements, the row sum must
@@ -587,7 +588,7 @@ FE_Nedelec<dim>::initialize_embedding ()
           {
             double sum = 0;
             for (unsigned int col=0; col<this->dofs_per_cell; ++col)
-              sum += this->prolongation[c](row,col);
+              sum += this->prolongation[iso][c](row,col);
             Assert (std::fabs(sum-.5) < 1e-14,
                     ExcInternalError());
           };
@@ -600,6 +601,7 @@ template <int dim>
 void
 FE_Nedelec<dim>::initialize_restriction ()
 {
+  unsigned int iso=RefinementCase<dim>::isotropic_refinement-1;
   switch (dim)
     {
       case 2:   // 2d
@@ -689,14 +691,14 @@ FE_Nedelec<dim>::initialize_restriction ()
                                                // always, in the
                                                // canonical direction
                                                // of lines
-              for (unsigned int c=0; c<GeometryInfo<dim>::children_per_cell; ++c)
-                this->restriction[c].reinit (this->dofs_per_cell,
-                                             this->dofs_per_cell);
+              for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
+                this->restriction[iso][c].reinit (this->dofs_per_cell,
+                                                 this->dofs_per_cell);
              
-             this->restriction[0](0,0) = 2.;
-             this->restriction[1](1,1) = 2.;
-             this->restriction[0](2,2) = 2.;
-             this->restriction[2](3,3) = 2.;
+             this->restriction[iso][0](0,0) = 2.;
+             this->restriction[iso][1](1,1) = 2.;
+             this->restriction[iso][0](2,2) = 2.;
+             this->restriction[iso][2](3,3) = 2.;
 
              break;
            };
@@ -730,23 +732,23 @@ FE_Nedelec<dim>::initialize_restriction ()
                                               // cell to get at the
                                               // values of each of
                                               // the 12 lines
-              for (unsigned int c=0; c<GeometryInfo<dim>::children_per_cell; ++c)
-                this->restriction[c].reinit (this->dofs_per_cell,
-                                             this->dofs_per_cell);
-             this->restriction[0](0,0) = 2.;
-             this->restriction[1](1,1) = 2.;
-             this->restriction[0](2,2) = 2.;
-             this->restriction[2](3,3) = 2.;
+              for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
+                this->restriction[iso][c].reinit (this->dofs_per_cell,
+                                                 this->dofs_per_cell);
+             this->restriction[iso][0](0,0) = 2.;
+             this->restriction[iso][1](1,1) = 2.;
+             this->restriction[iso][0](2,2) = 2.;
+             this->restriction[iso][2](3,3) = 2.;
               
-             this->restriction[4](4,4) = 2.;
-             this->restriction[5](5,5) = 2.;
-             this->restriction[4](6,6) = 2.;
-             this->restriction[6](7,7) = 2.;
+             this->restriction[iso][4](4,4) = 2.;
+             this->restriction[iso][5](5,5) = 2.;
+             this->restriction[iso][4](6,6) = 2.;
+             this->restriction[iso][6](7,7) = 2.;
               
-             this->restriction[0](8,8) = 2.;
-             this->restriction[1](9,9) = 2.;
-             this->restriction[2](10,10) = 2.;
-             this->restriction[3](11,11) = 2.;
+             this->restriction[iso][0](8,8) = 2.;
+             this->restriction[iso][1](9,9) = 2.;
+             this->restriction[iso][2](10,10) = 2.;
+             this->restriction[iso][3](11,11) = 2.;
               
              break;
            };
@@ -1285,7 +1287,8 @@ FE_Nedelec<dim>::fill_fe_subface_values (const Mapping<dim>                   &m
                cell->face_orientation(face),
                cell->face_flip(face),
                cell->face_rotation(face),
-               quadrature.size()));
+               quadrature.size(),
+               cell->subface_case(face)));
 
                                   // get the flags indicating the
                                   // fields that have to be filled
@@ -1307,7 +1310,7 @@ FE_Nedelec<dim>::fill_fe_subface_values (const Mapping<dim>                   &m
   if (flags & update_values)
     {
       Assert (fe_data.shape_values[0].size() ==
-             GeometryInfo<dim>::subfaces_per_face *
+             GeometryInfo<dim>::max_children_per_face *
               GeometryInfo<dim>::faces_per_cell *
              n_q_points,
              ExcInternalError());
@@ -1339,7 +1342,7 @@ FE_Nedelec<dim>::fill_fe_subface_values (const Mapping<dim>                   &m
     {
       Assert (fe_data.shape_gradients.size() ==
               GeometryInfo<dim>::faces_per_cell *
-             GeometryInfo<dim>::subfaces_per_face *
+             GeometryInfo<dim>::max_children_per_face *
              n_q_points,
               ExcInternalError());
 
index 9a74b050f22256c882be26b8dcff412a3e85064d..1c5b27b1c1dd576b799f8c8515b07a1accbeaeb6 100644 (file)
@@ -25,7 +25,7 @@ DEAL_II_NAMESPACE_OPEN
 
 template <>
 const double * const
-FE_Nedelec<1>::Matrices::embedding[][GeometryInfo<1>::children_per_cell] =
+FE_Nedelec<1>::Matrices::embedding[][GeometryInfo<1>::max_children_per_cell] =
 {{0}};
 
 
index 30aa812bfe17d25c3f3b7d2c596fb5a33dd9f80a..5b30aadf1753306fdb6344bdcc35ca48672f0669 100644 (file)
@@ -73,7 +73,7 @@ namespace FE_Nedelec_2d
 
 template <>
 const double * const 
-FE_Nedelec<2>::Matrices::embedding[][GeometryInfo<2>::children_per_cell] =
+FE_Nedelec<2>::Matrices::embedding[][GeometryInfo<2>::max_children_per_cell] =
 {
       { FE_Nedelec_2d::q1_into_q1_refined_0, FE_Nedelec_2d::q1_into_q1_refined_1,
        FE_Nedelec_2d::q1_into_q1_refined_2, FE_Nedelec_2d::q1_into_q1_refined_3 }
index a61adb329bd1d856b6c3ff41f17955fd75bd6d60..0943d8f9fe6430b230b4e6f814cf0bdac59becde 100644 (file)
@@ -172,7 +172,7 @@ namespace FE_Nedelec_3d
 
 template <>
 const double * const 
-FE_Nedelec<3>::Matrices::embedding[][GeometryInfo<3>::children_per_cell] =
+FE_Nedelec<3>::Matrices::embedding[][GeometryInfo<3>::max_children_per_cell] =
 {
       { FE_Nedelec_3d::q1_into_q1_refined_0, FE_Nedelec_3d::q1_into_q1_refined_1,
        FE_Nedelec_3d::q1_into_q1_refined_2, FE_Nedelec_3d::q1_into_q1_refined_3,
index 5c1c895bf9f0ca0083205066a9b30103fd0cc8e4..34cb8648c44c13572b71ae8f8d4fc2f51d85e79e 100644 (file)
@@ -731,7 +731,8 @@ FE_PolyTensor<POLY,dim>::fill_fe_subface_values (
                   cell->face_orientation(face),
                   cell->face_flip(face),
                   cell->face_rotation(face),
-                  n_q_points);
+                  n_q_points,
+                  cell->subface_case(face));
 
   const UpdateFlags flags(fe_data.update_once | fe_data.update_each);
 
index 9290fc67cef7ddb3b2fc5f09a97f0ceae5ced87d..29aa0d8eca83d093a730df87457262183ec11b40 100644 (file)
@@ -1124,7 +1124,7 @@ FE_Q<3>::initialize_constraints ()
                                       // 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>::subfaces_per_face; ++subface)
+            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(),
@@ -1139,7 +1139,7 @@ FE_Q<3>::initialize_constraints ()
          inner_points[i++] = Point<dim-1> (ix*step, iy*step);
       
       for (unsigned int child=0; 
-          child<GeometryInfo<dim-1>::children_per_cell; ++child)
+          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));
@@ -1269,6 +1269,8 @@ template <int dim>
 void
 FE_Q<dim>::initialize_embedding ()
 {
+  unsigned int iso=RefinementCase<dim>::isotropic_refinement-1;
+
                                   // compute the interpolation
                                   // matrices in much the same way as
                                   // we do for the constraints. it's
@@ -1282,10 +1284,10 @@ FE_Q<dim>::initialize_embedding ()
   const std::vector<unsigned int> &index_map=
     this->poly_space.get_numbering();
   
-  for (unsigned int child=0; child<GeometryInfo<dim>::children_per_cell; ++child)
-    this->prolongation[child].reinit (this->dofs_per_cell,
-                                     this->dofs_per_cell);
-  for (unsigned int child=0; child<GeometryInfo<dim>::children_per_cell; ++child)
+  for (unsigned int child=0; child<GeometryInfo<dim>::max_children_per_cell; ++child)
+    this->prolongation[iso][child].reinit (this->dofs_per_cell,
+                                          this->dofs_per_cell);
+  for (unsigned int child=0; child<GeometryInfo<dim>::max_children_per_cell; ++child)
     {
       for (unsigned int j=0; j<this->dofs_per_cell; ++j)
        {
@@ -1378,15 +1380,15 @@ FE_Q<dim>::initialize_embedding ()
                                       // of the identity matrix and
                                       // its inverse is also its
                                       // transpose
-      subcell_interpolation.Tmmult (this->prolongation[child],
+      subcell_interpolation.Tmmult (this->prolongation[iso][child],
                                     cell_interpolation);
 
                                         // cut off very small values
                                         // here
       for (unsigned int i=0; i<this->dofs_per_cell; ++i)
        for (unsigned int j=0; j<this->dofs_per_cell; ++j)
-         if (std::fabs(this->prolongation[child](i,j)) < 2e-13*this->degree*dim)
-           this->prolongation[child](i,j) = 0.;
+         if (std::fabs(this->prolongation[iso][child](i,j)) < 2e-13*this->degree*dim)
+           this->prolongation[iso][child](i,j) = 0.;
 
                                       // and make sure that the row
                                       // sum is 1. this must be so
@@ -1396,7 +1398,7 @@ FE_Q<dim>::initialize_embedding ()
        {
          double sum = 0;
          for (unsigned int col=0; col<this->dofs_per_cell; ++col)
-           sum += this->prolongation[child](row,col);
+           sum += this->prolongation[iso][child](row,col);
          Assert (std::fabs(sum-1.) < 2e-13*this->degree*this->degree*dim,
                  ExcInternalError());
        }
@@ -1409,6 +1411,8 @@ template <int dim>
 void
 FE_Q<dim>::initialize_restriction ()
 {
+  unsigned int iso=RefinementCase<dim>::isotropic_refinement-1;
+
                                    // for these Lagrange interpolation
                                    // polynomials, construction of the
                                    // restriction matrices is
@@ -1454,8 +1458,8 @@ FE_Q<dim>::initialize_restriction ()
                                    // one child) by the same value
                                    // (compute on a later child), so
                                    // we don't have to care about this
-  for (unsigned int c=0; c<GeometryInfo<dim>::children_per_cell; ++c)
-    this->restriction[c].reinit (this->dofs_per_cell, this->dofs_per_cell);
+  for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
+    this->restriction[iso][c].reinit (this->dofs_per_cell, this->dofs_per_cell);
   for (unsigned int i=0; i<this->dofs_per_cell; ++i)
     {
       const Point<dim> p_cell
@@ -1487,13 +1491,13 @@ FE_Q<dim>::initialize_restriction ()
                                        // then find the children on
                                        // which the interpolation
                                        // point is located
-      for (unsigned int child=0; child<GeometryInfo<dim>::children_per_cell;
+      for (unsigned int child=0; child<GeometryInfo<dim>::max_children_per_cell;
            ++child)
         {
                                            // first initialize this
                                            // column of the matrix
           for (unsigned int j=0; j<this->dofs_per_cell; ++j)
-            this->restriction[child](mother_dof, j) = 0.;
+            this->restriction[iso][child](mother_dof, j) = 0.;
 
                                            // then check whether this
                                            // interpolation point is
@@ -1528,7 +1532,7 @@ FE_Q<dim>::initialize_restriction ()
                                                // it, set the
                                                // corresponding value
                                                // in the matrix
-              this->restriction[child](mother_dof, child_dof) = 1.;
+              this->restriction[iso][child](mother_dof, child_dof) = 1.;
             }
         }
     }
index 7a4810a9d96ae85d7e52dbbf31b558666627d517..c00a74f4507f81fc9b692d234ab7f10ec066410f 100644 (file)
@@ -68,11 +68,11 @@ FE_Q_Hierarchical<dim>::FE_Q_Hierarchical (const unsigned int degree)
                                   // @p{interface_constraints} matrices 
                                   // for all dimensions.
   std::vector<FullMatrix<double> >
-    dofs_cell (GeometryInfo<1>::children_per_cell,
+    dofs_cell (GeometryInfo<1>::max_children_per_cell,
               FullMatrix<double> (2*this->dofs_per_vertex + this->dofs_per_line,
                                   2*this->dofs_per_vertex + this->dofs_per_line));
   std::vector<FullMatrix<double> >
-    dofs_subcell (GeometryInfo<1>::children_per_cell,
+    dofs_subcell (GeometryInfo<1>::max_children_per_cell,
                  FullMatrix<double> (2*this->dofs_per_vertex + this->dofs_per_line,
                                      2*this->dofs_per_vertex + this->dofs_per_line));
                                   // build these fields, as they are
@@ -132,7 +132,7 @@ FE_Q_Hierarchical<dim>::build_dofs_cell (std::vector<FullMatrix<double> > &dofs_
 {
   const unsigned int dofs_1d = 2*this->dofs_per_vertex + this->dofs_per_line;
 
-  for (unsigned int c=0; c<GeometryInfo<1>::children_per_cell; ++c)
+  for (unsigned int c=0; c<GeometryInfo<1>::max_children_per_cell; ++c)
     for (unsigned int j=0; j<dofs_1d; ++j)
       for (unsigned int k=0; k<dofs_1d; ++k)
        {
@@ -210,7 +210,7 @@ initialize_constraints (const std::vector<FullMatrix<double> > &dofs_subcell)
        for (unsigned int i=0; i<dofs_1d; ++i)
          this->interface_constraints(0,i) = dofs_subcell[0](1,i); 
                                         // edge nodes
-       for (unsigned int c=0; c<GeometryInfo<1>::children_per_cell; ++c)
+       for (unsigned int c=0; c<GeometryInfo<1>::max_children_per_cell; ++c)
          for (unsigned int i=0; i<dofs_1d; ++i)
            for (unsigned int j=2; j<dofs_1d; ++j)
              this->interface_constraints(1 + c*(degree-1) + j - 2,i) = 
@@ -329,24 +329,26 @@ FE_Q_Hierarchical<dim>::
 initialize_embedding_and_restriction (const std::vector<FullMatrix<double> > &dofs_cell,
                                      const std::vector<FullMatrix<double> > &dofs_subcell)
 {
+  unsigned int iso=RefinementCase<dim>::isotropic_refinement-1;
+
   const unsigned int dofs_1d = 2*this->dofs_per_vertex + this->dofs_per_line;
   const std::vector<unsigned int> &renumber=
     this->poly_space.get_numbering();
   
-  for (unsigned int c=0; c<GeometryInfo<dim>::children_per_cell; ++c)
+  for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
     {
-      this->prolongation[c].reinit (this->dofs_per_cell, this->dofs_per_cell);
-      this->restriction[c].reinit (this->dofs_per_cell, this->dofs_per_cell);
+      this->prolongation[iso][c].reinit (this->dofs_per_cell, this->dofs_per_cell);
+      this->restriction[iso][c].reinit (this->dofs_per_cell, this->dofs_per_cell);
     }
 
                                   // the 1d case is particularly
                                   // simple, so special case it:
   if (dim==1)
     {
-      for (unsigned int c=0; c<GeometryInfo<dim>::children_per_cell; ++c)
+      for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
        {
-         this->prolongation[c].fill (dofs_subcell[c]);
-         this->restriction[c].fill (dofs_cell[c]);
+         this->prolongation[iso][c].fill (dofs_subcell[c]);
+         this->restriction[iso][c].fill (dofs_cell[c]);
        }
       return;
     }
@@ -367,20 +369,20 @@ initialize_embedding_and_restriction (const std::vector<FullMatrix<double> > &do
        {
          case 2:
          {
-           for (unsigned int c=0; c<GeometryInfo<2>::children_per_cell; ++c)
+           for (unsigned int c=0; c<GeometryInfo<2>::max_children_per_cell; ++c)
              {
                                                 // left/right line: 0/1
                const unsigned int c0 = c%2;
                                                 // bottom/top line: 0/1
                const unsigned int c1 = c/2;
 
-               this->prolongation[c](j,i) = 
+               this->prolongation[iso][c](j,i) = 
                  dofs_subcell[c0](renumber[j] % dofs_1d,
                                   renumber[i] % dofs_1d) *
                  dofs_subcell[c1]((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d,
                                   (renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d);
 
-               this->restriction[c](j,i) = 
+               this->restriction[iso][c](j,i) = 
                  dofs_cell[c0](renumber[j] % dofs_1d,
                                renumber[i] % dofs_1d) *
                  dofs_cell[c1]((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d,
@@ -391,7 +393,7 @@ initialize_embedding_and_restriction (const std::vector<FullMatrix<double> > &do
             
          case 3:
          {
-           for (unsigned int c=0; c<GeometryInfo<3>::children_per_cell; ++c)
+           for (unsigned int c=0; c<GeometryInfo<3>::max_children_per_cell; ++c)
              {
                                                 // left/right face: 0/1
                const unsigned int c0 = c%2;
@@ -400,7 +402,7 @@ initialize_embedding_and_restriction (const std::vector<FullMatrix<double> > &do
                                                 // bottom/top face: 0/1
                const unsigned int c2 = c/4;
 
-               this->prolongation[c](j,i) = 
+               this->prolongation[iso][c](j,i) = 
                  dofs_subcell[c0](renumber[j] % dofs_1d,
                                   renumber[i] % dofs_1d) *
                  dofs_subcell[c1](((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d) % dofs_1d,
@@ -408,7 +410,7 @@ initialize_embedding_and_restriction (const std::vector<FullMatrix<double> > &do
                  dofs_subcell[c2](((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d - (((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d ) % dofs_1d)) / dofs_1d,
                                   ((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d - (((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d ) % dofs_1d)) / dofs_1d);
 
-               this->restriction[c](j,i) = 
+               this->restriction[iso][c](j,i) = 
                  dofs_cell[c0](renumber[j] % dofs_1d,
                                renumber[i] % dofs_1d) *
                  dofs_cell[c1](((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d) % dofs_1d,
index 0fa237210c8a026534bd6930511a607535a4883f..4580642ebb7f49cc363a81fda8d469636327f605 100644 (file)
@@ -68,25 +68,25 @@ FE_RaviartThomas<dim>::FE_RaviartThomas (const unsigned int deg)
                                   // will be the correct ones, not
                                   // the raw shape functions anymore.
   
-
-                                  // initialize the various matrices
-  for (unsigned int i=0; i<GeometryInfo<dim>::children_per_cell; ++i)
-    {
-      this->prolongation[i].reinit (n_dofs, n_dofs);
-      this->restriction[i].reinit (n_dofs, n_dofs);
-    }
-  
+                                  // Reinit the vectors of
+                                  // restriction and prolongation
+                                  // matrices to the right sizes.
+                                  // Restriction only for isotropic
+                                  // refinement
+  this->reinit_restriction_and_prolongation_matrices(true);
+                                  // Fill prolongation matrices with embedding operators
   FETools::compute_embedding_matrices (*this, this->prolongation);
   initialize_restriction();
-  
-  FullMatrix<double> face_embeddings[GeometryInfo<dim>::subfaces_per_face];
-  for (unsigned int i=0; i<GeometryInfo<dim>::subfaces_per_face; ++i)
+
+                                  // TODO[TL]: for anisotropic refinement we will probably need a table of submatrices with an array for each refine case
+  FullMatrix<double> face_embeddings[GeometryInfo<dim>::max_children_per_face];
+  for (unsigned int i=0; i<GeometryInfo<dim>::max_children_per_face; ++i)
     face_embeddings[i].reinit (this->dofs_per_face, this->dofs_per_face);
   FETools::compute_face_embedding_matrices(*this, face_embeddings, 0, 0);
   this->interface_constraints.reinit((1<<(dim-1)) * this->dofs_per_face,
                                     this->dofs_per_face);
   unsigned int target_row=0;
-  for (unsigned int d=0;d<GeometryInfo<dim>::subfaces_per_face;++d)
+  for (unsigned int d=0;d<GeometryInfo<dim>::max_children_per_face;++d)
     for (unsigned int i=0;i<face_embeddings[d].m();++i)
       {
        for (unsigned int j=0;j<face_embeddings[d].n();++j)
@@ -261,8 +261,11 @@ template <>
 void
 FE_RaviartThomas<1>::initialize_restriction()
 {
-  for (unsigned int i=0;i<GeometryInfo<1>::children_per_cell;++i)
-    this->restriction[i].reinit(0,0);
+                                  // there is only one refinement case in 1d,
+                                  // which is the isotropic one (first index of
+                                  // the matrix array has to be 0)
+  for (unsigned int i=0;i<GeometryInfo<1>::max_children_per_cell;++i)
+    this->restriction[0][i].reinit(0,0);
 }
 
 #endif
@@ -281,6 +284,8 @@ template <int dim>
 void
 FE_RaviartThomas<dim>::initialize_restriction()
 {
+  const unsigned int iso=RefinementCase<dim>::isotropic_refinement-1;
+
   QGauss<dim-1> q_base (rt_order+1);
   const unsigned int n_face_points = q_base.size();
                                   // First, compute interpolation on
@@ -303,7 +308,7 @@ FE_RaviartThomas<dim>::initialize_restriction()
            = this->shape_value_component(i, q_face.point(k),
                                          GeometryInfo<dim>::unit_normal_direction[face]);
 
-      for (unsigned int sub=0;sub<GeometryInfo<dim>::subfaces_per_face;++sub)
+      for (unsigned int sub=0;sub<GeometryInfo<dim>::max_children_per_face;++sub)
        {
                                           // The weight fuctions for
                                           // the coarse face are
@@ -312,7 +317,8 @@ FE_RaviartThomas<dim>::initialize_restriction()
          Quadrature<dim> q_sub
            = QProjector<dim>::project_to_subface(q_base, face, sub);
          const unsigned int child
-           = GeometryInfo<dim>::child_cell_on_face(face, sub);
+           = GeometryInfo<dim>::child_cell_on_face(
+             RefinementCase<dim>::isotropic_refinement, face, sub);
          
                                           // On a certain face, we must
                                           // compute the moments of ALL
@@ -335,8 +341,8 @@ FE_RaviartThomas<dim>::initialize_restriction()
                                                   // subcell are NOT
                                                   // transformed, so we
                                                   // have to do it here.
-                 this->restriction[child](face*this->dofs_per_face+i_face,
-                                    i_child)
+                 this->restriction[iso][child](face*this->dofs_per_face+i_face,
+                                               i_child)
                    += Utilities::fixed_power<dim-1>(.5) * q_sub.weight(k)
                    * cached_values(i_child, k)
                    * this->shape_value_component(face*this->dofs_per_face+i_face,
@@ -375,7 +381,7 @@ FE_RaviartThomas<dim>::initialize_restriction()
       for (unsigned int d=0;d<dim;++d)
        cached_values(i,k,d) = this->shape_value_component(i, q_cell.point(k), d);
   
-  for (unsigned int child=0;child<GeometryInfo<dim>::children_per_cell;++child)
+  for (unsigned int child=0;child<GeometryInfo<dim>::max_children_per_cell;++child)
     {
       Quadrature<dim> q_sub = QProjector<dim>::project_to_child(q_cell, child);
       
@@ -384,8 +390,8 @@ FE_RaviartThomas<dim>::initialize_restriction()
          for (unsigned int d=0;d<dim;++d)
            for (unsigned int i_weight=0;i_weight<polynomials[d]->n();++i_weight)
              {
-               this->restriction[child](start_cell_dofs+i_weight*dim+d,
-                                  i_child)
+               this->restriction[iso][child](start_cell_dofs+i_weight*dim+d,
+                                             i_child)
                  += q_sub.weight(k)
                  * cached_values(i_child, k, d)
                  * polynomials[d]->compute_value(i_weight, q_sub.point(k));
index b023fbd6cf4caba40093f189ecad8ecca71406f2..7948173b862d69b7fb1b0314fb70b71b69dfd201 100644 (file)
@@ -68,19 +68,29 @@ FE_RaviartThomasNodal<dim>::FE_RaviartThomasNodal (const unsigned int deg)
                                   // will be the correct ones, not
                                   // the raw shape functions anymore.
   
-  for (unsigned int i=0; i<GeometryInfo<dim>::children_per_cell; ++i)
-    this->prolongation[i].reinit (this->dofs_per_cell,
-                                 this->dofs_per_cell);
+                                  // Reinit the vectors of
+                                  // prolongation matrices to the
+                                  // right sizes. There are no
+                                  // restriction matrices implemented
+  for (unsigned int ref_case=RefinementCase<dim>::cut_x;
+       ref_case<RefinementCase<dim>::isotropic_refinement+1; ++ref_case)
+    {
+      const unsigned int nc = GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));
+
+      for (unsigned int i=0;i<nc;++i)
+       this->prolongation[ref_case-1][i].reinit (n_dofs, n_dofs);
+    }
+                                  // Fill prolongation matrices with embedding operators
   FETools::compute_embedding_matrices (*this, this->prolongation);
-  
-  FullMatrix<double> face_embeddings[GeometryInfo<dim>::subfaces_per_face];
-  for (unsigned int i=0; i<GeometryInfo<dim>::subfaces_per_face; ++i)
+                                  // TODO[TL]: for anisotropic refinement we will probably need a table of submatrices with an array for each refine case
+  FullMatrix<double> face_embeddings[GeometryInfo<dim>::max_children_per_face];
+  for (unsigned int i=0; i<GeometryInfo<dim>::max_children_per_face; ++i)
     face_embeddings[i].reinit (this->dofs_per_face, this->dofs_per_face);
   FETools::compute_face_embedding_matrices(*this, face_embeddings, 0, 0);
   this->interface_constraints.reinit((1<<(dim-1)) * this->dofs_per_face,
                                     this->dofs_per_face);
   unsigned int target_row=0;
-  for (unsigned int d=0;d<GeometryInfo<dim>::subfaces_per_face;++d)
+  for (unsigned int d=0;d<GeometryInfo<dim>::max_children_per_face;++d)
     for (unsigned int i=0;i<face_embeddings[d].m();++i)
       {
        for (unsigned int j=0;j<face_embeddings[d].n();++j)
index de5ed06659bf6adc4fde6b8b8929213df6ae688f..350c6066d49b1313a571495329d38d9c67239c61 100644 (file)
@@ -984,10 +984,21 @@ compute_fill (const Mapping<dim>                   &mapping,
     {
       unsigned int offset = 0;
       if (face_no != invalid_face_number)
-       offset = (sub_no == invalid_face_number)
-                ? face_no * n_q_points
-                :(face_no * GeometryInfo<dim>::subfaces_per_face
-                  + sub_no) * n_q_points;
+       if (sub_no == invalid_face_number)
+         offset=QProjector<dim>::DataSetDescriptor
+                ::face(face_no,
+                       cell->face_orientation(face_no),
+                       cell->face_flip(face_no),
+                       cell->face_rotation(face_no),
+                       n_q_points);
+       else
+         offset=QProjector<dim>::DataSetDescriptor
+                ::subface(face_no, sub_no,
+                          cell->face_orientation(face_no),
+                          cell->face_flip(face_no),
+                          cell->face_rotation(face_no),
+                          n_q_points,
+                          cell->subface_case(face_no));
       this->compute_2nd (mapping, cell, offset, mapping_data, fe_data, data);
     }
 }
@@ -1633,93 +1644,100 @@ void FESystem<dim>::initialize ()
 {
   build_cell_tables();
   build_face_tables();
-  
-                                  // Check if some of the matrices of
-                                  // the base elements are void.
-  bool do_restriction = true;
-  bool do_prolongation = true;
 
-  for (unsigned int i=0; i<n_base_elements(); ++i)
+  for (unsigned int ref_case=RefinementCase<dim>::cut_x;
+       ref_case<RefinementCase<dim>::isotropic_refinement+1;
+       ++ref_case)
     {
-      if (base_element(i).restriction[0].n() == 0)
-       do_restriction = false;
-      if (base_element(i).prolongation[0].n() == 0)
-       do_prolongation = false;
-    }
+                                      // Check if some of the matrices of
+                                      // the base elements are void.
+                                      // repeat this check for each RefineCase
+      bool do_restriction = true;
+      bool do_prolongation = true;
+
+      for (unsigned int i=0; i<n_base_elements(); ++i)
+       {
+         if (base_element(i).restriction[ref_case-1][0].n() == 0)
+           do_restriction = false;
+         if (base_element(i).prolongation[ref_case-1][0].n() == 0)
+           do_prolongation = false;
+       }
   
-                                  // if we did not encounter void
-                                  // matrices, initialize the
-                                  // respective matrix sizes
-  if (do_restriction)
-    for (unsigned int i=0;i<GeometryInfo<dim>::children_per_cell;++i)
-      this->restriction[i].reinit(this->dofs_per_cell,
-                                  this->dofs_per_cell);
-  if (do_prolongation)
-    for (unsigned int i=0;i<GeometryInfo<dim>::children_per_cell;++i)
-      this->prolongation[i].reinit(this->dofs_per_cell,
-                                   this->dofs_per_cell);
+                                      // if we did not encounter void
+                                      // matrices, initialize the
+                                      // respective matrix sizes
+      if (do_restriction)
+       for (unsigned int i=0;i<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));++i)
+         this->restriction[ref_case-1][i].reinit(this->dofs_per_cell,
+                                                 this->dofs_per_cell);
+      if (do_prolongation)
+       for (unsigned int i=0;i<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));++i)
+         this->prolongation[ref_case-1][i].reinit(this->dofs_per_cell,
+                                                  this->dofs_per_cell);
        
-                                  // distribute the matrices of the
-                                  // base finite elements to the
-                                  // matrices of this object. for
-                                  // this, loop over all degrees of
-                                  // freedom and take the respective
-                                  // entry of the underlying base
-                                  // element.
-                                  //
-                                  // note that we by definition of a
-                                  // base element, they are
-                                  // independent, i.e. do not
-                                  // couple. only DoFs that belong to
-                                  // the same instance of a base
-                                  // element may couple
-  for (unsigned int i=0; i<this->dofs_per_cell; ++i)
-    for (unsigned int j=0; j<this->dofs_per_cell; ++j)
-      {
-                                        // first find out to which
-                                        // base element indices i and
-                                        // j belong, and which
-                                        // instance thereof in case
-                                        // the base element has a
-                                        // multiplicity greater than
-                                        // one. if they should not
-                                        // happen to belong to the
-                                        // same instance of a base
-                                        // element, then they cannot
-                                        // couple, so go on with the
-                                        // next index
-       if (this->system_to_base_table[i].first !=
-           this->system_to_base_table[j].first)
-         continue;
-
-                                        // so get the common base
-                                        // element and the indices
-                                        // therein:
-       const unsigned int
-         base = this->system_to_base_table[i].first.first;
-
-       const unsigned int
-         base_index_i = this->system_to_base_table[i].second,
-         base_index_j = this->system_to_base_table[j].second;
-
-                                        // if we are sure that DoFs i
-                                        // and j may couple, then
-                                        // copy entries of the
-                                        // matrices:
-       for (unsigned int child=0; child<GeometryInfo<dim>::children_per_cell; ++child)
+                                      // distribute the matrices of the
+                                      // base finite elements to the
+                                      // matrices of this object. for
+                                      // this, loop over all degrees of
+                                      // freedom and take the respective
+                                      // entry of the underlying base
+                                      // element.
+                                      //
+                                      // note that we by definition of a
+                                      // base element, they are
+                                      // independent, i.e. do not
+                                      // couple. only DoFs that belong to
+                                      // the same instance of a base
+                                      // element may couple
+      for (unsigned int i=0; i<this->dofs_per_cell; ++i)
+       for (unsigned int j=0; j<this->dofs_per_cell; ++j)
          {
-           if (do_restriction)
-             this->restriction[child] (i,j)
-               = (base_element(base)
-                   .get_restriction_matrix(child)(base_index_i,base_index_j));
+                                            // first find out to which
+                                            // base element indices i and
+                                            // j belong, and which
+                                            // instance thereof in case
+                                            // the base element has a
+                                            // multiplicity greater than
+                                            // one. if they should not
+                                            // happen to belong to the
+                                            // same instance of a base
+                                            // element, then they cannot
+                                            // couple, so go on with the
+                                            // next index
+           if (this->system_to_base_table[i].first !=
+               this->system_to_base_table[j].first)
+             continue;
+
+                                            // so get the common base
+                                            // element and the indices
+                                            // therein:
+           const unsigned int
+             base = this->system_to_base_table[i].first.first;
+
+           const unsigned int
+             base_index_i = this->system_to_base_table[i].second,
+             base_index_j = this->system_to_base_table[j].second;
+
+                                            // if we are sure that DoFs i
+                                            // and j may couple, then
+                                            // copy entries of the
+                                            // matrices:
+           for (unsigned int child=0; child<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case)); ++child)
+             {
+               if (do_restriction)
+                 this->restriction[ref_case-1][child] (i,j)
+                   = (base_element(base)
+                      .get_restriction_matrix(child, RefinementCase<dim>(ref_case))(
+                        base_index_i,base_index_j));
            
-           if (do_prolongation)
-             this->prolongation[child] (i,j)
-               = (base_element(base)
-                   .get_prolongation_matrix(child)(base_index_i,base_index_j));
+               if (do_prolongation)
+                 this->prolongation[ref_case-1][child] (i,j)
+                   = (base_element(base)
+                      .get_prolongation_matrix(child, RefinementCase<dim>(ref_case))(
+                        base_index_i,base_index_j));
+             };
          };
-      };
-
+    }
                                   // now set up the interface constraints.
                                   // this is kind'o hairy, so don't try
                                   // to do it dimension independent
index 8aecda90305ec46437e48fc023b753866252a947..83f3e21908995923dac176d262651f2c4bfe0af5 100644 (file)
@@ -560,112 +560,118 @@ FETools::compute_node_matrix(
 template<int dim, typename number>
 void
 FETools::compute_embedding_matrices(const FiniteElement<dim>& fe,
-                                   FullMatrix<number> (&matrices)[GeometryInfo<dim>::children_per_cell])
+                                   std::vector<std::vector<FullMatrix<number> > >& matrices)
 {
-  const unsigned int nc = GeometryInfo<dim>::children_per_cell;
   const unsigned int n  = fe.dofs_per_cell;
   const unsigned int nd = fe.n_components();
   const unsigned int degree = fe.degree;
-  
-  for (unsigned int i=0;i<nc;++i)
+
+                                  // loop over all possible refinement cases
+  for (unsigned int ref_case=RefinementCase<dim>::cut_x;
+       ref_case<RefinementCase<dim>::isotropic_refinement+1; ++ref_case)
     {
-      Assert(matrices[i].n() == n, ExcDimensionMismatch(matrices[i].n(),n));
-      Assert(matrices[i].m() == n, ExcDimensionMismatch(matrices[i].m(),n));
-    }
+      const unsigned int nc = GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));
+      for (unsigned int i=0;i<nc;++i)
+       {
+         Assert(matrices[ref_case-1][i].n() == n, ExcDimensionMismatch(matrices[ref_case-1][i].n(),n));
+         Assert(matrices[ref_case-1][i].m() == n, ExcDimensionMismatch(matrices[ref_case-1][i].m(),n));
+       }
   
-                                   // Set up a meshes, one with a single
-                                   // reference cell and refine it once
-  Triangulation<dim> tria;
-  GridGenerator::hyper_cube (tria, 0, 1);
-  tria.refine_global(1);
+                                      // Set up meshes, one with a single
+                                      // reference cell and refine it once
+      Triangulation<dim> tria;
+      GridGenerator::hyper_cube (tria, 0, 1);
+      tria.begin_active()->set_refine_flag(RefinementCase<dim>(ref_case));
+      tria.execute_coarsening_and_refinement();
 
-  MappingCartesian<dim> mapping;
-  QGauss<dim> q_fine(degree+1);
-  const unsigned int nq = q_fine.size();
+      MappingCartesian<dim> mapping;
+      QGauss<dim> q_fine(degree+1);
+      const unsigned int nq = q_fine.size();
   
-  FEValues<dim> fine (mapping, fe, q_fine,
-                     update_quadrature_points | update_JxW_values | update_values);
+      FEValues<dim> fine (mapping, fe, q_fine,
+                         update_quadrature_points | update_JxW_values | update_values);
   
-                                  // We search for the polynomial on
-                                  // the small cell, being equal to
-                                  // the coarse polynomial in all
-                                  // quadrature points.
+                                      // We search for the polynomial on
+                                      // the small cell, being equal to
+                                      // the coarse polynomial in all
+                                      // quadrature points.
                                    
-                                  // First build the matrix for this
-                                  // least squares problem. This
-                                  // contains the values of the fine
-                                  // cell polynomials in the fine
-                                  // cell grid points.
+                                      // First build the matrix for this
+                                      // least squares problem. This
+                                      // contains the values of the fine
+                                      // cell polynomials in the fine
+                                      // cell grid points.
                                    
-                                  // This matrix is the same for all
-                                  // children.
-  fine.reinit(tria.begin_active());
-  FullMatrix<number> A(nq*nd, n);
-  for (unsigned int d=0;d<nd;++d)
-    for (unsigned int k=0;k<nq;++k)
-      for (unsigned int j=0;j<n;++j)
-       A(k*nd+d,j) = fine.shape_value_component(j,k,d);
+                                      // This matrix is the same for all
+                                      // children.
+      fine.reinit(tria.begin_active());
+      FullMatrix<number> A(nq*nd, n);
+      for (unsigned int d=0;d<nd;++d)
+       for (unsigned int k=0;k<nq;++k)
+         for (unsigned int j=0;j<n;++j)
+           A(k*nd+d,j) = fine.shape_value_component(j,k,d);
 
-  Householder<double> H(A);
+      Householder<double> H(A);
   
-  Vector<number> v_coarse(nq*nd);
-  Vector<number> v_fine(n);
+      Vector<number> v_coarse(nq*nd);
+      Vector<number> v_fine(n);
   
-  unsigned int cell_number = 0;
-  for (typename Triangulation<dim>::active_cell_iterator fine_cell
-         = tria.begin_active();
-       fine_cell != tria.end(); ++fine_cell, ++cell_number)
-    {
-      fine.reinit(fine_cell);
-
-                                       // evaluate on the coarse cell (which
-                                       // is the first -- inactive -- cell on
-                                       // the lowest level of the
-                                       // triangulation we have created)
-      const Quadrature<dim> q_coarse (fine.get_quadrature_points(),
-                                      fine.get_JxW_values());
-      FEValues<dim> coarse (mapping, fe, q_coarse, update_values);
-      coarse.reinit(tria.begin(0));
-
-      FullMatrix<double> &this_matrix = matrices[cell_number];
-      
-                                      // Compute this once for each
-                                      // coarse grid basis function
-      for (unsigned int i=0;i<n;++i)
+      unsigned int cell_number = 0;
+      for (typename Triangulation<dim>::active_cell_iterator fine_cell
+            = tria.begin_active();
+          fine_cell != tria.end(); ++fine_cell, ++cell_number)
        {
-                                          // The right hand side of
-                                          // the least squares
-                                          // problem consists of the
-                                          // function values of the
-                                          // coarse grid function in
-                                          // each quadrature point.
-         for (unsigned int d=0;d<nd;++d)
-           for (unsigned int k=0;k<nq;++k)
-             v_coarse(k*nd+d) = coarse.shape_value_component(i,k,d);
-
-                                          // solve the least squares
-                                          // problem.
-         const double result = H.least_squares(v_fine, v_coarse);
-         Assert (result < 1.e-12, ExcLeastSquaresError(result));
+         fine.reinit(fine_cell);
+
+                                          // evaluate on the coarse cell (which
+                                          // is the first -- inactive -- cell on
+                                          // the lowest level of the
+                                          // triangulation we have created)
+         const Quadrature<dim> q_coarse (fine.get_quadrature_points(),
+                                         fine.get_JxW_values());
+         FEValues<dim> coarse (mapping, fe, q_coarse, update_values);
+         coarse.reinit(tria.begin(0));
+
+         FullMatrix<double> &this_matrix = matrices[ref_case-1][cell_number];
+      
+                                          // Compute this once for each
+                                          // coarse grid basis function
+         for (unsigned int i=0;i<n;++i)
+           {
+                                              // The right hand side of
+                                              // the least squares
+                                              // problem consists of the
+                                              // function values of the
+                                              // coarse grid function in
+                                              // each quadrature point.
+             for (unsigned int d=0;d<nd;++d)
+               for (unsigned int k=0;k<nq;++k)
+                 v_coarse(k*nd+d) = coarse.shape_value_component(i,k,d);
+
+                                              // solve the least squares
+                                              // problem.
+             const double result = H.least_squares(v_fine, v_coarse);
+             Assert (result < 1.e-12, ExcLeastSquaresError(result));
            
-                                          // Copy into the result
-                                          // matrix. Since the matrix
-                                          // maps a coarse grid
-                                          // function to a fine grid
-                                          // function, the columns
-                                          // are fine grid.
-         for (unsigned int j=0;j<n;++j)
-           this_matrix(j,i) = v_fine(j);
+                                              // Copy into the result
+                                              // matrix. Since the matrix
+                                              // maps a coarse grid
+                                              // function to a fine grid
+                                              // function, the columns
+                                              // are fine grid.
+             for (unsigned int j=0;j<n;++j)
+               this_matrix(j,i) = v_fine(j);
+           }
+                                          // Remove small entries from
+                                          // the matrix
+         for (unsigned int i=0; i<this_matrix.m(); ++i)
+           for (unsigned int j=0; j<this_matrix.n(); ++j)
+             if (std::fabs(this_matrix(i,j)) < 1e-12)
+               this_matrix(i,j) = 0.;
        }
-                                      // Remove small entries from
-                                      // the matrix
-      for (unsigned int i=0; i<this_matrix.m(); ++i)
-       for (unsigned int j=0; j<this_matrix.n(); ++j)
-         if (std::fabs(this_matrix(i,j)) < 1e-12)
-           this_matrix(i,j) = 0.;
+      Assert (cell_number == GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case)),
+             ExcInternalError());
     }
-  Assert (cell_number == GeometryInfo<dim>::children_per_cell,
-          ExcInternalError());
 }
 
 
@@ -675,11 +681,11 @@ FETools::compute_embedding_matrices(const FiniteElement<dim>& fe,
 template<int dim, typename number>
 void
 FETools::compute_face_embedding_matrices(const FiniteElement<dim>& fe,
-                                        FullMatrix<number> (&matrices)[GeometryInfo<dim>::subfaces_per_face],
+                                        FullMatrix<number> (&matrices)[GeometryInfo<dim>::max_children_per_face],
                                         const unsigned int face_coarse,
                                         const unsigned int face_fine)
 {
-  const unsigned int nc = GeometryInfo<dim>::subfaces_per_face;
+  const unsigned int nc = GeometryInfo<dim>::max_children_per_face;
   const unsigned int n  = fe.dofs_per_face;
   const unsigned int nd = fe.n_components();
   const unsigned int degree = fe.degree;
@@ -785,7 +791,7 @@ FETools::compute_face_embedding_matrices(const FiniteElement<dim>& fe,
   
   
   
-  for (unsigned int cell_number = 0; cell_number < GeometryInfo<dim>::subfaces_per_face;
+  for (unsigned int cell_number = 0; cell_number < GeometryInfo<dim>::max_children_per_face;
        ++cell_number)
     {
       const Quadrature<dim> q_coarse
@@ -793,8 +799,8 @@ FETools::compute_face_embedding_matrices(const FiniteElement<dim>& fe,
       FEValues<dim> coarse (mapping, fe, q_coarse, update_values);
       
       typename Triangulation<dim>::active_cell_iterator fine_cell
-       = tria.begin(0)->child(GeometryInfo<dim>::child_cell_on_face(face_coarse,
-                                                                    cell_number));
+       = tria.begin(0)->child(GeometryInfo<dim>::child_cell_on_face(
+         tria.begin(0)->refinement_case(), face_coarse, cell_number));
       fine.reinit(fine_cell);
       coarse.reinit(tria.begin(0));
       
@@ -841,113 +847,127 @@ FETools::compute_face_embedding_matrices(const FiniteElement<dim>& fe,
 template<int dim, typename number>
 void
 FETools::compute_projection_matrices(const FiniteElement<dim>& fe,
-                                    FullMatrix<number> (&matrices)[GeometryInfo<dim>::children_per_cell])
+                                    std::vector<std::vector<FullMatrix<number> > >& matrices)
 {
-  const unsigned int nc = GeometryInfo<dim>::children_per_cell;
   const unsigned int n  = fe.dofs_per_cell;
   const unsigned int nd = fe.n_components();
   const unsigned int degree = fe.degree;
-  
-  for (unsigned int i=0;i<nc;++i)
+
+                                  // loop over all possible refinement cases
+  for (unsigned int ref_case = RefinementCase<dim>::cut_x;
+       ref_case<RefinementCase<dim>::isotropic_refinement+1; ++ref_case)
     {
-      Assert(matrices[i].n() == n, ExcDimensionMismatch(matrices[i].n(),n));
-      Assert(matrices[i].m() == n, ExcDimensionMismatch(matrices[i].m(),n));
-    }
-  
-  Triangulation<dim> tr;
-  GridGenerator::hyper_cube (tr, 0, 1);
-  tr.refine_global(1);
-  
-  MappingCartesian<dim> mapping;
-  QGauss<dim> q_fine(degree+1);
-  const unsigned int nq = q_fine.size();
-  
-  FEValues<dim> coarse (mapping, fe, q_fine,
-                       update_quadrature_points | update_JxW_values | update_values);
-  FEValues<dim> fine (mapping, fe, q_fine,
-                     update_quadrature_points | update_JxW_values | update_values);
-  
-  typename Triangulation<dim>::cell_iterator coarse_cell
-    = tr.begin(0);
-                                  // Compute the coarse level mass
-                                  // matrix
-  coarse.reinit(coarse_cell);
-  FullMatrix<number> A(n, n);
-  for (unsigned int k=0;k<nq;++k)
-    for (unsigned int i=0;i<n;++i)
-      for (unsigned int j=0;j<n;++j)
-       if (fe.is_primitive())
-         A(i,j) += coarse.JxW(k)
-                  * coarse.shape_value(i,k)
-                  * coarse.shape_value(j,k);
-       else
-         for (unsigned int d=0;d<nd;++d)
-           A(i,j) = coarse.JxW(k)
-                    * coarse.shape_value_component(i,k,d)
-                    * coarse.shape_value_component(j,k,d);
-  
-  Householder<double> H(A);
+      const unsigned int
+       nc = GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));
 
-  Vector<number> v_coarse(n);
-  Vector<number> v_fine(n);
+      for (unsigned int i=0;i<nc;++i)
+       {
+         Assert(matrices[ref_case-1][i].n() == n,
+                ExcDimensionMismatch(matrices[ref_case-1][i].n(),n));
+         Assert(matrices[ref_case-1][i].m() == n,
+                ExcDimensionMismatch(matrices[ref_case-1][i].m(),n));
+       }
   
-  for (unsigned int cell_number=0;cell_number<GeometryInfo<dim>::children_per_cell;++cell_number)
-    {
-      FullMatrix<double> &this_matrix = matrices[cell_number];
-      
-                                      // Compute right hand side,
-                                      // which is a fine level basis
-                                      // function tested with the
-                                      // coarse level functions.
-      fine.reinit(coarse_cell->child(cell_number));
-      Quadrature<dim> q_coarse (fine.get_quadrature_points(),
-                               fine.get_JxW_values());
-      FEValues<dim> coarse (mapping, fe, q_coarse, update_values);
+      Triangulation<dim> tr;
+      GridGenerator::hyper_cube (tr, 0, 1);
+      tr.begin_active()->set_refine_flag(RefinementCase<dim>(ref_case));
+      tr.execute_coarsening_and_refinement();
+  
+      MappingCartesian<dim> mapping;
+      QGauss<dim> q_fine(degree+1);
+      const unsigned int nq = q_fine.size();
+  
+      FEValues<dim> coarse (mapping, fe, q_fine,
+                           update_quadrature_points |
+                           update_JxW_values |
+                           update_values);
+      FEValues<dim> fine (mapping, fe, q_fine,
+                         update_quadrature_points |
+                         update_JxW_values |
+                         update_values);
+  
+      typename Triangulation<dim>::cell_iterator coarse_cell
+       = tr.begin(0);
+                                      // Compute the coarse level mass
+                                      // matrix
       coarse.reinit(coarse_cell);
+      FullMatrix<number> A(n, n);
+      for (unsigned int k=0;k<nq;++k)
+       for (unsigned int i=0;i<n;++i)
+         for (unsigned int j=0;j<n;++j)
+           if (fe.is_primitive())
+             A(i,j) += coarse.JxW(k)
+                       * coarse.shape_value(i,k)
+                       * coarse.shape_value(j,k);
+           else
+             for (unsigned int d=0;d<nd;++d)
+               A(i,j) = coarse.JxW(k)
+                        * coarse.shape_value_component(i,k,d)
+                        * coarse.shape_value_component(j,k,d);
+  
+      Householder<double> H(A);
+
+      Vector<number> v_coarse(n);
+      Vector<number> v_fine(n);
+  
+      for (unsigned int cell_number=0;cell_number<nc;++cell_number)
+       {
+         FullMatrix<double> &this_matrix = matrices[ref_case-1][cell_number];
+      
+                                          // Compute right hand side,
+                                          // which is a fine level basis
+                                          // function tested with the
+                                          // coarse level functions.
+         fine.reinit(coarse_cell->child(cell_number));
+         Quadrature<dim> q_coarse (fine.get_quadrature_points(),
+                                   fine.get_JxW_values());
+         FEValues<dim> coarse (mapping, fe, q_coarse, update_values);
+         coarse.reinit(coarse_cell);
       
-                                      // Build RHS
+                                          // Build RHS
 
-                                      // Outer loop over all fine
-                                      // grid shape functions phi_j
-      for (unsigned int j=0;j<fe.dofs_per_cell;++j)
-       {
-         v_fine = 0.;
-                                          // Loop over all quadrature points
-         for (unsigned int k=0;k<fine.n_quadrature_points;++k)
+                                          // Outer loop over all fine
+                                          // grid shape functions phi_j
+         for (unsigned int j=0;j<fe.dofs_per_cell;++j)
            {
-                                              // integrate the scalar
-                                              // product
-                                              // (phi_i,phi_j) for
-                                              // all coarse shape
-                                              // functions to get the
-                                              // right hand side
-             for (unsigned int i=0;i<fe.dofs_per_cell;++i)
+             v_fine = 0.;
+                                              // Loop over all quadrature points
+             for (unsigned int k=0;k<fine.n_quadrature_points;++k)
                {
-                 if (fe.is_primitive())
-                   v_fine(i) += fine.JxW(k)
-                                * coarse.shape_value(i,k)
-                                * fine.shape_value(j,k);
-                 else
-                   for (unsigned int d=0;d<nd;++d)
-                     v_fine(i) += fine.JxW(k)
-                                  * coarse.shape_value_component(i,k,d)
-                                  * fine.shape_value_component(j,k,d);
+                                                  // integrate the scalar
+                                                  // product
+                                                  // (phi_i,phi_j) for
+                                                  // all coarse shape
+                                                  // functions to get the
+                                                  // right hand side
+                 for (unsigned int i=0;i<fe.dofs_per_cell;++i)
+                   {
+                     if (fe.is_primitive())
+                       v_fine(i) += fine.JxW(k)
+                                    * coarse.shape_value(i,k)
+                                    * fine.shape_value(j,k);
+                     else
+                       for (unsigned int d=0;d<nd;++d)
+                         v_fine(i) += fine.JxW(k)
+                                      * coarse.shape_value_component(i,k,d)
+                                      * fine.shape_value_component(j,k,d);
+                   }
                }
+                                              // RHS ready. Solve system
+                                              // and enter row into
+                                              // matrix
+             H.least_squares(v_coarse, v_fine);
+             for (unsigned int i=0;i<fe.dofs_per_cell;++i)
+               this_matrix(i,j) = v_coarse(i);
            }
-                                          // RHS ready. Solve system
-                                          // and enter row into
-                                          // matrix
-         H.least_squares(v_coarse, v_fine);
-         for (unsigned int i=0;i<fe.dofs_per_cell;++i)
-           this_matrix(i,j) = v_coarse(i);
-       }
       
-                                      // Remove small entries from
-                                      // the matrix
-      for (unsigned int i=0; i<this_matrix.m(); ++i)
-       for (unsigned int j=0; j<this_matrix.n(); ++j)
-         if (std::fabs(this_matrix(i,j)) < 1e-12)
-           this_matrix(i,j) = 0.;
+                                          // Remove small entries from
+                                          // the matrix
+         for (unsigned int i=0; i<this_matrix.m(); ++i)
+           for (unsigned int j=0; j<this_matrix.n(); ++j)
+             if (std::fabs(this_matrix(i,j)) < 1e-12)
+               this_matrix(i,j) = 0.;
+       }
     }
 }
 
@@ -1424,8 +1444,7 @@ void FETools::extrapolate(const DoFHandler<dim> &dof1,
                                             // cell has active
                                             // children
            bool active_children=false;
-           for (unsigned int child_n=0;
-                child_n<GeometryInfo<dim>::children_per_cell; ++child_n)
+           for (unsigned int child_n=0; child_n<cell->n_children(); ++child_n)
              if (cell->child(child_n)->active())
                {
                  active_children=true;
@@ -1875,16 +1894,16 @@ void FETools::get_projection_matrix<deal_II_dimension>
 
 template
 void FETools::compute_embedding_matrices<deal_II_dimension>
-(const FiniteElement<deal_II_dimension> &, FullMatrix<double> (&)[GeometryInfo<deal_II_dimension>::children_per_cell]);
+(const FiniteElement<deal_II_dimension> &, std::vector<std::vector<FullMatrix<double> > >&);
 
 template
 void FETools::compute_face_embedding_matrices<deal_II_dimension>
-(const FiniteElement<deal_II_dimension> &, FullMatrix<double> (&matrices)[GeometryInfo<deal_II_dimension>::subfaces_per_face],
+(const FiniteElement<deal_II_dimension> &, FullMatrix<double> (&matrices)[GeometryInfo<deal_II_dimension>::max_children_per_face],
  unsigned int, unsigned int);
 
 template
 void FETools::compute_projection_matrices<deal_II_dimension>
-(const FiniteElement<deal_II_dimension> &, FullMatrix<double> (&)[GeometryInfo<deal_II_dimension>::children_per_cell]);
+(const FiniteElement<deal_II_dimension> &, std::vector<std::vector<FullMatrix<double> > >&);
 
 template
 void FETools::interpolate<deal_II_dimension>
index 62247421f524ff1bd0bc8cac6859f02b873e61c7..991cd04fd8c6178aca4722920cc4ef184aee7253 100644 (file)
@@ -308,6 +308,12 @@ FEValuesData<dim>::initialize (const unsigned int        n_quadrature_points,
   if (flags & update_JxW_values)
     this->JxW_values.resize(n_quadrature_points);
 
+  if (flags & update_jacobians)
+    this->jacobians.resize(n_quadrature_points);
+
+  if (flags & update_jacobian_grads)
+    this->jacobian_grads.resize(n_quadrature_points);
+
   if (flags & update_boundary_forms)
     this->boundary_forms.resize(n_quadrature_points);
 
@@ -1378,7 +1384,9 @@ void FEValues<dim>::do_reinit ()
                                     quadrature,
                                     *this->mapping_data,
                                     this->quadrature_points,
-                                    this->JxW_values);
+                                    this->JxW_values,
+                                    this->jacobians,
+                                    this->jacobian_grads);
   
   this->get_fe().fill_fe_values(this->get_mapping(),
                                *this->present_cell,
@@ -1761,11 +1769,11 @@ void FESubfaceValues<dim>::reinit (const typename DoFHandler<dim>::cell_iterator
                                   // we must use following workaround
                                   // of two separate assertions
   Assert (cell->face(face_no)->has_children() ||
-         subface_no < GeometryInfo<dim>::subfaces_per_face,
-         ExcIndexRange (subface_no, 0, GeometryInfo<dim>::subfaces_per_face));
+         subface_no < GeometryInfo<dim>::max_children_per_face,
+         ExcIndexRange (subface_no, 0, GeometryInfo<dim>::max_children_per_face));
   Assert (!cell->face(face_no)->has_children() ||
-         subface_no < cell->face(face_no)->n_children(),
-         ExcIndexRange (subface_no, 0, cell->face(face_no)->n_children()));
+         subface_no < cell->face(face_no)->number_of_children(),
+         ExcIndexRange (subface_no, 0, cell->face(face_no)->number_of_children()));
 
   Assert (cell->has_children() == false,
           ExcMessage ("You can't use subface data for cells that are "
@@ -1806,8 +1814,8 @@ void FESubfaceValues<dim>::reinit (const typename hp::DoFHandler<dim>::cell_iter
          typename FEValuesBase<dim>::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)->n_children(),
-         ExcIndexRange (subface_no, 0, cell->face(face_no)->n_children()));
+  Assert (subface_no < cell->face(face_no)->number_of_children(),
+         ExcIndexRange (subface_no, 0, cell->face(face_no)->number_of_children()));
   Assert (cell->has_children() == false,
           ExcMessage ("You can't use subface data for cells that are "
                       "already refined. Iterate over their children "
@@ -1841,8 +1849,8 @@ void FESubfaceValues<dim>::reinit (const typename MGDoFHandler<dim>::cell_iterat
           typename FEValuesBase<dim>::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)->n_children(),
-         ExcIndexRange (subface_no, 0, cell->face(face_no)->n_children()));
+  Assert (subface_no < cell->face(face_no)->number_of_children(),
+         ExcIndexRange (subface_no, 0, cell->face(face_no)->number_of_children()));
   Assert (cell->has_children() == false,
           ExcMessage ("You can't use subface data for cells that are "
                       "already refined. Iterate over their children "
@@ -1899,18 +1907,77 @@ template <int dim>
 void FESubfaceValues<dim>::do_reinit (const unsigned int face_no,
                                       const unsigned int subface_no)
 {
-
-                                  // set the present face index
+                                  // first of all, set the present_face_index
+                                  // (if available)
   const typename Triangulation<dim>::cell_iterator cell=*this->present_cell;
-  unsigned int real_subface_no=subface_no;
-  if (dim==3)
-    real_subface_no=GeometryInfo<dim>::standard_to_real_face_vertex(
-      subface_no, cell->face_orientation(face_no), cell->face_flip(face_no), cell->face_rotation(face_no));
-  if (cell->face(face_no)->has_children())
-    this->present_face_index=cell->face(face_no)->child_index(real_subface_no);
-  else
-    this->present_face_index=cell->face_index(face_no);
 
+  if (!cell->face(face_no)->has_children())
+                                    // no subfaces at all, so set
+                                    // present_face_index to this face rather
+                                    // than any subface
+    this->present_face_index=cell->face_index(face_no);
+  else
+    if (dim!=3)
+      this->present_face_index=cell->face(face_no)->child_index(subface_no);
+    else
+      {
+                                        // this is the same logic we use in
+                                        // cell->neighbor_child_on_subface(). See
+                                        // there for an explanation of the
+                                        // different cases
+       unsigned int subface_index=numbers::invalid_unsigned_int;
+       switch (cell->subface_case(face_no))
+         {
+           case internal::SubfaceCase<3>::case_x:
+           case internal::SubfaceCase<3>::case_y:
+           case internal::SubfaceCase<3>::case_xy:
+                 subface_index=cell->face(face_no)->child_index(subface_no);
+                 break;
+           case internal::SubfaceCase<3>::case_x1y2y:
+           case internal::SubfaceCase<3>::case_y1x2x:
+                 subface_index=cell->face(face_no)->child(subface_no/2)->child_index(subface_no%2);
+                 break;
+           case internal::SubfaceCase<3>::case_x1y:
+           case internal::SubfaceCase<3>::case_y1x:
+                 switch (subface_no)
+                   {
+                     case 0:
+                     case 1:
+                           subface_index=cell->face(face_no)->child(0)->child_index(subface_no);
+                           break;
+                     case 2:
+                           subface_index=cell->face(face_no)->child_index(1);
+                           break;
+                     default:
+                           Assert(false, ExcInternalError());
+                   }
+                 break;
+           case internal::SubfaceCase<3>::case_x2y:
+           case internal::SubfaceCase<3>::case_y2x:
+                 switch (subface_no)
+                   {
+                     case 0:
+                           subface_index=cell->face(face_no)->child_index(0);
+                           break;
+                     case 1:
+                     case 2:
+                           subface_index=cell->face(face_no)->child(1)->child_index(subface_no-1);
+                           break;
+                     default:
+                           Assert(false, ExcInternalError());
+                   }
+                 break;
+           default:
+                 Assert(false, ExcInternalError());
+                 break;
+         }
+       Assert(subface_index!=numbers::invalid_unsigned_int,
+              ExcInternalError());
+       this->present_face_index=subface_index;
+      }
+  
+                                  // now ask the mapping and the finite element
+                                  // to do the actual work
   this->get_mapping().fill_fe_subface_values(*this->present_cell,
                                              face_no, subface_no,
                                             this->quadrature,
index 2a0d0010c937b5f9cea17f94cb768f7c4af9a90d..323b5afc24ed23c5482a3bcfe0e183e0097abf62 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 by the deal.II authors
+//    Copyright (C) 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
@@ -148,11 +148,25 @@ MappingCartesian<dim>::compute_fill (const typename Triangulation<dim>::cell_ite
       Assert (face_no+1 < GeometryInfo<dim>::faces_per_cell+1,
              ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
 
-      Assert ((sub_no == invalid_face_number)
-              ||
-              (sub_no+1 < GeometryInfo<dim>::subfaces_per_face+1),
+                                  // We would like to check for
+                                  // sub_no < cell->face(face_no)->n_children(),
+                                  // but unfortunately the current
+                                  // function is also called for
+                                  // faces without children (see
+                                  // tests/fe/mapping.cc). Therefore,
+                                  // we must use following workaround
+                                  // of two separate assertions
+#if deal_II_dimension != 1
+      Assert ((sub_no == invalid_face_number) ||
+              cell->face(face_no)->has_children() ||
+              (sub_no+1 < GeometryInfo<dim>::max_children_per_face+1),
               ExcIndexRange (sub_no, 0,
-                             GeometryInfo<dim>::subfaces_per_face));
+                             GeometryInfo<dim>::max_children_per_face));
+      Assert ((sub_no == invalid_face_number) ||
+              !cell->face(face_no)->has_children() ||
+              (sub_no < cell->face(face_no)->n_children()),
+              ExcIndexRange (sub_no, 0, cell->face(face_no)->n_children()));
+#endif
     }
   else
                                     // invalid face number, so
@@ -211,10 +225,11 @@ MappingCartesian<dim>::compute_fill (const typename Triangulation<dim>::cell_ite
            :
                                             // called from FESubfaceValues
            QProjector<dim>::DataSetDescriptor::subface (face_no, sub_no,
-                                                         cell->face_orientation(face_no),
-                                                         cell->face_flip(face_no),
-                                                         cell->face_rotation(face_no),
-                                                         quadrature_points.size())
+                                                        cell->face_orientation(face_no),
+                                                        cell->face_flip(face_no),
+                                                        cell->face_rotation(face_no),
+                                                        quadrature_points.size(),
+                                                        cell->subface_case(face_no))
           ));
 
       for (unsigned int i=0; i<quadrature_points.size(); ++i)
@@ -286,7 +301,9 @@ 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) const
+                std::vector<double>& JxW_values,
+               std::vector<Tensor<2,dim> >& jacobians,
+               std::vector<Tensor<3,dim> >& jacobian_grads) const
 {
                                   // convert data object to internal
                                   // data for this class. fails with
@@ -314,6 +331,21 @@ fill_fe_values (const typename Triangulation<dim>::cell_iterator& cell,
       for (unsigned int i=0; i<JxW_values.size();++i)
        JxW_values[i] = J * q.weight(i);
     }
+                                  // "compute" Jacobian at the quadrature
+                                  // points, which are all the same
+  if (data.current_update_flags() & update_jacobians)
+    for (unsigned int i=0; i<jacobians.size();++i)
+      {
+       jacobians[i]=Tensor<2,dim>();
+       for (unsigned int j=0; j<dim; ++j)
+         jacobians[j][j]=data.length[j];
+      }
+                                  // "compute" the derivative of the Jacobian
+                                  // at the quadrature points, which are all
+                                  // zero of course
+  if (data.current_update_flags() & update_jacobian_grads)
+    for (unsigned int i=0; i<jacobian_grads.size();++i)
+      jacobian_grads[i]=Tensor<3,dim>();
 }
 
 
@@ -397,8 +429,24 @@ MappingCartesian<dim>::fill_fe_subface_values (const typename Triangulation<dim>
       J *= data.length[d];
   
   if (data.current_update_flags() & update_JxW_values)
-    for (unsigned int i=0; i<JxW_values.size();++i)
-      JxW_values[i] = J * q.weight(i) / GeometryInfo<dim>::subfaces_per_face;
+    {
+                                      // Here,
+                                      // cell->face(face_no)->n_children()
+                                      // would be the right choice,
+                                      // but unfortunately the
+                                      // current function is also
+                                      // called for faces without
+                                      // children (see
+                                      // tests/fe/mapping.cc). Add
+                                      // following switch to avoid
+                                      // diffs in tests/fe/mapping.OK
+      const unsigned int n_subfaces=
+       cell->face(face_no)->has_children() ?
+       cell->face(face_no)->n_children() :
+       GeometryInfo<dim>::max_children_per_face;
+      for (unsigned int i=0; i<JxW_values.size();++i)
+       JxW_values[i] = J * q.weight(i) / n_subfaces;
+    }
 
   if (data.current_update_flags() & update_boundary_forms)
     for (unsigned int i=0; i<boundary_forms.size();++i)
index 18d8cff15c07bc63fc4f2da913e9ad1f8483fee5..66e4899d8793fbbdcd27b2917826f878e9dbacbd 100644 (file)
@@ -216,8 +216,14 @@ MappingQ<dim>::compute_shapes_virtual (const std::vector<Point<dim> > &unit_poin
       grads.resize(n_shape_functions);
     }
   
-                                  // dummy variable of size 0
+//                                // dummy variable of size 0
   std::vector<Tensor<2,dim> > grad2;
+  if (data.shape_second_derivatives.size()!=0)
+    {
+      Assert(data.shape_second_derivatives.size()==n_shape_functions*n_points,
+            ExcInternalError());
+      grad2.resize(n_shape_functions);
+    }
 
   
   if (data.shape_values.size()!=0 || data.shape_derivatives.size()!=0)
@@ -232,6 +238,10 @@ MappingQ<dim>::compute_shapes_virtual (const std::vector<Point<dim> > &unit_poin
        if (data.shape_derivatives.size()!=0)
          for (unsigned int i=0; i<n_shape_functions; ++i)
            data.derivative(point,renumber[i]) = grads[i];
+
+       if (data.shape_second_derivatives.size()!=0)
+         for (unsigned int i=0; i<n_shape_functions; ++i)
+           data.second_derivative(point,renumber[i]) = grad2[i];
       }
 }
 
@@ -295,7 +305,9 @@ MappingQ<dim>::fill_fe_values (const typename Triangulation<dim>::cell_iterator
                               const Quadrature<dim>                &q,
                               typename Mapping<dim>::InternalDataBase       &mapping_data,
                               std::vector<Point<dim> >             &quadrature_points,
-                              std::vector<double>                  &JxW_values) const
+                              std::vector<double>                  &JxW_values,
+                              std::vector<Tensor<2,dim> >          &jacobians,
+                              std::vector<Tensor<3,dim> >          &jacobian_grads) const
 {
                                   // convert data object to internal
                                   // data for this class. fails with
@@ -321,7 +333,8 @@ MappingQ<dim>::fill_fe_values (const typename Triangulation<dim>::cell_iterator
     p_data=&data;
   
   MappingQ1<dim>::fill_fe_values(cell, q, *p_data,
-                                quadrature_points, JxW_values);
+                                quadrature_points, JxW_values,
+                                jacobians, jacobian_grads);
 }
 
 
@@ -371,7 +384,7 @@ MappingQ<dim>::fill_fe_face_values (const typename Triangulation<dim>::cell_iter
     p_data=&data;
 
   const unsigned int n_q_points=q.size();
-  this->compute_fill_face (cell, face_no, false,
+  this->compute_fill_face (cell, face_no, deal_II_numbers::invalid_unsigned_int,
                            n_q_points,
                            QProjector<dim>::DataSetDescriptor::
                            face (face_no,
@@ -435,7 +448,7 @@ MappingQ<dim>::fill_fe_subface_values (const typename Triangulation<dim>::cell_i
     p_data=&data;
 
   const unsigned int n_q_points=q.size();
-  this->compute_fill_face (cell, face_no, true,
+  this->compute_fill_face (cell, face_no, sub_no,
                            n_q_points,
                            QProjector<dim>::DataSetDescriptor::
                            subface (face_no, sub_no,
index 1393441f8978bb792f8324c51f2b1a8bf30f87f7..877748f94713bfa19980b48d2119146de65faf50 100644 (file)
@@ -108,6 +108,14 @@ MappingQ1<1>::compute_shapes_virtual (const std::vector<Point<1> > &unit_points,
          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;
+       }
+
     }
 }
 
@@ -149,6 +157,27 @@ MappingQ1<2>::compute_shapes_virtual (const std::vector<Point<2> > &unit_points,
          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;
+       }
     }
 }
 
@@ -211,6 +240,86 @@ MappingQ1<3>::compute_shapes_virtual (const std::vector<Point<3> > &unit_points,
          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;
+         
+         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;
+       }
     }
 }
 
@@ -232,7 +341,9 @@ MappingQ1<dim>::update_once (const UpdateFlags in) const
            | update_contravariant_transformation
            | update_JxW_values
            | update_boundary_forms
-           | update_normal_vectors))
+           | update_normal_vectors
+           | update_jacobians
+           | update_jacobian_grads))
     out |= update_transformation_gradients;
 
   return out;
@@ -252,7 +363,9 @@ MappingQ1<dim>::update_each (const UpdateFlags in) const
                                      | update_JxW_values
                                      | update_cell_JxW_values
                                      | update_boundary_forms
-                                     | update_normal_vectors));
+                                     | update_normal_vectors
+                                     | update_jacobians
+                                     | update_jacobian_grads));
 
                                   // add a few flags. note that some
                                   // flags appear in both conditions
@@ -280,6 +393,8 @@ MappingQ1<dim>::update_each (const UpdateFlags in) const
   
       if (out & (update_covariant_transformation
                 | update_JxW_values
+                | update_jacobians
+                | update_jacobian_grads
                 | update_boundary_forms
                 | update_normal_vectors))
        out |= update_contravariant_transformation;
@@ -325,6 +440,9 @@ MappingQ1<dim>::compute_data (const UpdateFlags      update_flags,
   if (flags & update_contravariant_transformation)
     data.contravariant.resize(n_original_q_points);
 
+  if (flags & update_jacobian_grads)
+    data.shape_second_derivatives.resize(data.n_shape_functions * n_q_points);
+  
   compute_shapes (q.get_points(), data);
 }
 
@@ -488,14 +606,7 @@ MappingQ1<dim>::compute_fill (const typename Triangulation<dim>::cell_iterator &
                data.contravariant.end(),
                Tensor<2,dim>());
     }
-  
-  if (update_flags & update_jacobian_grads)
-    {
-      Assert(false, ExcNotImplemented());
-//      Assert (covariant_grads.size () == n_q_points,
-//           ExcDimensionMismatch(covariant_grads.size(), n_q_points));
-    }
-  
+
                                   // if necessary, recompute the
                                   // support points of the
                                   // transformation of this cell
@@ -530,10 +641,10 @@ MappingQ1<dim>::compute_fill (const typename Triangulation<dim>::cell_iterator &
       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]);
+           data.contravariant[point][i][j]
+             += (data.derivative(point+data_set, k)[j]
+                 *
+                 data.mapping_support_points[k][i]);
 
                                       // invert contravariant for
                                       // covariant transformation
@@ -564,7 +675,9 @@ MappingQ1<dim>::fill_fe_values (const typename Triangulation<dim>::cell_iterator
                                const Quadrature<dim>                &q,
                                typename Mapping<dim>::InternalDataBase      &mapping_data,
                                std::vector<Point<dim> >                  &quadrature_points,
-                               std::vector<double>                       &JxW_values) const
+                               std::vector<double>                       &JxW_values,
+                               std::vector<Tensor<2,dim> >               &jacobians,
+                               std::vector<Tensor<3,dim> >               &jacobian_grads) const
 {
   InternalData *data_ptr = dynamic_cast<InternalData *> (&mapping_data);
   Assert(data_ptr!=0, ExcInternalError());
@@ -588,6 +701,38 @@ MappingQ1<dim>::fill_fe_values (const typename Triangulation<dim>::cell_iterator
       for (unsigned int point=0; point<n_q_points; ++point)
        JxW_values[point]
          = determinant(data.contravariant[point])*weights[point];
+    }
+
+                                  // copy values from InternalData to vector
+                                  // given by reference
+  if (update_flags & update_jacobians)
+    {      
+      Assert (jacobians.size() == n_q_points,
+             ExcDimensionMismatch(jacobians.size(), n_q_points));
+      for (unsigned int point=0; point<n_q_points; ++point)
+       jacobians[point]
+         = data.contravariant[point];
+    }
+                                  // calculate values of the derivatives of the
+                                  // Jacobians. do it here, since we only do it
+                                  // for cells, not faces.
+  if (update_flags & update_jacobian_grads)
+    {
+      Assert (jacobian_grads.size() == n_q_points,
+             ExcDimensionMismatch(jacobian_grads.size(), n_q_points));
+      std::fill(jacobian_grads.begin(),
+               jacobian_grads.end(),
+               Tensor<3,dim>());
+
+      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)
+             for (unsigned int l=0; l<dim; ++l)
+               jacobian_grads[point][i][j][l]
+                 += (data.second_derivative(point+DataSetDescriptor::cell (), k)[j][l]
+                     *
+                     data.mapping_support_points[k][i]);
     }
 }
 
@@ -597,7 +742,7 @@ template <int dim>
 void
 MappingQ1<dim>::compute_fill_face (const typename Triangulation<dim>::cell_iterator &cell,
                                   const unsigned int      face_no,
-                                  const bool              is_subface,
+                                  const unsigned int      subface_no,
                                   const unsigned int      n_q_points,
                                   const DataSetDescriptor data_set,
                                   const std::vector<double>   &weights,
@@ -675,8 +820,12 @@ MappingQ1<dim>::compute_fill_face (const typename Triangulation<dim>::cell_itera
            if (update_flags & update_JxW_values)
              {
                JxW_values[i] = f * weights[i];
-               if (is_subface)
-                 JxW_values[i] /= GeometryInfo<dim>::subfaces_per_face;
+               if (subface_no!=deal_II_numbers::invalid_unsigned_int)
+                 {
+                   const double area_ratio=GeometryInfo<dim>::subface_ratio(
+                     cell->subface_case(face_no), subface_no);
+                   JxW_values[i] *= area_ratio;
+                 }
              }
            if (update_flags & update_normal_vectors)
               normal_vectors[i] = boundary_forms[i] / f;
@@ -720,7 +869,7 @@ MappingQ1<dim>::fill_fe_face_values (const typename Triangulation<dim>::cell_ite
 
   const unsigned int n_q_points = q.size();
   
-  compute_fill_face (cell, face_no, false,
+  compute_fill_face (cell, face_no, deal_II_numbers::invalid_unsigned_int,
                     n_q_points,
                     DataSetDescriptor::face (face_no,
                                               cell->face_orientation(face_no),
@@ -756,13 +905,14 @@ MappingQ1<dim>::fill_fe_subface_values (const typename Triangulation<dim>::cell_
 
   const unsigned int n_q_points = q.size();
   
-  compute_fill_face (cell, face_no, true,
+  compute_fill_face (cell, face_no, sub_no,
                     n_q_points,
                     DataSetDescriptor::subface (face_no, sub_no,
                                                 cell->face_orientation(face_no),
                                                 cell->face_flip(face_no),
                                                 cell->face_rotation(face_no),
-                                                n_q_points),
+                                                n_q_points,
+                                                cell->subface_case(face_no)),
                     q.get_weights(),
                     data,
                     quadrature_points,
@@ -779,7 +929,7 @@ template <>
 void
 MappingQ1<1>::compute_fill_face (const Triangulation<1>::cell_iterator &,
                                 const unsigned int,
-                                const bool,
+                                const unsigned int,
                                 const unsigned int,
                                 const DataSetDescriptor,
                                 const std::vector<double> &,
index 0852d5a0663183a2930e0785ea7de1ec2f13665f..c1207500ff797a7e3c9266f8127af43f58861cb8 100644 (file)
@@ -205,26 +205,36 @@ GridRefinement::refine_and_coarsen_fixed_number (Triangulation<dim> &tria,
                                       // refining cells and instead try to
                                       // only coarsen as many as it would
                                       // take to get to the target
+      
+                                      // as we have no information on cells
+                                      // being refined isotropically or
+                                      // anisotropically, assume isotropic
+                                      // refinement here, though that may
+                                      // result in a worse approximation
       refine_cells  = 0;
       coarsen_cells = (tria.n_active_cells() - max_n_cells) *
-                     GeometryInfo<dim>::children_per_cell /
-                     (GeometryInfo<dim>::children_per_cell - 1);
+                     GeometryInfo<dim>::max_children_per_cell /
+                     (GeometryInfo<dim>::max_children_per_cell - 1);
     }
                                   // otherwise, see if we would exceed the
                                   // maximum desired number of cells with the
                                   // number of cells that are likely going to
                                   // result from refinement. here, each cell
                                   // to be refined is replaced by
-                                  // C=GeometryInfo<dim>::children_per_cell
+                                  // C=GeometryInfo<dim>::max_children_per_cell
                                   // new cells, i.e. there will be C-1 more
                                   // cells than before. similarly, C cells
                                   // will be replaced by 1
+
+                                  // again, this is true for isotropically
+                                  // refined cells. we take this as an
+                                  // approximation of a mixed refinement.
   else if (static_cast<unsigned int>
           (tria.n_active_cells()
-           + refine_cells * (GeometryInfo<dim>::children_per_cell - 1)
+           + refine_cells * (GeometryInfo<dim>::max_children_per_cell - 1)
            - (coarsen_cells *
-              (GeometryInfo<dim>::children_per_cell - 1) /
-              GeometryInfo<dim>::children_per_cell))
+              (GeometryInfo<dim>::max_children_per_cell - 1) /
+              GeometryInfo<dim>::max_children_per_cell))
           >
           max_n_cells)
     {
@@ -241,10 +251,10 @@ GridRefinement::refine_and_coarsen_fixed_number (Triangulation<dim> &tria,
        1. *
        (max_n_cells - tria.n_active_cells())
        /
-       (refine_cells * (GeometryInfo<dim>::children_per_cell - 1)
+       (refine_cells * (GeometryInfo<dim>::max_children_per_cell - 1)
         - (coarsen_cells *
-           (GeometryInfo<dim>::children_per_cell - 1) /
-           GeometryInfo<dim>::children_per_cell));
+           (GeometryInfo<dim>::max_children_per_cell - 1) /
+           GeometryInfo<dim>::max_children_per_cell));
       refine_cells  = static_cast<int> (refine_cells * alpha);
       coarsen_cells = static_cast<int> (coarsen_cells * alpha);
     }
@@ -325,16 +335,22 @@ GridRefinement::refine_and_coarsen_fixed_fraction (Triangulation<dim> &tria,
                                   // over the limit and if so use a function
                                   // that knows how to deal with this
                                   // situation
+
+                                  // note, that at this point, we have no
+                                  // information about anisotropically refined
+                                  // cells, thus use the situation of purely
+                                  // isotropic refinement as guess for a mixed
+                                  // refinemnt as well.
   {
     const unsigned int refine_cells  = pp - tmp.begin(),
                       coarsen_cells = tmp.end() - qq;
 
     if (static_cast<unsigned int>
        (tria.n_active_cells()
-        + refine_cells * (GeometryInfo<dim>::children_per_cell - 1)
+        + refine_cells * (GeometryInfo<dim>::max_children_per_cell - 1)
         - (coarsen_cells *
-           (GeometryInfo<dim>::children_per_cell - 1) /
-           GeometryInfo<dim>::children_per_cell))
+           (GeometryInfo<dim>::max_children_per_cell - 1) /
+           GeometryInfo<dim>::max_children_per_cell))
        >
        max_n_cells)
       {
index 487443be793260a341b47c046553de1a62403337..c4e4d402fe645154cc4fedae6790c87b652784d2 100644 (file)
@@ -950,8 +950,6 @@ GridTools::get_finest_common_cells (const Container &mesh_1,
           ExcMessage ("The two containers must be represent triangulations that "
                       "have the same coarse meshes"));
 
-  const unsigned int dim = Container::dimension;
-
                                    // the algorithm goes as follows:
                                    // first, we fill a list with pairs
                                    // of iterators common to the two
@@ -994,7 +992,9 @@ GridTools::get_finest_common_cells (const Container &mesh_1,
           &&
           cell_pair->second->has_children())
         {
-          for (unsigned int c=0; c<GeometryInfo<dim>::children_per_cell; ++c)
+         Assert(cell_pair->first->refinement_case()==
+                cell_pair->second->refinement_case(), ExcNotImplemented());
+          for (unsigned int c=0; c<cell_pair->first->n_children(); ++c)
             cell_list.push_back (std::make_pair (cell_pair->first->child(c),
                                                  cell_pair->second->child(c)));
 
@@ -1016,13 +1016,17 @@ GridTools::get_finest_common_cells (const Container &mesh_1,
         ++cell_pair;
     }
 
-                                   // just to make sure everything is
-                                   // ok, validate that all pairs have
-                                   // at least one active iterator
+                                   // just to make sure everything is ok,
+                                   // validate that all pairs have at least one
+                                   // active iterator or have different
+                                   // refinement_cases
   for (cell_pair = cell_list.begin(); cell_pair != cell_list.end(); ++cell_pair)
-    Assert (!cell_pair->first->has_children()
+    Assert (cell_pair->first->active()
             ||
-            !cell_pair->second->has_children(),
+            cell_pair->second->active()
+           ||
+           (cell_pair->first->refinement_case()
+            != cell_pair->second->refinement_case()),
             ExcInternalError());
 
   return cell_list;
index 0a77d6db36e3d58f2f8dd5868d869c532e3dc311..d0ccbe2c556e79b053baf022e4b601fa9ab44339 100644 (file)
@@ -133,9 +133,19 @@ InterGridMap<GridClass>::set_mapping (const cell_iterator &src_cell,
                                   // if both cells have children, we may
                                   // recurse further into the hierarchy
   if (src_cell->has_children() && dst_cell->has_children())
-    for (unsigned int c=0; c<GeometryInfo<GridClass::dimension>::children_per_cell; ++c)
-      set_mapping (src_cell->child(c),
-                  dst_cell->child(c));
+    {
+      Assert(src_cell->n_children()==
+            GeometryInfo<GridClass::dimension>::max_children_per_cell,
+            ExcNotImplemented());
+      Assert(dst_cell->n_children()==
+            GeometryInfo<GridClass::dimension>::max_children_per_cell,
+            ExcNotImplemented());
+      Assert(src_cell->refinement_case()==dst_cell->refinement_case(),
+            ExcNotImplemented());
+      for (unsigned int c=0; c<GeometryInfo<GridClass::dimension>::max_children_per_cell; ++c)
+       set_mapping (src_cell->child(c),
+                    dst_cell->child(c));
+    }
   else
     if (src_cell->has_children() &&
        !dst_cell->has_children())
index ca121b498ab52b0ba0ab116054f8f5df1449f30b..e17af5fadf691ff8a06f92febfb54a7691986949 100644 (file)
@@ -21,6 +21,7 @@
 #include <base/geometry_info.h>
 #include <grid/grid_tools.h>
 #include <grid/magic_numbers.h>
+#include <fe/mapping_q1.h>
 #include <lac/vector.h>
 
 #include <algorithm>
 
 DEAL_II_NAMESPACE_OPEN
 
+// anonymous namespace for internal helper functions
+namespace{
+                                  // return, wheter a given @p cell will be
+                                  // coarsened, which is the case if all
+                                  // 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)
+  {
+                                    // only cells with children should be
+                                    // considered for coarsening
+    
+    if (cell->has_children())
+      {
+       unsigned int children_to_coarsen=0;
+       const unsigned int n_children=cell->n_children();
+    
+       for (unsigned int c=0; c<n_children; ++c)
+         if (cell->child(c)->active() &&
+             cell->child(c)->coarsen_flag_set())
+           ++children_to_coarsen;
+       if (children_to_coarsen==n_children)
+         return true;
+       else
+         for (unsigned int c=0; c<n_children; ++c)
+           if (cell->child(c)->active())
+             cell->child(c)->clear_coarsen_flag();
+      }
+                                    // no children, so no coarsening
+                                    // possible. however, no children also
+                                    // means that this cell will be in the same
+                                    // state as if it had children and was
+                                    // coarsened. So, what should we return -
+                                    // false or true?
+                                    // make sure we do not have to do this at
+                                    // all...
+    Assert(cell->has_children(), ExcInternalError());
+                                    // ... and then simply return false 
+    return false;
+  }
+
+
+                                  // return, whether the face @p face_no of the
+                                  // given @p cell will be refined after the
+                                  // current refinement step, considering
+                                  // refine and coarsen flags and considering
+                                  // only those refinemnts that will be caused
+                                  // by the neighboring cell.
+
+                                  // this function is used on both active cells
+                                  // and cells with children. on cells with
+                                  // children it also of interest to know 'how'
+                                  // the face will be refined. thus there is an
+                                  // additional third argument @p
+                                  // expected_face_ref_case returning just
+                                  // that. be aware, that this vriable will
+                                  // only contain useful information if this
+                                  // function is called for an active cell.
+                                  //
+                                  // 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)
+  {
+                                    // 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);
+
+                                    // If we are at the boundary, there is no
+                                    // neighbor which could refine the face
+    if (neighbor.state()!=IteratorState::valid)
+      return false;
+    
+    if (neighbor->has_children())
+                                    // if the neighbor is refined, he may be
+                                    // coarsened. if so, then it won't refine
+                                    // the face, no matter what else happens
+      if (cell_will_be_coarsened(neighbor))
+       return false;
+      else
+                                        // if the neighor is refined, then he
+                                        // is also refined at our current
+                                        // face. He will stay so without
+                                        // coarsening, so return true in that
+                                        // case.
+       {
+         expected_face_ref_case=cell->face(face_no)->refinement_case();
+         return true;
+       }
+    
+                                    // now, the neighbor is not refined, but
+                                    // perhaps he will be
+    const RefinementCase<dim> nb_ref_flag=neighbor->refine_flag_set();
+    if (nb_ref_flag)
+      {
+                                        // now we need to know, which of the
+                                        // neighbors faces points towards us
+       const unsigned int neighbor_neighbor=cell->neighbor_face_no(face_no);
+                                        // check, whether the cell will be
+                                        // refined in a way that refines our
+                                        // face
+       const RefinementCase<dim-1> face_ref_case=
+         GeometryInfo<dim>::face_refinement_case(nb_ref_flag,
+                                                 neighbor_neighbor,
+                                                 neighbor->face_orientation(neighbor_neighbor),
+                                                 neighbor->face_flip(neighbor_neighbor),
+                                                 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 int this_face_index=cell->face_index(face_no);
+
+                                            // there are still two basic
+                                            // possibilities here: the neighbor
+                                            // might be coarser or as coarse
+                                            // as we are
+           if (neighbor_face->index()==this_face_index)
+                                              // the neighbor is as coarse as
+                                              // we are and will be refined at
+                                              // the face of consideration, so
+                                              // return true
+             {
+               expected_face_ref_case = face_ref_case;
+               return true;
+             }
+           else
+             {
+               
+                                                // the neighbor is coarser.
+                                                // this is the most complicated
+                                                // case. It might be, that the
+                                                // neighbor's face will be
+                                                // refined, but that we will
+                                                // not see this, as we are
+                                                // refined in a similar way.
+
+                                                // so, the neighbor's face must
+                                                // have children. check, if our
+                                                // cell's face is one of these
+                                                // (it could also be a
+                                                // grand_child)
+               for (unsigned int c=0; c<neighbor_face->n_children(); ++c)
+                 if (neighbor_face->child_index(c)==this_face_index)
+                                                    // if the flagged refine
+                                                    // case of the face is a
+                                                    // subset or the same as
+                                                    // the current refine case,
+                                                    // then the face, as seen
+                                                    // from our cell, won't be
+                                                    // refined by the neighbor
+                   if ((neighbor_face->refinement_case() | face_ref_case)
+                       == neighbor_face->refinement_case())
+                     return false;
+                   else
+                     {
+                                                        // if we are active, we
+                                                        // must be an
+                                                        // anisotropic child
+                                                        // and the coming
+                                                        // face_ref_case is
+                                                        // isotropic. Thus,
+                                                        // from our cell we
+                                                        // will see exactly the
+                                                        // opposite refine case
+                                                        // that the face has
+                                                        // now...
+                       Assert(face_ref_case==RefinementCase<dim-1>::isotropic_refinement, ExcInternalError());
+                       expected_face_ref_case = ~neighbor_face->refinement_case();
+                       return true;
+                     }
+               
+                                                // so, obviously we were not
+                                                // one of the children, but a
+                                                // grandchild. This is only
+                                                // possible in 3d.
+               Assert(dim==3, ExcInternalError());
+                                                // In that case, however, no
+                                                // matter what the neighbor
+                                                // does, he won't be finer
+                                                // after the next refinement
+                                                // step.
+               return false;
+             }
+         }// if face will be refined
+      }// if neighbor is flagged for refinement
+
+                                    // no cases left, so the neighbor will not
+                                    // refine the face
+    return false;
+  }
+
+                                  // verison 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)
+  {
+    RefinementCase<dim-1> dummy = RefinementCase<dim-1>::no_refinement;
+    return face_will_be_refined_by_neighbor_internal(cell, face_no, dummy);
+  }
+
+                                  // version of above function for active cells
+                                  // 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)
+  {
+    return face_will_be_refined_by_neighbor_internal(cell, face_no,
+                                                    expected_face_ref_case);
+  }
+  
+}// end of anonymous namespace
+
+
 template <int dim>
 const StraightBoundary<dim>
 Triangulation<dim>::straight_boundary = StraightBoundary<dim>();
@@ -50,6 +275,7 @@ 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
@@ -234,9 +460,10 @@ void Triangulation<dim>::copy_triangulation (const Triangulation<dim> &old_tria)
   
   
                                   // copy normal elements
-  vertices      = old_tria.vertices;
-  vertices_used = old_tria.vertices_used;
-  smooth_grid   = old_tria.smooth_grid;
+  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);
 
@@ -309,7 +536,7 @@ void Triangulation<1>::create_triangulation (const std::vector<Point<1> >    &v,
                                   // reserve enough space
   levels.push_back (new internal::Triangulation::TriaLevel<dim>);
   levels[0]->reserve_space (cells.size(), dim);
-  levels[0]->cells.reserve_space (cells.size());
+  levels[0]->cells.reserve_space (0,cells.size());
   
                                   // make up cells
   raw_line_iterator next_free_line = begin_raw_line ();
@@ -593,8 +820,8 @@ void Triangulation<2>::create_triangulation (const std::vector<Point<2> >    &v,
   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 (needed_lines.size());
-  levels[0]->cells.reserve_space (cells.size());
+  faces->lines.reserve_space (0,needed_lines.size());
+  levels[0]->cells.reserve_space (0,cells.size());
 
                                   // make up lines
   if (true) 
@@ -1017,7 +1244,7 @@ Triangulation<3>::create_triangulation (const std::vector<Point<3> >    &v,
   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 (needed_lines.size());
+  faces->lines.reserve_space (0,needed_lines.size());
 
                                   // make up lines
   if (true) 
@@ -1197,7 +1424,7 @@ Triangulation<3>::create_triangulation (const std::vector<Point<3> >    &v,
                                   // the arrays of the Triangulation
                                   //
                                   // first reserve enough space
-  faces->quads.reserve_space (needed_quads.size());
+  faces->quads.reserve_space (0,needed_quads.size());
   
   if (true) 
     {
@@ -2018,12 +2245,14 @@ void Triangulation<dim>::refine_global (const unsigned int times)
 template <int dim>
 void Triangulation<dim>::save_refine_flags (std::vector<bool> &v) const
 {
-  v.resize (n_active_cells(), false);
+  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, ++i)
-    *i = cell->refine_flag_set();
+  for (; cell!=endc; ++cell)
+    for (unsigned int j=0; j<dim; ++j,++i)
+      if (cell->refine_flag_set() & (1<<j) )
+       *i = true;
 }
 
 
@@ -2053,16 +2282,25 @@ void Triangulation<dim>::load_refine_flags (std::istream &in)
 template <int dim>
 void Triangulation<dim>::load_refine_flags (const std::vector<bool> &v)
 {
-  AssertThrow (v.size() == n_active_cells(), ExcGridReadError());
+  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, ++i)
-    if (*i == true)
-      cell->set_refine_flag();
-    else
-      cell->clear_refine_flag();
+   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();
+     }
 }
 
 
@@ -2118,6 +2356,13 @@ void Triangulation<dim>::load_coarsen_flags (const std::vector<bool> &v)
 }
 
 
+template <int dim>
+bool Triangulation<dim>::get_anisotropic_refinement_flag() const
+{
+  return anisotropic_refinement;
+}
+
+
 #if deal_II_dimension == 1
 
 template <>
@@ -2138,9 +2383,10 @@ void Triangulation<1>::clear_user_pointers ()
 
 
 template <>
-void Triangulation<1>::clear_user_flags ()
+void Triangulation<1>::clear_user_flags_line ()
 {
-  clear_user_flags_line();
+  for (unsigned int level=0; level<levels.size(); ++level)
+    levels[level]->cells.clear_user_flags();
 }
 
 
@@ -2150,11 +2396,19 @@ void Triangulation<1>::clear_user_flags_quad ()
 {}
 
 
+
 template <>
 void Triangulation<1>::clear_user_flags_hex ()
 {}
 
 
+
+template <>
+void Triangulation<1>::clear_user_flags ()
+{
+  clear_user_flags_line();
+}
+
 #endif
 
 
@@ -2179,10 +2433,10 @@ void Triangulation<2>::clear_user_pointers ()
 
 
 template <>
-void Triangulation<2>::clear_user_flags ()
+void Triangulation<2>::clear_user_flags_quad ()
 {
-  clear_user_flags_line ();
-  clear_user_flags_quad ();  
+  for (unsigned int level=0; level<levels.size(); ++level)
+    levels[level]->cells.clear_user_flags();
 }
 
 
@@ -2192,6 +2446,14 @@ void Triangulation<2>::clear_user_flags_hex ()
 {}
 
 
+
+template <>
+void Triangulation<2>::clear_user_flags ()
+{
+  clear_user_flags_line ();
+  clear_user_flags_quad ();  
+}
+
 #endif
 
 
@@ -2217,49 +2479,44 @@ void Triangulation<3>::clear_user_pointers ()
 
 
 template <>
-void Triangulation<3>::clear_user_flags ()
+void Triangulation<3>::clear_user_flags_quad ()
 {
-  clear_user_flags_line ();
-  clear_user_flags_quad ();
-  clear_user_flags_hex ();
+  faces->quads.clear_user_flags();
 }
 
 
 
-#endif
-
-
-template <int dim>
-void Triangulation<dim>::clear_user_flags_line ()
+template <>
+void Triangulation<3>::clear_user_flags_hex ()
 {
-  line_iterator line = begin_line(),
-               endl = end_line();
-  for (; line!=endl; ++line)
-    line->clear_user_flag ();
+  for (unsigned int level=0; level<levels.size(); ++level)
+    levels[level]->cells.clear_user_flags();
 }
 
 
 
-template <int dim>
-void Triangulation<dim>::clear_user_flags_quad ()
+template <>
+void Triangulation<3>::clear_user_flags ()
 {
-  quad_iterator quad = begin_quad(),
-               endq = end_quad();
-  for (; quad!=endq; ++quad)
-    quad->clear_user_flag ();
+  clear_user_flags_line ();
+  clear_user_flags_quad ();
+  clear_user_flags_hex ();
 }
 
+#endif
+
 
+#if deal_II_dimension > 1
 
 template <int dim>
-void Triangulation<dim>::clear_user_flags_hex ()
+void Triangulation<dim>::clear_user_flags_line ()
 {
-  hex_iterator hex  = begin_hex(),
-               endh = end_hex();
-  for (; hex!=endh; ++hex)
-    hex->clear_user_flag ();
+  faces->lines.clear_user_flags();
 }
 
+#endif
+
+
 
 
 template <int dim>
@@ -4987,12 +5244,14 @@ Triangulation<1>::execute_refinement ()
                                       // created on that level
       levels[level+1]->reserve_space(
        used_cells+
-       GeometryInfo<1>::children_per_cell * flagged_cells, 1);
+       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>::children_per_cell*flagged_cells);
+       reserve_space (GeometryInfo<1>::max_children_per_cell*flagged_cells, 0);
       
       needed_vertices += flagged_cells;
     }
@@ -5068,7 +5327,7 @@ Triangulation<1>::execute_refinement ()
            second_child->clear_user_data ();
 
                                             // insert first child
-           cell->set_children (first_child->index());
+           cell->set_children (0, first_child->index());
            first_child->clear_children ();
            first_child->set (internal::Triangulation
                               ::TriaObject<1> (cell->vertex_index(0),
@@ -5212,12 +5471,27 @@ Triangulation<2>::execute_refinement ()
     }
 
 
-                                  // first clear user flags for
-                                  // lines; we're going to use them
-                                  // to flag which lines need
-                                  // refinement
+                                  // 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_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
@@ -5227,7 +5501,6 @@ Triangulation<2>::execute_refinement ()
                                   // - there are, but prepare_refinement
                                   //   added another empty level
   unsigned int needed_vertices = 0;
-  unsigned int needed_lines  = 0;
   for (int level=levels.size()-2; level>=0; --level)
     {
                                       // count number of flagged
@@ -5235,45 +5508,72 @@ Triangulation<2>::execute_refinement ()
                                       // compute how many new
                                       // vertices and new lines will
                                       // be needed
-      unsigned int flagged_cells = 0;
+      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()) 
          {
-           ++flagged_cells;
+           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;
 
-                                            // new vertex at center
-                                            // of cell is needed in
-                                            // any case
-           ++needed_vertices;
-                                            // also the four inner
-                                            // lines
-           needed_lines += 4;
+             }
            
-                                            // 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;
+                                                // 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)
              {
-               line_iterator line = cell->line(line_no);
-               
-               if (line->has_children() == false) 
-                 line->set_user_flag ();
+               if (GeometryInfo<dim>::face_refinement_case(
+                     cell->refine_flag_set(), line_no)==RefinementCase<dim>::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
@@ -5286,16 +5586,16 @@ Triangulation<2>::execute_refinement ()
                                       // used_cells cells already
                                       // existing on the next higher
                                       // level as well as for the
-                                      // 4*flagged_cells that will be
+                                      // needed_cells that will be
                                       // created on that level
-      levels[level+1]->reserve_space (used_cells+4*flagged_cells, 2);
+      levels[level+1]->reserve_space (used_cells+needed_cells, 2);
 
                                       // reserve space for
-                                      // 4*flagged_cells
+                                      // needed_cells
                                       // new quads on the next higher
                                       // level
       levels[level+1]->cells.
-       reserve_space (4*flagged_cells);
+        reserve_space (needed_cells,0);
     }
 
                                   // now count the lines which
@@ -5304,14 +5604,22 @@ Triangulation<2>::execute_refinement ()
     if (line->user_flag_set())
       {
        Assert (line->has_children() == false, ExcInternalError());
-       needed_lines    += 2;
-       needed_vertices += 1;
+       n_lines_in_pairs += 2;
+       needed_vertices  += 1;
       }
-
                                   // reserve space for
-                                  // needed_lines new lines
+                                  // 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 (needed_lines);
+    reserve_space (n_lines_in_pairs, 0);
   
                                   // add to needed vertices how many
                                   // vertices are already in use
@@ -5337,16 +5645,16 @@ Triangulation<2>::execute_refinement ()
                                   //  index of next unused vertex
   unsigned int next_unused_vertex = 0;
 
-                                  // first for lines
-                                  //
-                                  // only active objects can be
-                                  // refined further
+                                  // first the refinement of lines.
+                                  // children are stored pairwise
   if (true)
     {
+                                      // 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())
          {
@@ -5371,24 +5679,37 @@ Triangulation<2>::execute_refinement ()
          
                                             // now that we created
                                             // the right point, make
-                                            // up the two child lines
-                                            // (++ takes care of the
-                                            // end of the vector)
-           while (next_unused_line->used() == true)
-             ++next_unused_line;
-                                            // there should always be
-                                            // two consecutive unused
+                                            // 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 (next_unused_line->index());
+           line->set_children (0, next_unused_line->index());
          
                                             // set the two new lines
-           raw_line_iterator children[2] = { next_unused_line,
-                                             ++next_unused_line };
+           const raw_line_iterator children[2] = { next_unused_line,
+                                                   ++next_unused_line };
                                             // some tests; if any of
                                             // the iterators should
                                             // be invalid, then
@@ -5423,463 +5744,98 @@ Triangulation<2>::execute_refinement ()
          }
     }
 
+  
                                   // 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;
+  
   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_line_iterator next_unused_line = begin_raw_line ();
       raw_cell_iterator next_unused_cell = begin_raw (level+1);
 
       for (; cell!=endc; ++cell) 
        if (cell->refine_flag_set()) 
          {
-                                            // clear refinement flag
-           cell->clear_refine_flag ();
-
-                                            // do some additional
-                                            // checks.
-#ifdef DEBUG
-           for (unsigned int neighbor=0;
-                neighbor<GeometryInfo<dim>::faces_per_cell; ++neighbor)
-             if (cell->neighbor(neighbor).state() == IteratorState::valid)
-               Assert (((cell->neighbor(neighbor)->level() == cell->level()) &&
-                        (cell->neighbor(neighbor)->coarsen_flag_set() == false))  ||
-                       ((cell->neighbor(neighbor)->level() == cell->level()-1) &&
-                        (cell->neighbor(neighbor)->refine_flag_set() == true)),
-                       ExcInternalError());
-#endif
+                                            // set the user flag to
+                                            // indicate, that at least one
+                                            // line is at the boundary
            
-/* 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
-       
-   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-.                              .->-.->-.
+                                            // 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);
+         }
+    }
 
-     
-   Third:
-   Set up an array of neighbors:
-   
-   6  7
-   .--.--.
-   1|  |  |3
-   .--.--.
-   0|  |  |2
-   .--.--.
-   4   5
+                                  // re-compute number of lines and
+                                  // quads
+  update_number_cache ();
 
-   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}.
+#ifdef DEBUG
+  for (unsigned int level=0; level<levels.size(); ++level) 
+    levels[level]->cells.monitor_memory (2);
 
-   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.
+                                  // 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 ());
 
-   Convention:
-   The created children are numbered like this:
+  cell_iterator cell = begin(),
+               endc = end();
+  while (cell != endc)
+    Assert (!(cell++)->refine_flag_set(), ExcInternalError ());
+#endif
+}
 
-   .--.--.
-   |2 . 3|
-   .--.--.
-   |0 | 1|
-   .--.--.
-*/
-           
-                                            // 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;
+#endif
 
-                                            // collect the indices
-                                            // all vertices
-           int new_vertices[9] = {cell->vertex_index(0),
-                                  cell->vertex_index(1),
-                                  cell->vertex_index(2),
-                                  cell->vertex_index(3),
-                                  cell->line(0)->child(0)->vertex_index(1),
-                                  cell->line(1)->child(0)->vertex_index(1),
-                                  cell->line(2)->child(0)->vertex_index(1),
-                                  cell->line(3)->child(0)->vertex_index(1),
-                                  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;
-
-                                            // Now the lines:
-
-                                            // lines 0-7 already
-                                            // exist, create only the
-                                            // four interior lines
-                                            // 8-11
-           raw_line_iterator new_lines[12];
-           unsigned int l=0;
-           for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell;
-                ++face_no)
-             for (unsigned int child_no=0;
-                  child_no<GeometryInfo<dim>::subfaces_per_face; ++child_no, ++l)
-               new_lines[l]=cell->line(face_no)->child(child_no);
-           Assert(l==8, ExcInternalError());
-               
-           for (; l<12; ++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 deal_II_dimension == 3
 
-           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]));
-       
-           for (l=8; l<12; ++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 new
-                                            // cells!
-           
-                                            // search for next unused
-                                            // cell the four children
-                                            // have to be put into
-                                            // the array
-                                            // consecutively
-           while (next_unused_cell->used() == true)
-             ++next_unused_cell;
-
-           const unsigned int n_children=GeometryInfo<dim>::children_per_cell;
-           raw_cell_iterator subcells[n_children];
-           for (unsigned int i=0; i<n_children; ++i) 
-             {
-               Assert (next_unused_cell->used() == false,
-                       ExcCellShouldBeUnused());
-               subcells[i] = next_unused_cell;
-               ++next_unused_cell;
-             }
-
-
-           cell->set_children (subcells[0]->index());
-
-           Assert(n_children==4, ExcNotImplemented());
-           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()));
-
-           for (unsigned int i=0; i<n_children; ++i)
-             {
-               subcells[i]->set_used_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.
-                                            //
-                                            // to do so, first
-                                            // collect the iterators
-                                            // pointing to the 4x2
-                                            // neighbors of this
-                                            // cell.
-                                            //
-                                            // note that in case the
-                                            // neighboring cell is
-                                            // not refined, 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 neighbor_cells[n_children][2];
-           for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell;
-                ++face)
-             {
-               const cell_iterator neighbor = cell->neighbor(face);
-
-                                                // if no neighbor
-               if (neighbor.state() != IteratorState::valid)
-                 for (unsigned int child_face=0;
-                      child_face<GeometryInfo<dim>::subfaces_per_face;
-                      ++child_face)
-                   neighbor_cells[face][child_face] = neighbor;
-               
-               else
-                                                  // neighbor exists
-                 {
-                                                    // neighbor's
-                                                    // level must not
-                                                    // be higher
-                                                    // (else
-                                                    // something went
-                                                    // wrong when
-                                                    // constructing
-                                                    // either of the
-                                                    // two cells) and
-                                                    // not lower
-                                                    // since then
-                                                    // this cell
-                                                    // should not
-                                                    // have been
-                                                    // refined.
-                   Assert (neighbor->level() == cell->level(),
-                           ExcInternalError());
-
-                                                    // now there are
-                                                    // two
-                                                    // possibilities:
-                                                    // either the
-                                                    // neighbor has
-                                                    // no children or
-                                                    // it has
-                                                    // children. these
-                                                    // must be
-                                                    // terminal then.
-                   if (!neighbor->has_children())
-                     for (unsigned int child_face=0;
-                          child_face<GeometryInfo<dim>::subfaces_per_face;
-                          ++child_face)
-                       neighbor_cells[face][child_face] = neighbor;
-                   else
-                                                      // neighbor has
-                                                      // children
-                     {
-                                                        // first find
-                                                        // the face
-                                                        // of the
-                                                        // neighbor
-                                                        // adjacent
-                                                        // to which
-                                                        // the
-                                                        // present
-                                                        // cell is
-                       const unsigned int nb_nb = cell->neighbor_of_neighbor(face);
-                       Assert (nb_nb<GeometryInfo<dim>::faces_per_cell,
-                               ExcInternalError());
-
-                                                        // and set
-                                                        // the
-                                                        // neighbors
-                                                        // accordingly
-                       for (unsigned int c=0;
-                            c<GeometryInfo<dim>::subfaces_per_face; ++c)
-                         {
-                           neighbor_cells[face][c]
-                             = neighbor->child(GeometryInfo<dim>::
-                                                child_cell_on_face(nb_nb, c));
-                           
-                           Assert (neighbor_cells[face][c].state() ==
-                                   IteratorState::valid,
-                                   ExcInternalError());
-                           Assert (!neighbor_cells[face][c]->has_children(),
-                                   ExcInternalError());
-                         }
-                     }
-                 }
-             }
-
-                                            // now we've got all
-                                            // neighbors, so set them
-                                            // in the new cells
-           subcells[0]->set_neighbor (0, neighbor_cells[0][0]);
-           subcells[0]->set_neighbor (1, subcells[1]);
-           subcells[0]->set_neighbor (2, neighbor_cells[2][0]);
-           subcells[0]->set_neighbor (3, subcells[2]);
-
-           subcells[1]->set_neighbor (0, subcells[0]);
-           subcells[1]->set_neighbor (1, neighbor_cells[1][0]);
-           subcells[1]->set_neighbor (2, neighbor_cells[2][1]);
-           subcells[1]->set_neighbor (3, subcells[3]);
-
-           subcells[2]->set_neighbor (0, neighbor_cells[0][1]);
-           subcells[2]->set_neighbor (1, subcells[3]);
-           subcells[2]->set_neighbor (2, subcells[0]);
-           subcells[2]->set_neighbor (3, neighbor_cells[3][0]);
-
-           subcells[3]->set_neighbor (0, subcells[2]);
-           subcells[3]->set_neighbor (1, neighbor_cells[1][1]);
-           subcells[3]->set_neighbor (2, subcells[1]);
-           subcells[3]->set_neighbor (3, neighbor_cells[3][1]);
-
-                                            // now we need to set the
-                                            // neighbors' neighborship
-                                            // information; this is
-                                            // only necessary if the
-                                            // neighboring cell is
-                                            // refined, i.e. is on
-                                            // the same level as the
-                                            // new children of the
-                                            // present cell
-           for (unsigned int nb=0; nb<GeometryInfo<dim>::faces_per_cell; ++nb)
-             for (unsigned int subface=0;
-                  subface<GeometryInfo<dim>::subfaces_per_face; ++subface)
-               if ((neighbor_cells[nb][subface].state() ==
-                    IteratorState::valid) &&
-                   (neighbor_cells[nb][subface]->level() ==
-                    cell->level()+1))
-                 {
-                                                    // ok, the
-                                                    // neighbor is a
-                                                    // refined one
-                                                    // and we need to
-                                                    // set one of the
-                                                    // new children
-                                                    // as its
-                                                    // neighbor
-                   const cell_iterator neighbor = neighbor_cells[nb][subface];
-
-                                                    // find which
-                                                    // neighbor
-                                                    // pointer is to
-                                                    // be reset; this
-                                                    // pointer still
-                                                    // points to the
-                                                    // present cell
-                   unsigned int face;
-                   for (face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-                     if (neighbor->neighbor(face) == cell)
-                       break;
-
-                   Assert (face<GeometryInfo<dim>::faces_per_cell,
-                           ExcInternalError());
-
-                   neighbor->set_neighbor(face, subcells[
-                                            GeometryInfo<dim>::child_cell_on_face(nb, subface)]);
-                 }
-
-                                            // note that the
-                                            // refinement flag was
-                                            // already cleared at the
-                                            // beginning of this loop
-           
-         }
-    }
-
-                                  // re-compute number of lines and
-                                  // quads
-  update_number_cache ();
-
-
-#ifdef DEBUG
-  for (unsigned int level=0; level<levels.size(); ++level) 
-    levels[level]->cells.monitor_memory (2);
-
-                                  // 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 ());
-
-  cell_iterator cell = begin(),
-               endc = end();
-  while (cell != endc)
-    Assert (!(cell++)->refine_flag_set(), ExcInternalError ());
-#endif
-}
-
-#endif
-
-
-#if deal_II_dimension == 3
-
-template <>
-void
-Triangulation<3>::execute_refinement ()
-{
-  const unsigned int dim = 3;
+template <>
+void
+Triangulation<3>::execute_refinement ()
+{
+  const unsigned int dim = 3;
 
                                   // check whether a new level is
                                   // needed we have to check for this
@@ -5905,12 +5861,23 @@ Triangulation<3>::execute_refinement ()
                                   // and lines; we're going to use them
                                   // to flag which lines and quads
                                   // need refinement
+  faces->quads.clear_user_data();
+  
   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();
-
-
+    {
+      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};
+  
                                   // check how much space is needed
                                   // on every level
                                   // we need not check the highest
@@ -5920,63 +5887,138 @@ Triangulation<3>::execute_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    = 0;
-  unsigned int needed_quads    = 0;
-  int level;
-  for (level=levels.size()-2; level>=0; --level)
+  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 flagged_cells = 0;
-
+      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()) 
          {
-           ++flagged_cells;
-
-                                            // new vertex at center
-                                            // of cell is needed in
+           RefinementCase<dim> ref_case=acell->refine_flag_set();
+           
+                                            // now for interior vertices, lines
+                                            // and quads, which are needed in
                                             // any case
-           ++needed_vertices;
-                                            // also the six inner
-                                            // lines
-           needed_lines += 6;
-                                            // and the 12 inner quads
-           needed_quads += 12;
+           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 and
-                                            // lines for refinement;
+                                            // mark all faces for refinement;
                                             // checking locally
-                                            // whether the neighbor
-                                            // would also like to
-                                            // refine them is rather
-                                            // difficult for lines so
+                                            // 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
-                                            // lines need refinement;
-                                            // same for the quads
+                                            // 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 (aface->has_children() == false) 
-                 {
-                   aface->set_user_flag ();
-                   for (unsigned int line=0; line<4; ++line)
-                     if (aface->line(line)->has_children() == false)
-                       aface->line(line)->set_user_flag ();
-                 }
-             }
-         }
+         }// if refine_flag set and for all cells on this level
+      
 
                                       // count number of used cells on
                                       // the next higher level
@@ -5992,42 +6034,84 @@ Triangulation<3>::execute_refinement ()
                                       // level as well as for the
                                       // 8*flagged_cells that will be
                                       // created on that level
-      levels[level+1]->reserve_space (used_cells+8*flagged_cells, 3);
+      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 (8*flagged_cells);
-    }
-
+      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())
-      {
-       Assert (quad->has_children() == false, ExcInternalError());
-       needed_quads    += 4;
-       needed_lines    += 4;
-       needed_vertices += 1;
-      }
+    {
+      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())
       {
-       Assert (line->has_children() == false, ExcInternalError());
-       needed_lines += 2;
+       needed_lines_pair += 2;
        needed_vertices += 1;
       }
 
                                   // reserve space for
                                   // needed_lines new lines
+                                  // stored in pairs
   faces->lines.
-    reserve_space (needed_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);
+    reserve_space (needed_quads_pair,needed_quads_single);
+
 
                                   // add to needed vertices how many
                                   // vertices are already in use
@@ -6086,14 +6170,13 @@ Triangulation<3>::execute_refinement ()
   unsigned int next_unused_vertex = 0;
 
                                   // first for lines
-                                  // only active objects can be
-                                  // refined further;
   if (true)
     {
+                                      // 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())
@@ -6122,9 +6205,11 @@ Triangulation<3>::execute_refinement ()
                                             // up the two child lines
                                             // (++ takes care of the
                                             // end of the vector)
-           while (next_unused_line->used() == true)
-             ++next_unused_line;
-                                            // there should always be
+           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
@@ -6132,11 +6217,11 @@ Triangulation<3>::execute_refinement ()
                                             // then set the child
                                             // pointer of the present
                                             // line
-           line->set_children (next_unused_line->index());
+           line->set_children (0, next_unused_line->index());
          
                                             // set the two new lines
-           raw_line_iterator children[2] = { next_unused_line,
-                                             ++next_unused_line };
+           const raw_line_iterator children[2] = { next_unused_line,
+                                                   ++next_unused_line };
                                             // some tests; if any of
                                             // the iterators should
                                             // be invalid, then
@@ -6175,312 +6260,871 @@ Triangulation<3>::execute_refinement ()
                                   ///////////////////////////////////////
                                   // now refine marked quads
                                   ///////////////////////////////////////
-                                  //
-                                  // only active objects can be
-                                  // refined further;
-  if (true)
-    {
-      active_quad_iterator quad = begin_active_quad(),
-                          endq = end_quad();
-      raw_line_iterator next_unused_line = begin_raw_line ();
-      raw_quad_iterator next_unused_quad = begin_raw_quad ();
-      
-      for (; quad!=endq; ++quad)
-       if (quad->user_flag_set())
-         {
-                                            // this quad 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 (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;
-         
-                                            // 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)
-             {
-               while (next_unused_line->used() == true)
-                 ++next_unused_line;
-               new_lines[i] = next_unused_line;
-               ++next_unused_line;
+                                  // here we encounter several cases:
 
-               Assert (new_lines[i]->used() == false,
-                        ExcCellShouldBeUnused());
-             }
+                                  // a) the quad is unrefined and shall be
+                                  // refined isotropically
 
-                                            // 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());
-             }
+                                  // 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)
 
-                                            // 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
-           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 for
-                                            // the four newly to be
-                                            // created quads.  note
-                                            // that there should
-                                            // always be four
-                                            // consecutive free slots
-                                            // for them
-           raw_quad_iterator new_quads[4];
-
-           while (next_unused_quad->used() == true)
-             ++next_unused_quad;
+                                  // d) the quad is refined anisotropically and
+                                  // shall be refined isotropically (this is
+                                  // reduced to case b) for the anisotropic
+                                  // children)
 
-           new_quads[0] = next_unused_quad;
-           Assert (new_quads[0]->used() == false, ExcCellShouldBeUnused());
+                                  // 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...)
 
-           ++next_unused_quad;
-           new_quads[1] = next_unused_quad;
-           Assert (new_quads[1]->used() == false, ExcCellShouldBeUnused());
+                                  // 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 ();
 
-           ++next_unused_quad;
-           new_quads[2] = next_unused_quad;
-           Assert (new_quads[2]->used() == false, ExcCellShouldBeUnused());
+      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>::cut_xy ||
+                    quad->refinement_case()==RefinementCase<dim>::no_refinement,
+                    ExcInternalError());
+             
+                                              // this quad needs to be refined
+                                              // anisotropically
+             Assert(quad->user_index() == RefinementCase<dim>::cut_x ||
+                    quad->user_index() == RefinementCase<dim>::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>::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);
+               }
 
-           ++next_unused_quad;
-           new_quads[3] = next_unused_quad;
-           Assert (new_quads[3]->used() == false, ExcCellShouldBeUnused());
+             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());
 
-                                            // note these quads as
-                                            // children to the
-                                            // present one
-           quad->set_children (new_quads[0]->index());
-
-           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 ();
-         }
-    }
 
-                                  ///////////////////////////////////
-                                  // 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);
+             if (aniso_quad_ref_case==RefinementCase<dim>::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>::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));
+               }
 
-      for (; hex!=endh; ++hex)
-       if (hex->refine_flag_set())
-         {
-                                            // do some additional
-                                            // checks.
-#ifdef DEBUG
-           for (unsigned int neighbor=0;
-                neighbor<GeometryInfo<dim>::faces_per_cell; ++neighbor)
-             if (hex->neighbor(neighbor).state() == IteratorState::valid)
-               Assert (((hex->neighbor(neighbor)->level() == hex->level()) &&
-                        (hex->neighbor(neighbor)->coarsen_flag_set() == false))  ||
-                       ((hex->neighbor(neighbor)->level() == hex->level()-1) &&
-                        (hex->neighbor(neighbor)->refine_flag_set() == true)),
-                       ExcInternalError());
-#endif
+                                              // test, whether this face is
+                                              // refined isotropically
+                                              // already. if so, set the
+                                              // correct children pointers.
+             if (quad->refinement_case()==RefinementCase<dim>::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>::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>::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]=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)
+                       {
+                         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>::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 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();
+                     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>::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>::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>::cut_x ||
+                 quad_ref_case==RefinementCase<dim>::cut_y)
+               {
+                                                  // set the 'opposite' refine case for children
+                 quad->child(0)->set_user_index(RefinementCase<dim>::cut_xy-quad_ref_case);
+                 quad->child(1)->set_user_index(RefinementCase<dim>::cut_xy-quad_ref_case);
+                                                  // refine the inner line
+                 line_iterator middle_line;
+                 if (quad_ref_case==RefinementCase<dim>::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());
+                   }
+                                                  // 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>::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
            
@@ -6491,127 +7135,60 @@ Triangulation<3>::execute_refinement ()
                                             // can't do it anymore
                                             // once the cell has
                                             // children
+           const RefinementCase<dim> ref_case=hex->refine_flag_set();
            hex->clear_refine_flag ();
-
-                                            // 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;
-           
-                                            // 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)->child(0)->vertex(3) *
-                                             1./12.;
-
-                                            // now that we created
-                                            // the right point, make
-                                            // up the six lines
-                                            // interior to the hex
-                                            // (++ takes care of the
-                                            // end of the vector)
-           raw_line_iterator new_lines[6];
-
-           for (unsigned int i=0; i<6; ++i)
+           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 (static_cast<unsigned char> (ref_case))
              {
-               while (next_unused_line->used() == true)
-                 ++next_unused_line;
-               new_lines[i] = next_unused_line;
-               ++next_unused_line;
-
-               Assert (new_lines[i]->used() == false,
-                        ExcCellShouldBeUnused());
+               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;
              }
-
-                                            // 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  |
-                                            // *--*--*       *--*--*
-                                             //
-                                             // note that asking for child 0 and
-                                             // vertex 3 within that is
-                                             // invariant with respect to the
-                                             // face orientation, rotation and
-                                             // flip, so we do not have to ask
-                                             // here
-           const unsigned int vertex_indices[7]
-             = { hex->face(0)->child(0)->vertex_index(3),
-                 hex->face(1)->child(0)->vertex_index(3),
-                 hex->face(2)->child(0)->vertex_index(3),
-                 hex->face(3)->child(0)->vertex_index(3),
-                 hex->face(4)->child(0)->vertex_index(3),
-                 hex->face(5)->child(0)->vertex_index(3),
-                 next_unused_vertex 
-             };
            
-           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]));
-
-           for (unsigned int i=0; i<6; ++i)
+                                            // 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();
@@ -6620,85 +7197,88 @@ Triangulation<3>::execute_refinement ()
                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);
+             }
+
+                                            // 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
 
-                                            // now for the
-                                            // quads. 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  |
-                                            // *---*---*       *---*---*
-                                             //
-                                             // this time we have to
-                                             // take into account
-                                             // whether the different
-                                             // faces are oriented
-                                             // correctly or in the
-                                             // opposite direction, so
-                                             // store that up front
-
-                                            // TODO: shorten this
-           
                                             // face_orientation
             const bool f_or[6]
               = { hex->face_orientation (0),
@@ -6726,522 +7306,2411 @@ Triangulation<3>::execute_refinement ()
                   hex->face_rotation (4),
                   hex->face_rotation (5) };
 
-                                            // 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[30]
-             = {
-                   hex->face(0)->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)->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)->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)->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)->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)->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)->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)->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)->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)->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)->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)->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)->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)->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)->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)->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)->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)->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)->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)->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)->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)->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)->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)->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
-             };
-
-           unsigned int line_indices[30];
-           for (unsigned int i=0; i<30; ++i)
-             line_indices[i]=lines[i]->index();
-           
-                                            // 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[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.
-           for (unsigned int i=0; i<24; ++i)
-             if (lines[i]->vertex_index((i+1)%2)==vertex_indices[i/4])
-               line_orientation[i]=true;
-             else
+                                            // 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 (static_cast<unsigned char> (ref_case))
+             {
+               case RefinementCase<dim>::cut_x:
                {
-                                                  // it must be the other way
-                                                  // round then
-                 Assert(lines[i]->vertex_index(i%2)==vertex_indices[i/4],
-                        ExcInternalError());
-                 line_orientation[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[i]=true;
-
+                                                  //////////////////////////////
+                                                  //
+                                                  //     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:
            
-                                            // find some space for
-                                            // the 12 newly to be
-                                            // created quads.
-           raw_quad_iterator new_quads[12];
-
-           for (unsigned int i=0; i<12; ++i)
-             {
-               while (next_unused_quad->used() == true)
-                 ++next_unused_quad;
-               new_quads[i] = next_unused_quad;
-               ++next_unused_quad;
-
-               Assert (new_quads[i]->used() == false,
-                        ExcCellShouldBeUnused());
-             }
+                                                  // 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<dim>::cut_x) ? 1 : 3),        //0
+                         hex->face(3)->child(0)
+                         ->line((hex->face(3)->refinement_case() == RefinementCase<dim>::cut_x) ? 1 : 3),        //1
+                         hex->face(4)->child(0)
+                         ->line((hex->face(4)->refinement_case() == RefinementCase<dim>::cut_x) ? 1 : 3),        //2
+                         hex->face(5)->child(0)
+                         ->line((hex->face(5)->refinement_case() == RefinementCase<dim>::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)
+                   };
 
-                                            // 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-*
+                 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:
            
-           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]));
-
-                                            // set flags
-           for (unsigned int i=0; i<12; ++i)
-             {
-               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, chnage this
-                                                // afterwards, if necessary
-               for (unsigned int j=0; j<GeometryInfo<dim>::lines_per_face; ++j)
-                 new_quads[i]->set_line_orientation(j,true);
-             }  
-                                            // 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]);
+                                                  // 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<dim>::cut_x) ? 1 : 3),        //0
+                         hex->face(1)->child(0)
+                         ->line((hex->face(1)->refinement_case() == RefinementCase<dim>::cut_x) ? 1 : 3),        //1
+                         hex->face(4)->child(0)
+                         ->line((hex->face(4)->refinement_case() == RefinementCase<dim>::cut_x) ? 1 : 3),        //2
+                         hex->face(5)->child(0)
+                         ->line((hex->face(5)->refinement_case() == RefinementCase<dim>::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<dim>::cut_x) ? 1 : 3),        //0
+                         hex->face(1)->child(0)
+                         ->line((hex->face(1)->refinement_case() == RefinementCase<dim>::cut_x) ? 1 : 3),        //1
+                         hex->face(2)->child(0)
+                         ->line((hex->face(2)->refinement_case() == RefinementCase<dim>::cut_x) ? 1 : 3),        //2
+                         hex->face(3)->child(0)
+                         ->line((hex->face(3)->refinement_case() == RefinementCase<dim>::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()
+                   };
 
-                                            /////////////////////////////////
-                                            // create the eight new hexes
-                                            //
-                                            // again first collect
-                                            // some data.  here, we
-                                            // need the indices of a
-                                            // whole lotta
-                                            // quads. they 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.
-                                            //
-                                            // TODO: simplify this
-           const unsigned int quad_indices[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)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0])),  //12
-                   hex->face(0)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[0],f_fl[0],f_ro[0])),
-                   hex->face(0)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[0],f_fl[0],f_ro[0])),
-                   hex->face(0)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0])),
-
-                   hex->face(1)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1])),  //16
-                   hex->face(1)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[1],f_fl[1],f_ro[1])),
-                   hex->face(1)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[1],f_fl[1],f_ro[1])),
-                   hex->face(1)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1])),
-
-                   hex->face(2)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2])),  //20
-                   hex->face(2)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[2],f_fl[2],f_ro[2])),
-                   hex->face(2)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[2],f_fl[2],f_ro[2])),
-                   hex->face(2)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2])),
-
-                   hex->face(3)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3])),  //24
-                   hex->face(3)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[3],f_fl[3],f_ro[3])),
-                   hex->face(3)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[3],f_fl[3],f_ro[3])),
-                   hex->face(3)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3])),
-
-                   hex->face(4)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4])),  //28
-                   hex->face(4)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[4],f_fl[4],f_ro[4])),
-                   hex->face(4)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[4],f_fl[4],f_ro[4])),
-                   hex->face(4)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4])),
-
-                   hex->face(5)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5])),  //32
-                   hex->face(5)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[5],f_fl[5],f_ro[5])),
-                   hex->face(5)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[5],f_fl[5],f_ro[5])),
-                   hex->face(5)->child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
-             };
-
-
-                                            // find some space for
-                                            // the eight newly to be
-                                            // created hexes.  note
-                                            // that there should
-                                            // always be eight
-                                            // consecutive free slots
-                                            // for them
-           raw_hex_iterator new_hexes[8];
-
-           while (next_unused_hex->used() == true)
-             ++next_unused_hex;
-
-           for (unsigned int i=0; i<8; ++i)
-             {
-               new_hexes[i] = next_unused_hex;
-               Assert (new_hexes[i]->used() == false,
-                        ExcCellShouldBeUnused());
-               ++next_unused_hex;
-             }
+                 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>(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<dim>::cut_x) ? 1 : 3),        //0
+                         hex->face(1)->child(0)
+                         ->line((hex->face(1)->refinement_case() == RefinementCase<dim>::cut_x) ? 1 : 3),        //1
+                         hex->face(2)->child(0)
+                         ->line((hex->face(2)->refinement_case() == RefinementCase<dim>::cut_x) ? 1 : 3),        //2
+                         hex->face(3)->child(0)
+                         ->line((hex->face(3)->refinement_case() == RefinementCase<dim>::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)==hex->face(3+i/4)->middle_vertex_index())
+                     line_orientation_xy[i]=true;
+                   else
+                     {
+                                                        // 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;
+                     }
+                                                  // 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:
+               {
+                                                  //////////////////////////////
+                                                  //
+                                                  //     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<dim>::cut_x) ? 1 : 3),        //0
+                         hex->face(1)->child(0)
+                         ->line((hex->face(1)->refinement_case() == RefinementCase<dim>::cut_x) ? 1 : 3),        //1
+                         hex->face(4)->child(0)
+                         ->line((hex->face(4)->refinement_case() == RefinementCase<dim>::cut_x) ? 1 : 3),        //2
+                         hex->face(5)->child(0)
+                         ->line((hex->face(5)->refinement_case() == RefinementCase<dim>::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)==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]);
+
+                                                  // 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>(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<dim>::cut_x) ? 1 : 3),        //0
+                         hex->face(3)->child(0)
+                         ->line((hex->face(3)->refinement_case() == RefinementCase<dim>::cut_x) ? 1 : 3),        //1
+                         hex->face(4)->child(0)
+                         ->line((hex->face(4)->refinement_case() == RefinementCase<dim>::cut_x) ? 1 : 3),        //2
+                         hex->face(5)->child(0)
+                         ->line((hex->face(5)->refinement_case() == RefinementCase<dim>::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(-1+i/4)->middle_vertex_index())
+                     line_orientation_yz[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_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])),
+
+                         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 (vertices_used[next_unused_vertex] == true)
+                   ++next_unused_vertex;
+                 Assert (next_unused_vertex < vertices.size(),
+                         ExcTooFewVerticesAllocated());
+                 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)
+                 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];
+                     
+                 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]);
 
-                                            // note these hexes as
-                                            // children to the
-                                            // present cell
-           hex->set_children (new_hexes[0]->index());
-
-                                            // 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]));
+                 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.
            
-                                            // 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]));
-            
-
-           for (unsigned int i=0; i<8; ++i)
-             {
-               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());
-              }
-            
-                                             // 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 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
                                              //
-                                             // set the flag to true
-                                             // for all faces
-                                             // initially, then go the
-                                             // other way round and
-                                             // reset faces that are
-                                             // at the boundary of the
-                                             // mother cube
+                                             // 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
-           for (unsigned int i=0; i<8; ++i)
-              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);
-               }
            
+                                            // 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<GeometryInfo<dim>::subfaces_per_face; ++s)
+              for (unsigned int s=0;
+                  s<std::max(GeometryInfo<dim-1>::n_children(GeometryInfo<dim>::face_refinement_case(ref_case,f)),
+                             1U);
+                  ++s)
                 {
-                 new_hexes[GeometryInfo<dim>::child_cell_on_face(f,s)]
-                   ->set_face_orientation(f, hex->face_orientation(f));
-                 new_hexes[GeometryInfo<dim>::child_cell_on_face(f,s)]
-                   ->set_face_flip(f, hex->face_flip(f));
-                 new_hexes[GeometryInfo<dim>::child_cell_on_face(f,s)]
-                   ->set_face_rotation(f, hex->face_rotation(f));
+                 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]);
                }
-            
-#ifdef DEBUG
-                                            // check consistency
-                                            // against
-                                            // GeometryInfo<3>::child_cell_on_face
-           for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
-             for (unsigned int s=0; s<GeometryInfo<dim>::subfaces_per_face; ++s) 
-               Assert(hex->face(f)->child(s)==hex->child(
-                        GeometryInfo<dim>::child_cell_on_face(
-                          f, s, hex->face_orientation(f), hex->face_flip(f), hex->face_rotation(f)))->face(f), ExcInternalError());
-#endif
 
                                             /////////////////////////////////
                                             // now the only thing still
@@ -7249,334 +9718,108 @@ Triangulation<3>::execute_refinement ()
                                             // neighborship
                                             // information.
                                             //
-                                            // to do so, first
-                                            // collect the iterators
-                                            // pointing to the 6x4
-                                            // neighbors of this
-                                            // cell.
-                                            //
-                                            // note that in case the
-                                            // neighboring cell is
-                                            // not refined, 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 neighbor_cells[6][4];
-           for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell;
-                ++face)
+                                            // the easiest part is setting the
+                                            // inner neighbors, i.e. children
+                                            // neighboring other children of
+                                            // the same mother cube.
+           switch (static_cast<unsigned char> (ref_case))
              {
-               const cell_iterator neighbor = hex->neighbor(face);
-
-                                                // if no neighbor
-               if (neighbor.state() != IteratorState::valid)
-                 for (unsigned int child_face=0;
-                      child_face<GeometryInfo<dim>::subfaces_per_face;
-                      ++child_face)
-                   neighbor_cells[face][child_face] = neighbor;
-               
-               else
-                                                  // neighbor exists
-                 {
-                                                    // neighbor's
-                                                    // level must not
-                                                    // be higher
-                                                    // (else
-                                                    // something went
-                                                    // wrong when
-                                                    // constructing
-                                                    // either of the
-                                                    // two cells) and
-                                                    // not lower
-                                                    // since then
-                                                    // this cell
-                                                    // should not
-                                                    // have been
-                                                    // refined.
-                   Assert (neighbor->level() == hex->level(),
-                           ExcInternalError());
+               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]);
 
-                                                    // now there are
-                                                    // two
-                                                    // possibilities:
-                                                    // either the
-                                                    // neighbor has
-                                                    // no children or
-                                                    // it has
-                                                    // children. these
-                                                    // must be
-                                                    // terminal then.
-                   if (!neighbor->has_children())
-                     for (unsigned int child_face=0;
-                          child_face<GeometryInfo<dim>::subfaces_per_face;
-                          ++child_face)
-                       neighbor_cells[face][child_face] = neighbor;
-                   else
-                                                      // neighbor has
-                                                      // children;
-                                                      // now it's
-                                                      // getting
-                                                      // complicated
-                     {
-                                                        // first find
-                                                        // the face
-                                                        // of the
-                                                        // neighbor
-                                                        // adjacent
-                                                        // to which
-                                                        // the
-                                                        // present
-                                                        // cell is
-                       const unsigned int nb_nb = hex->neighbor_of_neighbor(face);
-                       Assert (nb_nb<GeometryInfo<dim>::faces_per_cell,
-                               ExcInternalError());
-
-                                                        // now the
-                                                        // four child
-                                                        // cells of
-                                                        // neighbor
-                                                        // adjacent
-                                                        // to the
-                                                        // present
-                                                        // cell can
-                                                        // be
-                                                        // obtained
-                                                        // by a
-                                                        // function
-                                                        // of
-                                                        // GeometryInfo. however,
-                                                        // if our face or the
-                                                        // neighbor's
-                                                        // face has
-                                                        // non-standard
-                                                        // orientation, flip or rotation,
-                                                        // then we
-                                                        // run into
-                                                        // trouble
-                                                        // and have
-                                                        // to swap
-                                                        // subfaces
-                                                        // to account
-                                                        // for
-                                                        // that.
-                                                         //
-                                                        // it is quite
-                                                        // difficult to find
-                                                        // out, which neighbors
-                                                        // child is adjacent to
-                                                        // a given child of our
-                                                        // current cell. it is
-                                                        // easier to determine
-                                                        // the children
-                                                        // adjacent to a given
-                                                        // subface in both
-                                                        // cases. here, we
-                                                        // consider that for
-                                                        // the neighbor, when
-                                                        // we set the neighbors
-                                                        // of our children we
-                                                        // will consider it for
-                                                        // the children of our
-                                                        // current cell.
-
-                       for (unsigned int c=0;
-                            c<GeometryInfo<dim>::subfaces_per_face; ++c)
-                         {
-                           neighbor_cells[face][c]
-                             = neighbor->child(GeometryInfo<dim>::
-                                               child_cell_on_face(nb_nb, c,
-                                                                  neighbor->face_orientation(nb_nb),
-                                                                  neighbor->face_flip(nb_nb),
-                                                                  neighbor->face_rotation(nb_nb)));
-                           
-                           Assert (neighbor_cells[face][c].state() ==
-                                   IteratorState::valid,
-                                   ExcInternalError());
-                           Assert (!neighbor_cells[face][c]->has_children(),
-                                   ExcInternalError());
-                         }
-                     }
-                 }
-             }
+                     new_hexes[1]->set_neighbor(1, new_hexes[3]);
+                     new_hexes[1]->set_neighbor(4, new_hexes[0]);
 
-                                            // now we've got all
-                                            // neighbors, so set them
-                                            // in the new cells
-           
-                                            // the subface ordering
-                                            // is as follows
-                                            // face 0 and 1:
-                                            //        * 
-                                            //       /| 
-                                            //      * | 
-                                            //    y/|3* 
-                                            //    * |/| 
-                                            //    |2* |x
-                                            //    |/|1* 
-                                            //    * |/  
-                                            //    |0*   
-                                            //    |/    
-                                            //    *
-                                            // face 2 and 3:
-                                            //  x
-                                            //  *---*---*
-                                            //  | 1 | 3 |
-                                            //  *---*---*
-                                            //  | 0 | 2 |
-                                            //  *---*---*y
-                                            // face 4 and 5:
-                                            //       y
-                                            //      *---*---*
-                                            //     / 2 / 3 /
-                                            //    *---*---*
-                                            //   / 0 / 1 /
-                                            //  *---*---*x
-
-                                            // Step 1: set all 'outer neighbors'
-           for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-             for (unsigned int sub=0; sub<GeometryInfo<dim>::subfaces_per_face; ++sub)
-               new_hexes[GeometryInfo<dim>::
-                         child_cell_on_face(face,sub,
-                                            hex->face_orientation(face),
-                                            hex->face_flip(face),
-                                            hex->face_rotation(face))]
-                 ->set_neighbor(face,neighbor_cells[face][sub]);
-                                            // Step 2: set all 'inner
-                                            // neighbors', i.e. neighbors that
-                                            // are itself children of our
-                                            // current cell
-
-                                            // TODO: do we really want to test
-                                            // (assert) this static information
-                                            // for each cell?
-           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]);
-           Assert(GeometryInfo<dim>::child_cell_on_face(0,0)==0, ExcInternalError());
-           Assert(GeometryInfo<dim>::child_cell_on_face(2,0)==0, ExcInternalError());
-           Assert(GeometryInfo<dim>::child_cell_on_face(4,0)==0, ExcInternalError());
-
-           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]);
-           Assert(GeometryInfo<dim>::child_cell_on_face(1,0)==1, ExcInternalError());
-           Assert(GeometryInfo<dim>::child_cell_on_face(2,2)==1, ExcInternalError());
-           Assert(GeometryInfo<dim>::child_cell_on_face(4,1)==1, ExcInternalError());
-
-           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]);
-           Assert(GeometryInfo<dim>::child_cell_on_face(0,1)==2, ExcInternalError());
-           Assert(GeometryInfo<dim>::child_cell_on_face(3,0)==2, ExcInternalError());
-           Assert(GeometryInfo<dim>::child_cell_on_face(4,2)==2, ExcInternalError());
-
-           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]);
-           Assert(GeometryInfo<dim>::child_cell_on_face(1,1)==3, ExcInternalError());
-           Assert(GeometryInfo<dim>::child_cell_on_face(3,2)==3, ExcInternalError());
-           Assert(GeometryInfo<dim>::child_cell_on_face(4,3)==3, ExcInternalError());
-
-           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]);
-           Assert(GeometryInfo<dim>::child_cell_on_face(0,2)==4, ExcInternalError());
-           Assert(GeometryInfo<dim>::child_cell_on_face(2,1)==4, ExcInternalError());
-           Assert(GeometryInfo<dim>::child_cell_on_face(5,0)==4, ExcInternalError());
-
-           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]);
-           Assert(GeometryInfo<dim>::child_cell_on_face(1,2)==5, ExcInternalError());
-           Assert(GeometryInfo<dim>::child_cell_on_face(2,3)==5, ExcInternalError());
-           Assert(GeometryInfo<dim>::child_cell_on_face(5,1)==5, ExcInternalError());
-
-           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]);
-           Assert(GeometryInfo<dim>::child_cell_on_face(0,3)==6, ExcInternalError());
-           Assert(GeometryInfo<dim>::child_cell_on_face(3,1)==6, ExcInternalError());
-           Assert(GeometryInfo<dim>::child_cell_on_face(5,2)==6, ExcInternalError());
-
-           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]);
-           Assert(GeometryInfo<dim>::child_cell_on_face(1,3)==7, ExcInternalError());
-           Assert(GeometryInfo<dim>::child_cell_on_face(3,3)==7, ExcInternalError());
-           Assert(GeometryInfo<dim>::child_cell_on_face(5,3)==7, ExcInternalError());
-
-
-                                            // now we need to set the
-                                            // neighbors' neighborship
-                                            // information; this is
-                                            // only necessary if the
-                                            // neighboring cell is
-                                            // refined, i.e. is on
-                                            // the same level as the
-                                            // new children of the
-                                            // present cell
-           for (unsigned int nb=0; nb<GeometryInfo<dim>::faces_per_cell; ++nb)
-             for (unsigned int subface=0;
-                  subface<GeometryInfo<dim>::subfaces_per_face; ++subface)
-               if ((neighbor_cells[nb][subface].state() ==
-                    IteratorState::valid) &&
-                   (neighbor_cells[nb][subface]->level() ==
-                    hex->level()+1))
-                 {
-                                                    // ok, the
-                                                    // neighbor is a
-                                                    // refined one
-                                                    // and we need to
-                                                    // set one of the
-                                                    // new children
-                                                    // as its
-                                                    // neighbor
-                   const cell_iterator neighbor = neighbor_cells[nb][subface];
-
-                                                    // find which
-                                                    // neighbor
-                                                    // pointer is to
-                                                    // be reset; this
-                                                    // pointer still
-                                                    // points to the
-                                                    // present cell
-                   unsigned int face;
-                   for (face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-                     if (neighbor->neighbor(face) == hex)
-                       break;
+                     new_hexes[2]->set_neighbor(0, new_hexes[0]);
+                     new_hexes[2]->set_neighbor(5, new_hexes[3]);
 
-                   Assert (face<GeometryInfo<dim>::faces_per_cell,
-                           ExcInternalError());
-                                                    // check, that the face we
-                                                    // found is consistent with
-                                                    // the information obtained
-                                                    // by the
-                                                    // neighbor_of_neighbor()
-                                                    // function
-                   Assert (face==hex->neighbor_of_neighbor(nb),
-                           ExcInternalError());
+                     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]);
 
-                                                     // then figure out which of the new
-                                                     // cells points to this neighbor.
-                                                    //
-                                                     // We have considered
-                                                     // face-orientation, -flip
-                                                     // and -rotation issues in
-                                                     // the construction of the
-                                                     // neighbor_cells array,
-                                                     // now we have to consider
-                                                     // it for this cell as
-                                                     // well.
-                   int c = GeometryInfo<dim>::child_cell_on_face(nb,subface,
-                                                                 hex->face_orientation(nb),
-                                                                 hex->face_flip(nb),
-                                                                 hex->face_rotation(nb));
-                   neighbor->set_neighbor(face,new_hexes[c]);
-                 }
+                     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(hex, true);
 
                                             // note that the
                                             // refinement flag was
@@ -7585,6 +9828,15 @@ Triangulation<3>::execute_refinement ()
          }
     }
 
+                                  // 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 ();
@@ -7617,10 +9869,20 @@ Triangulation<3>::execute_refinement ()
                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
 
 
@@ -7633,9 +9895,13 @@ void Triangulation<dim>::execute_coarsening ()
                                   // 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> cell_count(0);
+  std::vector<unsigned int> line_cell_count(0);
+  std::vector<unsigned int> quad_cell_count(0);
   if (dim==3)
-    count_cells_at_line(cell_count);
+    {
+      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
@@ -7649,7 +9915,7 @@ void Triangulation<dim>::execute_coarsening ()
                                   // used, to avoid confusion and because
                                   // non-active cells can't be flagged for
                                   // coarsening. Note that because of the
-                                  // effects of @p{prepare_coarsening}, of a
+                                  // 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
@@ -7662,8 +9928,7 @@ void Triangulation<dim>::execute_coarsening ()
       if (cell->child(0)->coarsen_flag_set())
        {
          cell->set_user_flag();
-         for (unsigned int child=0;
-              child<GeometryInfo<dim>::children_per_cell; ++child)
+         for (unsigned int child=0; child<cell->n_children(); ++child)
            {
              Assert (cell->child(child)->coarsen_flag_set(),
                      ExcInternalError());
@@ -7693,7 +9958,7 @@ void Triangulation<dim>::execute_coarsening ()
                                         // use a separate function,
                                         // since this is dimension
                                         // specific
-       delete_children (cell, cell_count);
+       delete_children (cell, line_cell_count, quad_cell_count);
 
                                   // re-compute number of lines and
                                   // quads
@@ -7709,6 +9974,93 @@ void Triangulation<dim>::execute_coarsening ()
 }
 
 
+
+#if deal_II_dimension == 1
+
+template<>
+void
+Triangulation<1>::prevent_distorted_boundary_cells ()
+{}
+
+#else
+
+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)
+               {
+                                                  // 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 () 
 {}
@@ -7726,6 +10078,11 @@ void Triangulation<3>::prepare_refinement_dim_dependent ()
                                   // 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
@@ -7743,16 +10100,30 @@ void Triangulation<3>::prepare_refinement_dim_dependent ()
       fix_coarsen_flags ();
 
       
-                                      // flag those lines that will
-                                      // be refined
-      for (active_cell_iterator cell=begin_active(); cell!=end(); ++cell)
+                                      // 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 the line is not yet
-                                            // refined, it will be in
-                                            // the process
-           if (!cell->line(line)->has_children())
-             cell->line(line)->set_user_flag();
+         {
+           for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+             if (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(), line)
+                 ==RefinementCase<dim>::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<dim>::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
@@ -7792,14 +10163,33 @@ void Triangulation<3>::prepare_refinement_dim_dependent ()
                            ExcInternalError());
                    
                    if (cell->line(line)->child(c)->user_flag_set () &&
-                       !cell->refine_flag_set())
+                       (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(),
+                                                                line)
+                        ==RefinementCase<dim>::no_refinement))
                      {
                                                         // tag this
                                                         // cell for
                                                         // refinement
                        cell->clear_coarsen_flag ();
-                       cell->set_refine_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<dim>::cut_x)
+                                                            // flag a line,
+                                                            // that will be
+                                                            // refined
+                           cell->line(l)->set_user_flag();
                                                         // note that
                                                         // we have
                                                         // changed
@@ -7815,7 +10205,10 @@ void Triangulation<3>::prepare_refinement_dim_dependent ()
                                                         // refinement
                        for (unsigned int line=0;
                             line<GeometryInfo<dim>::lines_per_cell; ++line)
-                         if (!cell->line(line)->has_children())
+                         if (!cell->line(line)->has_children() &&
+                             (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(),
+                                                                      line)
+                              !=RefinementCase<dim>::no_refinement))
                            cell->line(line)->set_user_flag();
                        
                        break;
@@ -7835,148 +10228,41 @@ void Triangulation<3>::prepare_refinement_dim_dependent ()
                                       // if any of the lines will be
                                       // refined, then we may not
                                       // coarsen the present cell
-      for (active_cell_iterator cell=last_active(); cell!=end(); --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->coarsen_flag_set())
+         if (cell->user_flag_set())
            for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
-             {
-               if (cell->line(line)->user_flag_set())
-                 {
-                   cell->clear_coarsen_flag ();
-                   mesh_changed = true;
-               
-                   goto next_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
-                                                //
-                                                // the problem is that finding
-                                                // all cells that are behind an
-                                                // edge in 3d is somewhat of a
-                                                // pain and worst of all
-                                                // introduces a quadratic
-                                                // behavior in this algorithm. on
-                                                // the other hand, not many cells
-                                                // have their coarsen flag set
-                                                // usually, and fixing
-                                                // refine_and_coarsen_3d is a
-                                                // somewhat important case
-               if (cell->line(line)->has_children())
-                 {
-                   bool cant_be_coarsened = false;
-
-                                                    // loop over all cells of this
-                                                    // level to find neighbors of
-                                                    // this cell and edge
-                   for (cell_iterator edge_neighbor=begin(cell->level());
-                        ((cant_be_coarsened == false)
-                         &&
-                         (edge_neighbor != end(cell->level())));
-                        ++edge_neighbor)
-                     if (edge_neighbor != cell)
-                       for (unsigned int e=0; e<GeometryInfo<dim>::lines_per_cell; ++e)
-                         if (edge_neighbor->line(e) == cell->line(line))
-                           {
-                                                              // this is a cell
-                                                              // that is adjacent
-                                                              // to the present
-                                                              // cell across this
-                                                              // edge. so treat
-                                                              // it, but only if
-                                                              // it is actually
-                                                              // refined or will
-                                                              // be refined
-                             if (! (edge_neighbor->has_children()
-                                    ||
-                                    (!edge_neighbor->has_children() &&
-                                     edge_neighbor->refine_flag_set())))
-                               break;
-
-                                                              // figure out if
-                                                              // the neighbor is
-                                                              // going to be
-                                                              // coarsened. as a
-                                                              // post-condition
-                                                              // of the call to
-                                                              // fix_coarsen_flags(),
-                                                              // either all
-                                                              // children of a
-                                                              // cell must be
-                                                              // flagged for
-                                                              // coarsening, or
-                                                              // none may. above
-                                                              // we delete some
-                                                              // coarsen flags,
-                                                              // and in the next
-                                                              // call to
-                                                              // fix_coarsen_flags()
-                                                              // the flags to all
-                                                              // siblings will be
-                                                              // removed. we will
-                                                              // check here if
-                                                              // still all
-                                                              // children have
-                                                              // that flag set
-                             unsigned int n_children_flagged = 0;
-                             for (unsigned int c=0; c<GeometryInfo<dim>::children_per_cell; ++c)
-                               if ((edge_neighbor->child(c)->has_children() == false)
-                                   &&
-                                   edge_neighbor->child(c)->coarsen_flag_set())
-                                 ++n_children_flagged;
-                         
-                                                              // now, if not all
-                                                              // children are
-                                                              // flagged, then
-                                                              // the neighboring
-                                                              // cell isn't going
-                                                              // to be
-                                                              // coarsened. that
-                                                              // means that the
-                                                              // common edge
-                                                              // isn't going to
-                                                              // be coarsened and
-                                                              // that we can't
-                                                              // coarsen the
-                                                              // present cell
-                             if (n_children_flagged !=
-                                 GeometryInfo<dim>::children_per_cell)
-                               cant_be_coarsened = true;
-
-
-                                                              // neighbor was
-                                                              // found. no reason
-                                                              // to keep looping
-                                                              // over edges of
-                                                              // the possible
-                                                              // edge_neighbor
-                             break;
-                           }
-
-                   if (cant_be_coarsened == true)
-                     {
-                       cell->clear_coarsen_flag ();
-                       mesh_changed = true;
-
-                       goto next_cell;
-                     }
-                 }
-             }
-         next_cell:
-         ;
+             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<dim>::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);
@@ -7985,6 +10271,90 @@ void Triangulation<3>::prepare_refinement_dim_dependent ()
 #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 ()
 {
@@ -8009,30 +10379,29 @@ void Triangulation<dim>::fix_coarsen_flags ()
                                   // turned into user flags of the
                                   // mother cell if coarsening is
                                   // possible or deleted
-                                  // otherwise. Coarsen flags of
+                                  // otherwise.
+  clear_user_flags ();
+                                  // Coarsen flags of
                                   // cells with no mother cell,
                                   // i.e. on the coarsest level are
                                   // deleted explicitly.
-  clear_user_flags ();
-      
+  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 we are on the coarsest
-                                      // level, delete coarsen flag
-                                      // since no coarsening possible
+                                      // already on the finest level
       if (cell->active()) 
-       {
-         if (cell->level() == 0)
-           cell->clear_coarsen_flag();
-         continue;
-       }
-         
-      unsigned int flagged_children = 0;
-      for (unsigned int child=0; child<GeometryInfo<dim>::children_per_cell; ++child)
+       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()) 
          {
@@ -8045,7 +10414,7 @@ void Triangulation<dim>::fix_coarsen_flags ()
                                       // flag this cell for
                                       // coarsening if all children
                                       // were flagged
-      if (flagged_children == GeometryInfo<dim>::children_per_cell)
+      if (flagged_children == n_children)
        cell->set_user_flag();
     }
       
@@ -8083,80 +10452,57 @@ void Triangulation<dim>::fix_coarsen_flags ()
                                   // to be sure that these flags are final
   for (cell=last(); cell!=endc; --cell)
     if (cell->user_flag_set())
-      {
-       bool coarsening_allowed = true;
-
-       if (dim > 1)
+                                      // if allowed: flag the
+                                      // children for coarsening
+      if (coarsening_allowed(cell))
+       for (unsigned int c=0; c<cell->n_children(); ++c)
          {
-           for (unsigned int c=0;
-                (c<GeometryInfo<dim>::children_per_cell) && (coarsening_allowed==true);
-                ++c)
-             for (unsigned int n=0; n<GeometryInfo<dim>::faces_per_cell; ++n)
-               {
-                 const cell_iterator child_neighbor = cell->child(c)->neighbor(n);
-                 if ((child_neighbor.state() == IteratorState::valid)
-                     &&
-                     (child_neighbor->level()==cell->level()+1)
-                     &&
-                     ((child_neighbor->has_children()
-                       &&
-                       !child_neighbor->user_flag_set())
-                      ||
-                      (child_neighbor->has_children()
-                       &&
-                       child_neighbor->refine_flag_set())))
-                   {
-                     coarsening_allowed = false;
-                     break;
-                   }
-               }
+           Assert (cell->child(c)->refine_flag_set()==false,
+                   ExcInternalError());
+           
+           cell->child(c)->set_coarsen_flag();
          }
-       
-                                        // if allowed: tag the
-                                        // children for coarsening
-       if (coarsening_allowed)
-         for (unsigned int c=0; c<GeometryInfo<dim>::children_per_cell; ++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 ();
 }
 
 
+#if deal_II_dimension == 1
 
-template <int dim>
-bool Triangulation<dim>::prepare_coarsening_and_refinement ()
+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[2];
-  save_coarsen_flags (flags_before[0]);
-  save_refine_flags (flags_before[1]);
+  std::vector<bool> flags_before;
+  save_coarsen_flags (flags_before);
 
                                   // do nothing in 1d, except setting
                                   // the coarsening flags correctly
-  if (dim == 1)
-    {
-      fix_coarsen_flags ();
+  fix_coarsen_flags ();
+  
+  std::vector<bool> flags_after;
+  save_coarsen_flags (flags_after);
+  
+  return (flags_before != flags_after);
+}
+
+#endif
 
-      std::vector<bool> flags_after[2];
-      save_coarsen_flags (flags_after[0]);
-      save_refine_flags (flags_after[1]);
 
-      return ((flags_before[0] != flags_after[0]) ||
-             (flags_before[1] != flags_after[1]));
-    }
 
-                                  // for all other dimensions
+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
@@ -8227,6 +10573,9 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
                                   //    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
@@ -8255,7 +10604,7 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
                                   //    need to be refined. This step
                                   //    only sets refinement flags and does
                                   //    not set coarsening flags.
-                                  //    If the path_level_1 flag is set, then
+                                  //    If the patch_level_1 flag is set, then
                                   //    eliminate_unrefined_islands,
                                   //    eliminate_refined_inner_islands and
                                   //    eliminate_refined_boundary_islands will
@@ -8298,29 +10647,29 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
                                   // 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 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)
-       {
-         typename Triangulation<dim>::active_cell_iterator
-           cell=begin_active(1),
-           endc=end_active(1);
-         
-         for (; cell!=endc; ++cell)
-           cell->clear_coarsen_flag();
-       }
-
-
                                       //////////////////////////////////////
                                       // STEP 1:
                                       //    do not coarsen a cell if 'most of
@@ -8339,33 +10688,16 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
            {
              if (!cell->active())
                {
-                                                  // count the children whose
-                                                  // coarsen_flags are set
-                 unsigned int n_childrens_coarsen_flags_set=0;
-                 for (unsigned int c=0;
-                      c<GeometryInfo<dim>::children_per_cell; ++c)
-                   if (cell->child(c)->active() &&
-                       cell->child(c)->coarsen_flag_set())
-                     ++n_childrens_coarsen_flags_set;
-
-                                                  // only do
-                                                  // something if all
-                                                  // children are
-                                                  // flagged for
-                                                  // coarsening since
-                                                  // only then are
-                                                  // they coarsened
-                                                  // anyway.
-                 if (n_childrens_coarsen_flags_set==
-                     GeometryInfo<dim>::children_per_cell)
+                                                  // 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
-                                                      // after the
-                                                      // next step
+                                                      // 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)
@@ -8374,46 +10706,29 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
                          if (neighbor.state() == IteratorState::valid)
                            {
                              ++n_neighbors;
-
-                             bool not_active_neighbor_will_be_coarsened=false;
-                             unsigned int
-                               n_neighbors_childrens_coarsen_flags_set=0;
-                             if (!neighbor->active())
-                               {
-                                 for (unsigned int c=0;
-                                      c<GeometryInfo<dim>::children_per_cell; ++c)
-                                   if (neighbor->child(c)->active() &&
-                                       neighbor->child(c)->coarsen_flag_set())
-                                     ++n_neighbors_childrens_coarsen_flags_set;
-
-                                 if (n_neighbors_childrens_coarsen_flags_set
-                                     ==GeometryInfo<dim>::children_per_cell)
-                                   not_active_neighbor_will_be_coarsened=true;
-                               }
-
-
-                             if ((neighbor->active() &&
-                                  neighbor->refine_flag_set()) ||
-                                 !not_active_neighbor_will_be_coarsened)
+                             if (face_will_be_refined_by_neighbor(cell,n))
                                ++count;
                            }
                        }
-                     
-                     if ((dim==1 && count==n_neighbors) ||
-                         (dim>1 && (count==n_neighbors ||
-                                    (count>=n_neighbors-1 &&
-                                     n_neighbors==
-                                     GeometryInfo<dim>::faces_per_cell))))
-                       for (unsigned int c=0;
-                            c<GeometryInfo<dim>::children_per_cell; ++c)
+                                                      // 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
@@ -8450,7 +10765,7 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
                                                 // active
                bool all_children_active = true;
                if (!cell->active())
-                 for (unsigned int c=0; c<GeometryInfo<dim>::children_per_cell; ++c)
+                 for (unsigned int c=0; c<cell->n_children(); ++c)
                    if (!cell->child(c)->active()) 
                      {
                        all_children_active = false;
@@ -8482,31 +10797,13 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
                      {
                        const cell_iterator neighbor = cell->neighbor(n);
                        if (neighbor.state() == IteratorState::valid)
+                       {
                          ++total_neighbors;
 
-                       if (neighbor.state() == IteratorState::valid)
-                         {
-                           if ((neighbor->active() &&
-                                !neighbor->refine_flag_set()) ||
-                               (neighbor->level() == cell->level()-1))
-                             ++unrefined_neighbors;
-                           else
-                             if (!neighbor->active())
-                                                                // maybe this cell's
-                                                                // children will be
-                                                                // coarsened
-                               {
-                                 unsigned int tagged_children = 0;
-                                 for (unsigned int c=0;
-                                      c<GeometryInfo<dim>::children_per_cell;
-                                      ++c)
-                                   if (neighbor->child(c)->coarsen_flag_set())
-                                     ++tagged_children;
-                                 if (tagged_children ==
-                                     GeometryInfo<dim>::children_per_cell)
-                                   ++unrefined_neighbors;
-                               }
-                         }
+                         if (!face_will_be_refined_by_neighbor(cell,n))
+                           ++unrefined_neighbors;
+                       }
+                       
                      }
                    
                                                     // if all
@@ -8549,17 +10846,14 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
                          (smooth_grid & eliminate_refined_boundary_islands)) )
                        &&
                        (total_neighbors != 0))
-                     {
-                       if (!cell->active())
-                         for (unsigned int c=0;
-                              c<GeometryInfo<dim>::children_per_cell; ++c)
-                           {
-                             cell->child(c)->clear_refine_flag ();
-                             cell->child(c)->set_coarsen_flag ();
-                           }
-                       else
-                         cell->clear_refine_flag();
-                     }
+                     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();
                  }
              }
        }
@@ -8568,8 +10862,18 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
                                       // STEP 3:
                                       //    limit the level difference of
                                       //    neighboring cells at each vertex.
-      if (smooth_grid & limit_level_difference_at_vertices) 
+                                      //
+                                      //    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
@@ -8641,46 +10945,158 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
          for (; cell!=endc; ++cell) 
            {
                                               // if cell is already
-                                              // flagged for
+                                              // flagged for (isotropic)
                                               // refinement: nothing
                                               // to do anymore
-             if (cell->refine_flag_set())
+             if (cell->refine_flag_set()==RefinementCase<dim>::isotropic_refinement)
                continue;
-                 
-             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))
-                 {
-                                                    // neighbor may
-                                                    // only be on the
-                                                    // same level or
-                                                    // one level
-                                                    // below because
-                                                    // of the
-                                                    // regularisation
-                                                    // above
-                   Assert ((cell->neighbor_level(face)==cell->level()) ||
-                           (cell->neighbor_level(face)==cell->level()-1),
-                           ExcInternalError());
-                   if ((cell->neighbor_level(face) == cell->level()) &&
-                       (cell->neighbor(face)->refine_flag_set() ||
-                        cell->neighbor(face)->has_children()))
-                     ++refined_neighbors;
-                   else
-                     ++unrefined_neighbors;
-                 }
 
-             if (unrefined_neighbors < refined_neighbors)
+                                              // 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))
                {
-                 if (cell->coarsen_flag_set())
-                   cell->clear_coarsen_flag();
-                 cell->set_refine_flag ();
+                                                  // 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.
@@ -8731,13 +11147,14 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
                                           // set_refine_flag and
                                           // clear_coarsen_flag of
                                           // all children.
-         unsigned int n_children=GeometryInfo<dim>::children_per_cell;
          for (cell_iterator cell = begin(); cell != end(); ++cell)
            if (!cell->active() && cell->child(0)->active())
              {
+               const unsigned int n_children=cell->n_children();
+               
                                                 // cell is found to
                                                 // be a patch
-               bool any_refine_flag_set=false;
+               RefinementCase<dim> combined_ref_case = RefinementCase<dim>::no_refinement;
                for (unsigned int i=0; i<n_children; ++i)
                  {
                    cell_iterator child=cell->child(i);
@@ -8748,21 +11165,21 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
                                                     // i.e. no child
                                                     // is refined.
                    Assert(child->active(), ExcInternalError());
+                                                    // combine the refine cases
+                                                    // of all children
+                   combined_ref_case=combined_ref_case |
+                                     child->refine_flag_set();
+                   
                    
-                   if (child->refine_flag_set())
-                     {
-                       any_refine_flag_set=true;
-                       break;
-                     }
                  }
-               if (any_refine_flag_set)
+               if (combined_ref_case != RefinementCase<dim>::no_refinement)
                  {
                    for (unsigned int i=0; i<n_children; ++i)
                      {
                        cell_iterator child=cell->child(i);
 
                        child->clear_coarsen_flag();
-                       child->set_refine_flag();
+                       child->set_refine_flag(combined_ref_case);
                      }
                  }
              }
@@ -8782,6 +11199,8 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
                !cell->child(0)->active() &&
                cell->child(0)->child(0)->active())
              {
+               const unsigned int n_children=cell->n_children();
+               unsigned int n_grandchildren=0;         
                                                 // count all coarsen
                                                 // flags of the
                                                 // grandchildren.
@@ -8811,7 +11230,9 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
                                                         // child is
                                                         // found to
                                                         // be a patch
-                       for (unsigned int cc=0; cc<n_children; ++cc)
+                       const unsigned int nn_children=child->n_children();
+                       n_grandchildren += nn_children;
+                       for (unsigned int cc=0; cc<nn_children; ++cc)
                          {
                            cell_iterator grand_child=child->child(cc);
                                                             // check
@@ -8826,7 +11247,7 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
                      }
                  }
                
-               if (n_coarsen_flags!=n_children*n_children)
+               if (n_coarsen_flags!=n_grandchildren)
                  {
                                                     // clear all
                                                     // grandchildren's
@@ -8838,7 +11259,8 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
                    
                        if (child->child(0)->active())
                          {
-                           for (unsigned int cc=0; cc<n_children; ++cc)
+                           const unsigned int nn_children=child->n_children();
+                           for (unsigned int cc=0; cc<nn_children; ++cc)
                              {
                                cell_iterator grand_child=child->child(cc);
                                Assert(grand_child->active(), ExcInternalError());
@@ -8850,50 +11272,404 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
                  }
              }
        }
+
+                                      //////////////////////////////////
+                                      //
+                                      //  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
-      for (active_cell_iterator cell = last_active(); cell != end(); --cell)
-       if (cell->refine_flag_set() == true) 
-         {
-                                            // loop over neighbors of cell
-           for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
-             if (cell->neighbor(i).state() == IteratorState::valid)
-               {
-                                                  // regularisation?
-                 if ((cell->neighbor_level(i) == cell->level()-1)
-                     &&
-                     (cell->neighbor(i)->refine_flag_set() == false))
-                   {
-                     cell->neighbor(i)->clear_coarsen_flag();
-                     cell->neighbor(i)->set_refine_flag();
-                   }
-                 else
-                   if ((cell->neighbor_level(i) == cell->level())
-                       &&
-                       (cell->neighbor(i)->coarsen_flag_set() == true))
-                                                      // if this cell will
-                                                      // be refined and the
-                                                      // neighbor may or may
-                                                      // not be coarsened
-                                                      // (depending on whether
-                                                      // all children of its
-                                                      // mother cell are tagged
-                                                      // for coarsening), then
-                                                      // disallow coarsening.
-                                                      // to do so, it suffices
-                                                      // to delete the coarsen
-                                                      // flag from one child,
-                                                      // namely our present
-                                                      // neighbor
-                     cell->neighbor(i)->clear_coarsen_flag ();
-               }
-         }
-
+                                      //
+                                      //    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>::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
@@ -8907,7 +11683,6 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
                                       //    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];
@@ -8922,8 +11697,8 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
 
                                       // set the flags for the next loop
                                       // already
-      flags_before_loop[0] = flags_after_loop[0];
-      flags_before_loop[1] = flags_after_loop[1];
+      flags_before_loop[0].swap(flags_after_loop[0]);
+      flags_before_loop[1].swap(flags_after_loop[1]);
     }
   while (mesh_changed_in_this_loop);
 
@@ -8942,24 +11717,51 @@ bool Triangulation<dim>::prepare_coarsening_and_refinement ()
 #if deal_II_dimension == 3
 
 template <>
-void Triangulation<3>::count_cells_at_line (std::vector<unsigned int> &cell_count)
+void Triangulation<3>::count_cells_at_line (std::vector<unsigned int> &line_cell_count)
 {
-  cell_count.clear();
-  cell_count.resize(n_raw_lines(),0);
+  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)
-      ++cell_count[cell->line_index(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_line (std::vector<unsigned int> &cell_count)
+void Triangulation<dim>::count_cells_at_quad (std::vector<unsigned int> &quad_cell_count)
 {
   Assert(false, ExcNotImplemented());
-  cell_count.clear();
+  quad_cell_count.clear();
 }
 
 #endif
@@ -8970,9 +11772,9 @@ void Triangulation<dim>::count_cells_at_line (std::vector<unsigned int> &cell_co
 
 template <>
 void Triangulation<1>::delete_children (cell_iterator &cell,
+                                       std::vector<unsigned int> &,
                                        std::vector<unsigned int> &)
 {
-  const unsigned int dim=1;
                                   // first we need to reset the
                                   // neighbor pointers of the
                                   // neighbors of this cell's
@@ -9043,15 +11845,14 @@ void Triangulation<1>::delete_children (cell_iterator &cell,
 
                                   // delete the vertex which will not
                                   // be needed anymore. This vertex
-                                  // is the second of the second line
-                                  // of the first child
+                                  // 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<GeometryInfo<dim>::children_per_cell; ++child)
+  for (unsigned int child=0; child<cell->n_children(); ++child)
     {
       cell->child(child)->clear_user_data();
       cell->child(child)->clear_user_flag();
@@ -9060,7 +11861,7 @@ void Triangulation<1>::delete_children (cell_iterator &cell,
 
 
                                   // delete pointer to children
-  cell->set_children (-1);
+  cell->clear_children ();
   cell->clear_user_flag();
 }
 
@@ -9071,391 +11872,1475 @@ void Triangulation<1>::delete_children (cell_iterator &cell,
 
 template <>
 void Triangulation<2>::delete_children (cell_iterator &cell,
+                                       std::vector<unsigned int> &,
                                        std::vector<unsigned int> &)
 {
   const unsigned int dim=2;
-                                  // 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.  For two or
-                                  // more dimensions, the neighbors
-                                  // of the children may only be on
-                                  // the same level or on the level
-                                  // of this cell (the case that the
-                                  // neighbors are more refined than
-                                  // the children was eliminated in
-                                  // @p{prepare_coarsening}
-  for (unsigned int child=0; child<GeometryInfo<dim>::children_per_cell; ++child)
-    for (unsigned int n=0; n<GeometryInfo<dim>::faces_per_cell;
-        ++n)
+  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))
       {
-       const cell_iterator neighbor = cell->child(child)->neighbor(n);
-                                        // do nothing if at boundary
-       if (neighbor.state() != IteratorState::valid)
-         continue;
+       if (GeometryInfo<dim>::face_refinement_case(ref_case, face_no)
+           ==RefinementCase<dim>::no_refinement)
+         cell->set_neighbor(face_no,cell->child(face_no%2)->neighbor(face_no));
+       
+       cell_iterator neighbor=cell->neighbor(face_no);
        
-       Assert ((neighbor->level()==cell->level()) ||
-               (neighbor->level()==cell->level()+1),
-               ExcInternalError());
+                                        // 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.
        
-                                        // if the neighbor's level is
-                                        // the same as that of
-                                        // @p{cell}, then it's
-                                        // neighbor pointers points
-                                        // to this cell rather than
-                                        // to this cell's child. In
-                                        // that case we need not do
-                                        // anything.  If the neighbor
-                                        // is refined as often as are
-                                        // the children, we need to
-                                        // reset those neigbor
-                                        // pointers that point to the
-                                        // child of this cell; when
-                                        // resetting the neighbor
-                                        // pointers of neighbors of
-                                        // one of the children, we
-                                        // will also reset the
-                                        // neighbor pointers other
-                                        // children to the present
-                                        // cell, but this does no
-                                        // harm since we delete the
-                                        // children afterwards anyway
-       if (neighbor->level() == cell->level()+1)
-         for (unsigned int neighbor_neighbor=0;
-              neighbor_neighbor<GeometryInfo<dim>::faces_per_cell;
-              ++neighbor_neighbor)
-           if (neighbor->neighbor(neighbor_neighbor) == cell->child(child))
-             neighbor->set_neighbor(neighbor_neighbor, cell);
+                                        // 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>::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>::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
-  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();
-
-                                  // for the four faces: if the
-                                  // neighbor does not itself need
-                                  // the subfaces, delete them. note
-                                  // that since dim>1 the level of a
-                                  // neighbor is either one less or
-                                  // the same as that of cell
+                                  // 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)->level() == cell->level()-1) ||
-       ((cell->neighbor(face)->level() == cell->level()) &&
-        !cell->neighbor(face)->has_children()))
+    if (((cell->neighbor(face).state() != IteratorState::valid) ||
+        (!cell->neighbor(face)->has_children())) &&
+       (GeometryInfo<dim>::face_refinement_case(ref_case,face)
+        !=RefinementCase<dim>::no_refinement))
       {
+       line_iterator line=cell->face(face);
                                         // delete middle vertex
-       vertices_used[cell->face(face)->child(0)->vertex_index(1)] = false;
+       vertices_used[line->child(0)->vertex_index(1)] = false;
                                         // delete the two subfaces
        for (unsigned int subface=0;
-            subface<GeometryInfo<dim>::subfaces_per_face; ++subface)
+            subface<line->n_children(); ++subface)
          {
-           cell->face(face)->child(subface)->clear_user_data ();
-           cell->face(face)->child(subface)->clear_user_flag ();
-           cell->face(face)->child(subface)->clear_used_flag ();
+           line->child(subface)->clear_user_data ();
+           line->child(subface)->clear_user_flag ();
+           line->child(subface)->clear_used_flag ();
          }
        
-       cell->face(face)->clear_children();
+       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 (static_cast<unsigned char> (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<GeometryInfo<dim>::children_per_cell; ++child)
+  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->set_children (-1);
-  cell->clear_user_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>::no_refinement,
+            ExcInternalError());
+
+      switch (static_cast<unsigned char> (quad->refinement_case()))
+       {
+         case RefinementCase<dim>::no_refinement:
+                                                // nothing to do as the quad
+                                                // is not refined
+               break;
+         case RefinementCase<dim>::cut_x:
+         case RefinementCase<dim>::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<dim>::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<dim>::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<dim>::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<dim>::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>::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<dim>::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
 
-#endif
+   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.
 
-#if deal_II_dimension == 3
+   Convention:
+   The created children are numbered like this:
 
+   .--.--.
+   |2 . 3|
+   .--.--.
+   |0 | 1|
+   .--.--.
+*/
 
-template <>
-void Triangulation<3>::delete_children (cell_iterator &cell,
-                                       std::vector<unsigned int> &cell_count)
-{
-  const unsigned int dim=3;
-  Assert(cell_count.size()==n_raw_lines(), ExcInternalError());
-  
-                                  // 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.  For two or
-                                  // more dimensions, the neighbors
-                                  // of the children may only be on
-                                  // the same level or on the level
-                                  // of this cell (the case that the
-                                  // neighbors are more refined than
-                                  // the children was eliminated in
-                                  // @p{prepare_coarsening}
-  for (unsigned int child=0; child<GeometryInfo<dim>::children_per_cell; ++child)
-    for (unsigned int n=0; n<GeometryInfo<dim>::faces_per_cell; ++n)
-      {
-       const cell_iterator neighbor = cell->child(child)->neighbor(n);
-                                        // do nothing if at boundary
-       if (neighbor.state() != IteratorState::valid)
-         continue;
-       
-       Assert ((neighbor->level()==cell->level()) ||
-               (neighbor->level()==cell->level()+1),
-               ExcInternalError());
-       
-                                        // if the neighbor's level is
-                                        // the same as that of
-                                        // @p{cell}, then it's
-                                        // neighbor pointers points
-                                        // to this cell rather than
-                                        // to this cell's child. In
-                                        // that case we need not do
-                                        // anything.  If the neighbor
-                                        // is refined as often as are
-                                        // the children, we need to
-                                        // reset those neigbor
-                                        // pointers that point to the
-                                        // child of this cell; when
-                                        // resetting the neighbor
-                                        // pointers of neighbors of
-                                        // one of the children, we
-                                        // will also reset the
-                                        // neighbor pointers other
-                                        // children to the present
-                                        // cell, but this does no
-                                        // harm since we delete the
-                                        // children afterwards anyway
-       if (neighbor->level() == cell->level()+1)
-         for (unsigned int neighbor_neighbor=0;
-              neighbor_neighbor<GeometryInfo<dim>::faces_per_cell;
-              ++neighbor_neighbor)
-           if (neighbor->neighbor(neighbor_neighbor) == cell->child(child))
-             neighbor->set_neighbor(neighbor_neighbor, cell);
-      }
+                                  // 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;
 
-                                  // 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;
+      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;
+    
 
-                                  ///////////////////////////////////////
-                                  // delete interior quads and lines
-                                  //
-                                  // first set up a list of these
-                                  // line's and quad's indices
-  const quad_iterator interior_quads[12]
-    = {  cell->child(0)->face(1),
-        cell->child(2)->face(1),
-        cell->child(4)->face(1),
-        cell->child(6)->face(1),
-
-        cell->child(0)->face(3),
-        cell->child(1)->face(3),
-        cell->child(4)->face(3),
-        cell->child(5)->face(3),
-
-        cell->child(0)->face(5),
-        cell->child(1)->face(5),
-        cell->child(2)->face(5),
-        cell->child(3)->face(5) 
-    };
-
-  const line_iterator interior_lines[6]
-    = {  cell->child(0)->line(5),
-        cell->child(0)->line(7),
-        cell->child(0)->line(11),
-
-        cell->child(7)->line(0),
-        cell->child(7)->line(2),
-        cell->child(7)->line(8),
-    };
-
-                                  // clear user pointers, to avoid that
-                                  // they may appear at unwanted places
-                                  // later on...
-                                  // same for user flags, then finally
-                                  // delete thes quads and lines
-  for (unsigned int q=0; q<12; ++q)
+                                      // 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
+           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)
     {
-      interior_quads[q]->clear_user_data();
-      interior_quads[q]->clear_user_flag();
-      interior_quads[q]->clear_used_flag();
+      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;
 
-  for (unsigned int l=0; l<6; ++l)
+      Assert (new_lines[l]->used() == false,
+             ExcCellShouldBeUnused());
+    }
+           
+  if (ref_case==RefinementCase<dim>::cut_xy)
     {
-      interior_lines[l]->clear_user_data();
-      interior_lines[l]->clear_user_flag();
-      interior_lines[l]->clear_used_flag();
+                                      //   .-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]));
     }
-
-                                  // for the six faces: if the
-                                  // neighbor does not itself need
-                                  // the subfaces, delete them. note
-                                  // that since dim>1 the level of a
-                                  // neighbor is either one less or
-                                  // the same as that of cell
-  for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face) 
-    if ((cell->neighbor(face).state() != IteratorState::valid) ||
-       (cell->neighbor(face)->level() == cell->level()-1) ||
-       ((cell->neighbor(face)->level() == cell->level()) &&
-        !cell->neighbor(face)->has_children()))
-      {
-       quad_iterator quad = cell->face(face);
-       
-                                        // delete middle vertex
-       vertices_used[quad->child(0)->vertex_index(3)] = false;
-
-       const line_iterator interior_lines[4]
-         = { quad->child(0)->line(1),
-             quad->child(0)->line(3),
-             quad->child(3)->line(0),
-             quad->child(3)->line(2) 
-         };
-
-                                        // delete interior lines
-       for (unsigned int l=0; l<4; ++l)
-         {
-           interior_lines[l]->clear_user_data ();
-           interior_lines[l]->clear_user_flag ();
-           interior_lines[l]->clear_used_flag ();
-         }
-       
-                                        // delete the four subfaces
-       for (unsigned int subface=0;
-            subface<GeometryInfo<dim>::subfaces_per_face; ++subface)
-         {
-           quad->child(subface)->clear_user_data ();
-           quad->child(subface)->clear_user_flag ();
-           quad->child(subface)->clear_used_flag ();
-         }
-       
-       quad->clear_children();
-      }
-
-                                  // invalidate children
-  for (unsigned int child=0; child<GeometryInfo<dim>::children_per_cell; ++child)
+  else if (ref_case==RefinementCase<dim>::cut_x)
     {
-      cell->child(child)->clear_user_data();
-      cell->child(child)->clear_user_flag();
+                                      //   .-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 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();
+  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;
+    }
 
-                                  // delete pointer to children
-  cell->clear_children ();
-  cell->clear_user_flag();
+  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()));
+    }
+           
 
-                                  // now there still are the 12 lines of this
-                                  // hex which are refined and which may need
-                                  // coarsening. As we got the number of cells
-                                  // containing this line, we can simply use
-                                  // that information here.
-
-                                  // if in debug mode: make sure that
-                                  // none of the lines of this cell
-                                  // is twice refined; else, deleting
-                                  // this cell's children will result
-                                  // in an invalid state. also 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<12; ++line_no)
+  for (unsigned int i=0; i<n_children; ++i)
     {
-      line_iterator line=cell->line(line_no);
-      
-      Assert (line->has_children(),
-              ExcInternalError());
-      for (unsigned int c=0; c<2; ++c)
-       {
-         Assert (!line->child(c)->has_children(),
-                 ExcInternalError());
-                                          // decrease the number of cells
-                                          // referencing this line by one, as
-                                          // one of those was one of our former
-                                          // children
-         --cell_count[line->child_index(c)];
-       }
-                                      // the cell counters for both
-                                      // line_children have to be the same
-      Assert(cell_count[line->child_index(0)] ==
-            cell_count[line->child_index(1)],
-            ExcInternalError());
+      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);
       
-      if (cell_count[line->child_index(0)]==0)
+      else
+                                        // neighbor exists
        {
-                                          // 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;
-               
-         for (unsigned int child=0; child<2; ++child)
+                                          // 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())
            {
-             line->child(child)->clear_user_data();
-             line->child(child)->clear_user_flag();
-             line->child(child)->clear_used_flag();
+                                              // 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   |
+                                                  // |       |       |
+                                                  // |       |       |
+                                                  //  ---------------
                
-         line->clear_children();
-       }
+                                                  // 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>::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            
+}
 #endif
 
 
+
 template <int dim>
 void Triangulation<dim>::write_bool_vector (const unsigned int  magic_number1,
                                            const std::vector<bool> &v,
@@ -9869,6 +13754,339 @@ 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>::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>::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 (static_cast<unsigned char> (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>;
index 5b4a937e9d3ee05fc6d14b0613b8e65b27cfc19b..9605514cc9f36cd21521baa7c0388b7073ad24ae 100644 (file)
@@ -31,6 +31,97 @@ template <int structdim,int dim>
 const unsigned int TriaAccessor<structdim,dim>::objectdim;
 
 
+// anonymous namespace with two little 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)
+  {
+    Assert(face->has_children(), ExcInternalError());
+    Assert(subface_no<face->n_children(), ExcInternalError());
+
+    if(face->child(subface_no)->has_children())
+                                      // although the subface is refine, it
+                                      // still matches the face of the cell
+                                      // invoking the
+                                      // neighbor_of_coarser_neighbor
+                                      // function. this means that we are
+                                      // looking from one cell (anisotropic
+                                      // child) to a coarser neighbor which is
+                                      // refined stronger than we are
+                                      // (isotropically). So we won't be able
+                                      // to use the neighbor_child_on_subface
+                                      // function anyway, as the neighbor is
+                                      // not active. In this case, simply
+                                      // return the subface_no.
+      return subface_no;
+    
+    const bool first_child_has_children=face->child(0)->has_children();
+                                    // if the first child has children
+                                    // (FaceRefineCase case_x1y or case_y1x),
+                                    // then the current subface_no needs to be
+                                    // 1 and the result of this function is 2,
+                                    // else simply return the given number,
+                                    // which is 0 or 1 in an anisotropic case
+                                    // (case_x, case_y, casex2y or casey2x) or
+                                    // 0...3 in an isotropic case (case_xy)
+    return subface_no + first_child_has_children;
+  }
+
+
+  
+                                  // given the number of face's child
+                                  // (subface_no) and grandchild
+                                  // (subsubface_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,
+                                   const unsigned int                               subsubface_no)
+  {
+    Assert(face->has_children(), ExcInternalError());
+                                    // the subface must be refined, otherwise
+                                    // we would have ended up in the second
+                                    // function of this name...
+    Assert(face->child(subface_no)->has_children(), ExcInternalError());
+    Assert(subsubface_no<face->child(subface_no)->n_children(), ExcInternalError());
+                                    // This can only be an anisotropic refinement case
+    Assert(face->refinement_case() < RefinementCase<2>::isotropic_refinement,
+          ExcInternalError());
+    
+    const bool first_child_has_children=face->child(0)->has_children();
+
+    const unsigned int e = deal_II_numbers::invalid_unsigned_int;
+    
+                                    // array containing the translation of the
+                                    // numbers,
+                                    //
+                                    // 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]
+      =
+      {{{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
+       {{1,2},       // second subface, first  subsubface, first_child_has_children==no and yes
+       {2,3}}};     // second subface, second subsubface, first_child_has_children==no and yes
+    
+    Assert(translated_subface_no[subface_no][subsubface_no][first_child_has_children]!=e,
+          ExcInternalError());
+
+    return translated_subface_no[subface_no][subsubface_no][first_child_has_children];
+  }
+}
+
+
+
+
+
 /*------------------------ Functions: LineAccessor ---------------------------*/
 
 template <int dim>
@@ -224,9 +315,10 @@ TriaObjectAccessor<1, dim>::recursively_clear_user_index () const
 
 
 template <int dim>
-void TriaObjectAccessor<1, dim>::set_children (const int index) const
+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));
@@ -239,7 +331,7 @@ void TriaObjectAccessor<1, dim>::set_children (const int index) const
 template <int dim>
 void TriaObjectAccessor<1, dim>::clear_children () const
 {
-  set_children (-1);
+  set_children (0,-1);
 }
 
 
@@ -538,15 +630,18 @@ TriaObjectAccessor<2, dim>::recursively_clear_user_index () const
 
 
 template <int dim>
-void TriaObjectAccessor<2, dim>::set_children (const int index) const
+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) ||
-         (!has_children() && (index>=0)),
+         (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[this->present_index] = index;
+  objects().children[2*this->present_index+i/2] = index;
 }
 
 
@@ -554,7 +649,8 @@ void TriaObjectAccessor<2, dim>::set_children (const int index) const
 template <int dim>
 void TriaObjectAccessor<2, dim>::clear_children () const
 {
-  set_children (-1);
+  set_children (0, -1);
+  set_children (2, -1);
 }
 
 
@@ -1079,14 +1175,18 @@ TriaObjectAccessor<3, dim>::recursively_clear_user_index () const
 #if deal_II_dimension == 3
 
 template <>
-void TriaObjectAccessor<3, 3>::set_children (const int index) const
+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) ||
-         (!has_children() && (index>=0)),
+         (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[this->present_index] = index;
+  this->tria->levels[this->present_level]->cells.children[4*this->present_index+i/2] = index;
 }
 
 #endif
@@ -1095,7 +1195,10 @@ void TriaObjectAccessor<3, 3>::set_children (const int index) const
 template <int dim>
 void TriaObjectAccessor<3, dim>::clear_children () const
 {
-  set_children (-1);
+  set_children (0,-1);
+  set_children (2,-1);
+  set_children (4,-1);
+  set_children (6,-1);
 }
 
 
@@ -2201,12 +2304,8 @@ void CellAccessor<dim>::set_neighbor (const unsigned int i,
 
 
 template <int dim>
-unsigned int CellAccessor<dim>::neighbor_of_neighbor (const unsigned int neighbor) const
+unsigned int CellAccessor<dim>::neighbor_of_neighbor_internal (const unsigned int neighbor) const
 {
-                                  // make sure that the neighbor is
-                                  // not on a coarser level
-  Assert (neighbor_level(neighbor) == this->present_level,
-         TriaAccessorExceptions::ExcNeighborIsCoarser());
   Assert (neighbor < GeometryInfo<dim>::faces_per_cell,
          TriaAccessorExceptions::ExcInvalidNeighbor(neighbor));
 
@@ -2235,39 +2334,129 @@ unsigned int CellAccessor<dim>::neighbor_of_neighbor (const unsigned int neighbo
     = GeometryInfo<dim>::opposite_face[neighbor];
   
   if (neighbor_cell->face_index (neighbor_guess) == this_face_index)
-      return neighbor_guess;
+    return neighbor_guess;
   else
                                     // if the guess was false, then
                                     // we need to loop over all
                                     // neighbors and find the number
                                     // the hard way
     {
-      for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-       if (neighbor_cell->face_index (face) == this_face_index)
-         return face;
-
-                                      // we should never get here,
-                                      // since then we did not find
-                                      // our way back...
-      Assert (false, ExcInternalError());
+      for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
+       if (neighbor_cell->face_index (face_no) == this_face_index)
+         return face_no;
+
+                                      // running over all neighbors
+                                      // faces we did not find the
+                                      // present face. Thereby the
+                                      // neighbor must be coarser
+                                      // than the present
+                                      // cell. Return an invalid
+                                      // unsigned int in this case.
       return numbers::invalid_unsigned_int;
     }
 }
 
 
 
+template <int dim>
+unsigned int CellAccessor<dim>::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());
+
+  return n2;
+}
+
+
+
+template <int dim>
+bool
+CellAccessor<dim>::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>
 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_level(neighbor) < this->present_level,
+  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);
+  
+                                  // 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);
+  
+  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);
+       }
+    }
+  
+                                  // 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));
-  Assert (dim>1, ExcImpossibleInDim(dim));
-  
+                                  // make sure that the neighbor is
+                                  // on a coarser level
+  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);
   
@@ -2279,7 +2468,7 @@ CellAccessor<dim>::neighbor_of_coarser_neighbor (const unsigned int neighbor) co
                                   // we want to know the
                                   // neighbor_of_neighbor if
                                   // neighbor==1 (the right
-                                  // neighbor), then we will get 3
+                                  // neighbor), then we will get 0
                                   // (the left neighbor) in most
                                   // cases. look up this relationship
                                   // in the table provided by
@@ -2293,15 +2482,22 @@ CellAccessor<dim>::neighbor_of_coarser_neighbor (const unsigned int neighbor) co
   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 the result, but don't forget
-                                        // to take care of possible rotation,
-                                        // flip and wrong orientation of the
-                                        // neighbor's face...
-       return std::make_pair (face_no_guess,
-                              GeometryInfo<dim>::real_to_standard_face_vertex(subface_no,
-                                                                              neighbor_cell->face_orientation(face_no_guess),
-                                                                              neighbor_cell->face_flip(face_no_guess),
-                                                                              neighbor_cell->face_rotation(face_no_guess)));
+                                            // 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
@@ -2316,15 +2512,20 @@ CellAccessor<dim>::neighbor_of_coarser_neighbor (const unsigned int neighbor) co
          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 the result, but don't forget
-                                                // to take care of possible rotation,
-                                                // flip and wrong orientation of the
-                                                // neighbor's face...
-               return std::make_pair (face_no,
-                                      GeometryInfo<dim>::real_to_standard_face_vertex(subface_no,
-                                                                                      neighbor_cell->face_orientation(face_no),
-                                                                                      neighbor_cell->face_flip(face_no),
-                                                                                      neighbor_cell->face_rotation(face_no)));
+                                            // 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));
        }
     }
   
@@ -2336,6 +2537,8 @@ CellAccessor<dim>::neighbor_of_coarser_neighbor (const unsigned int neighbor) co
                         numbers::invalid_unsigned_int);
 }
 
+#endif
+
 
 
 template <int dim>
@@ -2398,17 +2601,33 @@ neighbor_child_on_subface (const unsigned int face,
           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)->level() == this->level(),
-          ExcMessage ("The neighbor must be on the same level as this cell!"));
   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(neighbor_neighbor,subface);
-
-  return this->neighbor(face)->child(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())
+    {
+      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));
+      
+    }
+  
+  return sub_neighbor;
 }
 
 #endif
@@ -2425,58 +2644,312 @@ neighbor_child_on_subface (const unsigned int face,
           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)->level() == this->level(),
-          ExcMessage ("The neighbor must be on the same level as this cell!"));
   Assert (this->neighbor(face)->has_children() == true,
           ExcMessage ("The neighbor must have children!"));
-                                  // this function returns they neighbor's
+                                  // this function returns the neighbor's
                                   // child on a given face and
-                                  // subface. However, irrespective of the
-                                  // actual face orientation, flip and rotation
-                                  // of the cells face it returns that child,
-                                  // which is neighboring the subface which
-                                  // would be subface number @p subface, if the
-                                  // face was in standard orientation. thus,
-                                  // our first task is to extract the
-                                  // information, which real_subface_no
-                                  // corresponds to that for the actual face,
-                                  // which might have non-standard orientation,
-                                  // flip and rotation.
-
-                                  // to this end: the subfaces are numbered
-                                  // according to the vertices of the
-                                  // face. thus we can use the
-                                  // standard_to_real_face_vertex function in
-                                  // GeometryInfo<dim> to translate the given
-                                  // subface to the real_subface_no
-  unsigned int real_subface_no=GeometryInfo<3>::
-                              standard_to_real_face_vertex(subface,
-                                                           this->face_orientation(face),
-                                                           this->face_flip(face),
-                                                           this->face_rotation(face));
-                                  // get the neighbor's number for the given
-                                  // face and the neighbor
-  const unsigned int neighbor_neighbor
-    = this->neighbor_of_neighbor (face);
+                                  // 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());
+  
+  unsigned int neighbor_neighbor;
+  TriaIterator<3,CellAccessor<3> > neighbor_child;
   const TriaIterator<3,CellAccessor<3> > neighbor=this->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_neighbor, real_subface_no,
-                                         neighbor->face_orientation(neighbor_neighbor),
-                                         neighbor->face_flip(neighbor_neighbor),
-                                         neighbor->face_rotation(neighbor_neighbor));
-  const TriaIterator<3,CellAccessor<3> > 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(real_subface_no) ==
-         neighbor_child->face(neighbor_neighbor)),
-         ExcInternalError());
+  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);
+      
+                                      // 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);
+       }
+      
+      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)
+             {
+               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;
+  
 }
 
 #endif
index bd8c62523c422fe99902feea52e60b14b39dd704..7e33d3d3df14376cecdbff1dba219ceda86581d3 100644 (file)
@@ -39,7 +39,7 @@ namespace internal
           refine_flags.reserve (total_cells);
           refine_flags.insert (refine_flags.end(),
                                total_cells - refine_flags.size(),
-                               false);
+                               RefinementCase<dim>::no_refinement);
       
           coarsen_flags.reserve (total_cells);
           coarsen_flags.insert (coarsen_flags.end(),
@@ -70,8 +70,8 @@ namespace internal
                                        // they may over-allocate by up to
                                        // as many elements as an integer
                                        // has bits
-      Assert (refine_flags.size() <= refine_flags.capacity() + sizeof(int)*8 ||
-              refine_flags.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
+      Assert (refine_flags.size() <=
+             refine_flags.capacity()  + DEAL_II_MIN_VECTOR_CAPACITY,
               ExcMemoryWasted ("refine_flags",
                                refine_flags.size(), refine_flags.capacity()));
       Assert (coarsen_flags.size() <= coarsen_flags.capacity() + sizeof(int)*8 ||
@@ -97,10 +97,10 @@ namespace internal
     unsigned int
     TriaLevel<dim>::memory_consumption () const
     {
-      return (MemoryConsumption::memory_consumption (refine_flags) +
-              MemoryConsumption::memory_consumption (coarsen_flags) +
+      return (MemoryConsumption::memory_consumption (coarsen_flags) +
               MemoryConsumption::memory_consumption (neighbors) +
-              MemoryConsumption::memory_consumption (cells));
+              MemoryConsumption::memory_consumption (cells) +
+              MemoryConsumption::memory_consumption (refine_flags));
     }
 
 // This specialization should be only temporary, until the TriaObjects
@@ -123,7 +123,7 @@ namespace internal
           refine_flags.reserve (total_cells);
           refine_flags.insert (refine_flags.end(),
                                total_cells - refine_flags.size(),
-                               false);
+                               RefinementCase<3>::no_refinement);
       
           coarsen_flags.reserve (total_cells);
           coarsen_flags.insert (coarsen_flags.end(),
@@ -153,8 +153,8 @@ namespace internal
                                        // they may over-allocate by up to
                                        // as many elements as an integer
                                        // has bits
-      Assert (refine_flags.size() <= refine_flags.capacity() + sizeof(int)*8 ||
-              refine_flags.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
+      Assert (refine_flags.size() <=
+             refine_flags.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
               ExcMemoryWasted ("refine_flags",
                                refine_flags.size(), refine_flags.capacity()));
       Assert (coarsen_flags.size() <= coarsen_flags.capacity() + sizeof(int)*8 ||
@@ -179,10 +179,10 @@ namespace internal
     unsigned int
     TriaLevel<3>::memory_consumption () const
     {
-      return (MemoryConsumption::memory_consumption (refine_flags) +
-              MemoryConsumption::memory_consumption (coarsen_flags) +
+      return (MemoryConsumption::memory_consumption (coarsen_flags) +
               MemoryConsumption::memory_consumption (neighbors) +
-              MemoryConsumption::memory_consumption (cells));
+              MemoryConsumption::memory_consumption (cells) +
+              MemoryConsumption::memory_consumption (refine_flags));
     }
 
 #endif
diff --git a/deal.II/deal.II/source/grid/tria_objects.all_dimensions.cc b/deal.II/deal.II/source/grid/tria_objects.all_dimensions.cc
new file mode 100644 (file)
index 0000000..4950342
--- /dev/null
@@ -0,0 +1,595 @@
+//---------------------------------------------------------------------------
+//    $Id$
+//    Version: $Name$
+//
+//    Copyright (C) 2006, 2007 by the deal.II authors
+//
+//    This file is subject to QPL and may not be  distributed
+//    without copyright and license information. Please refer
+//    to the file deal.II/doc/license.html for the  text  and
+//    further information on this license.
+//
+//---------------------------------------------------------------------------
+
+
+#include <base/memory_consumption.h>
+#include <grid/tria_objects.h>
+#include <grid/tria.h>
+#include <grid/tria_iterator.h>
+#include <grid/tria_accessor.h>
+
+#include <algorithm>
+#include <functional>
+
+    
+
+DEAL_II_NAMESPACE_OPEN
+
+namespace internal
+{
+  namespace Triangulation
+  {    
+    template<>
+    void
+    TriaObjects<TriaObject<1> >::reserve_space (const unsigned int new_lines_in_pairs,
+                                     const unsigned int new_lines_single)
+    {
+      Assert(new_lines_in_pairs%2==0, ExcInternalError());
+
+      next_free_single=0;
+      next_free_pair=0;
+      reverse_order_next_free_single=false;
+      
+                                      // count the number of lines, of
+                                      // unused single lines and of
+                                      // unused pairs of lines
+      unsigned int n_lines=0;
+      unsigned int n_unused_pairs=0;
+      unsigned int n_unused_singles=0;
+      for (unsigned int i=0; i<used.size(); ++i)
+       {
+         if (used[i])
+           ++n_lines;
+         else if (i+1<used.size())
+           {
+             if (used[i+1])
+               {
+                 ++n_unused_singles;
+                 if (next_free_single==0)
+                   next_free_single=i;
+               }
+             else
+               {
+                 ++n_unused_pairs;
+                 if (next_free_pair==0)
+                   next_free_pair=i;
+                 ++i;
+               }
+           }
+         else
+           ++n_unused_singles;
+       }
+      Assert(n_lines+2*n_unused_pairs+n_unused_singles==used.size(),
+            ExcInternalError());
+
+                                      // how many single lines are needed in
+                                      // addition to n_unused_singles?
+      const int additional_single_lines=
+       new_lines_single-n_unused_singles;
+
+      unsigned int new_size=
+       used.size() + new_lines_in_pairs - 2*n_unused_pairs;
+      if (additional_single_lines>0)
+       new_size+=additional_single_lines;
+
+                                       // only allocate space if necessary
+      if (new_size>cells.size()) 
+        {
+          cells.reserve (new_size);
+          cells.insert (cells.end(),
+                       new_size-cells.size(),
+                       TriaObject<1> ());
+  
+          used.reserve (new_size);
+          used.insert (used.end(),
+                      new_size-used.size(),
+                      false);
+  
+          user_flags.reserve (new_size);
+          user_flags.insert (user_flags.end(),
+                            new_size-user_flags.size(),
+                            false);
+      
+          children.reserve (new_size);
+          children.insert (children.end(),
+                          new_size-children.size(),
+                          -1);
+
+          material_id.reserve (new_size);
+          material_id.insert (material_id.end(),
+                             new_size-material_id.size(),
+                             255);
+
+          user_data.reserve (new_size);
+          user_data.insert (user_data.end(),
+                           new_size-user_data.size(),
+                           UserData());
+       }
+
+      if (n_unused_singles==0)
+       {
+         next_free_single=new_size-1;
+         reverse_order_next_free_single=true;
+       }
+    }
+
+
+    template<>
+    void
+    TriaObjects<TriaObject<2> >::reserve_space (const unsigned int new_quads_in_pairs,
+                                     const unsigned int new_quads_single)
+    {
+      Assert(new_quads_in_pairs%2==0, ExcInternalError());
+      
+      next_free_single=0;
+      next_free_pair=0;
+      reverse_order_next_free_single=false;
+
+                                      // count the number of lines, of
+                                      // unused single lines and of
+                                      // unused pairs of lines
+      unsigned int n_quads=0;
+      unsigned int n_unused_pairs=0;
+      unsigned int n_unused_singles=0;
+      for (unsigned int i=0; i<used.size(); ++i)
+       {
+         if (used[i])
+           ++n_quads;
+         else if (i+1<used.size())
+           {
+             if (used[i+1])
+               {
+                 ++n_unused_singles;
+                 if (next_free_single==0)
+                   next_free_single=i;
+               }
+             else
+               {
+                 ++n_unused_pairs;
+                 if (next_free_pair==0)
+                   next_free_pair=i;
+                 ++i;
+               }
+           }
+         else
+           ++n_unused_singles;
+       }
+      Assert(n_quads+2*n_unused_pairs+n_unused_singles==used.size(),
+            ExcInternalError());
+
+                                      // how many single quads are needed in
+                                      // addition to n_unused_quads?
+      const int additional_single_quads=
+       new_quads_single-n_unused_singles;
+
+      unsigned int new_size=
+       used.size() + new_quads_in_pairs - 2*n_unused_pairs;
+      if (additional_single_quads>0)
+       new_size+=additional_single_quads;
+
+                                       // only allocate space if necessary
+      if (new_size>cells.size())
+        {
+          cells.reserve (new_size);
+          cells.insert (cells.end(),
+                       new_size-cells.size(),
+                       TriaObject<2> ());
+      
+          used.reserve (new_size);
+          used.insert (used.end(),
+                      new_size-used.size(),
+                      false);
+  
+          user_flags.reserve (new_size);
+          user_flags.insert (user_flags.end(),
+                            new_size-user_flags.size(),
+                            false);
+  
+          children.reserve (2*new_size);
+          children.insert (children.end(),
+                          2*new_size-children.size(),
+                          -1);
+
+         refinement_cases.reserve (new_size);
+         refinement_cases.insert (refinement_cases.end(),
+                              new_size - refinement_cases.size(),
+                              RefinementCase<2>::no_refinement);
+         
+
+          material_id.reserve (new_size);
+          material_id.insert (material_id.end(),
+                             new_size-material_id.size(),
+                             255);
+
+          user_data.reserve (new_size);
+          user_data.insert (user_data.end(),
+                           new_size-user_data.size(),
+                           UserData());
+        }
+
+      if (n_unused_singles==0)
+       {
+         next_free_single=new_size-1;
+         reverse_order_next_free_single=true;
+       }
+    }
+
+
+    void
+    TriaObjectsHex::reserve_space (const unsigned int new_hexes)
+    {
+      const unsigned int new_size = new_hexes +
+                                    std::count_if (used.begin(),
+                                                   used.end(),
+                                                   std::bind2nd (std::equal_to<bool>(), true));
+
+                                       // see above...
+      if (new_size>cells.size())
+        {
+          cells.reserve (new_size);
+          cells.insert (cells.end(),
+                       new_size-cells.size(),
+                       TriaObject<3> ());
+      
+          used.reserve (new_size);
+          used.insert (used.end(),
+                      new_size-used.size(),
+                      false);
+  
+          user_flags.reserve (new_size);
+          user_flags.insert (user_flags.end(),
+                            new_size-user_flags.size(),
+                            false);
+  
+          children.reserve (4*new_size);
+          children.insert (children.end(),
+                          4*new_size-children.size(),
+                          -1);
+
+          material_id.reserve (new_size);
+          material_id.insert (material_id.end(),
+                             new_size-material_id.size(),
+                             255);
+
+          user_data.reserve (new_size);
+          user_data.insert (user_data.end(),
+                           new_size-user_data.size(),
+                           UserData());
+
+          face_orientations.reserve (new_size * GeometryInfo<3>::faces_per_cell);
+          face_orientations.insert (face_orientations.end(),
+                                   new_size * GeometryInfo<3>::faces_per_cell
+                                   - face_orientations.size(),
+                                   true);
+
+         refinement_cases.reserve (new_size);
+         refinement_cases.insert (refinement_cases.end(),
+                              new_size-refinement_cases.size(),
+                              RefinementCase<3>::no_refinement);
+
+          face_flips.reserve (new_size * GeometryInfo<3>::faces_per_cell);
+          face_flips.insert (face_flips.end(),
+                                   new_size * GeometryInfo<3>::faces_per_cell
+                                   - face_flips.size(),
+                                   false);
+          face_rotations.reserve (new_size * GeometryInfo<3>::faces_per_cell);
+          face_rotations.insert (face_rotations.end(),
+                                   new_size * GeometryInfo<3>::faces_per_cell
+                                   - face_rotations.size(),
+                                   false);
+        }
+      next_free_single=next_free_pair=0;
+    }
+
+
+    void
+    TriaObjectsQuad3D::reserve_space (const unsigned int new_quads_in_pairs,
+                                     const unsigned int new_quads_single)
+    {
+      Assert(new_quads_in_pairs%2==0, ExcInternalError());
+
+      next_free_single=0;
+      next_free_pair=0;
+      reverse_order_next_free_single=false;
+
+                                      // count the number of lines, of unused
+                                      // single lines and of unused pairs of
+                                      // lines
+      unsigned int n_quads=0;
+      unsigned int n_unused_pairs=0;
+      unsigned int n_unused_singles=0;
+      for (unsigned int i=0; i<used.size(); ++i)
+       {
+         if (used[i])
+           ++n_quads;
+         else if (i+1<used.size())
+           {
+             if (used[i+1])
+               {
+                 ++n_unused_singles;
+                 if (next_free_single==0)
+                   next_free_single=i;
+               }
+             else
+               {
+                 ++n_unused_pairs;
+                 if (next_free_pair==0)
+                   next_free_pair=i;
+                 ++i;
+               }
+           }
+         else
+           ++n_unused_singles;
+       }
+      Assert(n_quads+2*n_unused_pairs+n_unused_singles==used.size(),
+            ExcInternalError());
+
+                                      // how many single quads are needed in
+                                      // addition to n_unused_quads?
+      const int additional_single_quads=
+       new_quads_single-n_unused_singles;
+
+      unsigned int new_size=
+       used.size() + new_quads_in_pairs - 2*n_unused_pairs;
+      if (additional_single_quads>0)
+       new_size+=additional_single_quads;
+      
+                                       // see above...
+      if (new_size>cells.size())
+        {
+                                          // reseve space for the base class
+         TriaObjects<TriaObject<2> >::reserve_space(new_quads_in_pairs,new_quads_single);
+                                          // reserve the field of the derived
+                                          // class
+          line_orientations.reserve (new_size * GeometryInfo<2>::lines_per_cell);
+          line_orientations.insert (line_orientations.end(),
+                                   new_size * GeometryInfo<2>::lines_per_cell
+                                   - line_orientations.size(),
+                                   true);
+        }
+
+      if (n_unused_singles==0)
+       {
+         next_free_single=new_size-1;
+         reverse_order_next_free_single=true;
+       }
+    }
+    
+
+    template<>
+    void
+    TriaObjects<TriaObject<1> >::monitor_memory (const unsigned int) const
+    {
+                                       // check that we have not allocated
+                                       // too much memory. note that bool
+                                       // vectors allocate their memory in
+                                       // chunks of whole integers, so
+                                       // they may over-allocate by up to
+                                       // as many elements as an integer
+                                       // has bits
+      Assert (cells.size() <=
+             cells.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+              ExcMemoryWasted ("lines",
+                               cells.size(), cells.capacity()));
+      Assert (children.size() <=
+             children.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+              ExcMemoryWasted ("children",
+                               children.size(), children.capacity()));
+      Assert (used.size() <= used.capacity() + sizeof(int)*8 ||
+              used.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
+              ExcMemoryWasted ("used",
+                               used.size(), used.capacity()));
+      Assert (user_flags.size() <= user_flags.capacity() + sizeof(int)*8 ||
+              user_flags.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
+              ExcMemoryWasted ("user_flags",
+                               user_flags.size(), user_flags.capacity()));
+      Assert (cells.size() == used.size(),
+              ExcMemoryInexact (cells.size(), used.size()));
+      Assert (cells.size() == user_flags.size(),
+              ExcMemoryInexact (cells.size(), user_flags.size()));
+      Assert (cells.size() == children.size(),
+              ExcMemoryInexact (cells.size(), children.size()));
+      Assert (cells.size() == material_id.size(),
+              ExcMemoryInexact (cells.size(), material_id.size()));
+      Assert (cells.size() == user_data.size(),
+              ExcMemoryInexact (cells.size(), user_data.size()));
+    }
+
+
+    template<>
+    void
+    TriaObjects<TriaObject<2> >::monitor_memory (const unsigned int) const
+    {
+                                       // check that we have not allocated
+                                       // too much memory. note that bool
+                                       // vectors allocate their memory in
+                                       // chunks of whole integers, so
+                                       // they may over-allocate by up to
+                                       // as many elements as an integer
+                                       // has bits
+      Assert (cells.size() <=
+             cells.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+              ExcMemoryWasted ("quads",
+                               cells.size(), cells.capacity()));
+      Assert (children.size() <=
+             children.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+              ExcMemoryWasted ("children",
+                               children.size(), children.capacity()));
+      Assert (used.size() <= used.capacity() + sizeof(int)*8 ||
+              used.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
+              ExcMemoryWasted ("used",
+                               used.size(), used.capacity()));
+      Assert (user_flags.size() <= user_flags.capacity() + sizeof(int)*8 ||
+              user_flags.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
+              ExcMemoryWasted ("user_flags",
+                               user_flags.size(), user_flags.capacity()));
+      Assert (cells.size() == used.size(),
+              ExcMemoryInexact (cells.size(), used.size()));
+      Assert (cells.size() == user_flags.size(),
+              ExcMemoryInexact (cells.size(), user_flags.size()));
+      Assert (2*cells.size() == children.size(),
+              ExcMemoryInexact (cells.size(), children.size()));
+      Assert (cells.size() == refinement_cases.size(),
+              ExcMemoryInexact (cells.size(), refinement_cases.size()));
+      Assert (cells.size() == material_id.size(),
+              ExcMemoryInexact (cells.size(), material_id.size()));
+      Assert (cells.size() == user_data.size(),
+              ExcMemoryInexact (cells.size(), user_data.size()));
+    }
+
+
+    void
+    TriaObjectsHex::monitor_memory (const unsigned int) const
+    {
+                                       // check that we have not allocated
+                                       // too much memory. note that bool
+                                       // vectors allocate their memory in
+                                       // chunks of whole integers, so
+                                       // they may over-allocate by up to
+                                       // as many elements as an integer
+                                       // has bits
+      Assert (cells.size() <=
+             cells.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+              ExcMemoryWasted ("hexes",
+                               cells.size(), cells.capacity()));
+      Assert (children.size() <=
+             children.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+              ExcMemoryWasted ("children",
+                               children.size(), children.capacity()));
+      Assert (used.size() <= used.capacity() + sizeof(int)*8 ||
+              used.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
+              ExcMemoryWasted ("used",
+                               used.size(), used.capacity()));
+      Assert (user_flags.size() <= user_flags.capacity() + sizeof(int)*8 ||
+              user_flags.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
+              ExcMemoryWasted ("user_flags",
+                               user_flags.size(), user_flags.capacity()));
+      Assert (cells.size() == used.size(),
+              ExcMemoryInexact (cells.size(), used.size()));
+      Assert (cells.size() == user_flags.size(),
+              ExcMemoryInexact (cells.size(), user_flags.size()));
+      Assert (4*cells.size() == children.size(),
+              ExcMemoryInexact (cells.size(), children.size()));
+      Assert (cells.size() == material_id.size(),
+              ExcMemoryInexact (cells.size(), material_id.size()));
+      Assert (cells.size() == user_data.size(),
+              ExcMemoryInexact (cells.size(), user_data.size()));
+      Assert (cells.size() * GeometryInfo<3>::faces_per_cell
+              == face_orientations.size(),
+              ExcMemoryInexact (cells.size() * GeometryInfo<3>::faces_per_cell,
+                                face_orientations.size()));
+      Assert (cells.size() * GeometryInfo<3>::faces_per_cell
+              == face_flips.size(),
+              ExcMemoryInexact (cells.size() * GeometryInfo<3>::faces_per_cell,
+                                face_flips.size()));
+      Assert (cells.size() * GeometryInfo<3>::faces_per_cell
+              == face_rotations.size(),
+              ExcMemoryInexact (cells.size() * GeometryInfo<3>::faces_per_cell,
+                                face_rotations.size()));
+    }
+
+
+    void
+    TriaObjectsQuad3D::monitor_memory (const unsigned int) const
+    {
+                                       // check that we have not allocated
+                                       // too much memory. note that bool
+                                       // vectors allocate their memory in
+                                       // chunks of whole integers, so
+                                       // they may over-allocate by up to
+                                       // as many elements as an integer
+                                       // has bits
+      Assert (cells.size() * GeometryInfo<2>::lines_per_cell
+              == line_orientations.size(),
+              ExcMemoryInexact (cells.size() * GeometryInfo<2>::lines_per_cell,
+                                line_orientations.size()));
+      TriaObjects<TriaObject<2> >::monitor_memory (3);
+      
+    }
+
+
+    template <typename G>
+    void
+    TriaObjects<G>::clear()
+    {
+      cells.clear();
+      children.clear();
+      refinement_cases.clear();
+      used.clear();
+      user_flags.clear();
+      material_id.clear();
+      user_data.clear();
+      user_data_type = data_unknown;
+    }
+    
+
+    void
+    TriaObjectsHex::clear()
+    {
+      TriaObjects<TriaObject<3> >::clear();
+      face_orientations.clear();
+      face_flips.clear();
+      face_rotations.clear();
+    }
+
+
+    void
+    TriaObjectsQuad3D::clear()
+    {
+      TriaObjects<TriaObject<2> >::clear();
+      line_orientations.clear();
+    }
+    
+    
+    template<typename G>
+    unsigned int
+    TriaObjects<G>::memory_consumption () const
+    {
+      return (MemoryConsumption::memory_consumption (cells) +
+              MemoryConsumption::memory_consumption (children) +
+              MemoryConsumption::memory_consumption (used) +
+              MemoryConsumption::memory_consumption (user_flags) +
+              MemoryConsumption::memory_consumption (material_id) +
+              MemoryConsumption::memory_consumption (refinement_cases) +
+             user_data.capacity() * sizeof(UserData) + sizeof(user_data));
+    }
+  
+
+    unsigned int
+    TriaObjectsHex::memory_consumption () const
+    {
+      return (MemoryConsumption::memory_consumption (face_orientations) +
+             MemoryConsumption::memory_consumption (face_flips) +
+             MemoryConsumption::memory_consumption (face_rotations) +
+             TriaObjects<TriaObject<3> >::memory_consumption() );
+    }
+
+
+    unsigned int
+    TriaObjectsQuad3D::memory_consumption () const
+    {
+      return (MemoryConsumption::memory_consumption (line_orientations) +
+             this->TriaObjects<TriaObject<2> >::memory_consumption() );
+    }
+
+    
+
+                                    // explicit instantiations
+
+    template class TriaObjects<TriaObject<1> >;
+    template class TriaObjects<TriaObject<2> >;
+  }
+}
+
+DEAL_II_NAMESPACE_CLOSE
+
index 148eb1ab317cb334f64a47a729e1d5ac7d9fa470..16fe8d842f9361401e90c53a607ec5e98e73c12b 100644 (file)
@@ -14,9 +14,9 @@
 
 #include <base/memory_consumption.h>
 #include <grid/tria_objects.h>
-
-#include <algorithm>
-#include <functional>
+#include <grid/tria.h>
+#include <grid/tria_iterator.h>
+#include <grid/tria_accessor.h>
 
     
 
@@ -26,393 +26,262 @@ namespace internal
 {
   namespace Triangulation
   {    
-    template<>
-    void
-    TriaObjects<TriaObject<1> >::reserve_space (const unsigned int new_lines)
+    template <>
+    template <int dim>
+    typename dealii::Triangulation<dim>::raw_line_iterator
+    TriaObjects<TriaObject<1> >::next_free_single_line (const dealii::Triangulation<dim> &tria)
     {
-      const unsigned int new_size = new_lines +
-                                    std::count_if (used.begin(),
-                                                   used.end(),
-                                                   std::bind2nd (std::equal_to<bool>(), true));
-
-                                       // only allocate space if necessary
-      if (new_size>cells.size()) 
-        {
-          cells.reserve (new_size);
-          cells.insert (cells.end(),
-                       new_size-cells.size(),
-                       TriaObject<1> ());
-  
-          used.reserve (new_size);
-          used.insert (used.end(),
-                      new_size-used.size(),
-                      false);
-  
-          user_flags.reserve (new_size);
-          user_flags.insert (user_flags.end(),
-                            new_size-user_flags.size(),
-                            false);
+                                      // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
       
-          children.reserve (new_size);
-          children.insert (children.end(),
-                          new_size-children.size(),
-                          -1);
-
-          material_id.reserve (new_size);
-          material_id.insert (material_id.end(),
-                             new_size-material_id.size(),
-                             255);
-
-          user_data.reserve (new_size);
-          user_data.insert (user_data.end(),
-                           new_size-user_data.size(),
-                           UserData());
-        };
-    }
-
-
-    template<>
-    void
-    TriaObjects<TriaObject<2> >::reserve_space (const unsigned int new_quads)
-    {
-      const unsigned int new_size = new_quads +
-                                    std::count_if (used.begin(),
-                                                   used.end(),
-                                                   std::bind2nd (std::equal_to<bool>(), true));
-
-                                       // see above...
-      if (new_size>cells.size())
-        {
-          cells.reserve (new_size);
-          cells.insert (cells.end(),
-                       new_size-cells.size(),
-                       TriaObject<2> ());
+      int pos=next_free_single,
+        last=used.size()-1;
+      if (!reverse_order_next_free_single)
+       {
+                                          // first sweep forward, only use
+                                          // really single slots, do not use
+                                          // pair slots
+         for (; pos<last; ++pos)
+           if (!used[pos])
+             if (used[++pos])
+               {
+                                                  // this was a single slot
+                 pos-=1;
+                 break;
+               }
+         if (pos>=last)
+           {
+             reverse_order_next_free_single=true;
+             next_free_single=used.size()-1;
+             pos=used.size()-1;
+           }
+         else
+           next_free_single=pos+1;
+       }
       
-          used.reserve (new_size);
-          used.insert (used.end(),
-                      new_size-used.size(),
-                      false);
-  
-          user_flags.reserve (new_size);
-          user_flags.insert (user_flags.end(),
-                            new_size-user_flags.size(),
-                            false);
-  
-          children.reserve (new_size);
-          children.insert (children.end(),
-                          new_size-children.size(),
-                          -1);
-
-          material_id.reserve (new_size);
-          material_id.insert (material_id.end(),
-                             new_size-material_id.size(),
-                             255);
-
-          user_data.reserve (new_size);
-          user_data.insert (user_data.end(),
-                           new_size-user_data.size(),
-                           UserData());
-        };
+      if(reverse_order_next_free_single)
+       {
+                                          // second sweep, use all slots, even
+                                          // in pairs
+         for(;pos>=0;--pos)
+           if (!used[pos])
+             break;
+         if (pos>0)
+           next_free_single=pos-1;
+         else
+                                            // no valid single line anymore
+           return tria.end_line();
+       }
+
+      return typename dealii::Triangulation<dim>::raw_line_iterator(&tria,0,pos);
     }
+    
+         
 
-
-    void
-    TriaObjectsHex::reserve_space (const unsigned int new_hexes)
+    template <>
+    template <int dim>
+    typename dealii::Triangulation<dim>::raw_line_iterator
+    TriaObjects<TriaObject<1> >::next_free_pair_line (const dealii::Triangulation<dim> &tria)
     {
-      const unsigned int new_size = new_hexes +
-                                    std::count_if (used.begin(),
-                                                   used.end(),
-                                                   std::bind2nd (std::equal_to<bool>(), true));
-
-                                       // see above...
-      if (new_size>cells.size())
-        {
-          cells.reserve (new_size);
-          cells.insert (cells.end(),
-                       new_size-cells.size(),
-                       TriaObject<3> ());
+                                      // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
       
-          used.reserve (new_size);
-          used.insert (used.end(),
-                      new_size-used.size(),
-                      false);
-  
-          user_flags.reserve (new_size);
-          user_flags.insert (user_flags.end(),
-                            new_size-user_flags.size(),
-                            false);
-  
-          children.reserve (new_size);
-          children.insert (children.end(),
-                          new_size-children.size(),
-                          -1);
-
-          material_id.reserve (new_size);
-          material_id.insert (material_id.end(),
-                             new_size-material_id.size(),
-                             255);
-
-          user_data.reserve (new_size);
-          user_data.insert (user_data.end(),
-                           new_size-user_data.size(),
-                           UserData());
-
-          face_orientations.reserve (new_size * GeometryInfo<3>::faces_per_cell);
-          face_orientations.insert (face_orientations.end(),
-                                   new_size * GeometryInfo<3>::faces_per_cell
-                                   - face_orientations.size(),
-                                   true);
-          face_flips.reserve (new_size * GeometryInfo<3>::faces_per_cell);
-          face_flips.insert (face_flips.end(),
-                                   new_size * GeometryInfo<3>::faces_per_cell
-                                   - face_flips.size(),
-                                   false);
-          face_rotations.reserve (new_size * GeometryInfo<3>::faces_per_cell);
-          face_rotations.insert (face_rotations.end(),
-                                   new_size * GeometryInfo<3>::faces_per_cell
-                                   - face_rotations.size(),
-                                   false);
-        };
+      int pos=next_free_pair,
+        last=used.size()-1;
+      for (; pos<last; ++pos)
+       if (!used[pos])
+         if (!used[++pos])
+           {
+                                              // this was a pair slot
+             pos-=1;
+             break;
+           }
+      if (pos>=last)
+                                        // no free slot
+       return tria.end_line();
+      else
+       next_free_pair=pos+2;
+      
+      return typename dealii::Triangulation<dim>::raw_line_iterator(&tria,0,pos);
     }
 
 
-    void
-    TriaObjectsQuad3D::reserve_space (const unsigned int new_quads)
-    {
-      const unsigned int new_size = new_quads +
-                                    std::count_if (used.begin(),
-                                                   used.end(),
-                                                   std::bind2nd (std::equal_to<bool>(), true));
-
-                                       // see above...
-      if (new_size>cells.size())
-        {
-          TriaObjects<TriaObject<2> >::reserve_space(new_quads);
-          line_orientations.reserve (new_size * GeometryInfo<2>::lines_per_cell);
-          line_orientations.insert (line_orientations.end(),
-                                   new_size * GeometryInfo<2>::lines_per_cell
-                                   - line_orientations.size(),
-                                   true);
-        };
-    }
     
-
-    template<>
-    void
-    TriaObjects<TriaObject<1> >::monitor_memory (const unsigned int) const
+    template <>
+    template <int dim>
+    typename dealii::Triangulation<dim>::raw_quad_iterator
+    TriaObjects<TriaObject<1> >::next_free_single_quad (const dealii::Triangulation<dim> &tria)
     {
-                                       // check that we have not allocated
-                                       // too much memory. note that bool
-                                       // vectors allocate their memory in
-                                       // chunks of whole integers, so
-                                       // they may over-allocate by up to
-                                       // as many elements as an integer
-                                       // has bits
-      Assert (cells.size() <=
-             cells.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
-              ExcMemoryWasted ("lines",
-                               cells.size(), cells.capacity()));
-      Assert (children.size() <=
-             children.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
-              ExcMemoryWasted ("children",
-                               children.size(), children.capacity()));
-      Assert (used.size() <= used.capacity() + sizeof(int)*8 ||
-              used.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
-              ExcMemoryWasted ("used",
-                               used.size(), used.capacity()));
-      Assert (user_flags.size() <= user_flags.capacity() + sizeof(int)*8 ||
-              user_flags.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
-              ExcMemoryWasted ("user_flags",
-                               user_flags.size(), user_flags.capacity()));
-      Assert (cells.size() == used.size(),
-              ExcMemoryInexact (cells.size(), used.size()));
-      Assert (cells.size() == user_flags.size(),
-              ExcMemoryInexact (cells.size(), user_flags.size()));
-      Assert (cells.size() == children.size(),
-              ExcMemoryInexact (cells.size(), children.size()));
-      Assert (cells.size() == material_id.size(),
-              ExcMemoryInexact (cells.size(), material_id.size()));
-      Assert (cells.size() == user_data.size(),
-              ExcMemoryInexact (cells.size(), user_data.size()));
+      Assert(false, ExcWrongIterator("quad","line"));
+      return tria.end_quad();
     }
 
 
-    template<>
-    void
-    TriaObjects<TriaObject<2> >::monitor_memory (const unsigned int) const
+
+    template <>
+    template <int dim>
+    typename dealii::Triangulation<dim>::raw_quad_iterator
+    TriaObjects<TriaObject<1> >::next_free_pair_quad (const dealii::Triangulation<dim> &tria)
     {
-                                       // check that we have not allocated
-                                       // too much memory. note that bool
-                                       // vectors allocate their memory in
-                                       // chunks of whole integers, so
-                                       // they may over-allocate by up to
-                                       // as many elements as an integer
-                                       // has bits
-      Assert (cells.size() <=
-             cells.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
-              ExcMemoryWasted ("quads",
-                               cells.size(), cells.capacity()));
-      Assert (children.size() <=
-             children.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
-              ExcMemoryWasted ("children",
-                               children.size(), children.capacity()));
-      Assert (used.size() <= used.capacity() + sizeof(int)*8 ||
-              used.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
-              ExcMemoryWasted ("used",
-                               used.size(), used.capacity()));
-      Assert (user_flags.size() <= user_flags.capacity() + sizeof(int)*8 ||
-              user_flags.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
-              ExcMemoryWasted ("user_flags",
-                               user_flags.size(), user_flags.capacity()));
-      Assert (cells.size() == used.size(),
-              ExcMemoryInexact (cells.size(), used.size()));
-      Assert (cells.size() == user_flags.size(),
-              ExcMemoryInexact (cells.size(), user_flags.size()));
-      Assert (cells.size() == children.size(),
-              ExcMemoryInexact (cells.size(), children.size()));
-      Assert (cells.size() == material_id.size(),
-              ExcMemoryInexact (cells.size(), material_id.size()));
-      Assert (cells.size() == user_data.size(),
-              ExcMemoryInexact (cells.size(), user_data.size()));
+      Assert(false, ExcWrongIterator("quad","line"));
+      return tria.end_quad();
     }
 
 
-    void
-    TriaObjectsHex::monitor_memory (const unsigned int) const
+    
+    template <>
+    template <int dim>
+    typename dealii::Triangulation<dim>::raw_quad_iterator
+    TriaObjects<TriaObject<2> >::next_free_single_quad (const dealii::Triangulation<dim> &tria)
     {
-                                       // check that we have not allocated
-                                       // too much memory. note that bool
-                                       // vectors allocate their memory in
-                                       // chunks of whole integers, so
-                                       // they may over-allocate by up to
-                                       // as many elements as an integer
-                                       // has bits
-      Assert (cells.size() <=
-             cells.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
-              ExcMemoryWasted ("hexes",
-                               cells.size(), cells.capacity()));
-      Assert (children.size() <=
-             children.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
-              ExcMemoryWasted ("children",
-                               children.size(), children.capacity()));
-      Assert (used.size() <= used.capacity() + sizeof(int)*8 ||
-              used.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
-              ExcMemoryWasted ("used",
-                               used.size(), used.capacity()));
-      Assert (user_flags.size() <= user_flags.capacity() + sizeof(int)*8 ||
-              user_flags.size()<DEAL_II_MIN_BOOL_VECTOR_CAPACITY,
-              ExcMemoryWasted ("user_flags",
-                               user_flags.size(), user_flags.capacity()));
-      Assert (cells.size() == used.size(),
-              ExcMemoryInexact (cells.size(), used.size()));
-      Assert (cells.size() == user_flags.size(),
-              ExcMemoryInexact (cells.size(), user_flags.size()));
-      Assert (cells.size() == children.size(),
-              ExcMemoryInexact (cells.size(), children.size()));
-      Assert (cells.size() == material_id.size(),
-              ExcMemoryInexact (cells.size(), material_id.size()));
-      Assert (cells.size() == user_data.size(),
-              ExcMemoryInexact (cells.size(), user_data.size()));
-      Assert (cells.size() * GeometryInfo<3>::faces_per_cell
-              == face_orientations.size(),
-              ExcMemoryInexact (cells.size() * GeometryInfo<3>::faces_per_cell,
-                                face_orientations.size()));
-      Assert (cells.size() * GeometryInfo<3>::faces_per_cell
-              == face_flips.size(),
-              ExcMemoryInexact (cells.size() * GeometryInfo<3>::faces_per_cell,
-                                face_flips.size()));
-      Assert (cells.size() * GeometryInfo<3>::faces_per_cell
-              == face_rotations.size(),
-              ExcMemoryInexact (cells.size() * GeometryInfo<3>::faces_per_cell,
-                                face_rotations.size()));
+                                      // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
+      
+      int pos=next_free_single,
+        last=used.size()-1;
+      if (!reverse_order_next_free_single)
+       {
+                                          // first sweep forward, only use
+                                          // really single slots, do not use
+                                          // pair slots
+         for (; pos<last; ++pos)
+           if (!used[pos])
+             if (used[++pos])
+               {
+                                                  // this was a single slot
+                 pos-=1;
+                 break;
+               }
+         if (pos>=last)
+           {
+             reverse_order_next_free_single=true;
+             next_free_single=used.size()-1;
+             pos=used.size()-1;
+           }
+         else
+           next_free_single=pos+1;
+       }
+      
+      if(reverse_order_next_free_single)
+       {
+                                          // second sweep, use all slots, even
+                                          // in pairs
+         for(;pos>=0;--pos)
+           if (!used[pos])
+             break;
+         if (pos>0)
+           next_free_single=pos-1;
+         else
+                                            // no valid single quad anymore
+           return tria.end_quad();
+       }
+
+      return typename dealii::Triangulation<dim>::raw_quad_iterator(&tria,0,pos);
     }
+    
+         
 
-
-    void
-    TriaObjectsQuad3D::monitor_memory (const unsigned int) const
+    template <>
+    template <int dim>
+    typename dealii::Triangulation<dim>::raw_quad_iterator
+    TriaObjects<TriaObject<2> >::next_free_pair_quad (const dealii::Triangulation<dim> &tria)
     {
-                                       // check that we have not allocated
-                                       // too much memory. note that bool
-                                       // vectors allocate their memory in
-                                       // chunks of whole integers, so
-                                       // they may over-allocate by up to
-                                       // as many elements as an integer
-                                       // has bits
-      Assert (cells.size() * GeometryInfo<2>::lines_per_cell
-              == line_orientations.size(),
-              ExcMemoryInexact (cells.size() * GeometryInfo<2>::lines_per_cell,
-                                line_orientations.size()));
-      TriaObjects<TriaObject<2> >::monitor_memory (3);
+                                      // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
       
+      int pos=next_free_pair,
+        last=used.size()-1;
+      for (; pos<last; ++pos)
+       if (!used[pos])
+         if (!used[++pos])
+           {
+                                              // this was a pair slot
+             pos-=1;
+             break;
+           }
+      if (pos>=last)
+                                        // no free slot
+       return tria.end_quad();
+      else
+       next_free_pair=pos+2;
+      
+      return typename dealii::Triangulation<dim>::raw_quad_iterator(&tria,0,pos);
     }
 
 
-    template <typename G>
-    void
-    TriaObjects<G>::clear()
+    template <>
+    template <int dim>
+    typename dealii::Triangulation<dim>::raw_line_iterator
+    TriaObjects<TriaObject<2> >::next_free_single_line (const dealii::Triangulation<dim> &tria)
     {
-      cells.clear();
-      children.clear();
-      used.clear();
-      user_flags.clear();
-      material_id.clear();
-      user_data.clear();
-      user_data_type = data_unknown;
+      Assert(false, ExcWrongIterator("line","quad"));
+      return tria.end_line();
     }
-    
 
-    void
-    TriaObjectsHex::clear()
-    {
-      TriaObjects<TriaObject<3> >::clear();
-      face_orientations.clear();
-      face_flips.clear();
-      face_rotations.clear();
-    }
 
 
-    void
-    TriaObjectsQuad3D::clear()
-    {
-      TriaObjects<TriaObject<2> >::clear();
-      line_orientations.clear();
-    }
-    
-    
-    template<typename G>
-    unsigned int
-    TriaObjects<G>::memory_consumption () const
+    template <>
+    template <int dim>
+    typename dealii::Triangulation<dim>::raw_line_iterator
+    TriaObjects<TriaObject<2> >::next_free_pair_line (const dealii::Triangulation<dim> &tria)
     {
-      return (MemoryConsumption::memory_consumption (cells) +
-              MemoryConsumption::memory_consumption (children) +
-              MemoryConsumption::memory_consumption (used) +
-              MemoryConsumption::memory_consumption (user_flags) +
-              MemoryConsumption::memory_consumption (material_id) +
-             user_data.capacity() * sizeof(UserData) + sizeof(user_data));
+      Assert(false, ExcWrongIterator("line","quad"));
+      return tria.end_line();
     }
-  
 
-    unsigned int
-    TriaObjectsHex::memory_consumption () const
-    {
-      return (MemoryConsumption::memory_consumption (face_orientations) +
-             MemoryConsumption::memory_consumption (face_flips) +
-             MemoryConsumption::memory_consumption (face_rotations) +
-             TriaObjects<TriaObject<3> >::memory_consumption() );
-    }
 
 
-    unsigned int
-    TriaObjectsQuad3D::memory_consumption () const
+    template <>
+    template <int dim>
+    typename dealii::Triangulation<dim>::raw_hex_iterator
+    TriaObjects<TriaObject<3> >::next_free_hex (const dealii::Triangulation<dim> &tria,
+                                           const unsigned int               level)
     {
-      return (MemoryConsumption::memory_consumption (line_orientations) +
-             this->TriaObjects<TriaObject<2> >::memory_consumption() );
+                                      // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
+      
+      int pos=next_free_pair,
+        last=used.size()-1;
+      for (; pos<last; ++pos)
+       if (!used[pos])
+         {
+                                            // this should be a pair slot
+             Assert(!used[pos+1], ExcInternalError());
+             break;
+           }
+      if (pos>=last)
+                                        // no free slot
+       return tria.end_hex();
+      else
+       next_free_pair=pos+2;
+      
+      return typename dealii::Triangulation<dim>::raw_hex_iterator(&tria,level,pos);
     }
 
+
+    
+
+
                                     // explicit instantiations
 
-    template class TriaObjects<TriaObject<1> >;
-    template class TriaObjects<TriaObject<2> >;
+#if deal_II_dimension > 1
+    template dealii::Triangulation<deal_II_dimension>::raw_line_iterator
+    TriaObjects<TriaObject<1> >::next_free_single_line(const dealii::Triangulation<deal_II_dimension> &);
+    template dealii::Triangulation<deal_II_dimension>::raw_line_iterator
+    TriaObjects<TriaObject<1> >::next_free_pair_line(const dealii::Triangulation<deal_II_dimension> &);
+    template dealii::Triangulation<deal_II_dimension>::raw_quad_iterator
+    TriaObjects<TriaObject<1> >::next_free_single_quad(const dealii::Triangulation<deal_II_dimension> &);
+    template dealii::Triangulation<deal_II_dimension>::raw_quad_iterator
+    TriaObjects<TriaObject<1> >::next_free_pair_quad(const dealii::Triangulation<deal_II_dimension> &);
+
+    template dealii::Triangulation<deal_II_dimension>::raw_line_iterator
+    TriaObjects<TriaObject<2> >::next_free_single_line(const dealii::Triangulation<deal_II_dimension> &);
+    template dealii::Triangulation<deal_II_dimension>::raw_line_iterator
+    TriaObjects<TriaObject<2> >::next_free_pair_line(const dealii::Triangulation<deal_II_dimension> &);
+    template dealii::Triangulation<deal_II_dimension>::raw_quad_iterator
+    TriaObjects<TriaObject<2> >::next_free_single_quad(const dealii::Triangulation<deal_II_dimension> &);
+    template dealii::Triangulation<deal_II_dimension>::raw_quad_iterator
+    TriaObjects<TriaObject<2> >::next_free_pair_quad(const dealii::Triangulation<deal_II_dimension> &);
+#endif
+#if deal_II_dimension == 3
+    template dealii::Triangulation<deal_II_dimension>::raw_hex_iterator
+    TriaObjects<TriaObject<3> >::next_free_hex(const dealii::Triangulation<deal_II_dimension> &, const unsigned int);
+#endif
   }
 }
 
index 381747f7f664007333ef44c9853e3b5ce5432649..61c82c7bac6d7fb5fb9777f48ed17bc88303ccbc 100644 (file)
@@ -3508,30 +3508,25 @@ namespace hp
             {
                                                // 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:
+                                               // 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->neighbor(face)->level() < cell->level())
-                  ||
-                  cell->neighbor(face)->has_children()
+                  cell->face(face)->has_children()
                   ||
-                  ((cell->neighbor(face)->level() == cell->level())
-                   &&
-                   !cell->neighbor(face)->has_children()
-                   &&
-                   (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
+                 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
@@ -3593,15 +3588,13 @@ namespace hp
                                                // as before
               if (cell->at_boundary(face)
                   ||
-                  (cell->neighbor(face)->level() < cell->level())
+                  cell->face(face)->has_children()
                   ||
-                  cell->neighbor(face)->has_children()
-                  ||
-                  ((cell->neighbor(face)->level() == cell->level())
-                   &&
-                   !cell->neighbor(face)->has_children()
-                   &&
-                   (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
+                 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()]
@@ -3879,15 +3872,13 @@ namespace hp
                                                // same active_fe_index:
               if (cell->at_boundary(face)
                   ||
-                  (cell->neighbor(face)->level() < cell->level())
-                  ||
-                  cell->neighbor(face)->has_children()
+                  cell->face(face)->has_children()
                   ||
-                  ((cell->neighbor(face)->level() == cell->level())
-                   &&
-                   !cell->neighbor(face)->has_children()
-                   &&
-                   (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
+                 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
@@ -3952,15 +3943,13 @@ namespace hp
                                                // as before
               if (cell->at_boundary(face)
                   ||
-                  (cell->neighbor(face)->level() < cell->level())
+                  cell->face(face)->has_children()
                   ||
-                  cell->neighbor(face)->has_children()
-                  ||
-                  ((cell->neighbor(face)->level() == cell->level())
-                   &&
-                   !cell->neighbor(face)->has_children()
-                   &&
-                   (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
+                 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()]
@@ -4323,16 +4312,9 @@ namespace hp
   }
 
 
-  template <int dim>
-  void DoFHandler<dim>::pre_refinement_notification (const Triangulation<dim> &)
-  {
-    create_active_fe_table ();
-  }
-
 
-#if deal_II_dimension == 1
-  template <>
-  void DoFHandler<1>::pre_refinement_notification (const Triangulation<1> &tria)
+  template <int dim>
+  void DoFHandler<dim>::pre_refinement_notification (const Triangulation<dim> &tria)
   {
     create_active_fe_table ();
 
@@ -4343,53 +4325,26 @@ namespace hp
     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);
+       const unsigned int cells_on_level = tria.n_raw_cells(i);
        std::vector<bool> *has_children_level =
-          new std::vector<bool> (lines_on_level);
+          new std::vector<bool> (cells_on_level);
 
                                          // Check for each cell, if it has children.
-       std::transform (tria.levels[i]->cells.children.begin (),
-                       tria.levels[i]->cells.children.end (),
+       std::transform (tria.levels[i]->cells.refinement_cases.begin (),
+                       tria.levels[i]->cells.refinement_cases.end (),
                        has_children_level->begin (),
-                       std::bind2nd (std::not_equal_to<int>(), -1));
+                       std::bind2nd (std::not_equal_to<unsigned char>(),
+                                     static_cast<unsigned char>(RefinementCase<dim>::no_refinement)));
 
        has_children.push_back (has_children_level);
       }
   }
-#endif
-
-  
-#if deal_II_dimension == 2
-  template <>
-  void DoFHandler<2>::pre_refinement_notification (const Triangulation<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 quads_on_level = tria.n_raw_quads (i);
-       std::vector<bool> *has_children_level =
-          new std::vector<bool> (quads_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
 
-#if deal_II_dimension == 3
+#if deal_II_dimension == 1
   template <>
-  void DoFHandler<3>::pre_refinement_notification (const Triangulation<3> &tria)
+  void DoFHandler<1>::pre_refinement_notification (const Triangulation<1> &tria)
   {
     create_active_fe_table ();
 
@@ -4400,12 +4355,16 @@ namespace hp
     Assert (has_children.size () == 0, ExcInternalError ());
     for (unsigned int i=0; i<levels.size(); ++i)
       {
-       const unsigned int hexes_on_level = tria.n_raw_hexs(i);
+       const unsigned int cells_on_level = tria.n_raw_cells (i);
        std::vector<bool> *has_children_level =
-          new std::vector<bool> (hexes_on_level);
-
-                                         // Check for each cell, if it
-                                         // has children.
+          new std::vector<bool> (cells_on_level);
+
+                                         // Check for each cell, if it has
+                                         // children. here we cannot use
+                                         // refinement_cases, since it is unused in
+                                         // 1d (as there is only one choice
+                                         // anyway). use the 'children' vector
+                                         // instead
        std::transform (tria.levels[i]->cells.children.begin (),
                        tria.levels[i]->cells.children.end (),
                        has_children_level->begin (),
@@ -4416,6 +4375,7 @@ namespace hp
   }
 #endif
 
+
   template <int dim>
   void DoFHandler<dim>::post_refinement_notification (const Triangulation<dim> &tria)
   {
index c80bd4db3ea82d31779ad83fc6d3b1a0e8375b6f..8d815b14992c84b8d33ad99d30d52c35dd8f1371 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
@@ -166,13 +166,15 @@ void MGTransferBlockBase::build_matrices (
          {
            cell->get_mg_dof_indices (dof_indices_parent);
 
+           Assert(cell->n_children()==GeometryInfo<dim>::max_children_per_cell,
+                  ExcNotImplemented());
            for (unsigned int child=0; child<cell->n_children(); ++child)
              {
                                                 // set an alias to the
                                                 // prolongation matrix for
                                                 // this child
                const FullMatrix<double> &prolongation
-                 = mg_dof.get_fe().get_prolongation_matrix (child);
+                 = mg_dof.get_fe().get_prolongation_matrix (child, cell->refinement_case());
            
                cell->child(child)->get_mg_dof_indices (dof_indices_child);
 
@@ -203,13 +205,15 @@ void MGTransferBlockBase::build_matrices (
          {
            cell->get_mg_dof_indices (dof_indices_parent);
 
+           Assert(cell->n_children()==GeometryInfo<dim>::max_children_per_cell,
+                  ExcNotImplemented());
            for (unsigned int child=0; child<cell->n_children(); ++child)
              {
                                                 // set an alias to the
                                                 // prolongation matrix for
                                                 // this child
                const FullMatrix<double> &prolongation
-                 = mg_dof.get_fe().get_prolongation_matrix (child);
+                 = mg_dof.get_fe().get_prolongation_matrix (child, cell->refinement_case());
            
                cell->child(child)->get_mg_dof_indices (dof_indices_child);
 
index 3c7411bea9f6c19a9e990275f6467a1bf56637f0..506a233f6483cae66d4b109562ca4fb5653bda89 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
@@ -208,7 +208,7 @@ void MGTransferComponentBase::build_matrices (
                                                 // prolongation matrix for
                                                 // this child
                const FullMatrix<double> &prolongation
-                 = mg_dof.get_fe().get_prolongation_matrix (child);
+                 = mg_dof.get_fe().get_prolongation_matrix (child, cell->refinement_case());
            
                cell->child(child)->get_mg_dof_indices (dof_indices_child);
 
@@ -245,7 +245,7 @@ void MGTransferComponentBase::build_matrices (
                                                 // prolongation matrix for
                                                 // this child
                const FullMatrix<double> &prolongation
-                 = mg_dof.get_fe().get_prolongation_matrix (child);
+                 = mg_dof.get_fe().get_prolongation_matrix (child, cell->refinement_case());
            
                cell->child(child)->get_mg_dof_indices (dof_indices_child);
 
index b665fefebd8463f110137508f55e6dab4df1e922..326add90f7cb4c29226f4dfd236b1eb61a2c58d8 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
@@ -96,13 +96,15 @@ void MGTransferPrebuilt<number>::build_matrices (
          {
            cell->get_mg_dof_indices (dof_indices_parent);
 
+           Assert(cell->n_children()==GeometryInfo<dim>::max_children_per_cell,
+                  ExcNotImplemented());
            for (unsigned int child=0; child<cell->n_children(); ++child)
              {
                                                 // set an alias to the
                                                 // prolongation matrix for
                                                 // this child
                const FullMatrix<double> &prolongation
-                 = mg_dof.get_fe().get_prolongation_matrix (child);
+                 = mg_dof.get_fe().get_prolongation_matrix (child, cell->refinement_case());
 
                Assert (prolongation.n() != 0, ExcNoProlongation());
                
@@ -131,13 +133,15 @@ void MGTransferPrebuilt<number>::build_matrices (
          {
            cell->get_mg_dof_indices (dof_indices_parent);
 
+           Assert(cell->n_children()==GeometryInfo<dim>::max_children_per_cell,
+                  ExcNotImplemented());
            for (unsigned int child=0; child<cell->n_children(); ++child)
              {
                                                 // set an alias to the
                                                 // prolongation matrix for
                                                 // this child
                const FullMatrix<double> &prolongation
-                 = mg_dof.get_fe().get_prolongation_matrix (child);
+                 = mg_dof.get_fe().get_prolongation_matrix (child, cell->refinement_case());
            
                cell->child(child)->get_mg_dof_indices (dof_indices_child);
 
index b69e68ab8342e5afae3f5680e8aefa8838255e0a..0472fc83d8b2687834c6b64c420247ece0d606f3 100644 (file)
@@ -20,6 +20,7 @@
 #include <lac/petsc_vector.h>
 #include <lac/petsc_block_vector.h>
 #include <grid/tria_iterator.h>
+#include <grid/grid_tools.h>
 #include <dofs/dof_accessor.h>
 #include <dofs/dof_handler.h>
 #include <fe/fe.h>
@@ -740,7 +741,7 @@ approximate_cell (const Mapping<dim>                            &mapping,
                                   // active neighbors
   std::vector<typename DH<dim>::active_cell_iterator> active_neighbors;
   active_neighbors.reserve (GeometryInfo<dim>::faces_per_cell *
-                           GeometryInfo<dim>::subfaces_per_face);
+                           GeometryInfo<dim>::max_children_per_face);
 
                                       // vector
                                       // g=sum_i y_i (f(x+y_i)-f(x))/|y_i|
@@ -776,57 +777,8 @@ approximate_cell (const Mapping<dim>                            &mapping,
                                       // first collect all neighbor
                                       // cells in a vector, and then
                                       // collect the data from them
-      active_neighbors.clear ();
-      for (unsigned int n=0; n<GeometryInfo<dim>::faces_per_cell; ++n)
-       if (! cell->at_boundary(n))
-         {
-           typename DH<dim>::cell_iterator
-             neighbor = cell->neighbor(n);
-           if (neighbor->active())
-             active_neighbors.push_back (neighbor);
-           else
-             {
-                                                // check children
-                                                // of
-                                                // neighbor. note
-                                                // that in 1d
-                                                // children of
-                                                // the neighbor
-                                                // may be further
-                                                // refined, while
-                                                // they can't in
-                                                // more than one
-                                                // dimension. however,
-                                                // in 1d the case
-                                                // is simpler
-                                                // since we know
-                                                // what children
-                                                // bound to the
-                                                // present cell
-               if (dim == 1)
-                 {
-                   typename DH<dim>::cell_iterator
-                     neighbor_child = neighbor;
-                   while (neighbor_child->has_children())
-                     neighbor_child = neighbor_child->child (n==0 ? 1 : 0);
-                   
-                   Assert (neighbor_child->neighbor(n==0 ? 1 : 0)==cell,
-                           ExcInternalError());
-                   
-                   active_neighbors.push_back (neighbor_child);
-                 }
-               else
-                                                  // this neighbor has
-                                                  // children. find out
-                                                  // which border to the
-                                                  // present cell
-                 for (unsigned int c=0; c<neighbor->n_children(); ++c)
-                   for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
-                     if (neighbor->child(c)->neighbor(f) == cell)
-                         active_neighbors.push_back (neighbor->child(c));
-             };
-         };
-
+      GridTools::template get_active_neighbors<DH<dim> >(cell, active_neighbors);
+      
                                       // now loop over all active
                                       // neighbors and collect the
                                       // data we need
@@ -1034,7 +986,6 @@ DerivativeApproximation::
 derivative_norm(const Tensor<3,deal_II_dimension> &derivative);
 
 
-
 // static variables
 // 
 // on AIX, the linker is unhappy about some missing symbols. they
@@ -1047,7 +998,6 @@ DerivativeApproximation::Gradient<deal_II_dimension>::update_flags;
 template
 const UpdateFlags
 DerivativeApproximation::SecondDerivative<deal_II_dimension>::update_flags;
-
 template
 const UpdateFlags
 DerivativeApproximation::ThirdDerivative<deal_II_dimension>::update_flags;
index 38f23b390a054069a69ff3d1d4e815137a7b8558..119f06d71094230e20bce3ccc7af7b09686731c6 100644 (file)
@@ -745,8 +745,10 @@ estimate_some (const hp::MappingCollection<dim>                  &mapping,
                                           // then do the work below
          if ((face->has_children() == false) &&
              !cell->at_boundary(face_no) &&
-             (cell->neighbor(face_no)->level() == cell->level()) &&
-             (cell->neighbor(face_no)->index() < cell->index()))
+             (!cell->neighbor_is_coarser(face_no) &&
+              (cell->neighbor(face_no)->index() < cell->index() ||
+               (cell->neighbor(face_no)->index() == cell->index() &&
+                cell->neighbor(face_no)->level() < cell->level()))))
            continue;
          
                                           // if we already visited
@@ -766,7 +768,7 @@ estimate_some (const hp::MappingCollection<dim>                  &mapping,
                                           // integrate over the subfaces when
                                           // we visit the coarse cells.
          if (cell->at_boundary(face_no) == false)
-           if (cell->neighbor(face_no)->level() < cell->level())
+           if (cell->neighbor_is_coarser(face_no))
              continue;
          
                                           // if this face is part of the
index 8ad91606f6528265ce22abaab3ef908907b2aca3..8b71edda6e57c1985e64a002b5cffb2986261892 100644 (file)
@@ -201,13 +201,16 @@ prepare_for_coarsening_and_refinement(const std::vector<Vector<number> > &all_in
     }
   Assert((n_cells_to_coarsen+n_cells_to_stay_or_refine)==n_active_cells,
         ExcInternalError());
-  Assert(n_cells_to_coarsen%GeometryInfo<dim>::children_per_cell==0,
-        ExcInternalError());
-  Assert(n_cells_to_coarsen%GeometryInfo<dim>::children_per_cell==0,
-        ExcTriaPrepCoarseningNotCalledBefore());
+
+  unsigned int n_coarsen_fathers=0;
+  typename DH::cell_iterator
+    cell=dof_handler->begin();
+  for (; cell!=endc; ++cell)
+    if (!cell->active() && cell->child(0)->coarsen_flag_set())
+      ++n_coarsen_fathers;
   
-  const unsigned int n_coarsen_fathers = n_cells_to_coarsen /
-                                        GeometryInfo<dim>::children_per_cell;
+  if (n_cells_to_coarsen)
+    Assert(n_cells_to_coarsen>=2*n_coarsen_fathers, ExcInternalError());
 
                                   // allocate the needed memory. initialize
                                    // the following arrays in an efficient
@@ -225,7 +228,7 @@ prepare_for_coarsening_and_refinement(const std::vector<Vector<number> > &all_in
                                   // the 'to_stay_or_refine' cells 'n_sr' and
                                   // the 'coarsen_fathers' cells 'n_cf',
   unsigned int n_sr=0, n_cf=0;
-  typename DH::cell_iterator cell = dof_handler->begin();  
+  cell = dof_handler->begin();  
   for (; cell!=endc; ++cell) 
     {
       if (cell->active() && !cell->coarsen_flag_set())
index 61d80668fc7289a5f07b9ae2146a7a2816ce9243..64404ff0cc15b38815617c0f6fb894d5f8aea557 100644 (file)
@@ -2,7 +2,7 @@
 //    $Id$
 //    Version: $Name$
 //
-//    Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006 by the deal.II authors
+//    Copyright (C) 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
@@ -859,17 +859,19 @@ void TimeStepBase_Tria<dim>::refine_grid (const RefinementData refinement_data)
                                         // new. but since we loop over flagged
                                         // cells, we have to subtract 3/4 of
                                         // a cell for each flagged cell
+       Assert(!tria->get_anisotropic_refinement_flag(), ExcNotImplemented());
+       Assert(!previous_tria->get_anisotropic_refinement_flag(), ExcNotImplemented());
        double previous_cells = previous_tria->n_active_cells();
        typename Triangulation<dim>::active_cell_iterator cell, endc;
        cell = previous_tria->begin_active();
        endc = previous_tria->end();
        for (; cell!=endc; ++cell)
          if (cell->refine_flag_set())
-           previous_cells += (GeometryInfo<dim>::children_per_cell-1);
+           previous_cells += (GeometryInfo<dim>::max_children_per_cell-1);
          else
            if (cell->coarsen_flag_set())
-             previous_cells -= (GeometryInfo<dim>::children_per_cell-1) /
-                               GeometryInfo<dim>::children_per_cell;
+             previous_cells -= (GeometryInfo<dim>::max_children_per_cell-1) /
+                               GeometryInfo<dim>::max_children_per_cell;
            
                                         // @p{previous_cells} now gives the
                                         // number of cells which would result
@@ -892,11 +894,11 @@ void TimeStepBase_Tria<dim>::refine_grid (const RefinementData refinement_data)
        endc = tria->end();
        for (; cell!=endc; ++cell)
          if (cell->refine_flag_set())
-           estimated_cells += (GeometryInfo<dim>::children_per_cell-1);
+           estimated_cells += (GeometryInfo<dim>::max_children_per_cell-1);
          else
            if (cell->coarsen_flag_set())
-             estimated_cells -= (GeometryInfo<dim>::children_per_cell-1) /
-                                GeometryInfo<dim>::children_per_cell;
+             estimated_cells -= (GeometryInfo<dim>::max_children_per_cell-1) /
+                                GeometryInfo<dim>::max_children_per_cell;
 
                                         // calculate the allowed delta in
                                         // cell numbers; be more lenient
@@ -960,7 +962,7 @@ void TimeStepBase_Tria<dim>::refine_grid (const RefinementData refinement_data)
                                                 // cells tagged for refinement
 
                for (unsigned int i=0; i<delta_cells;
-                    i += GeometryInfo<dim>::children_per_cell-1)
+                    i += GeometryInfo<dim>::max_children_per_cell-1)
                  if (p_refinement_threshold != sorted_criteria.end())
                    ++p_refinement_threshold;
                  else
@@ -1021,7 +1023,7 @@ void TimeStepBase_Tria<dim>::refine_grid (const RefinementData refinement_data)
                                               // of sorted_criteria, which is
                                               // sorted in ascending order
              for (unsigned int i=0; i<delta_cells;
-                  i += (GeometryInfo<dim>::children_per_cell-1))
+                  i += (GeometryInfo<dim>::max_children_per_cell-1))
                if (p_refinement_threshold != p_coarsening_threshold)
                  --refinement_threshold;
                else
index 00d9015210c34040c11fe102d5d5aa959d6d76d8..550b427d67d633c71c86ae150733c29dd17c9aaf 100644 (file)
@@ -10,8 +10,9 @@ INPUT    = headers/ \
        ../../deal.II/include/multigrid \
        ../../deal.II/include/numerics \
        tutorial/doxygen \
+       ../news/changes.h \
        ../news/6.0.0-vs-6.1.0.h \
-       ../news/changes.h
+       ../news/anisotropic.html
 
 HTML_OUTPUT      = deal.II
 LATEX_OUTPUT     = LaTeX/deal.II
@@ -47,5 +48,6 @@ IMAGE_PATH             = images \
                         ../../examples/step-27/doc \
                         ../../examples/step-28/doc \
                         ../../examples/step-29/doc \
+                        ../../examples/step-30/doc
                         ../../examples/step-31/doc \
                         ../../examples/step-33/doc 
index 56c15480ea84b7e0b58d90ed3075d800ac6cb450..18aff051d33499eac842a3c1dd4196967801fa0e 100644 (file)
@@ -241,6 +241,10 @@ searching for programs with a certain functionality.
       <td> Solving a complex-valued Helmholtz equation. Sparse direct
       solvers. Dealing with parameter files.  </td></tr>
 
+  <tr><td><a href="../../doxygen/deal.II/step_30.html">Step-30</a></td>
+      <td> Anisotropic refinement for DG finite element methods.
+      </td></tr>
+
   <tr valign="top">
       <td><a href="../../doxygen/deal.II/step_33.html">Step-33</a></td>
       <td> A nonlinear hyperbolic conservation law: The Euler equations of
@@ -381,6 +385,13 @@ by topic:
   </tr>
 
   <tr valign="top">
+    <td></td>
+    <td><a href="../../doxygen/deal.II/step_30.html">Step-30</a></td>
+    <td> Anisotropic refinement for DG finite element methods.
+    </td>
+  </tr>
+
+  <tr>
     <td></td>
     <td><a href="../../doxygen/deal.II/step_16.html">Step-16</a></td> 
     <td> Multilevel preconditioners
index 5bb9a5f96135076126f4d9752af475d3a73b9ab3..3d63a1b7bfca215faad0590c2786705b51c6df2f 100644 (file)
@@ -1,24 +1,13 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN"
-   "http://www.w3.org/TR/REC-html40/frameset.dtd">
-<html>
-  <head>
-    <link href="../screen.css" rel="StyleSheet">
-    <title>The deal.II news page</title>
-    <meta name="author" content="the deal.II authors <authors@dealii.org>">
-    <meta name="keywords" content="deal.II"></head>
-    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<body>
-
-
-<h2>Changes between the main branch and the anisotropic branch</h2>
+/**
+ * @page anisotropic_changes Changes between the trunk and branch_anisotropic
 
 <p>
-This is the list of changes between the main subversion branch and the
-anisotropic branch of <acronym>deal.II</acronym> library. It is
-subdivided into changes made to the three sub-libraries <a
-href="#base">base</a>, <a href="#lac">lac</a>, and <a
-href="#deal.II">deal.II</a>, as well as changes to the <a
-href="#general">general infrastructure, documentation, etc</a>.
+This is the list of changes between the subversion trunk and the
+anisotropic branch of the deal.II library. It is subdivided into
+changes made to the three sub-libraries <a href="#base">base</a>, <a
+href="#lac">lac</a>, and <a href="#deal.II">deal.II</a>, as well as
+changes to the <a href="#general">general infrastructure,
+documentation, etc</a>.
 </p>
 
 <p>
@@ -41,43 +30,40 @@ refinement.
 
 <ol>
   <li> <p> 
-       Changed: The <code class="class">FiniteElement&lt;dim&gt;</code>::<code
-                class="member">get_prolongation_matrix</code> and <code
-                class="class">FiniteElement&lt;dim&gt;</code>::<code
-                class="member">get_restriction_matrix</code> functions now have an
-                additional argument of type <code>RefineCase::Type</code> to enable a
-                meaningful use of these matrices in case of anisotropic refinement. These
-                matrices are used for solution transfer and multigrid operations, but
-                there should be no need to use them in user codes directly. Note, that
-                the matrices are not fully implemented for all finite elements up to now.
-                <br> (Tobias Leicht 2006/07/04)
+       Changed: The FiniteElement::get_prolongation_matrix and
+       FiniteElement::get_restriction_matrix functions now have an
+       additional argument of type RefinementCase to enable a
+       meaningful use of these matrices in case of anisotropic
+       refinement. These matrices are used for solution transfer and
+       multigrid operations, but there should be no need to use them
+       in user codes directly. Note, that the matrices are not fully
+       implemented for all finite elements up to now.
+       <br>
+       (Tobias Leicht 2006/07/04)
        </p>
 
   <li> <p>
-       Changed: <code class="class">GeometryInfo</code>::<code
-       class="member">children_per_cell</code> has been replaced by
-       <code class="class">GeometryInfo</code>::<code
-       class="member">max_children_per_cell</code>, which represents
-       the maximum number of children a cell might have, i.e. the
-       number of children in the case of isotropic refinement. But
-       note, that this number will rarely be needed in user codes. In
-       general, the number of children of a cell varies from cell to
-       cell and can be obtained by <code>cell->n_children()</code>,
-       which gives the number of children of a specific
-       <code>cell</code> which is refined iso- or anisotropically.
+       Changed: <code>GeometryInfo::children_per_cell</code> has been
+       replaced by GeometryInfo::max_children_per_cell, which
+       represents the maximum number of children a cell might have,
+       i.e. the number of children in the case of isotropic
+       refinement. But note, that this number will rarely be needed in
+       user codes. In general, the number of children of a cell varies
+       from cell to cell and can be obtained by
+       <code>cell->n_children()</code>, which gives the number of
+       children of a specific <code>cell</code> which is refined iso-
+       or anisotropically.
        <br>
        (RH 2005/02/26)
        </p>
 
   <li> <p>
        Changed: The analogous change applies to the number of children
-       of a face. <code class="class">GeometryInfo</code>::<code
-       class="member">subfaces_per_face</code> has been replaced by
-       <code class="class">GeometryInfo</code>::<code
-       class="member">max_children_per_face</code>, which represents
-       the maximum number of children a face might have, i.e. the
-       number of children in the case of an isotropic refined face.
-       But note, that this number will rarely be needed in user
+       of a face. <code>GeometryInfo::subfaces_per_face</code> has
+       been replaced by GeometryInfo::max_children_per_face, which
+       represents the maximum number of children a face might have,
+       i.e. the number of children in the case of an isotropic refined
+       face.  But note, that this number will rarely be needed in user
        codes. In general, the number of children of a face varies from
        face to face and can be obtained by
        <code>face->n_children()</code>, which gives the number of
@@ -88,15 +74,13 @@ refinement.
        </p>
 
   <li> <p>
-       Changed: The <code class="class">GeometryInfo</code>::<code
-       class="member">child_cell_on_face</code> is generalized to
-       anisotropic refinement and has now an additional
-       <code>RefineCase::Type</code> argument. This function will
-       rarely be used in user codes, as e.g. the neighbor's child at a
-       specific face and subface should be accessed through
+       Changed: The GeometryInfo::child_cell_on_face function is
+       generalized to anisotropic refinement and has now an additional
+       RefinementCase argument. This function will rarely be used in
+       user codes, as e.g. the neighbor's child at a specific face and
+       subface should be accessed through
        <code>cell->neighbor_child_on_subface</code> rather than
-       through the <code class="class">GeometryInfo</code>::<code
-       class="member">child_cell_on_face</code> function.
+       through the GeometryInfo::child_cell_on_face function.
        <br>
        (RH 2005/02/27)
        </p>
@@ -129,55 +113,54 @@ refinement.
 
 <ol>
   <li> <p>
-       New: There is now a new <code
-       class="class">GeometryInfo&lt;dim&gt;</code>::<code
-       class="member">min_cell_refine_case</code> function which returns the
-       <code>RefineCase::Type</code> representing the smallest refinement case
-       of a cell for a given refinement of one of its faces. In 2D for example a
-       cell has to be refined at least with <code>RefineCase::cut_y</code> if
-       the left line (line 0) shall be refined. Another refinement possibility
-       for the cell would be <code>RefineCase::cut_xy</code>, but that is not
-       the minimal case.
+       New: There are now a new
+       GeometryInfo::min_cell_refinement_case_for_face_refinement
+       (resp. GeometryInfo::min_cell_refinement_case_for_line_refinement)
+       function which returns the RefinementCase representing the
+       smallest refinement case of a cell for a given refinement of
+       one of its faces (resp. lines). In 2D for example a cell has to
+       be refined at least with RefinementCase::cut_y if the left line
+       (line 0) shall be refined. Another refinement possibility for
+       the cell would be <code>RefinementCase::cut_xy</code>, but that
+       is not the minimal case.
        <br> 
        (Tobias Leicht 2006/06/28)
        </p>
 
   <li> <p>
-       New: There is now a new <code
-       class="class">GeometryInfo&lt;dim&gt;</code>::<code
-       class="member">line_refine_case</code> function which returns the
-       <code>RefineCase::Type</code> representing the refinement case of a line
-       for a given refinement case of the corresponding cell.
+       New: There is now a new GeometryInfo::line_refinement_case
+       function which returns the RefinementCase representing the
+       refinement case of a line for a given refinement case of the
+       corresponding cell.
        <br> 
        (Tobias Leicht 2006/06/28)
        </p>
 
   <li> <p>
-       New: The new <code class="class">GeometryInfo</code>::<code
-       class="member">n_children(ref_case)</code> function returns the
-       number of children a cell/face has when refined with the
-       <code>RefineCase::Type</code> <code>ref_case</code>.
+       New: The new
+       <tt>GeometryInfo<dim>::n_children(refinement_case)</tt>
+       function returns the number of children a cell/face has when
+       refined with the RefinementCase <tt>refinement_case</tt>.
        <br> 
        (RH 2005/11/07)
        </p>
 
   <li> <p>
-       New: Given a <code>RefineCase::Type</code> of a cell the new
-       <code class="class">GeometryInfo</code>::<code
-       class="member">face_refine_case</code> function returns the
-       <code>RefineCase::Type</code> of a face.  <br> (RH 2005/11/07)
+       New: Given a RefinementCase of a cell the new
+       GeometryInfo::face_refinement_case function returns the
+       RefinementCase of a face.
+       <br>
+       (RH 2005/11/07)
        </p>
 
   <li> <p>
-       New: There is now a new <code
-       class="class">GeometryInfo&lt;dim&gt;</code>::<code
-       class="member">isotropic_refinement</code> variable of type
-       <code>RefineCase::Type</code> representing the isotropic
+       New: There is now a new RefinementCase
+       GeometryInfo::isotropic_refinement representing the isotropic
        refinement case in <code>dim</code> dimensions,
-       i.e. <code>GeometryInfo&lt;1&gt;::isotropic_refinement=RefineCase::cut_x</code>,
-       <code>GeometryInfo&lt;2&gt;::isotropic_refinement=RefineCase::cut_xy</code>
+       i.e. <tt>GeometryInfo<1>::isotropic_refinement=RefinementCase::cut_x</tt>,
+       <tt>GeometryInfo<2>::isotropic_refinement=RefinementCase::cut_xy</tt>
        and
-       <code>GeometryInfo&lt;3&gt;::isotropic_refinement=RefineCase::cut_xyz</code>.
+       <tt>GeometryInfo<3>::isotropic_refinement=RefinementCase::cut_xyz</tt>.
        <br> 
        (RH 2005/03/03)
        </p>
@@ -188,169 +171,119 @@ refinement.
 <a name="lac"></a>
 <h3>lac</h3>
 
-<ol>
-</ol>
-
 
 
 <a name="deal.II"></a>
 <h3>deal.II</h3>
 
 <ol>
-  <li> <p> New: There is now a new <code
-                class="class">Triangulation&lt;dim&gt;</code>::<code
-                class="member">prevent_distorted_boundary_cell</code> function which is
-                only useful in case of anisotropic refinement. 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 anistropic refinement
-                here, the resulting cell may be strongly distorted, especially if it is
-                refined again later on. To prevent this problem, this function flags such
-                cells for isotropic refinement. It is called automatically from <code
-                class="member">prepare_coarsening_and_refinement</code>. Therefore this
-                should have no effect on user codes.
-                <br> 
-                (Tobias Leicht 2006/08/02)
-       </p>
-
   <li> <p>
-                New: There is now a new <code
-       class="class">Triangulation&lt;dim&gt;</code>::<code
-       class="member">tria_post_processing</code> function which is only useful
-                in case of anisotropic refinement. It is possible, that a cell is refined
-                only in one direciton and later all the children are refined in another
-                one. Summing up, this would be the same as isotropic refinement, but with
-                a higher number of cells, faces and levels involved. Therefore, after the
-                refinement process, this function is called automatically and catches
-                cells, for which the described conditions apply. They are coarsened and
-                refined isotropically again. However, this is really something
-       internal to the library and there should never be the need to use this
-       function in user_codes. Calling <code
-       class="class">Triangulation&lt;dim&gt;</code>::<code
-       class="member">execute_coarsening_and_refinement</code> will be all you
-       need.
-                <br> 
-                (Tobias Leicht 2006/06/29)
+       New: There is now a new
+       Triangulation::prevent_distorted_boundary_cells function which
+       only useful in case of anisotropic refinement. 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 anistropic refinement here, the resulting cell may be
+       strongly distorted, especially if it is refined again later
+       on. To prevent this problem, this function flags such cells for
+       isotropic refinement. It is called automatically from
+       Triangulation::prepare_coarsening_and_refinement. Therefore
+       this should have no effect on user codes.
+       <br>
+       (Tobias Leicht 2006/08/02)
        </p>
 
   <li> <p>
-                Extended: The<code
-       class="class">Triangulation&lt;dim&gt;</code>::<code
-       class="member">delete_children</code> now takes an additional argument
-                <code>keep_outer_faces</code> of type <code>bool</code> which has a
-                default value of <code>false</code>. If set to <code>true</code>, the
-                children of the cells faces are never deleted, even if the neighbor does
-                not need them. Normally, this would leed to wasted memory, therefore
-                this should only be done, if they are needed afterwards, e.g. if the cell
-                is refined again. However, this is really something
-       internal to the library and there should never be the need to use this
-       function in user_codes. Calling <code
-       class="class">Triangulation&lt;dim&gt;</code>::<code
-       class="member">execute_coarsening_and_refinement</code> will be all you
-       need.
-                <br> 
-                (Tobias Leicht 2006/06/29)
+       New: There is now a new Triangulation::create_children function
+       which actually sets up the children of a cell and updates the
+       neighbor information. This work has been done in
+       Triangulation::execute_refinement so far. Memory allocation has
+       to be done prior to the function call. However, this is really
+       something internal to the library and there should never be the
+       need to use this function in user_codes. Calling
+       Triangulation::execute_coarsening_and_refinement will be all
+       you need.
+       <br> 
+       (Tobias Leicht 2006/06/29)
        </p>
 
   <li> <p>
-                New: There is now a new <code
-       class="class">Triangulation&lt;dim&gt;</code>::<code
-       class="member">create_children</code> function which actually sets up the
-       children of a cell and updates the neighbor information. This work has
-       been done in <code class="class">Triangulation&lt;dim&gt;</code>::<code
-       class="member">execute_refinement</code> so far. Memory allocation has to
-       be done prior to the function call. However, this is really something
-       internal to the library and there should never be the need to use this
-       function in user_codes. Calling <code
-       class="class">Triangulation&lt;dim&gt;</code>::<code
-       class="member">execute_coarsening_and_refinement</code> will be all you
-       need.
-                <br> 
-                (Tobias Leicht 2006/06/29)
-       </p>
 
-  <li> <p>
-       New: A part of the functionality of <code
-       class="class">Triangulation&lt;dim&gt;</code>::<code
-       class="member">execute_coarsening</code> has been implemented in a new way
-       and shifted to the new function <code
-                class="class">Triangulation&lt;dim&gt;</code>::<code
-       class="member">coarsening_allowed</code>. This function decides,
+       New: A part of the functionality of Triangulation::execute_coarsening has been implemented in a new way
+       and shifted to the new function Triangulation::coarsening_allowed. This function decides,
        depending on the refinement situation of all a cells neighbors, if the
        cell may be coarsened, in which case the bool value <code>true</code> is
        returned. This is a functionality which is partly dimension dependend.
-                <br>   
-                However, there should never be any reason to use this function in user codes.
+       <br>    
+       However, there should never be any reason to use this function in user codes.
        <br> 
        (Tobias Leicht 2006/06/28)
        </p>
 
   <li> <p>
-       New: There is now a new accessor function <code
-       class="member">coarser_neighbor</code>, which returns a bool value
-       <code>true</code>, if the requested neighbor is a coarser one and
-       <code>false</code> if the neighbor is as refined as the current cell. This new
-       functionality is needed in the internals of the library to decide, if
-       <code>neighbor_of_neighbor</code> or
-       <code>neighbor_of_coarser_neighbor</code> has to be called. This decision
-       is trivial in case of isotropic refinement, where the level of the cell
-       and its neighbor is all the information needed. In case of aniostropic
-       refinement, this new function can be used.
+       New: There is now a new CellAccessor::neighbor_is_coarser function,
+       which returns a bool value <code>true</code>, if the requested
+       neighbor is a coarser one and <code>false</code> if the
+       neighbor is as refined as the current cell. This new
+       functionality is needed in the internals of the library to
+       decide, if <code>neighbor_of_neighbor</code> or
+       <code>neighbor_of_coarser_neighbor</code> has to be
+       called. This decision is trivial in case of isotropic
+       refinement, where the level of the cell and its neighbor is all
+       the information needed. In case of aniostropic refinement, this
+       new function can be used.
        <br> 
        (Tobias Leicht 2006/06/28)
        </p>
 
   <li> <p>
-       New: There is now a new <code
-       class="class">Triangulation&lt;dim&gt;</code>::<code
-       class="member">MeshSmoothing</code>::<code>allow_anisotropic_smoothing</code>
-       smoothing flag for triangulations. An important part of the smoothing
-       process for refinement and coarsen flags is to ensure, that no double
-       refinement takes places at any face. If a cell is refined twice, its
-       neighbor has to be refined at least once. However, technically it is not
-       always necessary to refine the neighbor isotropically, it may be
-       sufficient to choose only one direction for the refinement. While this
-       allows to reduce the number of newly created cells to a minimum, it is incompatible
-       with older versions of the library, as anisotropic refinement takes
-       place, even if all the explicitly set refinement flags ask for
-       isotropic refinement.
-                <br>
-                Therefore this functionality is off by default. However, in order to use
+       New: There is now a new
+       <code>Triangulation::MeshSmoothing::allow_anisotropic_smoothing</code>
+       smoothing flag for triangulations. An important part of the
+       smoothing process for refinement and coarsen flags is to
+       ensure, that no double refinement takes places at any face. If
+       a cell is refined twice, its neighbor has to be refined at
+       least once. However, technically it is not always necessary to
+       refine the neighbor isotropically, it may be sufficient to
+       choose only one direction for the refinement. While this allows
+       to reduce the number of newly created cells to a minimum, it is
+       incompatible with older versions of the library, as anisotropic
+       refinement takes place, even if all the explicitly set
+       refinement flags ask for isotropic refinement.
+       <br>
+       Therefore this functionality is off by default. However, in order to use
        the new feature of anisotropic refinement to full extend, this flag should
        be set explicitly.
-                <br>
-                Note, that for reasons of backwards compatibility this flag is NOT
-       included in the general
-       <code>MeshSmoothing</code>::<code>maximum_smoothing</code> flag.
+       <br>
+       Note, that for reasons of backwards compatibility this flag is
+       NOT included in the general <code>MeshSmoothing::maximum_smoothing</code>
+       flag.
        <br> 
        (Tobias Leicht 2006/06/28)
        </p>
 
   <li> <p>
-       New: There is now a new <code
-       class="class">TriaObjectAccessor</code>::<code
-       class="member">clear_refine_case</code> function.
+       New: There is now a new
+       TriaObjectAccessor::clear_refinement_case function.
        <br> 
        (RH 2005/12/19)
        </p>
 
   <li> <p>
-       Extended: The <code
-       class="class">CellAccessor&lt;dim&gt;</code>::<code
-       class="member">neighbor_of_neighbor</code> function is now
-       extended to anisotropic refinement.
+       Extended: The CellAccessor::neighbor_of_neighbor function is
+       now extended to anisotropic refinement.
        <br> 
        (RH 2005/12/15)
        </p>
 
   <li> <p>
        Extended (internal): Lines on <code>level>0</code> have always
-       been stored pairwise. In order to allow the creation of
-       single interior lines we now also allow storage of single lines. The
-       <code class="class">TriangulationLevel&lt;1&gt;</code>::<code
-       class="member">reserve_space</code> function now takes an
-       additional <code>n_consecutive_lines</code> parameter which
-       allows to create new single as well as pairs for lines
-       (<code>n_consecutive_lines=1</code> or
+       been stored pairwise. In order to allow the creation of single
+       interior lines we now also allow storage of single lines. The
+       <tt>TriangulationLevel<1>::reserve_space</tt> function
+       now takes an additional <code>n_consecutive_lines</code>
+       parameter which allows to create new single as well as pairs
+       for lines <code>n_consecutive_lines=1</code> or
        <code>n_consecutive_lines=2</code>, respectively.
        <br> 
        (RH 2005/12/15)
@@ -359,18 +292,17 @@ refinement.
   <li> <p>
        Changed: When allowing anisotropic refinement it cannot be
        guaranteed that all children of a cell are stored in
-       consecutive components of the <code>quads.quads</code> or the
-       <code>hexes.hexes</code> vector, respectively. It is only known
-       that children are stored at least in pairs. Therefore, it is
-       not sufficient any more to store the index of the first child
-       of a cell, only. Now the indices of every second child, i.e. of
-       the even numbered children, must be stored.  For this, the
-       <code>cell-></code><code class="member">set_children</code>
-       function now has a new argument representing the number of the
-       child for which the index shall be set. This function can only
-       be called for even numbered children. The same applies to the
-       <code>face-></code><code class="member">set_children</code>
-       function.
+       consecutive components of the TriaLevel::cells vector,
+       respectively. It is only known that children are stored at
+       least in pairs. Therefore, it is not sufficient any more to
+       store the index of the first child of a cell, only. Now the
+       indices of every second child, i.e. of the even numbered
+       children, must be stored.  For this, the
+       TriaObjectAccessor::set_children function for cells now has a
+       new argument representing the number of the child for which the
+       index shall be set. This function can only be called for even
+       numbered children. The same applies to the respective function
+       for faces.
        <br> 
        Finally, we note that these functions are for internal use,
        only.
@@ -379,12 +311,10 @@ refinement.
        </p>
 
   <li> <p>
-       Changed: The <code>cell-></code><code
-       class="member">refine_flag_set</code> function now returns a
-       <code>RefineCase::Type</code> argument instead of a boolean. Be
-       aware, that you now still can ask
-       <code>if(!cell->refine_flag_set())</code> ,
-       <code>if(cell->refine_flag_set()==false)</code> and
+       Changed: The CellAccessor::refine_flag_set function now returns
+       a RefinementCase argument instead of a boolean. Be aware, that
+       you now still can ask <code>if(!cell->refine_flag_set())</code>
+       , <code>if(cell->refine_flag_set()==false)</code> and
        <code>if(cell->refine_flag_set())</code> , but you cannot ask
        <code>if(cell->refine_flag_set()==true)</code> any more.
        <br>
@@ -392,71 +322,64 @@ refinement.
        </p>
 
   <li> <p>
-       Extended: The <code>cell-></code><code
-       class="member">set_refine_flag</code> function now has a new
-       <code>RefineCase::Type</code> argument which defaults to <code
-       class="class">GeometryInfo&lt;dim&gt;</code>::<code
-       class="member">isotropic_refinement</code>.
+       Extended: The CellAccessor::set_refine_flag function now has a
+       new RefinementCase argument which defaults to
+       <tt>GeometryInfo<dim>::isotropic_refinement</tt>.
        <br>
        (RH 2005/03/03)
        </p>
 
   <li> <p>
-       New: There is now a new enum <code>RefineCase::Type</code>
-       defined in <code>geometry_info.h</code>, which allows to
-       describe all possible (anisotropic and isotropic) refinement
-       cases in (1,) 2 and 3 dimensions.
+       New: There is now a new class RefinementCase defined in
+       <code>geometry_info.h</code>, which allows to describe all
+       possible (anisotropic and isotropic) refinement cases in (1,) 2
+       and 3 dimensions.
        <br> 
        (RH 2005/02/26)
        </p>
 
   <li> <p>
-       New: There is now a new <code
-       class="class">TriaObjectAccessor</code>::<code
-       class="member">n_children</code> function which returns the
-       number of children of the cell or face it was invoked for.
+       New: There is now a new TriaObjectAccessor::n_children function
+       which returns the number of children of the cell or face it was
+       invoked for.
        <br> 
        (RH 2005/02/26)
        </p>
 
   <li> <p>
-       New: There is now a new <code
-       class="class">TriaObjectAccessor</code>::<code
-       class="member">refine_case</code> function which returns the
-       <code>RefineCase::Type</code> a cell or face is refined with.
+       New: There is now a new TriaObjectAccessor::refinement_case
+       function which returns the RefinementCase a cell or face is
+       refined with.
        <br> 
        (RH 2005/02/26)
        </p>
 
   <li> <p>
-       New: There is now a new <code
-       class="class">TriaObjectAccessor</code>::<code
-       class="member">set_refine_case</code> function. This function
-       is mainly for internal use (required by <code
-       class="class">Triangulation</code>::<code
-       class="member">execute_coarsening_and_refinement</code>). It is
-       not provided for <code>dim=1</code> as there the refinement
-       case defaults to isotropic refinement.
-       <br> 
+       New (for internal use only): There is now a new
+       TriaObjectAccessor::set_refinement_case function. This function
+       is mainly for internal use (required by
+       Triangulation::execute_coarsening_and_refinement). It is not
+       provided for <code>dim=1</code> as there the refinement case
+       defaults to isotropic refinement.
+       <br>
+       Note, that users should still use the
+       CellAccessor::set_refine_flag function for setting the
+       RefinementCase of cells to be refined within the next
+       Triangulation::execute_coarsening_and_refinement function.
+       <br>
        (RH 2005/02/26)
        </p>
 
   <li> <p>
-       New: New <code>vector&lt;RefineCase::Type&gt;
-       refine_cases</code> vectors have been introduced in <code
-       class="class">TriangulationLevel&lt;2&gt;::QuadsData</code> and
-       <code
-       class="class">TriangulationLevel&lt;3&gt;::HexesData</code>. For
-       memory efficiency (but with a penalty on run-time) they might
-       be replaced by <code>vector&lt;vector&lt;bool&gt; &gt; (dim,
-       vector&lt;bool&gt; (n_quads/n_hexes))</code>, later.
+
+       New: New <code>vector@<RefinementCase@> refinement_cases</code>
+       vectors have been introduced in TriaObjects. For memory
+       efficiency (but with a penalty on run-time) they might be
+       replaced by <code>vector@<vector@<bool@> @> (dim, vector@<bool@>
+       (n_quads/n_hexes))</code>, later.
        <br> 
        (RH 2005/02/26)
        </p>
 </ol>
 
-<hr>
-Last update $Date$
-
-</body>
-</html>
+*/
index c1b26f949c3657d44ce7911baa261b1da1cc5c95..78c41006c588dd705a21990202c59b634ba730a5 100644 (file)
@@ -8,6 +8,10 @@ made to the three sub-libraries <a href="#base">base</a>,
 <a href="#lac">lac</a>, and <a href="#deal.II">deal.II</a>, as well as
 changes to the <a href="#general">general infrastructure,
 documentation, etc</a>.
+<br>
+Furthermore, all changes which have been performed en route to
+extending deal.II from isotropic to anisotropic refinement are listed
+in this <a href="anisotropic_changes.html">list</a>.
 </p>
 
 <p>
index 586048b2b43d54c799cf31684ba48fd4e3ca0992..4d8f2462785a6028c3fe6aedd86ecb711b9e9f95 100644 (file)
@@ -176,12 +176,9 @@ void Beta<dim>::value_list(const std::vector<Point<dim> > &points,
 
   for (unsigned int i=0; i<points.size(); ++i)
     {
-      const Point<dim> &p=points[i];
-      Point<dim> &beta=values[i];
-
-      beta(0) = -p(1);
-      beta(1) = p(0);
-      beta /= std::sqrt(beta.square());
+      values[i](0) = -points[i](1);
+      values[i](1) = points[i](0);
+      values[i] /= std::sqrt(values[i].square());
     }
 }
 
@@ -657,7 +654,7 @@ void DGMethod<dim>::setup_system ()
   sparsity_pattern.reinit (dof_handler.n_dofs(),
                           dof_handler.n_dofs(),
                           (GeometryInfo<dim>::faces_per_cell
-                           *GeometryInfo<dim>::subfaces_per_face+1)*fe.dofs_per_cell);
+                           *GeometryInfo<dim>::max_children_per_face+1)*fe.dofs_per_cell);
   
                                   // For DG discretizations we call
                                   // the function analogue to
index af63ba5f362c123ef995a9994fd57ef0b2c36ba9..c635cc6320567f2f3cb6cf2d5de8e9c39b0032eb 100644 (file)
@@ -1311,7 +1311,7 @@ assemble_cross_group_rhs_recursive (const EnergyGroup<dim>
                                    // cell that has children replaced
                                    // by one of its children:
   else
-    for (unsigned int child=0; child<GeometryInfo<dim>::children_per_cell;++child)
+    for (unsigned int child=0; child<GeometryInfo<dim>::max_children_per_cell;++child)
       {
        FullMatrix<double>   new_matrix (fe.dofs_per_cell, fe.dofs_per_cell);
        fe.get_prolongation_matrix(child).mmult (new_matrix,
diff --git a/deal.II/examples/step-30/Makefile b/deal.II/examples/step-30/Makefile
new file mode 100644 (file)
index 0000000..2004c65
--- /dev/null
@@ -0,0 +1,156 @@
+# $Id$
+
+
+# For the small projects Makefile, you basically need to fill in only
+# four fields.
+#
+# The first is the name of the application. It is assumed that the
+# application name is the same as the base file name of the single C++
+# file from which the application is generated.
+target = $(basename $(shell echo step-*.cc))
+
+# The second field determines whether you want to run your program in
+# debug or optimized mode. The latter is significantly faster, but no
+# run-time checking of parameters and internal states is performed, so
+# you should set this value to `on' while you develop your program,
+# and to `off' when running production computations.
+debug-mode = on
+
+
+# As third field, we need to give the path to the top-level deal.II
+# directory. You need to adjust this to your needs. Since this path is
+# probably the most often needed one in the Makefile internals, it is
+# designated by a single-character variable, since that can be
+# reference using $D only, i.e. without the parentheses that are
+# required for most other parameters, as e.g. in $(target).
+D = ../../
+
+
+# The last field specifies the names of data and other files that
+# shall be deleted when calling `make clean'. Object and backup files,
+# executables and the like are removed anyway. Here, we give a list of
+# files in the various output formats that deal.II supports.
+clean-up-files = *gmv *gnuplot *gpl *eps *pov
+
+
+
+
+#
+#
+# Usually, you will not need to change something beyond this point.
+#
+#
+# The next statement tell the `make' program where to find the
+# deal.II top level directory and to include the file with the global
+# settings
+include $D/common/Make.global_options
+
+
+# Since the whole project consists of only one file, we need not
+# consider difficult dependencies. We only have to declare the
+# libraries which we want to link to the object file, and there need
+# to be two sets of libraries: one for the debug mode version of the
+# application and one for the optimized mode. Here we have selected
+# the versions for 2d. Note that the order in which the libraries are
+# given here is important and that your applications won't link
+# properly if they are given in another order.
+#
+# You may need to augment the lists of libraries when compiling your
+# program for other dimensions, or when using third party libraries
+libs.g   = $(lib-deal2-2d.g) \
+           $(lib-deal2-3d.g) \
+           $(lib-lac.g)      \
+           $(lib-base.g)
+libs.o   = $(lib-deal2-2d.o) \
+           $(lib-deal2-3d.o) \
+           $(lib-lac.o)      \
+           $(lib-base.o)
+
+
+# We now use the variable defined above which switch between debug and
+# optimized mode to select the set of libraries to link with. Included
+# in the list of libraries is the name of the object file which we
+# will produce from the single C++ file. Note that by default we use
+# the extension .g.o for object files compiled in debug mode and .o for
+# object files in optimized mode (or whatever the local default on your
+# system is instead of .o).
+ifeq ($(debug-mode),on)
+  libraries = $(target).g.$(OBJEXT) $(libs.g)
+else
+  libraries = $(target).$(OBJEXT) $(libs.o)
+endif
+
+
+# Now comes the first production rule: how to link the single object
+# file produced from the single C++ file into the executable. Since
+# this is the first rule in the Makefile, it is the one `make' selects
+# if you call it without arguments.
+$(target) : $(libraries)
+       @echo ============================ Linking $@
+       @$(CXX) -o $@$(EXEEXT) $^ $(LIBS) $(LDFLAGS)
+
+
+# To make running the application somewhat independent of the actual
+# program name, we usually declare a rule `run' which simply runs the
+# program. You can then run it by typing `make run'. This is also
+# useful if you want to call the executable with arguments which do
+# not change frequently. You may then want to add them to the
+# following rule:
+run: $(target)
+       @echo ============================ Running $<
+       @./$(target)$(EXEEXT)
+
+
+# As a last rule to the `make' program, we define what to do when
+# cleaning up a directory. This usually involves deleting object files
+# and other automatically created files such as the executable itself,
+# backup files, and data files. Since the latter are not usually quite
+# diverse, you needed to declare them at the top of this file.
+clean:
+       -rm -f *.$(OBJEXT) *~ Makefile.dep $(target)$(EXEEXT) $(clean-up-files)
+
+
+# Since we have not yet stated how to make an object file from a C++
+# file, we should do so now. Since the many flags passed to the
+# compiler are usually not of much interest, we suppress the actual
+# command line using the `at' sign in the first column of the rules
+# and write the string indicating what we do instead.
+./%.g.$(OBJEXT) :
+       @echo ==============debug========= $(<F)
+       @$(CXX) $(CXXFLAGS.g) -c $< -o $@
+./%.$(OBJEXT) :
+       @echo ==============optimized===== $(<F)
+       @$(CXX) $(CXXFLAGS.o) -c $< -o $@
+
+
+# The following statement tells make that the rules `run' and `clean'
+# are not expected to produce files of the same name as Makefile rules
+# usually do.
+.PHONY: run clean
+
+
+# Finally there is a rule which you normally need not care much about:
+# since the executable depends on some include files from the library,
+# besides the C++ application file of course, it is necessary to
+# re-generate the executable when one of the files it depends on has
+# changed. The following rule to created a dependency file
+# `Makefile.dep', which `make' uses to determine when to regenerate
+# the executable. This file is automagically remade whenever needed,
+# i.e. whenever one of the cc-/h-files changed. Make detects whether
+# to remake this file upon inclusion at the bottom of this file.
+#
+# If the creation of Makefile.dep fails, blow it away and fail
+Makefile.dep: $(target).cc Makefile \
+              $(shell echo $D/*/include/*/*.h)
+       @echo ============================ Remaking $@
+       @$D/common/scripts/make_dependencies  $(INCLUDE) -B. $(target).cc \
+               > $@ \
+         || (rm -f $@ ; false)
+       @if test -s $@ ; then : else rm $@ ; fi
+
+
+# To make the dependencies known to `make', we finally have to include
+# them:
+include Makefile.dep
+
+
diff --git a/deal.II/examples/step-30/doc/intro.dox b/deal.II/examples/step-30/doc/intro.dox
new file mode 100644 (file)
index 0000000..e6d2606
--- /dev/null
@@ -0,0 +1,482 @@
+<a name="Intro"></a>
+<h1>Introduction</h1>
+
+
+<h3>Overview</h3>
+
+This example is devoted to <em>anisotropic refinement</em>, which extends to
+possibilities of local refinement. In most parts, this is a modification of the
+@ref step_12 "step-12" tutorial program, we use the same DG method for a linear transport
+equation. This program will cover the following topics:
+<ol>
+  <li> <em>Anisotropic refinement</em>: What is the meaning of anisotropic refinement?
+  <li> <em>Implementation</em>: Necessary modifications of code to work with anisotropically refined meshes.
+  <li> <em>Jump indicator</em>: A simple indicator for anisotropic refinement in
+  the context of DG methods.
+</ol>
+The discretization itself will not be discussed, and neither will
+implementation techniques not specific to anisotropic refinement used
+here. Please refer to @ref step_12 "step-12" for this.
+
+Please note, at the moment of writing this tutorial program, anisotropic
+refinement is only fully implemented for discontinuous Galerkin Finite
+Elements. This may later change (or may already have).
+
+
+<h3>Anisotropic refinement</h3>
+
+All the adaptive processes in the preceding tutorial programs were based on
+<em>isotropic</em> refinement of cells, which cuts all edges in half and forms
+new cells of these split edges (plus some additional edges, faces and vertices,
+of course). In deal.II, <em>anisotropic refinement</em> refers to the process of
+splitting only part of the edges while leaving the others unchanged. Consider a
+simple square cell, for example:
+@code
+  *-------*
+  |       |
+  |       |
+  |       |
+  *-------*
+@endcode 
+After the usual refinement it will consist of four children and look like this:
+@code
+  *---*---*
+  |   |   |
+  *---*---*     RefinementCase<2>::cut_xy
+  |   |   |
+  *---*---*
+@endcode
+The new anisotropic refinement may take two forms: either we can split the edges
+which are parallel to the horizontal x-axis, resulting in these two child cells:
+@code
+  *---*---*
+  |   |   |
+  |   |   |     RefinementCase<2>::cut_x
+  |   |   |
+  *---*---*
+@endcode
+or we can split the two edges which run along the y-axis, resulting again in two
+children, which look that way, however:
+@code
+  *-------*
+  |       |
+  *-------*     RefinementCase<2>::cut_y
+  |       |
+  *-------*
+@endcode
+All refinement cases of cells are described by an enumeration
+RefinementPossibilities::Possibilities, and the above anisotropic
+cases are called @p cut_x and @p cut_y for obvious reasons. The
+isotropic refinement case is called @p cut_xy in 2D and can be
+requested from the GeometryInfo class via
+GeometryInfo<2>::isotropic_refinement.
+
+In 3D, there is a third axis which can be split, the z-axis, and thus we
+have an additional refinement case @p cut_z here. Isotropic refinement will now
+refine a cell along the x-, y- and z-axes and thus be referred to as @p
+cut_xyz. Additional cases @p cut_xy, @p cut_xz and @p cut_yz exist, which refine
+a cell along two of the axes, but not along the third one. Given a hex cell with
+x-axis running to the right, y-axis 'into the page' and z-axis to the top,
+@code
+      *-----------*
+     /           /|
+    /           / |
+   /           /  |
+  *-----------*   |
+  |           |   |
+  |           |   * 
+  |           |  /
+  |           | /
+  |           |/
+  *-----------*
+@endcode 
+we have the isotropic refinement case,
+@code
+      *-----*-----*
+     /     /     /|
+    *-----*-----* |
+   /     /     /| *
+  *-----*-----* |/|
+  |     |     | * |
+  |     |     |/| * 
+  *-----*-----* |/
+  |     |     | *
+  |     |     |/
+  *-----*-----*
+
+     cut_xyz
+@endcode 
+three anisotropic cases which refine only one axis:
+@code
+      *-----*-----*           *-----------*           *-----------*  
+     /     /     /|          /           /|          /           /|  
+    /     /     / |         *-----------* |         /           / |  
+   /     /     /  |        /           /| |        /           /  *  
+  *-----*-----*   |       *-----------* | |       *-----------*  /|  
+  |     |     |   |       |           | | |       |           | / |  
+  |     |     |   *       |           | | *       |           |/  *  
+  |     |     |  /        |           | |/        *-----------*  /   
+  |     |     | /         |           | *         |           | /    
+  |     |     |/          |           |/          |           |/     
+  *-----*-----*           *-----------*           *-----------*      
+                                                                                                            
+     cut_x                   cut_y                   cut_z           
+@endcode 
+and three cases which refine two of the three axes:
+@code
+      *-----*-----*           *-----*-----*           *-----------*  
+     /     /     /|          /     /     /|          /           /|  
+    *-----*-----* |         /     /     / |         *-----------* |  
+   /     /     /| |        /     /     /  *        /           /| *  
+  *-----*-----* | |       *-----*-----*  /|       *-----------* |/|  
+  |     |     | | |       |     |     | / |       |           | * |  
+  |     |     | | *       |     |     |/  *       |           |/| *  
+  |     |     | |/        *-----*-----*  /        *-----------* |/   
+  |     |     | *         |     |     | /         |           | *    
+  |     |     |/          |     |     |/          |           |/     
+  *-----*-----*           *-----*-----*           *-----------*      
+                                                                                                            
+     cut_xy                  cut_xz                  cut_yz       
+@endcode 
+For 1D problems, anisotropic refinement can make no difference, as there is only
+one coordinate direction for a cell, so it is not possible to split it
+in any other way than isotropically.
+
+<h4>Motivation</h4>
+Adaptive local refinement is used to obtain fine meshes which are well adapted
+to solving the problem at hand efficiently. In short, the size of cells which
+produce a large error is reduced to obtain a better approximation of the
+solution to the problem at hand. However, a lot of problems contain anisotropic
+features. Prominent examples are shocks or boundary layers in compressible
+viscous flows. An efficient mesh approximates these features with cells of higher aspect ratio
+which are oriented according to the mentioned features. Using only isotropic
+refinement, the aspect ratios of the original mesh cells are preserved, as they
+are inherited by the children of a cell. Thus, starting from an isotropic mesh, a
+boundary layer will be refined in order to catch the rapid variation of the flow
+field in the wall normal direction, thus leading to cells with very small edge
+lengths both in normal and tangential direction. Usually, much higher edge
+lengths in tangential direction and thus significantly less cells could be used
+without a significant loss in approximation accuracy. An anisotropic
+refinement process can modify the aspect ratio from mother to child cells by a
+factor of two for each refinement step. In the course of several refinements,
+the aspect ratio of the fine cells can be optimized, saving a considerable
+number of cells and correspondingly degrees of freedom and thus computational
+resources, memory as well as CPU time.
+
+<h3>Implementation</h3>
+
+Most of the time, when we do finite element computations, we only consider one
+cell at a time, for example to calculate cell contributions to the global
+matrix, or to interpolate boundary values. However, sometimes we have to look
+at how cells are related in our algorithms. Relationships between cells come
+in two forms: neighborship and mother-child relationship. For the case of
+isotropic refinement, deal.II uses certain conventions (invariants) for cell
+relationships that are always maintained. For example, a refined cell always
+has exactly $2^{dim}$ children. And (except for the 1d case), two neighboring
+cells may differ by at most one refinement level: they are equally often
+refined or one of them is exactly once more refined, leaving exactly one
+hanging node on the common face. Almost all of the time these invariants are
+only of concern in the internal implementation of the library. However, there
+are cases where knowledge of them is also relevant to an application program.
+
+In the current context, it is worth noting that the kind of mesh refinement
+affects some of the most fundamental assumptions. Consequently, some of the
+usual code found in application programs will need modifications to exploit
+the features of meshes which were created using anisotropic
+refinement. For those interested in how deal.II evolved, it may be of
+interest that the losening of such invariants required some
+incompatible changes. For example, the library used to have a member
+GeometryInfo<dim>::children_per_cell that specified how many children
+a cell has once it is refined. For isotropic refinement, this number
+is equal to $2^{dim}$, as mentioned above. However, for anisotropic refinement, this number
+does not exist, as is can be either two or four in 2D and two, four or eight in
+3D, and the member GeometryInfo<dim>::children_per_cell has
+consequently been removed. It has now been replaced by
+GeometryInfo<dim>::max_children_per_cell which specifies the
+<i>maximum</i> number of children a cell can have. How many children a
+refined cell has was previously available as static informtion, but
+now it depends on the actual refinement state of a cell and can be
+retrieved using the function call <code>cell-@>n_children()</code>,
+a call that works equally well for both isotropic and anisotropic
+refinement. A very similar situation can be found for
+faces and their subfaces: the previously available variable
+GeometryInfo<dim>::subfaces_per_face no 
+longer exists; the pertinent information can now be queried using
+GeometryInfo<dim>::max_children_per_face or <code>face->n_children()</code>,
+depending on the context.
+
+Another important aspect, and the most important one in this tutorial, is
+the treatment of neighbor-relations when assembling jump terms on the
+faces between cells. Looking at the documentation of the
+assemble_system functions in @ref step_12 "step-12" we notice, that we need to decide if a
+neighboring cell is coarser, finer or on the same (refinement) level as our
+current cell. These decisions do not work in the same way for anisotropic
+refinement as the information given by the <em>level</em> of a cell is not
+enough to completely characterize anisotropic cells; for example, are
+the terminal children of a two-dimensional
+cell that is first cut in $x$-direction and whose children are then
+cut in $y$-direction on level 2, or are they on level 1 as they would
+be if the cell would have been refined once isotropically, resulting
+in the same set of finest cells?
+
+After anisotropic refinement, a coarser neighbor is not necessarily
+exactly one level below ours, but can pretty much have any level
+relative to the current one; in fact, it can even be on a higher
+level even though it is coarser. Thus the decisions
+have to be made on a different basis, whereas the intention of the
+decisions stays the same. 
+
+In the following, we will discuss the cases that can happen when we
+want to compute contributions to the matrix (or right hand side) of
+the form 
+@f[
+  \int_{\partial K} \varphi_i(x) \varphi_j(x) \; dx
+@f]
+or similar; remember that we integrate terms like this using the
+FEFaceValues and FESubfaceValues classes. We will also show how to
+write code that works for both isotropic and anisotropic refinement:
+
+<ul>
+  <li> <em>Finer neighbor</em>: If we are on an active cell and want
+  to integrate over a face $f\subset \partial K$, the first
+  possibility is that the neighbor behind this face is more refined,
+  i.e. has children occupying only part of the
+  common face. In this case, the face
+  under consideration has to be a refined one, which can determine by
+  asking <code>if(face->has_children())</code>. If this is true, we need to
+  loop over 
+  all subfaces and get the neighbors' child behind this subface, so that we can
+  reinit an FEFaceValues object with the neighbor and an FESubfaceValues object
+  with our cell and the respective subface. 
+
+  For isotropic refinement, this kind is reasonably simple because we
+  know that an invariant of the isotropically refined adaptive meshes
+  in deal.II is that neighbors can only differ by exactly one
+  refinement level. However, this isn't quite true any more for
+  anisotropically refined meshes, in particular in 3d; there,
+  the active cell we are interested on the other side of $f$ might not
+  actually be a child of our 
+  neighbor, but perhaps a grandchild or even a farther offspring. Fortunately,
+  this complexity is hidden in the internals of the library. All we need to do
+  is call the <code>cell->neighbor_child_on_subface(face_no, subface_no)</code>
+  function. Still, in 3D there are two cases which need special consideration:
+  <ul>
+    <li> If the neighbor is refined more than once anisotropically, it might be
+  that here are not two or four but actually three subfaces to
+  consider. Imagine 
+  the following refinement process of the (two-dimensional) face of
+  the (three-dimensional) neighbor cell we are considering: first the
+  face is refined along x, later on only the left subface is refined along y.
+@code
+   *-------*        *---*---*        *---*---*
+   |       |        |   |   |        |   |   |
+   |       |  --->  |   |   |  --->  *---*   |
+   |       |        |   |   |        |   |   |
+   *-------*        *---*---*        *---*---*
+@endcode
+     Here the number of subfaces is three. It is important to note the subtle
+  differences between <code>face->n_children()</code> and
+  <code>face->number_of_children()</code>. The first function returns the number of
+  immediate children, which would be two for the above example, whereas the
+  second returns the number of active offsprings, which is the correct three in
+  the example above. Using <code>face->number_of_children()</code> works for 
+  isotropic and anisotropic as well as 2D and 3D cases, so it should always be
+  used. It should be noted that if any of the cells behind the two
+  small subfaces on the left side of the rightmost image is further
+  refined, then the current cell (i.e. the side from which we are
+  viewing this common face) is going to be refined as well: this is so
+  because otherwise the invariant of having only one hanging node per
+  edge would be violated.
+
+    <li> It might be, that the neighbor is coarser, but still has children which
+  are finer than our current cell. This situation can occur if two equally
+  coarse cells are refined, where one of the cells has two children at the face
+  under consideration and the other one four. The cells in the next graphic are
+  only separated from each other to show the individual refinement cases. 
+@code
+      *-----------*     *-----------* 
+     /           /|    /           /| 
+    ############# |   +++++++++++++ | 
+   #           ## |  +           ++ * 
+  ############# # | +++++++++++++ +/| 
+  #           # # | +           + + | 
+  #           # # * +           +++ * 
+  #           # #/  +++++++++++++ +/  
+  #           # #   +           + +   
+  #           ##    +           ++    
+  #############     +++++++++++++     
+@endcode 
+
+  Here, the left two cells resulted from an anisotropic bisection of
+  the mother cell in $y$-direction, whereas the right four cells
+  resulted from a simultaneous anisotropic refinement in both the $y$-
+  and $z$-directions. 
+  The left cell marked with # has two finer neighbors marked with +, but the
+  actual neighbor of the left cell is the complete right mother cell, as the
+  two cells marked with + are finer and their direct mother is the one
+  large cell.
+  </ul>
+
+  However, it is comfortable to know, that
+  <code>cell->neighbor_child_on_subface(face_no,subface_no)</code> takes care of
+  these situations by itself, if you loop over the correct number of subfaces,
+  in the above example this is two. The FESubfaceValues<dim>::reinit function
+  takes care of this too, so that the resulting state is always correct. There
+  is one little aspect, however: For reiniting the neighbors FEFaceValues object
+  you need to know the index of the face that points toward the current
+  cell. Usually you assume that the neighbor you get directly is as coarse or as
+  fine as you, if it has children, thus this information can be obtained by the
+  <code>cell->neighbor_of_neighbor(face_no)</code> function. If the neighbor is
+  coarser, however, you would have to use
+  <code>cell->neighbor_of_coarser_neighbor(face_no).first</code> instead. In order
+  to make this easy for you, there is the new
+  <code>cell->neighbor_face_no(face_no)</code> function which does the correct thing
+  for you and returns the desired result.
+
+  <li> <em>Neighbor is as fine as our cell</em>: After we ruled out all cases in
+  which there are finer children, we only need to decide, whether the neighbor
+  is coarser here. For this, there is the
+  <code>cell->coarser_neighbor(face_no)</code> function returning a bool value. In
+  order to get the relevant case of a neighbor of the same coarseness we would
+  use <code>else if (!cell->coarser_neighbor(face_no))</code>. The code inside this
+  block can be left untouched. However, there is one thing to mention here: If
+  we want to use a rule, which cell should assemble certain terms on a given
+  face we might think of the rule presented in @ref step_12 "step-12". We know that we have to
+  leave out the part about comparing our cell's level with that of the neighbor
+  and replace it with the test for a coarser neighbor presented above. However,
+  we also have to consider the possibility that neighboring cells of same
+  coarseness have the same index (on different levels). Thus we have to include
+  the case where the cells have the same index, and give an additional
+  condition, which of the cells should assemble the terms, e.g. we can choose
+  the cell with lower level. The details of this concept can be seen in the
+  implementation below. 
+
+  <li> <em>Coarser neighbor</em>: The remaining case is obvious: If there are no
+  refined neighbors and the neighbor is not as fine as the current cell, then it needs
+  to be coarser. Thus we can leave the old condition phrase, simply using
+  <code>else</code>. The <code>cell->neighbor_of_coarser_neighbor(face_no)</code>
+  function takes care of all the complexity of anisotropic refinement combined
+  with possible non standard face orientation, flip and rotation on general 3D meshes.
+
+</ul>
+
+<h4>Mesh smoothing</h4>
+When a triangulation is refined, cells which were not flagged for refinement may
+be refined nonetheless. This is due to additional smoothing algorithms which are
+either necessary or requested explicitly. In particular, the restriction that there
+be at most one hanging node on each edge frequently forces the refinement of additional
+cells neighboring ones that are already finer and are flagged for
+further refinement.
+
+However, deal.II also implements a number of algorithms that make sure
+that resulting meshes are smoother than just the bare minimum, for
+example ensuring that there are no isolated refined cells surrounded
+by non-refined ones, since the additional degrees of freedom on these
+islands would almost all be constrained by hanging node
+constraints. (See the documentation of the Triangulation class and its
+Triangulation::MeshSmoothing member for more information on mesh
+smoothing.)
+
+Most of the smoothing algorithms that were originally developed for
+the isotropic case have been adapted to work in a very similar
+way for both anisotropic and isotropic refinement. There are two
+algorithms worth mentioning, however:
+<ol>
+  <li> <code>MeshSmoothing::limit_level_difference_at_vertices</code>: In an isotropic environment,
+  this algorithm tries to ensure a good approximation quality by reducing the
+  difference in refinement level of cells meeting at a common vertex. However,
+  there is no clear corresponding concept for anisotropic refinement, thus this
+  algorithm may not be used in combination with anisotropic refinement. This
+  restriction is enforced by an assertion which throws an error as soon as the
+  algorithm is called on a triangulation which has been refined anisotropically.
+
+  <li> <code>MeshSmoothing::allow_anisotropic_smoothing</code>: If refinement is introduced to
+  limit the number of hanging nodes, the additional cells are often not needed
+  to improve the approximation quality. This is especially true for DG
+  methods. If you set the flag <code>allow_anisotropic_smoothing</code> the
+  smoothing algorithm tries to minimize the number of probably unneeded
+  additional cells by using anisotropic refinement for the smoothing. If you set
+  this smoothing flag you might get anisotropically refined cells, even if you
+  never set a single refinement flag to anisotropic refinement. Be aware that
+  you should only use this flag, if your code respects the possibility of
+  anisotropic meshes. Combined with a suitable anisotropic indicator this flag
+  can help save additional cells and thus effort.
+</ol>
+
+
+<h3>Jump indicator</h3>
+
+Using the benefits of anisotropic refinement requires an indicator to catch
+anisotropic features of the solution and exploit them for the refinement
+process. Generally the anisotropic refinement process will consist of several
+steps: 
+<ol>
+  <li> Calculate an error indicator.
+  <li> Use the error indicator to flag cells for refinement, e.g. using a fixed
+  number or fraction of cells. Those cells will be flagged for isotropic
+  refinement automatically.
+  <li> Evaluate a distinct anisotropic indicator only on the flagged cells.
+  <li> Use the anisotropic indicator to set a new, anisotropic refinement flag
+  for cells where this is appropriate, leave the flags unchanged otherwise.
+  <li> Call Triangulation<dim>::execute_coarsening_and_refinement to perform the
+  requested refinement, using the requested isotropic and anisotropic flags.
+</ol>
+This approach is similar to the one we have used in @ref step_27 "step-27" 
+for hp refinement and
+has the great advantage of flexibility: Any error indicator can be
+used in the anisotropic process, i.e. if you have quite involved a posteriori
+goal-oriented error indicators available you can use them as easily as a simple
+Kelly error estimator. The anisotropic part of the refinement process is not
+influenced by this choice. Furthermore, simply leaving out the third and forth
+steps leads to the same isotropic refinement you used to get before any
+anisotropic changes in deal.II or your application program.
+As a last advantage, working only
+on cells flagged for refinement results in a faster evaluation of the
+anisotropic indicator, which can become noticeable on finer meshes with a lot of
+cells if the indicator is quite involved.
+
+Here, we use a very simple approach which is only applicable to DG
+methods. The general idea is quite simple: DG methods allow the discrete
+solution to jump over the faces of a cell, whereas it is smooth within each
+cell. Of course, in the limit we expect that the jumps tend to zero as
+we refine the mesh and approximate the true solution better and better.
+Thus, a large jump
+across a given face indicates that the cell should be refined (at least)
+orthogonal to that face, whereas a small jump does not lead to this
+conclusion. It is possible, of course, that the exact solution is not smooth and
+that it also features a jump. In that case, however, a large jump over one face
+indicates, that this face is more or less parallel to the jump and in the
+vicinity of it, thus again we would expect a refinement orthogonal to the face
+under consideration to be effective.
+
+The proposed indicator calculates the average jump $K_j$, i.e. the mean value of
+the absolute jump $|[u]|$ of the discrete solution $u$ over the two faces
+$f_i^j$, $i=1,2$, $j=1..d$ orthogonal to coordinate direction $j$ on the unit
+cell.
+@f[
+K_j = \frac{\sum_{i=1}^2 \int_{f_i^j}|[u]| dx}{\sum_{i=1}^2 |f_i^j|} .
+@f]
+If the average jump in one direction is larger than the average of the
+jumps in the other directions by a
+certain factor $\kappa$, i.e. if
+$K_i > \kappa \frac 1{d-1} \sum_{j=1, j\neq i}^d K_j$, the cell is refined only along that particular
+direction $i$, otherwise the cell is refined isotropically. 
+
+Such a criterion is easily generalized to systems of equations: the
+absolute value of the jump would be replaced by an appropriate norm of
+the vector-valued jump.
+
+
+
+<h3>The problem</h3>
+
+We solve the linear transport equation presented in @ref step_12 "step-12". The domain is
+extended to cover $[-1,1]\times[0,1]$ in 2D, where the flow field $\beta$ describes a
+counterclockwise quarter circle around the origin in the right half of the
+domain and is parallel to the x-axis in the left part of the domain. The inflow
+boundary is again located at $x=1$ and along the positive part of the x-axis,
+and the boundary conditions are chosen as in @ref step_12 "step-12". Compared to @ref step_12 "step-12" we
+only use the more effective second assembling technique. In order to make
+comparisons more effective, we decided to keep function names like @p
+assemble_system2 even if there is only one of these routines in this tutorial
+program.
diff --git a/deal.II/examples/step-30/doc/results.dox b/deal.II/examples/step-30/doc/results.dox
new file mode 100644 (file)
index 0000000..c608df5
--- /dev/null
@@ -0,0 +1,151 @@
+<h1>Results</h1>
+
+
+The output of this program consist of the console output, the eps
+files containing the grids, and the grids and solutions given in gnuplot format.
+@code
+Performing a 2D run with isotropic refinement...
+------------------------------------------------
+Cycle 0:
+   Number of active cells:       128
+   Number of degrees of freedom: 512
+Time of assemble_system2: 0.040003
+Writing grid to <grid-0.iso.eps>...
+Writing grid to <grid-0.iso.gnuplot>...
+Writing solution to <sol-0.iso.gnuplot>...
+Cycle 1:
+   Number of active cells:       239
+   Number of degrees of freedom: 956
+Time of assemble_system2: 0.072005
+Writing grid to <grid-1.iso.eps>...
+Writing grid to <grid-1.iso.gnuplot>...
+Writing solution to <sol-1.iso.gnuplot>...
+Cycle 2:
+   Number of active cells:       491
+   Number of degrees of freedom: 1964
+Time of assemble_system2: 0.144009
+Writing grid to <grid-2.iso.eps>...
+Writing grid to <grid-2.iso.gnuplot>...
+Writing solution to <sol-2.iso.gnuplot>...
+Cycle 3:
+   Number of active cells:       1031
+   Number of degrees of freedom: 4124
+Time of assemble_system2: 0.296019
+Writing grid to <grid-3.iso.eps>...
+Writing grid to <grid-3.iso.gnuplot>...
+Writing solution to <sol-3.iso.gnuplot>...
+Cycle 4:
+   Number of active cells:       2027
+   Number of degrees of freedom: 8108
+Time of assemble_system2: 0.576036
+Writing grid to <grid-4.iso.eps>...
+Writing grid to <grid-4.iso.gnuplot>...
+Writing solution to <sol-4.iso.gnuplot>...
+Cycle 5:
+   Number of active cells:       4019
+   Number of degrees of freedom: 16076
+Time of assemble_system2: 1.13607
+Writing grid to <grid-5.iso.eps>...
+Writing grid to <grid-5.iso.gnuplot>...
+Writing solution to <sol-5.iso.gnuplot>...
+
+Performing a 2D run with anisotropic refinement...
+--------------------------------------------------
+Cycle 0:
+   Number of active cells:       128
+   Number of degrees of freedom: 512
+Time of assemble_system2: 0.040003
+Writing grid to <grid-0.aniso.eps>...
+Writing grid to <grid-0.aniso.gnuplot>...
+Writing solution to <sol-0.aniso.gnuplot>...
+Cycle 1:
+   Number of active cells:       171
+   Number of degrees of freedom: 684
+Time of assemble_system2: 0.048003
+Writing grid to <grid-1.aniso.eps>...
+Writing grid to <grid-1.aniso.gnuplot>...
+Writing solution to <sol-1.aniso.gnuplot>...
+Cycle 2:
+   Number of active cells:       255
+   Number of degrees of freedom: 1020
+Time of assemble_system2: 0.072005
+Writing grid to <grid-2.aniso.eps>...
+Writing grid to <grid-2.aniso.gnuplot>...
+Writing solution to <sol-2.aniso.gnuplot>...
+Cycle 3:
+   Number of active cells:       397
+   Number of degrees of freedom: 1588
+Time of assemble_system2: 0.16401
+Writing grid to <grid-3.aniso.eps>...
+Writing grid to <grid-3.aniso.gnuplot>...
+Writing solution to <sol-3.aniso.gnuplot>...
+Cycle 4:
+   Number of active cells:       658
+   Number of degrees of freedom: 2632
+Time of assemble_system2: 0.192012
+Writing grid to <grid-4.aniso.eps>...
+Writing grid to <grid-4.aniso.gnuplot>...
+Writing solution to <sol-4.aniso.gnuplot>...
+Cycle 5:
+   Number of active cells:       1056
+   Number of degrees of freedom: 4224
+Time of assemble_system2: 0.304019
+Writing grid to <grid-5.aniso.eps>...
+Writing grid to <grid-5.aniso.gnuplot>...
+Writing solution to <sol-5.aniso.gnuplot>...
+@endcode
+
+This text output shows the reduction in the number of cells which results from
+the successive application of anisotropic refinement. After the last refinement
+step the savings have accumulated so much, that almost four times as many cells
+and thus dofs are needed in the isotropic case. The time needed for assembly
+scales with a similar factor.
+
+Now we show the solutions on the mesh after one and after five adaptive
+refinement steps for both the isotropic (left) and anisotropic refinement
+algorithms (right).
+
+<TABLE WIDTH="60%" ALIGN="center">
+  <tr>
+    <td ALIGN="center">
+      @image html step-30.sol-1.iso.png
+    </td>
+
+    <td ALIGN="center">
+      @image html step-30.sol-1.aniso.png
+    </td>
+  </tr>
+  <tr>
+    <td ALIGN="center">
+      @image html step-30.sol-5.iso.png
+    </td>
+
+    <td ALIGN="center">
+      @image html step-30.sol-5.aniso.png
+    </td>
+  </tr>
+</table>
+
+We see, that the solution on the anisotropically refined mesh is very similar to
+the solution obtained on the isotropically refined mesh. Thus the anisotropic
+indicator seems to effectively select the appropriate cells for anisotropic
+refinement. This observation is strengthened by the plot of the an adapted
+anisotropic grid, e.g. the grid after three refinement steps.
+
+@image html step-30.grid-3.aniso.png
+
+In the whole left part of the domain refinement is only performed along the
+y-axis of cells. In the right part of the domain the refinement is dominated by
+isotropic refinement, as the anisotropic feature of the solution - the jump from
+one to zero - is not well aligned with the mesh. However, at the bottom and
+leftmost parts of the quarter circle this jumps becomes more and more aligned
+with the mesh and the refinement algorithm reacts by creating anisotropic cells
+of increasing aspect ratio.
+
+It might seem that the necessary alignment of anisotropic features and the
+coarse mesh can decrease performance significantly for real world
+problems. However, that is not always the case. Considering boundary layers in
+compressible viscous flows, for example, the mesh is always aligned with the
+anisotropic features, thus anisotropic refinement will almost alway increase the
+efficiency of computations on adapted grids for these cases.
+
diff --git a/deal.II/examples/step-30/doc/step-30.grid-3.aniso.png b/deal.II/examples/step-30/doc/step-30.grid-3.aniso.png
new file mode 100644 (file)
index 0000000..89c9aaf
Binary files /dev/null and b/deal.II/examples/step-30/doc/step-30.grid-3.aniso.png differ
diff --git a/deal.II/examples/step-30/doc/step-30.sol-1.aniso.png b/deal.II/examples/step-30/doc/step-30.sol-1.aniso.png
new file mode 100644 (file)
index 0000000..5d82ebd
Binary files /dev/null and b/deal.II/examples/step-30/doc/step-30.sol-1.aniso.png differ
diff --git a/deal.II/examples/step-30/doc/step-30.sol-1.iso.png b/deal.II/examples/step-30/doc/step-30.sol-1.iso.png
new file mode 100644 (file)
index 0000000..1d9e828
Binary files /dev/null and b/deal.II/examples/step-30/doc/step-30.sol-1.iso.png differ
diff --git a/deal.II/examples/step-30/doc/step-30.sol-5.aniso.png b/deal.II/examples/step-30/doc/step-30.sol-5.aniso.png
new file mode 100644 (file)
index 0000000..140d092
Binary files /dev/null and b/deal.II/examples/step-30/doc/step-30.sol-5.aniso.png differ
diff --git a/deal.II/examples/step-30/doc/step-30.sol-5.iso.png b/deal.II/examples/step-30/doc/step-30.sol-5.iso.png
new file mode 100644 (file)
index 0000000..0174c28
Binary files /dev/null and b/deal.II/examples/step-30/doc/step-30.sol-5.iso.png differ
diff --git a/deal.II/examples/step-30/step-30.cc b/deal.II/examples/step-30/step-30.cc
new file mode 100644 (file)
index 0000000..0f4137e
--- /dev/null
@@ -0,0 +1,1196 @@
+/* $Id$ */
+/* Author: Tobias Leicht, 2007 */
+
+/*    $Id$       */
+/*    Version: $Name$                                          */
+/*                                                                */
+/*    Copyright (C) 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     */
+/*    to the file deal.II/doc/license.html for the  text  and     */
+/*    further information on this license.                        */
+
+                                // The deal.II include files have already
+                                // been covered in previous examples
+                                // and will thus not be further
+                                // commented on.
+#include <base/quadrature_lib.h>
+#include <base/function.h>
+#include <lac/vector.h>
+#include <lac/sparse_matrix.h>
+#include <grid/tria.h>
+#include <grid/grid_generator.h>
+#include <grid/grid_out.h>
+#include <grid/grid_refinement.h>
+#include <grid/tria_accessor.h>
+#include <grid/tria_iterator.h>
+#include <fe/fe_values.h>
+#include <dofs/dof_handler.h>
+#include <dofs/dof_accessor.h>
+#include <dofs/dof_tools.h>
+#include <numerics/data_out.h>
+#include <fe/mapping_q1.h>
+#include <fe/fe_dgq.h>
+#include <lac/solver_richardson.h>
+#include <lac/precondition_block.h>
+#include <numerics/derivative_approximation.h>
+#include <base/timer.h>
+
+                                // And this again is C++:
+#include <iostream>
+#include <fstream>
+
+                                // The last step is as in all
+                                // previous programs:
+using namespace dealii;
+
+                                // @sect3{Equation data}
+                                //
+                                // The classes describing equation data and the
+                                // actual assembly of individual terms are
+                                // almost entirely copied from step-12. We will
+                                // comment on differences.
+template <int dim>
+class RHS:  public Function<dim>
+{
+  public:
+    virtual void value_list (const std::vector<Point<dim> > &points,
+                            std::vector<double> &values,
+                            const unsigned int component=0) const;
+};
+
+
+template <int dim>
+class BoundaryValues:  public Function<dim>
+{
+  public:
+    virtual void value_list (const std::vector<Point<dim> > &points,
+                            std::vector<double> &values,
+                            const unsigned int component=0) const;
+};
+
+
+template <int dim>
+class Beta
+{
+  public:
+    Beta () {}
+    void value_list (const std::vector<Point<dim> > &points,
+                    std::vector<Point<dim> > &values) const;
+};
+
+
+template <int dim>
+void RHS<dim>::value_list(const std::vector<Point<dim> > &points,
+                         std::vector<double> &values,
+                         const unsigned int) const
+{
+  Assert(values.size()==points.size(),
+        ExcDimensionMismatch(values.size(),points.size()));
+
+  for (unsigned int i=0; i<values.size(); ++i)
+    values[i]=0;
+}
+
+
+                                // The flow field is chosen to be a
+                                // quarter circle with
+                                // counterclockwise flow direction
+                                // and with the origin as midpoint
+                                // for the right half of the domain
+                                // with positive $x$ values, whereas
+                                // the flow simply goes to the left
+                                // in the left part of the domain at
+                                // a velocity that matches the one
+                                // coming in from the right. In the
+                                // circular part the magnitude of the
+                                // flow velocity is proportional to
+                                // the distance from the origin. This
+                                // is a difference to step-12, where
+                                // the magnitude was 1
+                                // evereywhere. the new definition
+                                // leads to a linear variation of
+                                // $\beta$ along each given face of a
+                                // cell. On the other hand, the
+                                // solution $u(x,y)$ is exactly the
+                                // same as before.
+template <int dim>
+void Beta<dim>::value_list(const std::vector<Point<dim> > &points,
+                          std::vector<Point<dim> > &values) const
+{
+  Assert(values.size()==points.size(),
+        ExcDimensionMismatch(values.size(),points.size()));
+
+  for (unsigned int i=0; i<points.size(); ++i)
+    {
+      if (points[i](0) > 0)
+       {
+         values[i](0) = -points[i](1);
+         values[i](1) = points[i](0);
+       }
+      else
+       {
+         values[i] = Point<dim>();
+         values[i](0) = -points[i](1);
+       }
+    }
+}
+
+
+template <int dim>
+void BoundaryValues<dim>::value_list(const std::vector<Point<dim> > &points,
+                                      std::vector<double> &values,
+                                      const unsigned int) const
+{
+  Assert(values.size()==points.size(),
+        ExcDimensionMismatch(values.size(),points.size()));
+
+  for (unsigned int i=0; i<values.size(); ++i)
+    {
+      if (points[i](0)<0.5)
+       values[i]=1.;
+      else
+       values[i]=0.;
+    }
+}
+
+
+                                // @sect3{Class: DGTransportEquation}
+                                //
+                                // This declaration of this 
+                                // class is utterly unaffected by our
+                                // current changes.  The only
+                                // substantial change is that we use
+                                // only the second assembly scheme
+                                // described in step-12.
+template <int dim>
+class DGTransportEquation
+{
+  public:
+    DGTransportEquation();
+
+    void assemble_cell_term(const FEValues<dim>& fe_v,
+                           FullMatrix<double> &ui_vi_matrix,
+                           Vector<double> &cell_vector) const;
+    
+    void assemble_boundary_term(const FEFaceValues<dim>& fe_v,
+                               FullMatrix<double> &ui_vi_matrix,
+                               Vector<double> &cell_vector) const;
+    
+    void assemble_face_term2(const FEFaceValuesBase<dim>& fe_v,
+                            const FEFaceValuesBase<dim>& fe_v_neighbor,
+                            FullMatrix<double> &ui_vi_matrix,
+                            FullMatrix<double> &ue_vi_matrix,
+                            FullMatrix<double> &ui_ve_matrix,
+                            FullMatrix<double> &ue_ve_matrix) const;
+  private:
+    const Beta<dim> beta_function;
+    const RHS<dim> rhs_function;
+    const BoundaryValues<dim> boundary_function;
+};
+
+
+                                // Likewise, the constructor of the
+                                // class as well as the functions
+                                // assembling the terms corresponding
+                                // to cell interiors and boundary
+                                // faces are unchanged from
+                                // before. The function that
+                                // assembles face terms between cells
+                                // also did not change because all it
+                                // does is operate on two objects of
+                                // type FEFaceValuesBase (which is
+                                // the base class of both
+                                // FEFaceValues and
+                                // FESubfaceValues). Where these
+                                // objects come from, i.e. how they
+                                // are initialized, is of no concern
+                                // to this function: it simply
+                                // assumes that the quadrature points
+                                // on faces or subfaces represented
+                                // by the two objects correspond to
+                                // the same points in physical space.
+template <int dim>
+DGTransportEquation<dim>::DGTransportEquation ()
+               :
+               beta_function (),
+               rhs_function (),
+               boundary_function ()
+{}
+
+
+template <int dim>
+void DGTransportEquation<dim>::assemble_cell_term(
+  const FEValues<dim> &fe_v,
+  FullMatrix<double> &ui_vi_matrix,
+  Vector<double> &cell_vector) const
+{
+  const std::vector<double> &JxW = fe_v.get_JxW_values ();
+
+  std::vector<Point<dim> > beta (fe_v.n_quadrature_points);
+  std::vector<double> rhs (fe_v.n_quadrature_points);
+  
+  beta_function.value_list (fe_v.get_quadrature_points(), beta);
+  rhs_function.value_list (fe_v.get_quadrature_points(), rhs);
+  
+  for (unsigned int point=0; point<fe_v.n_quadrature_points; ++point)
+    for (unsigned int i=0; i<fe_v.dofs_per_cell; ++i) 
+      {
+       for (unsigned int j=0; j<fe_v.dofs_per_cell; ++j)
+         ui_vi_matrix(i,j) -= beta[point]*fe_v.shape_grad(i,point)*
+                             fe_v.shape_value(j,point) *
+                             JxW[point];
+       
+       cell_vector(i) += rhs[point] * fe_v.shape_value(i,point) * JxW[point];
+      }
+}
+
+
+template <int dim>
+void DGTransportEquation<dim>::assemble_boundary_term(
+  const FEFaceValues<dim>& fe_v,    
+  FullMatrix<double> &ui_vi_matrix,
+  Vector<double> &cell_vector) const
+{
+  const std::vector<double> &JxW = fe_v.get_JxW_values ();
+  const std::vector<Point<dim> > &normals = fe_v.get_normal_vectors ();
+
+  std::vector<Point<dim> > beta (fe_v.n_quadrature_points);
+  std::vector<double> g(fe_v.n_quadrature_points);
+  
+  beta_function.value_list (fe_v.get_quadrature_points(), beta);
+  boundary_function.value_list (fe_v.get_quadrature_points(), g);
+
+  for (unsigned int point=0; point<fe_v.n_quadrature_points; ++point)
+    {
+      const double beta_n=beta[point] * normals[point];      
+      if (beta_n>0)
+       for (unsigned int i=0; i<fe_v.dofs_per_cell; ++i)
+         for (unsigned int j=0; j<fe_v.dofs_per_cell; ++j)
+           ui_vi_matrix(i,j) += beta_n *
+                              fe_v.shape_value(j,point) *
+                              fe_v.shape_value(i,point) *
+                              JxW[point];
+      else 
+       for (unsigned int i=0; i<fe_v.dofs_per_cell; ++i)
+         cell_vector(i) -= beta_n *
+                           g[point] *
+                           fe_v.shape_value(i,point) *
+                           JxW[point];
+    }
+}
+
+
+template <int dim>
+void DGTransportEquation<dim>::assemble_face_term2(
+  const FEFaceValuesBase<dim>& fe_v,
+  const FEFaceValuesBase<dim>& fe_v_neighbor,      
+  FullMatrix<double> &ui_vi_matrix,
+  FullMatrix<double> &ue_vi_matrix,
+  FullMatrix<double> &ui_ve_matrix,
+  FullMatrix<double> &ue_ve_matrix) const
+{
+  const std::vector<double> &JxW = fe_v.get_JxW_values ();
+  const std::vector<Point<dim> > &normals = fe_v.get_normal_vectors ();
+
+  std::vector<Point<dim> > beta (fe_v.n_quadrature_points);
+  
+  beta_function.value_list (fe_v.get_quadrature_points(), beta);
+
+  for (unsigned int point=0; point<fe_v.n_quadrature_points; ++point)
+    {
+      const double beta_n=beta[point] * normals[point];
+      if (beta_n>0)
+       {
+         for (unsigned int i=0; i<fe_v.dofs_per_cell; ++i)
+           for (unsigned int j=0; j<fe_v.dofs_per_cell; ++j)
+             ui_vi_matrix(i,j) += beta_n *
+                                fe_v.shape_value(j,point) *
+                                fe_v.shape_value(i,point) *
+                                JxW[point];
+
+         for (unsigned int k=0; k<fe_v_neighbor.dofs_per_cell; ++k)
+           for (unsigned int j=0; j<fe_v.dofs_per_cell; ++j)
+             ui_ve_matrix(k,j) -= beta_n *
+                                 fe_v.shape_value(j,point) *
+                                 fe_v_neighbor.shape_value(k,point) *
+                                 JxW[point];
+       }
+      else
+       {
+         for (unsigned int i=0; i<fe_v.dofs_per_cell; ++i)
+           for (unsigned int l=0; l<fe_v_neighbor.dofs_per_cell; ++l)
+             ue_vi_matrix(i,l) += beta_n *
+                                 fe_v_neighbor.shape_value(l,point) *
+                                 fe_v.shape_value(i,point) *
+                                 JxW[point];
+
+         for (unsigned int k=0; k<fe_v_neighbor.dofs_per_cell; ++k)
+           for (unsigned int l=0; l<fe_v_neighbor.dofs_per_cell; ++l)
+             ue_ve_matrix(k,l) -= beta_n *
+                                  fe_v_neighbor.shape_value(l,point) *
+                                  fe_v_neighbor.shape_value(k,point) *
+                                  JxW[point];
+       }
+    }
+}
+
+
+                                // @sect3{Class: DGMethod}
+                                //
+                                // Even the main class of this
+                                // program stays more or less the
+                                // same. We omit one of the assembly
+                                // routines and use only the second,
+                                // more effective one of the two
+                                // presented in step-12. However, we
+                                // introduce a new routine
+                                // (set_anisotropic_flags) and modify
+                                // another one (refine_grid).
+template <int dim>
+class DGMethod
+{
+  public:
+    DGMethod (const bool anisotropic);
+    ~DGMethod ();
+
+    void run ();
+    
+  private:
+    void setup_system ();
+    void assemble_system1 ();
+    void assemble_system2 ();
+    void solve (Vector<double> &solution);
+    void refine_grid ();
+    void set_anisotropic_flags ();
+    void output_results (const unsigned int cycle) const;
+
+    Triangulation<dim>   triangulation;
+    const MappingQ1<dim> mapping;
+                                    // Again we want to use DG elements of
+                                    // degree 1 (but this is only specified in
+                                    // the constructor). If you want to use a
+                                    // DG method of a different degree replace
+                                    // 1 in the constructor by the new degree.
+    const unsigned int   degree;    
+    FE_DGQ<dim>          fe;
+    DoFHandler<dim>      dof_handler;
+
+    SparsityPattern      sparsity_pattern;
+    SparseMatrix<double> system_matrix;
+                                    // This is new, the threshold value used in
+                                    // the evaluation of the anisotropic jump
+                                    // indicator explained in the
+                                    // introduction. Its value is set to 3.0 in
+                                    // the constructor, but it can easily be
+                                    // changed to a different value greater
+                                    // than 1.
+    const double anisotropic_threshold_ratio;
+                                    // This is a bool flag indicating whether
+                                    // anisotropic refinement shall be used or
+                                    // not. It is set by the constructor, which
+                                    // takes an argument of the same name.
+    const bool anisotropic;
+    
+    const QGauss<dim>   quadrature;
+    const QGauss<dim-1> face_quadrature;
+    
+    Vector<double>       solution2;
+    Vector<double>       right_hand_side;
+    
+    const DGTransportEquation<dim> dg;
+};
+
+
+template <int dim>
+DGMethod<dim>::DGMethod (const bool anisotropic)
+               :
+               mapping (),
+                                                // Change here for DG
+                                                // methods of
+                                                // different degrees.
+               degree(1),
+               fe (degree),
+               dof_handler (triangulation),
+               anisotropic_threshold_ratio(3.),
+               anisotropic(anisotropic),
+                                                // As beta is a
+                                                // linear function,
+                                                // we can choose the
+                                                // degree of the
+                                                // quadrature for
+                                                // which the
+                                                // resulting
+                                                // integration is
+                                                // correct. Thus, we
+                                                // choose to use
+                                                // <code>degree+1</code>
+                                                // gauss points,
+                                                // which enables us
+                                                // to integrate
+                                                // exactly
+                                                // polynomials of
+                                                // degree
+                                                // <code>2*degree+1</code>,
+                                                // enough for all the
+                                                // integrals we will
+                                                // perform in this
+                                                // program.
+               quadrature (degree+1),
+               face_quadrature (degree+1),
+               dg ()
+{}
+
+
+template <int dim>
+DGMethod<dim>::~DGMethod () 
+{
+  dof_handler.clear ();
+}
+
+
+template <int dim>
+void DGMethod<dim>::setup_system ()
+{
+  dof_handler.distribute_dofs (fe);
+  sparsity_pattern.reinit (dof_handler.n_dofs(),
+                          dof_handler.n_dofs(),
+                          (GeometryInfo<dim>::faces_per_cell
+                           *GeometryInfo<dim>::max_children_per_face+1)*fe.dofs_per_cell);
+
+  DoFTools::make_flux_sparsity_pattern (dof_handler, sparsity_pattern);
+  
+  sparsity_pattern.compress();
+  
+  system_matrix.reinit (sparsity_pattern);
+
+  solution2.reinit (dof_handler.n_dofs());
+  right_hand_side.reinit (dof_handler.n_dofs());
+}
+
+
+                                // @sect4{Function: assemble_system2}
+                                //
+                                // We proceed with the
+                                // <code>assemble_system2</code> function that
+                                // implements the DG discretization in its
+                                // second version. This function is very
+                                // similar to the <code>assemble_system2</code>
+                                // function from step-12, even the four cases
+                                // considered for the neighbor-relations of a
+                                // cell are the same, namely a) cell is at the
+                                // boundary, b) there are finer neighboring
+                                // cells, c) the neighbor is neither coarser
+                                // nor finer and d) the neighbor is coarser.
+                                // However, the way in which we decide upon
+                                // which case we have are modified in the way
+                                // described in the introduction.
+template <int dim>
+void DGMethod<dim>::assemble_system2 () 
+{
+  const unsigned int dofs_per_cell = dof_handler.get_fe().dofs_per_cell;
+  std::vector<unsigned int> dofs (dofs_per_cell);
+  std::vector<unsigned int> dofs_neighbor (dofs_per_cell);
+
+  const UpdateFlags update_flags = update_values
+                                   | update_gradients
+                                   | update_quadrature_points
+                                   | update_JxW_values;
+  
+  const UpdateFlags face_update_flags = update_values
+                                        | update_quadrature_points
+                                        | update_JxW_values
+                                        | update_normal_vectors;
+  
+  const UpdateFlags neighbor_face_update_flags = update_values;
+
+  FEValues<dim> fe_v (
+    mapping, fe, quadrature, update_flags);
+  FEFaceValues<dim> fe_v_face (
+    mapping, fe, face_quadrature, face_update_flags);
+  FESubfaceValues<dim> fe_v_subface (
+    mapping, fe, face_quadrature, face_update_flags);
+  FEFaceValues<dim> fe_v_face_neighbor (
+    mapping, fe, face_quadrature, neighbor_face_update_flags);
+
+
+  FullMatrix<double> ui_vi_matrix (dofs_per_cell, dofs_per_cell);
+  FullMatrix<double> ue_vi_matrix (dofs_per_cell, dofs_per_cell);
+  
+  FullMatrix<double> ui_ve_matrix (dofs_per_cell, dofs_per_cell);
+  FullMatrix<double> ue_ve_matrix (dofs_per_cell, dofs_per_cell);
+  
+  Vector<double>  cell_vector (dofs_per_cell);
+
+  typename DoFHandler<dim>::active_cell_iterator
+    cell = dof_handler.begin_active(),
+    endc = dof_handler.end();
+  for (;cell!=endc; ++cell) 
+    {
+      ui_vi_matrix = 0;
+      cell_vector = 0;
+
+      fe_v.reinit (cell);
+
+      dg.assemble_cell_term(fe_v,
+                           ui_vi_matrix,
+                           cell_vector);
+      
+      cell->get_dof_indices (dofs);
+
+      for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
+       {
+         typename DoFHandler<dim>::face_iterator face=
+           cell->face(face_no);
+
+                                          // Case a)
+         if (face->at_boundary())
+           {
+             fe_v_face.reinit (cell, face_no);
+
+             dg.assemble_boundary_term(fe_v_face,
+                                       ui_vi_matrix,
+                                       cell_vector);
+           }
+         else
+           {
+             Assert (cell->neighbor(face_no).state() == IteratorState::valid,
+                     ExcInternalError());
+             typename DoFHandler<dim>::cell_iterator neighbor=
+               cell->neighbor(face_no);
+                                              // Case b), we decide that there
+                                              // are finer cells as neighbors
+                                              // by asking the face, whether it
+                                              // has children. if so, then
+                                              // there must also be finer cells
+                                              // which are children or farther
+                                              // offsprings of our neighbor.
+             if (face->has_children())
+               {
+                                                  // We need to know, which of
+                                                  // the neighbors faces points
+                                                  // in the direction of our
+                                                  // cell. Using the @p
+                                                  // neighbor_face_no function
+                                                  // we get this information
+                                                  // for both coarser and
+                                                  // non-coarser neighbors.
+                 const unsigned int neighbor2=
+                   cell->neighbor_face_no(face_no);
+
+                                                  // Now we loop over all
+                                                  // subfaces, i.e. the
+                                                  // children and possibly
+                                                  // grandchildren of the
+                                                  // current face.
+                 for (unsigned int subface_no=0;
+                      subface_no<face->number_of_children(); ++subface_no)
+                   {
+                                                      // To get the cell behind
+                                                      // the current subface we
+                                                      // can use the @p
+                                                      // neighbor_child_on_subface
+                                                      // function. it takes
+                                                      // care of all the
+                                                      // complicated situations
+                                                      // of anisotropic
+                                                      // refinement and
+                                                      // non-standard faces.
+                     typename DoFHandler<dim>::cell_iterator neighbor_child
+                        = cell->neighbor_child_on_subface (face_no, subface_no);
+                     Assert (!neighbor_child->has_children(), ExcInternalError());
+
+                                                      // The remaining part of
+                                                      // this case is
+                                                      // unchanged.
+                     ue_vi_matrix = 0;
+                     ui_ve_matrix = 0;
+                     ue_ve_matrix = 0;
+                     
+                     fe_v_subface.reinit (cell, face_no, subface_no);
+                     fe_v_face_neighbor.reinit (neighbor_child, neighbor2);
+
+                     dg.assemble_face_term2(fe_v_subface,
+                                            fe_v_face_neighbor,
+                                            ui_vi_matrix,
+                                            ue_vi_matrix,
+                                            ui_ve_matrix,
+                                            ue_ve_matrix);
+                 
+                     neighbor_child->get_dof_indices (dofs_neighbor);
+                                                               
+                     for (unsigned int i=0; i<dofs_per_cell; ++i)
+                       for (unsigned int j=0; j<dofs_per_cell; ++j)
+                         {
+                           system_matrix.add(dofs[i], dofs_neighbor[j],
+                                             ue_vi_matrix(i,j));
+                           system_matrix.add(dofs_neighbor[i], dofs[j],
+                                             ui_ve_matrix(i,j));
+                           system_matrix.add(dofs_neighbor[i], dofs_neighbor[j],
+                                             ue_ve_matrix(i,j));
+                         }
+                   }
+               }
+             else
+               {
+                                                  // Case c). We simply ask,
+                                                  // whether the neighbor is
+                                                  // coarser. If not, then it
+                                                  // is neither coarser nor
+                                                  // finer, since finer
+                                                  // neighbor would have been
+                                                  // reated above withz case
+                                                  // b). Of all the cases with
+                                                  // thesame refinement
+                                                  // situation of our cell and
+                                                  // the neighbor we want to
+                                                  // treat only one half, so
+                                                  // that each face is
+                                                  // considered only once. Thus
+                                                  // we have the additional
+                                                  // condition, that the cell
+                                                  // with the lower index does
+                                                  // the work. In the rare case
+                                                  // that both cells have the
+                                                  // same index, the cell with
+                                                  // lower level is selected.
+                 if (!cell->neighbor_is_coarser(face_no) &&
+                     (neighbor->index() > cell->index() ||
+                     (neighbor->level() < cell->level() &&
+                      neighbor->index() == cell->index())))
+                   {
+                                                      // Here we know, that the
+                                                      // neigbor is not coarser
+                                                      // so we can use the
+                                                      // usual @p
+                                                      // neighbor_of_neighbor
+                                                      // function. However, we
+                                                      // could also use the
+                                                      // more general @p
+                                                      // neighbor_face_no
+                                                      // function.
+                     const unsigned int neighbor2=cell->neighbor_of_neighbor(face_no);
+                     
+                     ue_vi_matrix = 0;
+                     ui_ve_matrix = 0;
+                     ue_ve_matrix = 0;
+                     
+                     fe_v_face.reinit (cell, face_no);
+                     fe_v_face_neighbor.reinit (neighbor, neighbor2);
+                     
+                     dg.assemble_face_term2(fe_v_face,
+                                            fe_v_face_neighbor,
+                                            ui_vi_matrix,
+                                            ue_vi_matrix,
+                                            ui_ve_matrix,
+                                            ue_ve_matrix);
+
+                     neighbor->get_dof_indices (dofs_neighbor);
+
+                     for (unsigned int i=0; i<dofs_per_cell; ++i)
+                       for (unsigned int j=0; j<dofs_per_cell; ++j)
+                         {
+                           system_matrix.add(dofs[i], dofs_neighbor[j],
+                                             ue_vi_matrix(i,j));
+                           system_matrix.add(dofs_neighbor[i], dofs[j],
+                                             ui_ve_matrix(i,j));
+                           system_matrix.add(dofs_neighbor[i], dofs_neighbor[j],
+                                             ue_ve_matrix(i,j));
+                         }
+                   }
+
+                                                  // We do not need to consider
+                                                  // case d), as those faces
+                                                  // are treated 'from the
+                                                  // other side within case b).
+               }
+           }
+       }
+      
+      for (unsigned int i=0; i<dofs_per_cell; ++i)
+       for (unsigned int j=0; j<dofs_per_cell; ++j)
+         system_matrix.add(dofs[i], dofs[j], ui_vi_matrix(i,j));
+      
+      for (unsigned int i=0; i<dofs_per_cell; ++i)
+       right_hand_side(dofs[i]) += cell_vector(i);
+    }
+}
+
+
+                                // @sect3{Solver}
+                                //
+                                // For this simple problem we use the simple
+                                // Richardson iteration again. The solver is
+                                // completely unaffected by our anisotropic
+                                // changes.
+template <int dim>
+void DGMethod<dim>::solve (Vector<double> &solution) 
+{
+  SolverControl           solver_control (1000, 1e-12, false, false);
+  SolverRichardson<>      solver (solver_control);
+
+  PreconditionBlockSSOR<SparseMatrix<double> > preconditioner;
+
+  preconditioner.initialize(system_matrix, fe.dofs_per_cell);
+
+  solver.solve (system_matrix, solution, right_hand_side,
+               preconditioner);
+}
+
+
+                                // @sect3{Refinement}
+                                //
+                                // We refine the grid according to the same
+                                // simple refinement criterion used in step-12,
+                                // namely an approximation to the
+                                // gradient of the solution.
+template <int dim>
+void DGMethod<dim>::refine_grid ()
+{
+  Vector<float> gradient_indicator (triangulation.n_active_cells());
+
+                                  // We approximate the gradient,
+  DerivativeApproximation::approximate_gradient (mapping,
+                                                dof_handler,
+                                                solution2,
+                                                gradient_indicator);
+
+                                  // and scale it to obtain an error indicator.
+  typename DoFHandler<dim>::active_cell_iterator
+    cell = dof_handler.begin_active(),
+    endc = dof_handler.end();
+  for (unsigned int cell_no=0; cell!=endc; ++cell, ++cell_no)
+    gradient_indicator(cell_no)*=std::pow(cell->diameter(), 1+1.0*dim/2);
+                                  // Then we use this indicator to flag the 30
+                                  // percent of the cells with highest error
+                                  // indicator to be refined.
+  GridRefinement::refine_and_coarsen_fixed_number (triangulation,
+                                                  gradient_indicator,
+                                                  0.3, 0.1);
+                                  // Now the refinement flags are set for those
+                                  // cells with a large error indicator. If
+                                  // nothing is done to change this, those
+                                  // cells will be refined isotropically. If
+                                  // the @p anisotropic flag given to this
+                                  // function is set, we now call the
+                                  // set_anisotropic_flags() function, which
+                                  // uses the jump indicator to reset some of
+                                  // the refinement flags to anisotropic
+                                  // refinement.
+  if (anisotropic)
+    set_anisotropic_flags();
+                                  // Now execute the refinement considering
+                                  // anisotropic as well as isotropic
+                                  // refinement flags.
+  triangulation.execute_coarsening_and_refinement ();
+}
+
+                                // Once an error indicator has been evaluated
+                                // and the cells with largerst error are
+                                // flagged for refinement we want to loop over
+                                // the flagged cells again to decide whether
+                                // they need isotropic refinemnt or whether
+                                // anisotropic refinement is more
+                                // appropriate. This is the anisotropic jump
+                                // indicator explained in the introduction.
+template <int dim>
+void DGMethod<dim>::set_anisotropic_flags ()
+{
+                                  // We want to evaluate the jump over faces of
+                                  // the flagged cells, so we need some objects
+                                  // to evaluate values of the solution on
+                                  // faces.
+  UpdateFlags face_update_flags
+    = UpdateFlags(update_values | update_JxW_values);
+
+  FEFaceValues<dim> fe_v_face (mapping, fe, face_quadrature, face_update_flags);
+  FESubfaceValues<dim> fe_v_subface (mapping, fe, face_quadrature, face_update_flags);
+  FEFaceValues<dim> fe_v_face_neighbor (mapping, fe, face_quadrature, update_values);
+
+                                  // Now we need to loop over all active cells.
+  typename DoFHandler<dim>::active_cell_iterator cell=dof_handler.begin_active(),
+                                                endc=dof_handler.end();
+  
+  for (; cell!=endc; ++cell)
+                                    // We only need to consider cells which are
+                                    // flaged for refinement.
+    if (cell->refine_flag_set())
+      {
+       Point<dim> jump;
+       Point<dim> area;
+       
+       for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
+         {
+           typename DoFHandler<dim>::face_iterator face = cell->face(face_no);
+      
+           if (!face->at_boundary())
+             {
+               Assert (cell->neighbor(face_no).state() == IteratorState::valid, ExcInternalError());
+               typename DoFHandler<dim>::cell_iterator neighbor = cell->neighbor(face_no);
+               
+               std::vector<double> u (fe_v_face.n_quadrature_points);
+               std::vector<double> u_neighbor (fe_v_face.n_quadrature_points);
+
+                                                // The four cases of different
+                                                // neighbor relations senn in
+                                                // the assembly routines are
+                                                // repeated much in the same
+                                                // way here.
+               if (face->has_children())
+                 {
+                                                    // The neighbor is refined.
+                                                    // First we store the
+                                                    // information, which of
+                                                    // the neighbor's faces
+                                                    // points in the direction
+                                                    // of our current
+                                                    // cell. This property is
+                                                    // inherited to the
+                                                    // children.
+                   unsigned int neighbor2=cell->neighbor_face_no(face_no);
+                                                    // Now we loop over all subfaces,
+                   for (unsigned int subface_no=0; subface_no<face->number_of_children(); ++subface_no)
+                     {
+                                                        // get an iterator
+                                                        // pointing to the cell
+                                                        // behind the present
+                                                        // subface...
+                       typename DoFHandler<dim>::cell_iterator neighbor_child = cell->neighbor_child_on_subface(face_no,subface_no);
+                       Assert (!neighbor_child->has_children(), ExcInternalError());
+                                                        // ... and reinit the
+                                                        // respective
+                                                        // FEFaceValues und
+                                                        // FESubFaceValues
+                                                        // objects.
+                       fe_v_subface.reinit (cell, face_no, subface_no);
+                       fe_v_face_neighbor.reinit (neighbor_child, neighbor2);
+                                                        // We obtain the function values
+                       fe_v_subface.get_function_values(solution2, u);
+                       fe_v_face_neighbor.get_function_values(solution2, u_neighbor);
+                                                        // as well as the
+                                                        // quadrature weights,
+                                                        // multiplied by the
+                                                        // jacobian determinant.
+                       const std::vector<double> &JxW = fe_v_subface.get_JxW_values ();
+                                                        // Now we loop over all
+                                                        // quadrature points
+                       for (unsigned int x=0; x<fe_v_subface.n_quadrature_points; ++x)
+                         {
+                                                            // and integrate
+                                                            // the absolute
+                                                            // value of the
+                                                            // jump of the
+                                                            // solution,
+                                                            // i.e. the
+                                                            // absolute value
+                                                            // of the
+                                                            // difference
+                                                            // between the
+                                                            // function value
+                                                            // seen from the
+                                                            // current cell and
+                                                            // the neighboring
+                                                            // cell,
+                                                            // respectively. We
+                                                            // know, that the
+                                                            // first two faces
+                                                            // are orthogonal
+                                                            // to the first
+                                                            // coordinate
+                                                            // direction on the
+                                                            // unit cell, the
+                                                            // second two faces
+                                                            // are orthogonal
+                                                            // to the second
+                                                            // coordinate
+                                                            // direction and so
+                                                            // on, so we
+                                                            // accumulate these
+                                                            // values ito
+                                                            // vectors with
+                                                            // <code>dim</code>
+                                                            // components.
+                           jump[face_no/2]+=std::fabs(u[x]-u_neighbor[x])*JxW[x];
+                                                            // We also sum up
+                                                            // the scaled
+                                                            // weights to
+                                                            // obtain the
+                                                            // measure of the
+                                                            // face.
+                           area[face_no/2]+=JxW[x];
+                         }
+                     }
+                 }
+               else 
+                 {
+                   if (!cell->neighbor_is_coarser(face_no)) 
+                     {
+                                                        // Our current cell and
+                                                        // the neighbor have
+                                                        // the same refinement
+                                                        // along the face under
+                                                        // consideration. Apart
+                                                        // from that, we do
+                                                        // much the same as
+                                                        // with one of the
+                                                        // subcells in the
+                                                        // above case.
+                       unsigned int neighbor2=cell->neighbor_of_neighbor(face_no);
+                 
+                       fe_v_face.reinit (cell, face_no);
+                       fe_v_face_neighbor.reinit (neighbor, neighbor2);
+                 
+                       fe_v_face.get_function_values(solution2, u);
+                       fe_v_face_neighbor.get_function_values(solution2, u_neighbor);
+                 
+                       const std::vector<double> &JxW = fe_v_face.get_JxW_values ();
+                 
+                       for (unsigned int x=0; x<fe_v_face.n_quadrature_points; ++x)
+                         {
+                           jump[face_no/2]+=std::fabs(u[x]-u_neighbor[x])*JxW[x];
+                           area[face_no/2]+=JxW[x];
+                         }
+                     }
+                   else //i.e. neighbor is coarser than cell
+                     {
+                                                        // Now the neighbor is
+                                                        // actually
+                                                        // coarser. This case
+                                                        // is new, in that it
+                                                        // did not occur in the
+                                                        // assembly
+                                                        // routine. Here, we
+                                                        // have to consider it,
+                                                        // but this is not
+                                                        // overly
+                                                        // complicated. We
+                                                        // simply use the @p
+                                                        // neighbor_of_coarser_neighbor
+                                                        // function, which
+                                                        // again takes care of
+                                                        // anisotropic
+                                                        // refinement and
+                                                        // non-standard face
+                                                        // orientation by
+                                                        // itself.
+                       std::pair<unsigned int,unsigned int> neighbor_face_subface
+                         = cell->neighbor_of_coarser_neighbor(face_no);
+                       Assert (neighbor_face_subface.first<GeometryInfo<dim>::faces_per_cell, ExcInternalError());
+                       Assert (neighbor_face_subface.second<neighbor->face(neighbor_face_subface.first)->number_of_children(),
+                               ExcInternalError());
+                       Assert (neighbor->neighbor_child_on_subface(neighbor_face_subface.first, neighbor_face_subface.second)
+                               == cell, ExcInternalError());
+                 
+                       fe_v_face.reinit (cell, face_no);
+                       fe_v_subface.reinit (neighbor, neighbor_face_subface.first,
+                                            neighbor_face_subface.second);
+                 
+                       fe_v_face.get_function_values(solution2, u);
+                       fe_v_subface.get_function_values(solution2, u_neighbor);
+                       
+                       const std::vector<double> &JxW = fe_v_face.get_JxW_values ();
+                 
+                       for (unsigned int x=0; x<fe_v_face.n_quadrature_points; ++x)
+                         {
+                           jump[face_no/2]+=std::fabs(u[x]-u_neighbor[x])*JxW[x];
+                           area[face_no/2]+=JxW[x];
+                         }
+                     }
+                 }
+             }
+         }
+                                        // Now we analyze the size of the mean
+                                        // jumps, which we get dividing the
+                                        // jumps by the measure of the
+                                        // respective faces.
+       double average_jumps[dim];
+       double sum_of_average_jumps=0.;
+       for (unsigned int i=0; i<dim; ++i)
+         {
+           average_jumps[i] = jump(i)/area(i);
+           sum_of_average_jumps += average_jumps[i];
+         }
+
+                                        // Now we loop over the <code>dim</code>
+                                        // coordinate directions of the unit
+                                        // cell and compare the average jump
+                                        // over the faces orthogional to that
+                                        // direction with the average jumnps
+                                        // over faces orthogonal to the
+                                        // remining direction(s). If the first
+                                        // is larger than the latter by a given
+                                        // factor, we refine only along hat
+                                        // axis. Otherwise we leave the
+                                        // refinement flag unchanged, resulting
+                                        // in isotropic refinement.
+       for (unsigned int i=0; i<dim; ++i)
+         if (average_jumps[i] > anisotropic_threshold_ratio*(sum_of_average_jumps-average_jumps[i]))
+           cell->set_refine_flag(RefinementCase<dim>::cut_axis(i));
+      }
+}
+  
+                                // @sect3{The Rest}
+                                //
+                                // The remaining part of the program is again
+                                // unmodified. Only the creation of the
+                                // original triangulation is changed in order
+                                // to reproduce the new domain.
+template <int dim>
+void DGMethod<dim>::output_results (const unsigned int cycle) const
+{
+  std::string refine_type;
+  if (anisotropic)
+    refine_type=".aniso";
+  else
+    refine_type=".iso";
+  
+  std::string filename = "grid-";
+  filename += ('0' + cycle);
+  Assert (cycle < 10, ExcInternalError());
+
+  filename += refine_type + ".eps";
+  std::cout << "Writing grid to <" << filename << ">..." << std::endl;
+  std::ofstream eps_output (filename.c_str());
+
+  GridOut grid_out;
+  grid_out.write_eps (triangulation, eps_output);
+
+  filename = "grid-";
+  filename += ('0' + cycle);
+  Assert (cycle < 10, ExcInternalError());
+  
+  filename += refine_type + ".gnuplot";
+  std::cout << "Writing grid to <" << filename << ">..." << std::endl;
+  std::ofstream gnuplot_grid_output (filename.c_str());
+
+  grid_out.write_gnuplot (triangulation, gnuplot_grid_output);
+  
+  filename = "sol-";
+  filename += ('0' + cycle);
+  Assert (cycle < 10, ExcInternalError());
+  
+  filename += refine_type + ".gnuplot";
+  std::cout << "Writing solution to <" << filename << ">..."
+           << std::endl;
+  std::ofstream gnuplot_output (filename.c_str());
+  
+  DataOut<dim> data_out;
+  data_out.attach_dof_handler (dof_handler);
+  data_out.add_data_vector (solution2, "u");
+
+  data_out.build_patches (degree);
+  
+  data_out.write_gnuplot(gnuplot_output);
+}
+
+
+template <int dim>
+void DGMethod<dim>::run () 
+{
+  for (unsigned int cycle=0; cycle<6; ++cycle)
+    {
+      std::cout << "Cycle " << cycle << ':' << std::endl;
+
+      if (cycle == 0)
+       {
+                                          // Create the rectangular domain.
+         Point<dim> p1,p2;
+         p1(0)=0;
+         p1(0)=-1;
+         for (unsigned int i=0; i<dim; ++i)
+           p2(i)=1.;
+                                          // Adjust the number of cells in
+                                          // different directions to obtain
+                                          // completely isotropic cells for the
+                                          // original mesh.
+         std::vector<unsigned int> repetitions(dim,1);
+         repetitions[0]=2;
+         GridGenerator::subdivided_hyper_rectangle (triangulation,
+                                                    repetitions,
+                                                    p1,
+                                                    p2);
+
+         triangulation.refine_global (5-dim);
+       }
+      else
+       refine_grid ();
+      
+
+      std::cout << "   Number of active cells:       "
+               << triangulation.n_active_cells()
+               << std::endl;
+
+      setup_system ();
+
+      std::cout << "   Number of degrees of freedom: "
+               << dof_handler.n_dofs()
+               << std::endl;
+
+      Timer assemble_timer;
+      assemble_system2 ();
+      std::cout << "Time of assemble_system2: "
+               << assemble_timer()
+               << std::endl;
+      solve (solution2);
+
+      output_results (cycle);
+    }
+}
+
+int main () 
+{
+  try
+    {
+                                      // If you want to run the program in 3D,
+                                      // simply change the following line to
+                                      // <code>const unsigned int dim = 3;</code>.
+      const unsigned int dim = 2;
+      
+      {
+                                        // First, we perform a run with
+                                        // isotropic refinement.
+       std::cout << "Performing a " << dim << "D run with isotropic refinement..." << std::endl
+                 << "------------------------------------------------" << std::endl;
+       DGMethod<dim> dgmethod_iso(false);
+       dgmethod_iso.run ();
+      }
+      
+      {
+                                        // Now we do a second run, this time
+                                        // with anisotropic refinement.
+       std::cout << std::endl
+                 << "Performing a " << dim << "D run with anisotropic refinement..." << std::endl
+                 << "--------------------------------------------------" << std::endl;
+       DGMethod<dim> dgmethod_aniso(true);
+       dgmethod_aniso.run ();
+      }
+    }
+  catch (std::exception &exc)
+    {
+      std::cerr << std::endl << std::endl
+               << "----------------------------------------------------"
+               << std::endl;
+      std::cerr << "Exception on processing: " << std::endl
+               << exc.what() << std::endl
+               << "Aborting!" << std::endl
+               << "----------------------------------------------------"
+               << std::endl;
+      return 1;
+    }
+  catch (...) 
+    {
+      std::cerr << std::endl << std::endl
+               << "----------------------------------------------------"
+               << std::endl;
+      std::cerr << "Unknown exception!" << std::endl
+               << "Aborting!" << std::endl
+               << "----------------------------------------------------"
+               << std::endl;
+      return 1;
+    };
+  
+  return 0;
+}
+
+
index 3e7d66353e3add106ed73c36857a2a3bef5fae26..f0d8925f55d2355215411fd41a3b85ca4c24a842 100644 (file)
@@ -944,7 +944,7 @@ void BoussinesqFlowProblem<dim>::assemble_rhs_T ()
                                               // refined. loop over
                                               // all sub faces
              for (unsigned int subface_no=0;
-                  subface_no<GeometryInfo<dim>::subfaces_per_face;
+                  subface_no<GeometryInfo<dim>::max_children_per_face;
                   ++subface_no)
                {
                  fe_subface_values.reinit (cell, face_no, subface_no);
index f9692f2b8b19121ffa5065e7d5380ab1c32db146..602d2ba20eb1c613fbc5c0fa0c081b8c5c250661 100644 (file)
@@ -1645,7 +1645,7 @@ GradientEstimation::estimate_interval (const DoFHandler<dim> &dof_handler,
                                   // neighbors is computed here.
   std::vector<typename DoFHandler<dim>::active_cell_iterator> active_neighbors;
   active_neighbors.reserve (GeometryInfo<dim>::faces_per_cell *
-                           GeometryInfo<dim>::subfaces_per_face);
+                           GeometryInfo<dim>::max_children_per_face);
 
                                   // Well then, after all these
                                   // preliminaries, lets start the
diff --git a/deal.II/todo b/deal.II/todo
new file mode 100644 (file)
index 0000000..ead9945
--- /dev/null
@@ -0,0 +1,144 @@
+1[DONE]  rename RefineCase -> RefinementCase
+
+2[DONE] rename FaceRefineCase -> FaceRefinementCase
+
+3[DONE] move FaceRefinementCase into internal namespace
+ [2,3:DONE:  FaceRefineCase has been renamed to internal::SubfaceCase which
+   is now derived from internal::SubfacePossibilities in analogy to
+   RefinementCase and RefinementPossibilities]
+
+4[DONE] move global anisotropic_refinement parameter to Triangulation,
+  throw exceptions when aniso data is required but not implemented
+
+5 one or two tests on aniso for continuous FE in 2d.
+
+6 make the DG tests in tests/aniso/ work
+
+7[DONE] add docu to FaceRefinementFlags.
+  "R: I think it is already there! W: What I meant is that the
+  documentation about which cases occur is there, but the explanation
+  why it is these cases and exactly these is missing. This was the
+  question about invariants. If you could add a couple of sentences that
+  would be helpful.
+
+8[DONE] modify FaceRefinementFlags according to the changes in RefinementFlags
+
+9[DONE] add some docu to the neighbor_is_coarser function like
+  "T: In an anisotropic setting, a cell con only be coarser than another
+   one at a given face, not on a general basis. The face of the finer
+cell is contained in the corresponding face of the coarser cell, the
+finer face is either a child or a grandchild of the coarser face. Of
+coarse we could try to add some sentences explaining this. By the way:
+consider two cells neighboring cells on an initial grid. We can NOT
+refine the cells in a way that one cell refines a face with cut_x and
+the neighboring one refines the same face with
+cut_y. Triangulation<dim>::prepare_coarsening_and_refinement() takes
+care of this situation and ensures that each face of a refined cell is
+completely contained in a single face of neighboring cells."
+
+10[DONE] setup a (doxygen) module for anisotropic, it should
+  "W: list the relevant classes, links to step-30, and links to a
+paper reference of the relevant algorithms. If we had a module
+anisotropic, we could for example list the RefinementCase and
+GeometryInfo, the Triangulation. Note, that classes can be part
+of several modules so the module would list everything that is related to
+anisotropic refinement"
+
+11[DONE] Swap arguments to FE::get_{restriction,prolongation}_matrix and
+give the refinement flag a default value to keep things compatible.
+
+12[DONE] Document FiniteElement::restriction and FiniteElement::prolongation
+indices and layout
+
+13[DONE] Modify documentation for changed FETools functions:
+   FETools::compute_{embedding,projection}_matrices
+
+14[DONE] Move the code that initializes the sizes of the
+FiniteElement::restriction and FiniteElement::prolongation members
+from individual FE implementations to a function in the base class,
+since it is always the same.
+
+15[DONE] doc/news/anisotropic.html:
+       I guess you started this file before we switched to using doxygen for
+       the changes file: It is no longer necessary to do things like 
+       <code class="class">CLASS</code> :: <code
+       class="member">MEMBER</code>. Since we run the changes.h file through
+       doxygen, it will automatically be linked to the right function if you
+       omit all the HTML stuff. Simply use the style in changes.h
+
+16[DONE] deal.II/source/grid/tria.cc:
+       In this file, you now have code like this:
+       ------------------------------
+       +                 Point<dim> new_bound=boundary[face->boundary_indicator()]
+       +#if deal_II_dimension == 2
+       +                                      ->get_new_point_on_line (face);
+       +#else
+       +                                      ->get_new_point_on_quad (face);
+       +#endif
+       ------------------------------
+       We've tried to avoid this because we always thought that eventually we
+       may want to go to a scheme where each file is only compiled once for
+       all space dimensions at the same time, by simply deleting all the #if
+       deal_II_dimension lines. This isn't going to work here. Would you mind
+       changing this somehow? I guess one way might be to give the Boundary
+       base class a method get_new_point_on_face and let it call either of
+       the two functions above. 
+
+16a[DONE] As a sidenote: this (and a great number of other) variables could well
+       have been made const, to allow the compiler to optimize and make it
+       clear to the reader that no further assignments are happening below.
+
+17 changes to Mapping*, FEValuesBase:
+       Can these be committed separately? I forgot what we said about the
+       name jacobian_grad -- I think we should settle on 'hessian' as unified
+       by Guido a while back. Are there any testcases that test the new
+       functionality?
+
+18[DONE] deal.II/include/fe/fe.h:
+       Add a comment to restriction_is_implemented() that it tests the stronger
+       requirement that the element does not only implement isotropic
+       restriction as tested by the isotropic_restriction_is_implemented()
+       function, but also anisotropic. Same for prolongation.
+
+19[DONE] deal.II/include/numerics/derivative_approximation.h:
+       The new function get_active_neighbors() would appear to be generally
+       useful. Could it be moved into the GridTools class? There are already
+       a few similar functions there.
+19a     Could be committed separately.
+
+20 deal.II/include/grid/tria_accessor.h:
+20a[DONE] The new function neighbor_is_coarser_internal() returns two values,
+       one as return value and one as reference argument. I find this
+       weird. Please let it return either a std::pair<...>
+   [20a DONE: The neighbor_is_coarser_internal has been replaced by a
+        new neighbor_of_coarser_internal function with simple interface]
+
+20b[DONE] In the functions flag_for_*_refinement(), make input arguments const.
+
+20c[DONE] iso_set_children(): please spell it out as "isotropic". We'll forget
+       what "iso" stood for once the anisotropic work has become normal for
+       us. Same for iso_child() etc.
+
+20d[DONE] middle_vertex_index(): please make it return an unsigned int and
+       return numbers::invalid_unsigned_int in case of an error. This is how
+       we do it all through the library.
+
+20e[DONE] there are several refine_case, clear_refine_case, set_refine_case
+       functions. please rename them to use refinement_case instead of
+       refine_case to match the name of the argument type.
+
+21[DONE] deal.II/include/grid/tria_accessor.templates.h:
+       many of the new functions in this file take input arguments that they
+       don't change but which are not marked as 'const'. please fix, they're
+       easy to find by searching for "(unsigned" or "(Refinement" for example.
+
+22[DONE] deal.II/include/grid/tria_levels.h:
+       please rename fields to refinement_case from refine_case. it would be
+       useful to also grep for any other occurrences of refine_case anywhere
+       left over.
+
+23[DONE] deal.II/include/grid/tria_objects.h:
+       in the documentation, use <code>...</code> instead of
+       <tt>...</tt>. More importantly, however, if you use a template
+       argument <dim> or <2> inside such a block, it needs to be written as
+       @<2@>

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.