]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Move the map_dof_to_boundary_indices functions from DoFHandler to DoFTools.
authorwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Fri, 25 Aug 2000 13:26:10 +0000 (13:26 +0000)
committerwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Fri, 25 Aug 2000 13:26:10 +0000 (13:26 +0000)
git-svn-id: https://svn.dealii.org/trunk@3273 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/deal.II/include/dofs/dof_handler.h
deal.II/deal.II/include/dofs/dof_tools.h
deal.II/deal.II/source/dofs/dof_handler.cc
deal.II/deal.II/source/dofs/dof_tools.cc
deal.II/deal.II/source/numerics/vectors.cc
deal.II/doc/news/2000/c-3-0.html

index 76ef6c1ee80dd4f59f0414aa590abf6235521c2a..e4efb28af0b3e1c4326436a7506a193a172fb23c 100644 (file)
@@ -216,69 +216,6 @@ class DoFDimensionInfo<3>
  * into new degree of freedom indices.
  *
  *
- * @sect3{Boundaries}
- *
- * When projecting the traces of functions to the boundary or parts thereof, one
- * needs to built matrices and vectors with the degrees of freedom on the
- * boundary. What is needed in this case is a numbering of the boundary degrees
- * of freedom, starting from zero on and not considering the degrees of freedom
- * in the interior. The @p{map_dof_to_boundary_indices} function does exactly
- * this, by providing a vector with as many entries as there are degrees of
- * freedom on the whole domain, with each entry being the number in the
- * numbering of the boundary or @p{-1} if the dof is not on the boundary. You
- * should always use this function to get the mapping between local (boundary)
- * and the global numbers, for example to build the mass matrix on the
- * boundary, or to get the global index of a degree of freedom if we want to
- * use the solution of the projection onto the boundary to eliminate the
- * boundary degrees of freedom from the global matrix.
- *
- * The algorithm to provide this numbering mapping is simple, but you should
- * not rely on it since it may be changed sometimes: we loop over all faces,
- * check whether it is on the boundary, if so get the global numbers of the
- * degrees of freedom on that face, and for each of these we give a
- * subsequent boundary number if none has already been given to this dof.
- * But it should be emphasized again that you should not try to use this
- * internal knowledge about the used algorithm, you are better off if you
- * just accept the mapping `as is'.
- *
- * Actually, there are two @p{map_dof_to_boundary_indices} functions, one
- * producing a numbering for all boundary degrees of freedom and one producing
- * a numbering for only parts of the boundary, namely those parts for which
- * the boundary indicator is listed in a set of indicators given to the
- * function. The latter case is needed if, for example, we would only want to
- * project the boundary values for the Dirichlet part of the boundary, not for
- * the other boundary conditions. You then give the function a list of boundary
- * indicators referring to Dirichlet parts on which the projection is to be
- * performed. The parts of the boundary on which you want to project need not
- * be contiguous; however, it is not guaranteed that the indices of each of the
- * boundary parts are continuous, i.e. the indices of degrees of freedom on
- * different parts may be intermixed.
- *
- * Degrees of freedom on the boundary but not on one of the specified
- * boundary parts are given the index @p{invalid_dof_index}, as if they
- * were in the interior. If no boundary indicator was given or if no
- * face of a cell has a boundary indicator contained in the given
- * list, the vector of new indices consists solely of @p{invalid_dof_index}s.
- *
- * The question what a degree of freedom on the boundary is, is not so easy.
- * It should really be a degree of freedom of which the respective basis
- * function has nonzero values on the boundary. At least for Lagrange elements
- * this definition is equal to the statement that the off-point of the trial
- * function, i.e. the point where the function assumes its nominal value (for
- * Lagrange elements this is the point where it has the function value @p{1}), is
- * located on the boundary. We do not check this directly, the criterion is
- * rather defined through the information the finite element class gives: the
- * @ref{FiniteElementBase} class defines the numbers of basis functions per vertex,
- * per line, and so on and the basis functions are numbered after this
- * information; a basis function is to be considered to be on the face of a
- * cell (and thus on the boundary if the cell is at the boundary) according
- * to its belonging to a vertex, line, etc but not to the cell. The finite
- * element uses the same cell-wise numbering so that we can say that if a
- * degree of freedom was numbered as one of the dofs on lines, we assume that
- * it is located on the line. Where the off-point actually is, is a secret of
- * the finite element (well, you can ask it, but we don't do it here) and not
- * relevant in this context.
- *
  *
  * @author Wolfgang Bangerth, 1998
  */
@@ -452,50 +389,6 @@ class DoFHandler  :  public Subscriptor,
                                      */
     unsigned int max_couplings_between_boundary_dofs () const;
 
-                                    /**
-                                     * Create a mapping from degree
-                                     * of freedom indices to the
-                                     * index of that degree of
-                                     * freedom on the boundary. After
-                                     * this operation, @p{mapping[dof]}
-                                     * gives the index of the the
-                                     * degree of freedom with global
-                                     * number @p{dof} in the list of
-                                     * degrees of freedom on the
-                                     * boundary.  If the degree of
-                                     * freedom requested is not on
-                                     * the boundary, the value of
-                                     * @p{mapping[dof]} is
-                                     * @p{invalid_dof_index}. This
-                                     * function is mainly used when
-                                     * setting up matrices and
-                                     * vectors on the boundary from
-                                     * the trial functions, which
-                                     * have global numbers, while the
-                                     * matrices and vectors use
-                                     * numbers of the trial functions
-                                     * local to the boundary.
-                                     *
-                                     * Prior content of @p{mapping} is deleted.
-                                     *
-                                     * This function is not implemented for
-                                     * one dimension. See the general doc
-                                     * for more information on boundary
-                                     * treatment.
-                                     */
-    void map_dof_to_boundary_indices (vector<unsigned int> &mapping) const;
-
-                                    /**
-                                     * Same as the previous function, except
-                                     * that only selected parts of the
-                                     * boundary are considered.
-                                     *
-                                     * See the general doc of this class for
-                                     * more information.
-                                     */
-    void map_dof_to_boundary_indices (const FunctionMap    &boundary_indicators,
-                                     vector<unsigned int> &mapping) const;
-
                                     /**
                                      *  @name Cell iterator functions
                                      */
index 2ac82095cb3149a9210f025a3da397527e31eb0f..9db699788251d658e6cebf83c771bc7988e3716e 100644 (file)
 
 #include <base/exceptions.h>
 #include <vector>
+#include <map>
 
 class SparsityPattern;
 template <typename number> class Vector;
 template <typename number> class FullMatrix;
+template <int dim> class Function;
 template <int dim> class DoFHandler;
 template <int dim> class MGDoFHandler;
 class ConstraintMatrix;
 template <template <int> class GridClass, int dim> class InterGridMap;
 
+
+
 /**
  * This is a collection of functions operating on, and manipulating
  * the numbers of degrees of freedom. The documentation of the member
@@ -35,6 +39,7 @@ template <template <int> class GridClass, int dim> class InterGridMap;
  * All member functions are static, so there is no need to create an
  * object of class @ref{DoFTools}.
  *
+ *
  * @sect3{Setting up sparsity patterns}
  *
  * When assembling system matrices, the entries are usually of the form
@@ -57,6 +62,80 @@ template <template <int> class GridClass, int dim> class InterGridMap;
  * other basis functions on a cell adjacent to the boundary vanish at the
  * boundary itself, except for those which are located on the boundary.
  *
+ *
+ *
+ * @sect3{DoF numberings on boundaries}
+ *
+ * When projecting the traces of functions to the boundary or parts
+ * thereof, one needs to build matrices and vectors with the degrees
+ * of freedom on the boundary. What is needed in this case is a
+ * numbering of the boundary degrees of freedom, starting from zero on
+ * and not considering the degrees of freedom in the interior. The
+ * @p{map_dof_to_boundary_indices} function does exactly this, by
+ * providing a vector with as many entries as there are degrees of
+ * freedom on the whole domain, with each entry being the number in
+ * the numbering of the boundary or
+ * @ref{DoFHandler}@p{::invalid_dof_index} if the dof is not on the
+ * boundary. You should always use this function to get the mapping
+ * between local (boundary) and the global numbers, for example to
+ * build the mass matrix on the boundary, or to get the global index
+ * of a degree of freedom if we want to use the solution of the
+ * projection onto the boundary to eliminate the boundary degrees of
+ * freedom from the global matrix.
+ *
+ * The algorithm to provide this numbering mapping is simple, but you
+ * should not rely on it since it may be changed sometimes: we loop
+ * over all faces, check whether it is on the boundary, if so get the
+ * global numbers of the degrees of freedom on that face, and for each
+ * of these we give a subsequent boundary number if none has already
+ * been given to this dof. But it should be emphasized again that you
+ * should not try to use this internal knowledge about the used
+ * algorithm, you are better off if you just accept the mapping `as
+ * is'.
+ *
+ * Actually, there are two @p{map_dof_to_boundary_indices} functions,
+ * one producing a numbering for all boundary degrees of freedom and
+ * one producing a numbering for only parts of the boundary, namely
+ * those parts for which the boundary indicator is listed in a set of
+ * indicators given to the function. The latter case is needed if, for
+ * example, we would only want to project the boundary values for the
+ * Dirichlet part of the boundary, not for the other boundary
+ * conditions. You then give the function a list of boundary
+ * indicators referring to Dirichlet parts on which the projection is
+ * to be performed. The parts of the boundary on which you want to
+ * project need not be contiguous; however, it is not guaranteed that
+ * the indices of each of the boundary parts are continuous, i.e. the
+ * indices of degrees of freedom on different parts may be intermixed.
+ *
+ * Degrees of freedom on the boundary but not on one of the specified
+ * boundary parts are given the index @p{invalid_dof_index}, as if
+ * they were in the interior. If no boundary indicator was given or if
+ * no face of a cell has a boundary indicator contained in the given
+ * list, the vector of new indices consists solely of
+ * @p{invalid_dof_index}s.
+ *
+ * The question what a degree of freedom on the boundary is, is not so
+ * easy.  It should really be a degree of freedom of which the
+ * respective basis function has nonzero values on the boundary. At
+ * least for Lagrange elements this definition is equal to the
+ * statement that the off-point of the trial function, i.e. the point
+ * where the function assumes its nominal value (for Lagrange elements
+ * this is the point where it has the function value @p{1}), is
+ * located on the boundary. We do not check this directly, the
+ * criterion is rather defined through the information the finite
+ * element class gives: the @ref{FiniteElementBase} class defines the
+ * numbers of basis functions per vertex, per line, and so on and the
+ * basis functions are numbered after this information; a basis
+ * function is to be considered to be on the face of a cell (and thus
+ * on the boundary if the cell is at the boundary) according to its
+ * belonging to a vertex, line, etc but not to the cell. The finite
+ * element uses the same cell-wise numbering so that we can say that
+ * if a degree of freedom was numbered as one of the dofs on lines, we
+ * assume that it is located on the line. Where the off-point actually
+ * is, is a secret of the finite element (well, you can ask it, but we
+ * don't do it here) and not relevant in this context.
+ *
+ *
  * @author Wolfgang Bangerth and others, 1998, 1999, 2000
  */
 class DoFTools
@@ -698,6 +777,58 @@ class DoFTools
                                   const InterGridMap<DoFHandler,dim> &coarse_to_fine_grid_map,
                                   ConstraintMatrix                   &constraints);
 
+                                    /**
+                                     * Create a mapping from degree
+                                     * of freedom indices to the
+                                     * index of that degree of
+                                     * freedom on the boundary. After
+                                     * this operation, @p{mapping[dof]}
+                                     * gives the index of the the
+                                     * degree of freedom with global
+                                     * number @p{dof} in the list of
+                                     * degrees of freedom on the
+                                     * boundary.  If the degree of
+                                     * freedom requested is not on
+                                     * the boundary, the value of
+                                     * @p{mapping[dof]} is
+                                     * @p{invalid_dof_index}. This
+                                     * function is mainly used when
+                                     * setting up matrices and
+                                     * vectors on the boundary from
+                                     * the trial functions, which
+                                     * have global numbers, while the
+                                     * matrices and vectors use
+                                     * numbers of the trial functions
+                                     * local to the boundary.
+                                     *
+                                     * Prior content of @p{mapping} is deleted.
+                                     *
+                                     * This function is not
+                                     * implemented for one
+                                     * dimension. See the general doc
+                                     * of this class for more
+                                     * information on boundary
+                                     * treatment.
+                                     */
+    template <int dim>
+    static void
+    map_dof_to_boundary_indices (const DoFHandler<dim> &dof_handler,
+                                vector<unsigned int>  &mapping);
+
+                                    /**
+                                     * Same as the previous function, except
+                                     * that only selected parts of the
+                                     * boundary are considered.
+                                     *
+                                     * See the general doc of this class for
+                                     * more information.
+                                     */
+    template <int dim>
+    static void
+    map_dof_to_boundary_indices (const DoFHandler<dim> &dof_handler,
+                                const map<unsigned char,const Function<dim>*> &boundary_indicators,
+                                vector<unsigned int>  &mapping);
+    
                                   
                                     /**
                                      * Exception
@@ -727,6 +858,14 @@ class DoFTools
                                      * Exception
                                      */
     DeclException0 (ExcGridsDontMatch);
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcNoFESelected);
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcInvalidBoundaryIndicator);
 };
 
 
index b4a01efd848491be50a3423967f00894f1bfd41c..74e1f23c88c562b8211f834429767f01b93cd11a 100644 (file)
@@ -1697,88 +1697,6 @@ unsigned int DoFHandler<3>::max_couplings_between_boundary_dofs () const {
 #endif
 
 
-#if deal_II_dimension == 1
-
-template <>
-void DoFHandler<1>::map_dof_to_boundary_indices (vector<unsigned int> &) const {
-  Assert (selected_fe != 0, ExcNoFESelected());
-  Assert (false, ExcNotImplemented());
-};
-
-
-template <>
-void DoFHandler<1>::map_dof_to_boundary_indices (const FunctionMap &,
-                                                vector<unsigned int> &) const {
-  Assert (selected_fe != 0, ExcNoFESelected());
-  Assert (false, ExcNotImplemented());
-};
-
-#endif
-
-
-template <int dim>
-void DoFHandler<dim>::map_dof_to_boundary_indices (vector<unsigned int> &mapping) const
-{
-  Assert (selected_fe != 0, ExcNoFESelected());
-
-  mapping.clear ();
-  mapping.insert (mapping.end(), n_dofs(), invalid_dof_index);
-  
-  const unsigned int dofs_per_face = selected_fe->dofs_per_face;
-  vector<unsigned int> dofs_on_face(dofs_per_face);
-  unsigned int next_boundary_index = 0;
-  
-  active_face_iterator face = begin_active_face(),
-                      endf = end_face();
-  for (; face!=endf; ++face)
-    if (face->at_boundary()) 
-      {
-       face->get_dof_indices (dofs_on_face);
-       for (unsigned int i=0; i<dofs_per_face; ++i)
-         if (mapping[dofs_on_face[i]] == invalid_dof_index)
-           mapping[dofs_on_face[i]] = next_boundary_index++;
-      };
-
-  Assert (next_boundary_index == n_boundary_dofs(),
-         ExcInternalError());
-};
-
-
-template <int dim>
-void DoFHandler<dim>::map_dof_to_boundary_indices (const FunctionMap    &boundary_indicators,
-                                                  vector<unsigned int> &mapping) const
-{
-  Assert (selected_fe != 0, ExcNoFESelected());
-  Assert (boundary_indicators.find(255) == boundary_indicators.end(),
-         ExcInvalidBoundaryIndicator());
-
-  mapping.clear ();
-  mapping.insert (mapping.end(), n_dofs(), invalid_dof_index);
-
-                                  // return if there is nothing to do
-  if (boundary_indicators.size() == 0)
-    return;
-  
-  const unsigned int dofs_per_face = selected_fe->dofs_per_face;
-  vector<unsigned int> dofs_on_face(dofs_per_face);
-  unsigned int next_boundary_index = 0;
-  
-  active_face_iterator face = begin_active_face(),
-                      endf = end_face();
-  for (; face!=endf; ++face)
-    if (boundary_indicators.find(face->boundary_indicator()) !=
-       boundary_indicators.end())
-      {
-       face->get_dof_indices (dofs_on_face);
-       for (unsigned int i=0; i<dofs_per_face; ++i)
-         if (mapping[dofs_on_face[i]] == invalid_dof_index)
-           mapping[dofs_on_face[i]] = next_boundary_index++;
-      };
-
-  Assert (next_boundary_index == n_boundary_dofs(boundary_indicators),
-         ExcInternalError());
-};
-
 
 #if deal_II_dimension == 1
 
index 751ec35c95ab436cf141e0f77491e9027947a79e..883f07c8b27b3dd891c59511449059566bc31a74 100644 (file)
@@ -1475,6 +1475,101 @@ DoFTools::compute_intergrid_constraints (const DoFHandler<dim>              &coa
 
 
 
+#if deal_II_dimension == 1
+
+template <>
+void DoFTools::map_dof_to_boundary_indices (const DoFHandler<1> &dof_handler,
+                                           vector<unsigned int> &)
+{
+  Assert (&dof_handler.get_fe() != 0, ExcNoFESelected());
+  Assert (false, ExcNotImplemented());
+};
+
+
+
+template <>
+void DoFTools::map_dof_to_boundary_indices (const DoFHandler<1> &dof_handler,
+                                           const map<unsigned char,const Function<1>*> &,
+                                           vector<unsigned int> &)
+{
+  Assert (&dof_handler.get_fe() != 0, ExcNoFESelected());
+  Assert (false, ExcNotImplemented());
+};
+
+
+#else
+
+
+template <int dim>
+void DoFTools::map_dof_to_boundary_indices (const DoFHandler<dim> &dof_handler,
+                                           vector<unsigned int>  &mapping)
+{
+  Assert (&dof_handler.get_fe() != 0, ExcNoFESelected());
+
+  mapping.clear ();
+  mapping.insert (mapping.end(), dof_handler.n_dofs(),
+                 DoFHandler<dim>::invalid_dof_index);
+  
+  const unsigned int dofs_per_face = dof_handler.get_fe().dofs_per_face;
+  vector<unsigned int> dofs_on_face(dofs_per_face);
+  unsigned int next_boundary_index = 0;
+  
+  typename DoFHandler<dim>::active_face_iterator face = dof_handler.begin_active_face(),
+                                                endf = dof_handler.end_face();
+  for (; face!=endf; ++face)
+    if (face->at_boundary()) 
+      {
+       face->get_dof_indices (dofs_on_face);
+       for (unsigned int i=0; i<dofs_per_face; ++i)
+         if (mapping[dofs_on_face[i]] == DoFHandler<dim>::invalid_dof_index)
+           mapping[dofs_on_face[i]] = next_boundary_index++;
+      };
+
+  Assert (next_boundary_index == dof_handler.n_boundary_dofs(),
+         ExcInternalError());
+};
+
+
+
+template <int dim>
+void DoFTools::map_dof_to_boundary_indices (const DoFHandler<dim> &dof_handler,
+                                           const map<unsigned char,const Function<dim>*> &boundary_indicators,
+                                           vector<unsigned int>  &mapping)
+{
+  Assert (&dof_handler.get_fe() != 0, ExcNoFESelected());
+  Assert (boundary_indicators.find(255) == boundary_indicators.end(),
+         ExcInvalidBoundaryIndicator());
+
+  mapping.clear ();
+  mapping.insert (mapping.end(), dof_handler.n_dofs(),
+                 DoFHandler<dim>::invalid_dof_index);
+
+                                  // return if there is nothing to do
+  if (boundary_indicators.size() == 0)
+    return;
+  
+  const unsigned int dofs_per_face = dof_handler.get_fe().dofs_per_face;
+  vector<unsigned int> dofs_on_face(dofs_per_face);
+  unsigned int next_boundary_index = 0;
+  
+  typename DoFHandler<dim>::active_face_iterator face = dof_handler.begin_active_face(),
+                                                endf = dof_handler.end_face();
+  for (; face!=endf; ++face)
+    if (boundary_indicators.find(face->boundary_indicator()) !=
+       boundary_indicators.end())
+      {
+       face->get_dof_indices (dofs_on_face);
+       for (unsigned int i=0; i<dofs_per_face; ++i)
+         if (mapping[dofs_on_face[i]] == DoFHandler<dim>::invalid_dof_index)
+           mapping[dofs_on_face[i]] = next_boundary_index++;
+      };
+
+  Assert (next_boundary_index == dof_handler.n_boundary_dofs(boundary_indicators),
+         ExcInternalError());
+};
+
+#endif
+
 
 
 // explicit instantiations
@@ -1562,3 +1657,20 @@ DoFTools::compute_intergrid_constraints (const DoFHandler<deal_II_dimension> &,
                                         const unsigned int                   ,
                                         const InterGridMap<DoFHandler,deal_II_dimension> &,
                                         ConstraintMatrix                    &);
+
+
+
+#if deal_II_dimension != 1
+
+template
+void
+DoFTools::map_dof_to_boundary_indices (const DoFHandler<deal_II_dimension> &,
+                                      vector<unsigned int> &);
+
+template
+void
+DoFTools::map_dof_to_boundary_indices (const DoFHandler<deal_II_dimension> &,
+                                      const map<unsigned char,const Function<deal_II_dimension>*> &,
+                                      vector<unsigned int> &);
+
+#endif 
index d022ef6802d42f2694f825678a8087a4cfa61a1c..537691b178dd7dbd5bf5b00fad0577e53ea94f18 100644 (file)
 #include <cmath>
 
 
-inline double sqr (const double x) {
+static inline double sqr (const double x)
+{
   return x*x;
 };
 
 
+
 template <int dim>
-inline double sqr_point (const Tensor<1,dim> &p) {
+inline double sqr_point (const Tensor<1,dim> &p)
+{
   return p * p;
 };
 
 
+
 template <int dim>
 void VectorTools::interpolate (const DoFHandler<dim> &dof,
                               const Function<dim>   &function,
@@ -278,6 +282,7 @@ void VectorTools::interpolate (const DoFHandler<dim> &dof,
 }
 
 
+
 template <int dim> void
 VectorTools::interpolate (const DoFHandler<dim>           &dof_1,
                          const DoFHandler<dim>           &dof_2,
@@ -454,6 +459,7 @@ void VectorTools::project (const DoFHandler<dim>    &dof,
 };
 
 
+
 template <int dim>
 void VectorTools::create_right_hand_side (const DoFHandler<dim>    &dof_handler,
                                          const Quadrature<dim>    &quadrature,
@@ -541,6 +547,7 @@ void VectorTools::create_right_hand_side (const DoFHandler<dim>    &dof_handler,
 };
 
 
+
 #if deal_II_dimension == 1
 
 template <>
@@ -700,10 +707,11 @@ VectorTools::interpolate_boundary_values (const DoFHandler<dim>    &dof,
 }
 
 
+
 template <int dim>
 void
 VectorTools::project_boundary_values (const DoFHandler<dim>    &dof,
-                                     const map<unsigned char,const Function<dim>*>        &boundary_functions,
+                                     const map<unsigned char,const Function<dim>*> &boundary_functions,
                                      const Quadrature<dim-1>  &q,
                                      map<unsigned int,double> &boundary_values)
 {
@@ -711,7 +719,8 @@ VectorTools::project_boundary_values (const DoFHandler<dim>    &dof,
          ExcComponentMismatch());
   
   vector<unsigned int> dof_to_boundary_mapping;
-  dof.map_dof_to_boundary_indices (boundary_functions, dof_to_boundary_mapping);
+  DoFTools::map_dof_to_boundary_indices (dof, boundary_functions,
+                                        dof_to_boundary_mapping);
   
                                   // set up sparsity structure
   SparsityPattern sparsity(dof.n_boundary_dofs(boundary_functions),
@@ -780,6 +789,7 @@ VectorTools::project_boundary_values (const DoFHandler<dim>    &dof,
 };
 
 
+
 template <int dim>
 void
 VectorTools::integrate_difference (const DoFHandler<dim>    &dof,
@@ -1188,6 +1198,7 @@ double VectorTools::compute_mean_value (const DoFHandler<deal_II_dimension> &dof
 
 
 
+
 // the following two functions are not derived from a template in 1d
 // and thus need no explicit instantiation
 #if deal_II_dimension > 1
index cdca5f31987fcd5819588eb2c2b3ca10a79ac8cd..0edd600ce1e2e52cb5efc38d3998d328193f1fcb 100644 (file)
 <h3>deal.II</h3>
 
 <ol>
+  <li> <p>
+       Changed: The 
+       <code class="member">map_dof_to_boundary_index</code>
+       functions have been moved from the <code class="class">DoFHandler</code>
+       to the <code class="class">DoFTools</code> class, in order to
+       further remove code from the big classes which is necessarily
+       needed there.
+       <br>
+       (WB 2000/08/25)
+       </p>
+
   <li> <p>
        New: there is now a class <code class="class">DataOutRotation</code>
        that can be used to output data which has been computed

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.