]> https://gitweb.dealii.org/ - dealii.git/commitdiff
FETools::lexicographic_to_hierarchic and other way round.
authorWolfgang Bangerth <bangerth@math.tamu.edu>
Fri, 31 Aug 2001 19:47:58 +0000 (19:47 +0000)
committerWolfgang Bangerth <bangerth@math.tamu.edu>
Fri, 31 Aug 2001 19:47:58 +0000 (19:47 +0000)
git-svn-id: https://svn.dealii.org/trunk@4928 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/deal.II/include/fe/fe_tools.h
deal.II/deal.II/source/fe/fe_q.cc
deal.II/deal.II/source/fe/fe_tools.cc
deal.II/doc/news/2001/c-3-1.html
tests/fe/numbering.cc
tests/fe/numbering.checked

index 963a011877f897d2203ed37ecd37c9e876f66489..b063585bf9c0c630459518db9464a3aff5874367 100644 (file)
@@ -19,6 +19,7 @@ template <typename number> class FullMatrix;
 template <int dim> class FiniteElement;
 template <int dim> class DoFHandler;
 template <typename number> class Vector;
+template <int dim> class FE_Q;
 
 #include <base/exceptions.h>
 
@@ -193,8 +194,77 @@ class FETools
                            const Vector<number>  &z1,
                            const DoFHandler<dim> &dof2,
                            Vector<number>        &z2);    
-  
-  
+
+                                    /**
+                                     * The numbering of the degrees
+                                     * of freedom in continous finite
+                                     * elements is hierarchic,
+                                     * i.e. in such a way that we
+                                     * first number the vertex dofs,
+                                     * in the order of the vertices
+                                     * as defined by the
+                                     * triangulation, then the line
+                                     * dofs in the order and
+                                     * respecting the direction of
+                                     * the lines, then the dofs on
+                                     * quads, etc. However, we could
+                                     * have, as well, numbered them
+                                     * in a lexicographic way,
+                                     * i.e. with indices first
+                                     * running in x-direction, then
+                                     * in y-direction and finally in
+                                     * z-direction. Discontinuous
+                                     * elements of class @ref{FE_DGQ}
+                                     * are numbered in this way, for
+                                     * example.
+                                     *
+                                     * This function constructs a
+                                     * table which lexicographic
+                                     * index each degree of freedom
+                                     * in the hierarchic numbering
+                                     * would have. It operates on the
+                                     * continuous finite element
+                                     * given as first argument, and
+                                     * outputs the lexicographic
+                                     * indices in the second.
+                                     *
+                                     * Note that since this function
+                                     * uses specifics of the
+                                     * continuous finite elements, it
+                                     * can only operate on objects of
+                                     * type @ref{FE_Q}.
+                                     *
+                                     * It is assumed that the size of
+                                     * the output argument already
+                                     * matches the correct size,
+                                     * which is equal to the number
+                                     * of degrees of freedom in the
+                                     * finite element.
+                                     */
+    template <int dim>
+    static void
+    hierarchic_to_lexicographic_numbering (const FE_Q<dim>           &fe,
+                                          std::vector<unsigned int> &h2l);
+
+                                    /**
+                                     * This is the reverse function
+                                     * to the above one, generating
+                                     * the map from the lexicographic
+                                     * to the hierarchical
+                                     * numbering. All the remarks
+                                     * made about the above function
+                                     * are also valid here.
+                                     */
+    template <int dim>
+    static void
+    lexicographic_to_hierarchic_numbering (const FE_Q<dim>           &fe,
+                                          std::vector<unsigned int> &l2h);
+    
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcInvalidFE);
+    
                                     /**
                                      * Exception
                                      */
index bc90a386c2e8af2c31cf793855e850d4a70cff16..d6c9b9695f145a556912f19bf935a06049c8461f 100644 (file)
@@ -25,7 +25,7 @@
 
 
 
-//TODO:[WB] move build_renumbering to FiniteElementData class
+//TODO:[RH] move build_renumbering to FiniteElementData class
 
 template <int dim>
 FE_Q<dim>::FE_Q (const unsigned int degree)
index 339e1f7fc08484a9e8bad0c64cc0dea331df2659..b986c746388a84a0f23fec362307d910950cdf42 100644 (file)
@@ -19,6 +19,7 @@
 #include <grid/tria_iterator.h>
 #include <fe/fe_tools.h>
 #include <fe/fe.h>
+#include <fe/fe_q.h>
 #include <fe/fe_values.h>
 #include <fe/mapping_q1.h>
 #include <dofs/dof_handler.h>
@@ -299,6 +300,412 @@ void FETools::extrapolate(const DoFHandler<dim> &dof1,
 
 
 
+template <int dim>
+void
+FETools::hierarchic_to_lexicographic_numbering (const FE_Q<dim>           &fe,
+                                               std::vector<unsigned int> &h2l)
+{
+  Assert (fe.n_components() == 1, ExcInvalidFE());
+  Assert (h2l.size() == fe.dofs_per_cell,
+         ExcDimensionMismatch (h2l.size(), fe.dofs_per_cell));
+
+  const unsigned int dofs_per_cell = fe.dofs_per_cell;
+                                  // polynomial degree
+  const unsigned int degree = fe.dofs_per_line+1;
+                                  // number of grid points in each
+                                  // direction
+  const unsigned int n = degree+1;
+
+                                  // the following lines of code are
+                                  // somewhat odd, due to the way the
+                                  // hierarchic numbering is
+                                  // organized. if someone would
+                                  // really want to understand these
+                                  // lines, you better draw some
+                                  // pictures where you indicate the
+                                  // indices and orders of vertices,
+                                  // lines, etc, along with the
+                                  // numbers of the degrees of
+                                  // freedom in hierarchical and
+                                  // lexicographical order
+  switch (dim)
+    {
+      case 1:
+      {
+       h2l[0] = 0;
+       h2l[1] = dofs_per_cell-1;
+       for (unsigned int i=2; i<dofs_per_cell; ++i)
+         h2l[i] = i-1;
+
+       break;
+      };
+
+      case 2:
+      {
+       unsigned int next_index = 0;
+                                        // first the four vertices
+       h2l[next_index++] = 0;
+       h2l[next_index++] = n-1;
+       h2l[next_index++] = n*n-1;
+       h2l[next_index++] = n*(n-1);
+                                        // first line
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         h2l[next_index++] = 1+i;
+                                        // second line
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         h2l[next_index++] = (2+i)*n-1;
+                                        // third line
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         h2l[next_index++] = n*(n-1)+i+1;
+                                        // fourth line
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         h2l[next_index++] = (1+i)*n;
+                                        // inside quad
+       Assert (fe.dofs_per_quad == fe.dofs_per_line*fe.dofs_per_line,
+               ExcInternalError());
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+           h2l[next_index++] = n*(i+1)+j+1;
+
+       Assert (next_index == fe.dofs_per_cell, ExcInternalError());
+
+       break;
+      };
+
+      case 3:
+      {
+       unsigned int next_index = 0;
+                                        // first the eight vertices
+       h2l[next_index++] = 0;
+       h2l[next_index++] = n-1;
+       h2l[next_index++] = (n-1)*(n*n+1);
+       h2l[next_index++] = (n-1)*n*n;
+       h2l[next_index++] = n*(n-1);
+       h2l[next_index++] = n*n-1;
+       h2l[next_index++] = n*n*n-1;
+       h2l[next_index++] = (n-1)*(n*n+n);
+
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         h2l[next_index++] = 1+i;
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         h2l[next_index++] = n-1+(i+1)*n*n;
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         h2l[next_index++] = n*n*(n-1)+i+1;
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         h2l[next_index++] = (i+1)*n*n;
+
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         h2l[next_index++] = 1+i+n*(n-1);
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         h2l[next_index++] = n-1+(i+1)*n*n+n*(n-1);
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         h2l[next_index++] = n*n*(n-1)+i+1+n*(n-1);
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         h2l[next_index++] = (i+1)*n*n+n*(n-1);
+
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         h2l[next_index++] = (i+1)*n;
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         h2l[next_index++] = n-1+(i+1)*n;
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         h2l[next_index++] = (n-1)*(n*n+1)+(i+1)*n;
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         h2l[next_index++] = (n-1)*n*n+(i+1)*n;
+
+                                        // inside quads
+       Assert (fe.dofs_per_quad == fe.dofs_per_line*fe.dofs_per_line,
+               ExcInternalError());
+                                        // quad 1
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+           h2l[next_index++] = (i+1)*n*n+j+1;
+                                        // quad 2
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+           h2l[next_index++] = (i+1)*n*n+n*(n-1)+j+1;
+                                        // quad 3
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+           h2l[next_index++] = n*(i+1)+j+1;
+                                        // quad 4
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+           h2l[next_index++] = (i+1)*n*n+n-1+n*(j+1);
+                                        // quad 5
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+           h2l[next_index++] = (n-1)*n*n+n*(i+1)+j+1;
+                                        // quad 6
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+           h2l[next_index++] = (i+1)*n*n+n*(j+1);
+
+                                        // inside hex
+       Assert (fe.dofs_per_hex == fe.dofs_per_quad*fe.dofs_per_line,
+               ExcInternalError());
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+           for (unsigned int k=0; k<fe.dofs_per_line; ++k)
+             h2l[next_index++] = n*n*(i+1)+n*(j+1)+k+1;
+
+       Assert (next_index == fe.dofs_per_cell, ExcInternalError());
+       
+       break;
+      };       
+
+      default:
+           Assert (false, ExcNotImplemented());
+    };
+};
+
+
+
+template <int dim>
+void
+FETools::lexicographic_to_hierarchic_numbering (const FE_Q<dim>           &fe,
+                                               std::vector<unsigned int> &l2h)
+{
+                                  // note: this function does the
+                                  // reverse operation of the
+                                  // previous one. nevertheless, they
+                                  // have been written independently
+                                  // from each other. the test
+                                  // "fe/numbering" checks that the
+                                  // output of the two functions is
+                                  // indeed the reverse of each other
+                                  // by checking that the
+                                  // concatenation of the two maps is
+                                  // the identity operation
+                                  //
+                                  // The experienced code reader will
+                                  // note that this function was not
+                                  // written by the same author than
+                                  // the previous one (although the
+                                  // author of the previous function
+                                  // cleaned up this if-block a
+                                  // little bit by introducing the
+                                  // arrays of numbers). Therefore,
+                                  // both authors have experienced
+                                  // the downsides of the hierarchic
+                                  // numbering of degrees of freedom
+                                  // in deal.II. Just to also provide
+                                  // some fun while reading code,
+                                  // here is the rant of the author
+                                  // of this function about the
+                                  // author of the previous one:
+                                  //
+                                  // "Unfortunately, somebody
+                                  // switched the upper corner points
+                                  // of a quad. The same person
+                                  // decided to find a very creative
+                                  // numbering of the vertices of a
+                                  // hexahedron. Therefore, this code
+                                  // looks quite sophisticated."
+                                  //
+                                  // NB: The "accused" same person
+                                  // claims to have had good reasons
+                                  // then, but seems to have
+                                  // forgotten about them. At least,
+                                  // the numbering was discussed with
+                                  // the complaining person back then
+                                  // when all began :-)
+  Assert (fe.n_components() == 1, ExcInvalidFE());
+  Assert (l2h.size() == fe.dofs_per_cell,
+         ExcDimensionMismatch (l2h.size(), fe.dofs_per_cell));
+                                  // polynomial degree
+  const unsigned int degree = fe.dofs_per_line+1;
+                                  // number of grid points in each
+                                  // direction
+  const unsigned int n = degree+1;
+
+  if (degree > 0)
+    {
+      Assert (fe.dofs_per_vertex == 1, ExcInternalError());
+      for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+       {
+         unsigned int index = 0;
+                                          // Find indices of vertices.
+         switch (dim)
+           {
+             case 1:
+             {
+               const unsigned int values[GeometryInfo<1>::vertices_per_cell]
+                 = { 0, degree };
+               index = values[i];
+               break;
+             };
+            
+             case 2:
+             {
+               const unsigned int values[GeometryInfo<2>::vertices_per_cell]
+                 = { 0, degree, n*degree+degree, n*degree };
+               index = values[i];
+               break;
+             };
+            
+             case 3:
+             {
+               const unsigned int values[GeometryInfo<3>::vertices_per_cell]
+                 = { 0, degree,
+                     n*n*degree + degree, n*n*degree,
+                     n*degree, n*degree+degree,
+                     n*n*degree + n*degree+degree, n*n*degree + n*degree};
+               index = values[i];
+               break;
+             };
+            
+             default:
+                   Assert(false, ExcNotImplemented());
+           }
+       
+         l2h[index] = i;
+       }
+    };
+  
+                                  // for degree 2 and higher: Lines,
+                                  // quads, hexes etc also carry
+                                  // degrees of freedom
+  if (degree > 1)
+    {
+      Assert (fe.dofs_per_line == degree-1, ExcInternalError());
+      Assert ((fe.dofs_per_quad == (degree-1)*(degree-1)) ||
+             (dim < 2), ExcInternalError());
+      Assert ((fe.dofs_per_hex == (degree-1)*(degree-1)*(degree-1)) ||
+             (dim < 3), ExcInternalError());
+           
+      for (int i=0; i<static_cast<signed int>(GeometryInfo<dim>::lines_per_cell); ++i)
+       {
+         unsigned int index = fe.first_line_index + i*fe.dofs_per_line;
+         unsigned int incr = 0;
+         unsigned int tensorstart = 0;
+                                          // This again looks quite
+                                          // strange because of the odd
+                                          // numbering scheme.
+         switch (i+100*dim)
+           {
+                                              // lines in x-direction
+             case 100:
+             case 200: case 202:
+             case 300: case 302: case 304: case 306:
+                   incr = 1;
+                   break;
+                                                    // lines in y-direction
+             case 201: case 203:
+             case 308: case 309: case 310: case 311:
+                   incr = n;
+                   break;
+                                                    // lines in z-direction
+             case 301: case 303: case 305: case 307:
+                   incr = n*n;
+                   break;
+             default:
+                   Assert(false, ExcNotImplemented());
+           }
+         switch (i+100*dim)
+           {
+                                              // x=y=z=0
+             case 100:
+             case 200: case 203:
+             case 300: case 303: case 308:
+                   tensorstart = 0;
+                   break;
+                                                    // x=1 y=z=0
+             case 201:
+             case 301: case 309:
+                   tensorstart = degree;
+                   break;
+                                                    // y=1 x=z=0
+             case 202:
+             case 304: case 307:
+                   tensorstart = n*degree;
+                   break;
+                                                    // x=z=1 y=0
+             case 310:
+                   tensorstart = n*n*degree+degree;
+                   break;
+                                                    // z=1 x=y=0
+             case 302: case 311:
+                   tensorstart = n*n*degree;
+                   break;
+                                                    // x=y=1 z=0
+             case 305:
+                   tensorstart = n*degree+degree;
+                   break;
+                                                    // y=z=1 x=0
+             case 306:
+                   tensorstart = n*n*n-n;
+                   break;
+             default:
+                   Assert(false, ExcNotImplemented());       
+           }
+         
+         for (unsigned int jx = 1; jx<degree ;++jx)
+           {
+             unsigned int tensorindex = tensorstart + jx * incr;
+             l2h[tensorindex] = index++;
+           }
+       }
+
+      for (int i=0; i<static_cast<signed int>(GeometryInfo<dim>::quads_per_cell); ++i)
+       {
+         unsigned int index = fe.first_quad_index+i*fe.dofs_per_quad;
+         unsigned int tensorstart = 0;
+         unsigned int incx = 0;
+         unsigned int incy = 0;
+         switch (i)
+           {
+             case 0:
+                   tensorstart = 0; incx = 1;
+                   if (dim==2)
+                     incy = n;
+                   else
+                     incy = n*n;
+                   break;
+             case 1:
+                   tensorstart = n*degree; incx = 1; incy = n*n;
+                   break;
+             case 2:
+                   tensorstart = 0; incx = 1; incy = n;
+                   break;
+             case 3:
+                   tensorstart = degree; incx = n; incy = n*n;
+                   break;
+             case 4:
+                   tensorstart = n*n*degree; incx = 1; incy = n;
+                   break;
+             case 5:
+                   tensorstart = 0; incx = n; incy = n*n;
+                   break;
+             default:
+                   Assert(false, ExcNotImplemented());       
+           }
+         
+         for (unsigned int jy = 1; jy<degree; jy++)
+           for (unsigned int jx = 1; jx<degree ;++jx)
+             {
+               unsigned int tensorindex = tensorstart
+                                          + jx * incx + jy * incy;
+               l2h[tensorindex] = index++;
+             }
+       }
+
+      for (int i=0; i<static_cast<signed int>(GeometryInfo<dim>::hexes_per_cell); ++i)
+       {
+         unsigned int index = fe.first_hex_index;
+         
+         for (unsigned int jz = 1; jz<degree; jz++)
+           for (unsigned int jy = 1; jy<degree; jy++)
+             for (unsigned int jx = 1; jx<degree; jx++)
+               {
+                 const unsigned int tensorindex = jx + jy*n + jz*n*n;
+                 l2h[tensorindex]=index++;
+               }  
+       } 
+    }
+};
+
+
+
 
 /*-------------- Explicit Instantiations -------------------------------*/
 
@@ -368,5 +775,14 @@ void FETools::extrapolate(const DoFHandler<deal_II_dimension> &,
                          const Vector<float> &,
                          const DoFHandler<deal_II_dimension> &,
                          Vector<float> &);
+template
+void
+FETools::hierarchic_to_lexicographic_numbering (const FE_Q<deal_II_dimension> &fe,
+                                               std::vector<unsigned int>     &h2l);
+template
+void
+FETools::lexicographic_to_hierarchic_numbering (const FE_Q<deal_II_dimension> &fe,
+                                               std::vector<unsigned int>     &h2l);
+
 
 /*----------------------------   fe_tools.cc     ---------------------------*/
index b81d6ad75f97d9de4303460d40f1a44ba8e38582..532206ed112983163784dd60f43a7943f54354b8 100644 (file)
@@ -573,6 +573,18 @@ documentation, etc</a>.
 <h3>deal.II</h3>
 
 <ol>
+  <li> <p> 
+       New: There are now two functions
+       <code
+       class="member">FETools::hierarchic_to_lexicographic_numbering</code>
+       and <code
+       class="member">FETools::lexicographic_to_hierarchic_numbering</code>
+       which map the hierarchical numbering used in continuous finite
+       element classes to a lexicographical numbering and back.
+       <br>
+       (WB 2001/08/31)
+       </p>
+
   <li> <p> 
        New: <code class="member">ConstraintMatrix::close</code>
        now simply returns instead of throwing an exception, if the
index faa2277643d0f7e45a9bdfe1fb3fffac5ed76abe..273e6498ba5c05048d115b7c7e11ca3cd829c8bc 100644 (file)
@@ -1,11 +1,13 @@
 // $Id$
 // Author: Wolfgang Bangerth, 2001
 //
-// Check the numbering of finite elements
+// Check the numbering of continuous Lagrange finite elements. it
+// constructs and independent numbering and compares it with the
+// result of two functions from the library
 
 #include <base/logstream.h>
 #include <fe/fe_q.h>
-#include <fe/fe_dgq.h>
+#include <fe/fe_tools.h>
 #include <vector>
 #include <fstream>
 
@@ -59,7 +61,8 @@ void check (const FE_Q<dim> &fe)
        for (unsigned int i=0; i<fe.dofs_per_line; ++i)
          hierarchic_to_lexicographic_numbering[next_index++] = (1+i)*n;
                                         // inside quad
-       Assert (fe.dofs_per_quad == fe.dofs_per_line*fe.dofs_per_line, ExcInternalError());
+       Assert (fe.dofs_per_quad == fe.dofs_per_line*fe.dofs_per_line,
+               ExcInternalError());
        for (unsigned int i=0; i<fe.dofs_per_line; ++i)
          for (unsigned int j=0; j<fe.dofs_per_line; ++j)
            hierarchic_to_lexicographic_numbering[next_index++] = n*(i+1)+j+1;
@@ -67,24 +70,119 @@ void check (const FE_Q<dim> &fe)
        break;
       };
 
+      case 3:
+      {
+       unsigned int next_index = 0;
+                                        // first the eight vertices
+       hierarchic_to_lexicographic_numbering[next_index++] = 0;
+       hierarchic_to_lexicographic_numbering[next_index++] = n-1;
+       hierarchic_to_lexicographic_numbering[next_index++] = (n-1)*(n*n+1);
+       hierarchic_to_lexicographic_numbering[next_index++] = (n-1)*n*n;
+       hierarchic_to_lexicographic_numbering[next_index++] = n*(n-1);
+       hierarchic_to_lexicographic_numbering[next_index++] = n*n-1;
+       hierarchic_to_lexicographic_numbering[next_index++] = n*n*n-1;
+       hierarchic_to_lexicographic_numbering[next_index++] = (n-1)*(n*n+n);
+
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         hierarchic_to_lexicographic_numbering[next_index++] = 1+i;
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         hierarchic_to_lexicographic_numbering[next_index++] = n-1+(i+1)*n*n;
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         hierarchic_to_lexicographic_numbering[next_index++] = n*n*(n-1)+i+1;
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         hierarchic_to_lexicographic_numbering[next_index++] = (i+1)*n*n;
+
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         hierarchic_to_lexicographic_numbering[next_index++] = 1+i+n*(n-1);
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         hierarchic_to_lexicographic_numbering[next_index++] = n-1+(i+1)*n*n+n*(n-1);
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         hierarchic_to_lexicographic_numbering[next_index++] = n*n*(n-1)+i+1+n*(n-1);
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         hierarchic_to_lexicographic_numbering[next_index++] = (i+1)*n*n+n*(n-1);
+
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         hierarchic_to_lexicographic_numbering[next_index++] = (i+1)*n;
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         hierarchic_to_lexicographic_numbering[next_index++] = n-1+(i+1)*n;
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         hierarchic_to_lexicographic_numbering[next_index++] = (n-1)*(n*n+1)+(i+1)*n;
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         hierarchic_to_lexicographic_numbering[next_index++] = (n-1)*n*n+(i+1)*n;
+
+                                        // inside quads
+       Assert (fe.dofs_per_quad == fe.dofs_per_line*fe.dofs_per_line,
+               ExcInternalError());
+                                        // quad 1
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+           hierarchic_to_lexicographic_numbering[next_index++] = (i+1)*n*n+j+1;
+                                        // quad 2
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+           hierarchic_to_lexicographic_numbering[next_index++] = (i+1)*n*n+n*(n-1)+j+1;
+                                        // quad 3
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+           hierarchic_to_lexicographic_numbering[next_index++] = n*(i+1)+j+1;
+                                        // quad 4
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+           hierarchic_to_lexicographic_numbering[next_index++] = (i+1)*n*n+n-1+n*(j+1);
+                                        // quad 5
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+           hierarchic_to_lexicographic_numbering[next_index++] = (n-1)*n*n+n*(i+1)+j+1;
+                                        // quad 6
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+           hierarchic_to_lexicographic_numbering[next_index++] = (i+1)*n*n+n*(j+1);
+
+                                        // inside hex
+       Assert (fe.dofs_per_hex == fe.dofs_per_quad*fe.dofs_per_line,
+               ExcInternalError());
+       for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+         for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+           for (unsigned int k=0; k<fe.dofs_per_line; ++k)
+             hierarchic_to_lexicographic_numbering[next_index++]
+               = n*n*(i+1)+n*(j+1)+k+1;
+       
+       break;
+      };
+       
+
       default:
            Assert (false, ExcNotImplemented());
     };
   
-                                  // now check with data from the lib
-  const std::vector<unsigned int> &
-    lexicographic_to_hierarchical_numbering = fe.get_renumber();
+                                  // now check with data from the
+                                  // lib: there we have the mapping
+                                  // the other way round, and we
+                                  // check that the concatenation of
+                                  // the two mappings is the
+                                  // identity. output the two maps to
+                                  // generate some output for
+                                  // automatic comparison
+  std::vector<unsigned int> l2h (fe.dofs_per_cell);
+  FETools::lexicographic_to_hierarchic_numbering (fe, l2h);
   for (unsigned int i=0; i<dofs_per_cell; ++i)
     {
-      Assert (lexicographic_to_hierarchical_numbering
-             [hierarchic_to_lexicographic_numbering[i]] == i,
+      Assert (l2h[hierarchic_to_lexicographic_numbering[i]] == i,
              ExcInternalError());
       logfile << dim << "d, degree=" << degree << ": "
-             << lexicographic_to_hierarchical_numbering[i]
+             << l2h[i]
              << ' '
              << hierarchic_to_lexicographic_numbering[i]
              << std::endl;
     };
+
+                                  // finally, we also have the
+                                  // forward map in the lib, so check
+                                  // for equality
+  std::vector<unsigned int> h2l (fe.dofs_per_cell);
+  FETools::hierarchic_to_lexicographic_numbering (fe, h2l);
+  Assert (hierarchic_to_lexicographic_numbering == h2l,
+         ExcInternalError());
 };
 
 
@@ -92,7 +190,7 @@ void check (const FE_Q<dim> &fe)
 template <int dim>
 void check_dim ()
 {
-  for (unsigned int degree=1; degree<4; ++degree)
+  for (unsigned int degree=1; degree<6; ++degree)
     {
       FE_Q<dim> fe(degree);
       check (fe);
@@ -109,6 +207,7 @@ int main ()
 
   check_dim<1> ();
   check_dim<2> ();
+  check_dim<3> ();
 };
 
 
index 446d3561d3fba939fbf8c7c42850222f3f5151d1..d2ea63be451d3cb21026a2eeeae8d8876c8a6e0d 100644 (file)
@@ -8,6 +8,17 @@
 1d, degree=3: 2 3
 1d, degree=3: 3 1
 1d, degree=3: 1 2
+1d, degree=4: 0 0
+1d, degree=4: 2 4
+1d, degree=4: 3 1
+1d, degree=4: 4 2
+1d, degree=4: 1 3
+1d, degree=5: 0 0
+1d, degree=5: 2 5
+1d, degree=5: 3 1
+1d, degree=5: 4 2
+1d, degree=5: 5 3
+1d, degree=5: 1 4
 2d, degree=1: 0 0
 2d, degree=1: 1 1
 2d, degree=1: 3 3
 2d, degree=3: 8 6
 2d, degree=3: 9 9
 2d, degree=3: 2 10
+2d, degree=4: 0 0
+2d, degree=4: 4 4
+2d, degree=4: 5 24
+2d, degree=4: 6 20
+2d, degree=4: 1 1
+2d, degree=4: 13 2
+2d, degree=4: 16 3
+2d, degree=4: 17 9
+2d, degree=4: 18 14
+2d, degree=4: 7 19
+2d, degree=4: 14 21
+2d, degree=4: 19 22
+2d, degree=4: 20 23
+2d, degree=4: 21 5
+2d, degree=4: 8 10
+2d, degree=4: 15 15
+2d, degree=4: 22 6
+2d, degree=4: 23 7
+2d, degree=4: 24 8
+2d, degree=4: 9 11
+2d, degree=4: 3 12
+2d, degree=4: 10 13
+2d, degree=4: 11 16
+2d, degree=4: 12 17
+2d, degree=4: 2 18
+2d, degree=5: 0 0
+2d, degree=5: 4 5
+2d, degree=5: 5 35
+2d, degree=5: 6 30
+2d, degree=5: 7 1
+2d, degree=5: 1 2
+2d, degree=5: 16 3
+2d, degree=5: 20 4
+2d, degree=5: 21 11
+2d, degree=5: 22 17
+2d, degree=5: 23 23
+2d, degree=5: 8 29
+2d, degree=5: 17 31
+2d, degree=5: 24 32
+2d, degree=5: 25 33
+2d, degree=5: 26 34
+2d, degree=5: 27 6
+2d, degree=5: 9 12
+2d, degree=5: 18 18
+2d, degree=5: 28 24
+2d, degree=5: 29 7
+2d, degree=5: 30 8
+2d, degree=5: 31 9
+2d, degree=5: 10 10
+2d, degree=5: 19 13
+2d, degree=5: 32 14
+2d, degree=5: 33 15
+2d, degree=5: 34 16
+2d, degree=5: 35 19
+2d, degree=5: 11 20
+2d, degree=5: 3 21
+2d, degree=5: 12 22
+2d, degree=5: 13 25
+2d, degree=5: 14 26
+2d, degree=5: 15 27
+2d, degree=5: 2 28
+3d, degree=1: 0 0
+3d, degree=1: 1 1
+3d, degree=1: 4 5
+3d, degree=1: 5 4
+3d, degree=1: 3 2
+3d, degree=1: 2 3
+3d, degree=1: 7 7
+3d, degree=1: 6 6
+3d, degree=2: 0 0
+3d, degree=2: 8 2
+3d, degree=2: 1 20
+3d, degree=2: 16 18
+3d, degree=2: 22 6
+3d, degree=2: 17 8
+3d, degree=2: 4 26
+3d, degree=2: 12 24
+3d, degree=2: 5 1
+3d, degree=2: 11 11
+3d, degree=2: 20 19
+3d, degree=2: 9 9
+3d, degree=2: 25 7
+3d, degree=2: 26 17
+3d, degree=2: 23 25
+3d, degree=2: 15 15
+3d, degree=2: 21 3
+3d, degree=2: 13 5
+3d, degree=2: 3 23
+3d, degree=2: 10 21
+3d, degree=2: 2 10
+3d, degree=2: 19 16
+3d, degree=2: 24 4
+3d, degree=2: 18 14
+3d, degree=2: 7 22
+3d, degree=2: 14 12
+3d, degree=2: 6 13
+3d, degree=3: 0 0
+3d, degree=3: 8 3
+3d, degree=3: 9 51
+3d, degree=3: 1 48
+3d, degree=3: 24 12
+3d, degree=3: 40 15
+3d, degree=3: 41 63
+3d, degree=3: 26 60
+3d, degree=3: 25 1
+3d, degree=3: 42 2
+3d, degree=3: 43 19
+3d, degree=3: 27 35
+3d, degree=3: 4 49
+3d, degree=3: 16 50
+3d, degree=3: 17 16
+3d, degree=3: 5 32
+3d, degree=3: 14 13
+3d, degree=3: 32 14
+3d, degree=3: 33 31
+3d, degree=3: 10 47
+3d, degree=3: 52 61
+3d, degree=3: 56 62
+3d, degree=3: 57 28
+3d, degree=3: 44 44
+3d, degree=3: 53 4
+3d, degree=3: 58 8
+3d, degree=3: 59 7
+3d, degree=3: 45 11
+3d, degree=3: 22 55
+3d, degree=3: 36 59
+3d, degree=3: 37 52
+3d, degree=3: 18 56
+3d, degree=3: 15 17
+3d, degree=3: 34 18
+3d, degree=3: 35 33
+3d, degree=3: 11 34
+3d, degree=3: 54 29
+3d, degree=3: 60 30
+3d, degree=3: 61 45
+3d, degree=3: 46 46
+3d, degree=3: 55 5
+3d, degree=3: 62 6
+3d, degree=3: 63 9
+3d, degree=3: 47 10
+3d, degree=3: 23 23
+3d, degree=3: 38 27
+3d, degree=3: 39 39
+3d, degree=3: 19 43
+3d, degree=3: 3 53
+3d, degree=3: 12 54
+3d, degree=3: 13 57
+3d, degree=3: 2 58
+3d, degree=3: 30 20
+3d, degree=3: 48 24
+3d, degree=3: 49 36
+3d, degree=3: 28 40
+3d, degree=3: 31 21
+3d, degree=3: 50 22
+3d, degree=3: 51 25
+3d, degree=3: 29 26
+3d, degree=3: 7 37
+3d, degree=3: 20 38
+3d, degree=3: 21 41
+3d, degree=3: 6 42
+3d, degree=4: 0 0
+3d, degree=4: 8 4
+3d, degree=4: 9 104
+3d, degree=4: 10 100
+3d, degree=4: 1 20
+3d, degree=4: 32 24
+3d, degree=4: 62 124
+3d, degree=4: 63 120
+3d, degree=4: 64 1
+3d, degree=4: 35 2
+3d, degree=4: 33 3
+3d, degree=4: 65 29
+3d, degree=4: 66 54
+3d, degree=4: 67 79
+3d, degree=4: 36 101
+3d, degree=4: 34 102
+3d, degree=4: 68 103
+3d, degree=4: 69 25
+3d, degree=4: 70 50
+3d, degree=4: 37 75
+3d, degree=4: 4 21
+3d, degree=4: 20 22
+3d, degree=4: 21 23
+3d, degree=4: 22 49
+3d, degree=4: 5 74
+3d, degree=4: 17 99
+3d, degree=4: 44 121
+3d, degree=4: 45 122
+3d, degree=4: 46 123
+3d, degree=4: 11 45
+3d, degree=4: 89 70
+3d, degree=4: 98 95
+3d, degree=4: 99 5
+3d, degree=4: 100 10
+3d, degree=4: 71 15
+3d, degree=4: 90 9
+3d, degree=4: 101 14
+3d, degree=4: 102 19
+3d, degree=4: 103 109
+3d, degree=4: 72 114
+3d, degree=4: 91 119
+3d, degree=4: 104 105
+3d, degree=4: 105 110
+3d, degree=4: 106 115
+3d, degree=4: 73 26
+3d, degree=4: 29 27
+3d, degree=4: 53 28
+3d, degree=4: 54 51
+3d, degree=4: 55 52
+3d, degree=4: 23 53
+3d, degree=4: 18 76
+3d, degree=4: 47 77
+3d, degree=4: 48 78
+3d, degree=4: 49 46
+3d, degree=4: 12 47
+3d, degree=4: 92 48
+3d, degree=4: 107 71
+3d, degree=4: 108 72
+3d, degree=4: 109 73
+3d, degree=4: 74 96
+3d, degree=4: 93 97
+3d, degree=4: 110 98
+3d, degree=4: 111 6
+3d, degree=4: 112 7
+3d, degree=4: 75 8
+3d, degree=4: 94 11
+3d, degree=4: 113 12
+3d, degree=4: 114 13
+3d, degree=4: 115 16
+3d, degree=4: 76 17
+3d, degree=4: 30 18
+3d, degree=4: 56 34
+3d, degree=4: 57 39
+3d, degree=4: 58 44
+3d, degree=4: 24 59
+3d, degree=4: 19 64
+3d, degree=4: 50 69
+3d, degree=4: 51 84
+3d, degree=4: 52 89
+3d, degree=4: 13 94
+3d, degree=4: 95 106
+3d, degree=4: 116 107
+3d, degree=4: 117 108
+3d, degree=4: 118 111
+3d, degree=4: 77 112
+3d, degree=4: 96 113
+3d, degree=4: 119 116
+3d, degree=4: 120 117
+3d, degree=4: 121 118
+3d, degree=4: 78 30
+3d, degree=4: 97 35
+3d, degree=4: 122 40
+3d, degree=4: 123 55
+3d, degree=4: 124 60
+3d, degree=4: 79 65
+3d, degree=4: 31 80
+3d, degree=4: 59 85
+3d, degree=4: 60 90
+3d, degree=4: 61 31
+3d, degree=4: 25 32
+3d, degree=4: 3 33
+3d, degree=4: 14 36
+3d, degree=4: 15 37
+3d, degree=4: 16 38
+3d, degree=4: 2 41
+3d, degree=4: 41 42
+3d, degree=4: 80 43
+3d, degree=4: 81 56
+3d, degree=4: 82 57
+3d, degree=4: 38 58
+3d, degree=4: 42 61
+3d, degree=4: 83 62
+3d, degree=4: 84 63
+3d, degree=4: 85 66
+3d, degree=4: 39 67
+3d, degree=4: 43 68
+3d, degree=4: 86 81
+3d, degree=4: 87 82
+3d, degree=4: 88 83
+3d, degree=4: 40 86
+3d, degree=4: 7 87
+3d, degree=4: 26 88
+3d, degree=4: 27 91
+3d, degree=4: 28 92
+3d, degree=4: 6 93
+3d, degree=5: 0 0
+3d, degree=5: 8 5
+3d, degree=5: 9 185
+3d, degree=5: 10 180
+3d, degree=5: 11 30
+3d, degree=5: 1 35
+3d, degree=5: 40 215
+3d, degree=5: 88 210
+3d, degree=5: 89 1
+3d, degree=5: 90 2
+3d, degree=5: 91 3
+3d, degree=5: 44 4
+3d, degree=5: 41 41
+3d, degree=5: 92 77
+3d, degree=5: 93 113
+3d, degree=5: 94 149
+3d, degree=5: 95 181
+3d, degree=5: 45 182
+3d, degree=5: 42 183
+3d, degree=5: 96 184
+3d, degree=5: 97 36
+3d, degree=5: 98 72
+3d, degree=5: 99 108
+3d, degree=5: 46 144
+3d, degree=5: 43 31
+3d, degree=5: 100 32
+3d, degree=5: 101 33
+3d, degree=5: 102 34
+3d, degree=5: 103 71
+3d, degree=5: 47 107
+3d, degree=5: 4 143
+3d, degree=5: 24 179
+3d, degree=5: 25 211
+3d, degree=5: 26 212
+3d, degree=5: 27 213
+3d, degree=5: 5 214
+3d, degree=5: 20 66
+3d, degree=5: 56 102
+3d, degree=5: 57 138
+3d, degree=5: 58 174
+3d, degree=5: 59 6
+3d, degree=5: 12 12
+3d, degree=5: 136 18
+3d, degree=5: 152 24
+3d, degree=5: 153 11
+3d, degree=5: 154 17
+3d, degree=5: 155 23
+3d, degree=5: 104 29
+3d, degree=5: 137 191
+3d, degree=5: 156 197
+3d, degree=5: 157 203
+3d, degree=5: 158 209
+3d, degree=5: 159 186
+3d, degree=5: 105 192
+3d, degree=5: 138 198
+3d, degree=5: 160 204
+3d, degree=5: 161 37
+3d, degree=5: 162 38
+3d, degree=5: 163 39
+3d, degree=5: 106 40
+3d, degree=5: 139 73
+3d, degree=5: 164 74
+3d, degree=5: 165 75
+3d, degree=5: 166 76
+3d, degree=5: 167 109
+3d, degree=5: 107 110
+3d, degree=5: 36 111
+3d, degree=5: 72 112
+3d, degree=5: 73 145
+3d, degree=5: 74 146
+3d, degree=5: 75 147
+3d, degree=5: 28 148
+3d, degree=5: 21 67
+3d, degree=5: 60 68
+3d, degree=5: 61 69
+3d, degree=5: 62 70
+3d, degree=5: 63 103
+3d, degree=5: 13 104
+3d, degree=5: 140 105
+3d, degree=5: 168 106
+3d, degree=5: 169 139
+3d, degree=5: 170 140
+3d, degree=5: 171 141
+3d, degree=5: 108 142
+3d, degree=5: 141 175
+3d, degree=5: 172 176
+3d, degree=5: 173 177
+3d, degree=5: 174 178
+3d, degree=5: 175 7
+3d, degree=5: 109 8
+3d, degree=5: 142 9
+3d, degree=5: 176 10
+3d, degree=5: 177 13
+3d, degree=5: 178 14
+3d, degree=5: 179 15
+3d, degree=5: 110 16
+3d, degree=5: 143 19
+3d, degree=5: 180 20
+3d, degree=5: 181 21
+3d, degree=5: 182 22
+3d, degree=5: 183 25
+3d, degree=5: 111 26
+3d, degree=5: 37 27
+3d, degree=5: 76 28
+3d, degree=5: 77 47
+3d, degree=5: 78 53
+3d, degree=5: 79 59
+3d, degree=5: 29 65
+3d, degree=5: 22 83
+3d, degree=5: 64 89
+3d, degree=5: 65 95
+3d, degree=5: 66 101
+3d, degree=5: 67 119
+3d, degree=5: 14 125
+3d, degree=5: 144 131
+3d, degree=5: 184 137
+3d, degree=5: 185 155
+3d, degree=5: 186 161
+3d, degree=5: 187 167
+3d, degree=5: 112 173
+3d, degree=5: 145 187
+3d, degree=5: 188 188
+3d, degree=5: 189 189
+3d, degree=5: 190 190
+3d, degree=5: 191 193
+3d, degree=5: 113 194
+3d, degree=5: 146 195
+3d, degree=5: 192 196
+3d, degree=5: 193 199
+3d, degree=5: 194 200
+3d, degree=5: 195 201
+3d, degree=5: 114 202
+3d, degree=5: 147 205
+3d, degree=5: 196 206
+3d, degree=5: 197 207
+3d, degree=5: 198 208
+3d, degree=5: 199 42
+3d, degree=5: 115 48
+3d, degree=5: 38 54
+3d, degree=5: 80 60
+3d, degree=5: 81 78
+3d, degree=5: 82 84
+3d, degree=5: 83 90
+3d, degree=5: 30 96
+3d, degree=5: 23 114
+3d, degree=5: 68 120
+3d, degree=5: 69 126
+3d, degree=5: 70 132
+3d, degree=5: 71 150
+3d, degree=5: 15 156
+3d, degree=5: 148 162
+3d, degree=5: 200 168
+3d, degree=5: 201 43
+3d, degree=5: 202 44
+3d, degree=5: 203 45
+3d, degree=5: 116 46
+3d, degree=5: 149 49
+3d, degree=5: 204 50
+3d, degree=5: 205 51
+3d, degree=5: 206 52
+3d, degree=5: 207 55
+3d, degree=5: 117 56
+3d, degree=5: 150 57
+3d, degree=5: 208 58
+3d, degree=5: 209 61
+3d, degree=5: 210 62
+3d, degree=5: 211 63
+3d, degree=5: 118 64
+3d, degree=5: 151 79
+3d, degree=5: 212 80
+3d, degree=5: 213 81
+3d, degree=5: 214 82
+3d, degree=5: 215 85
+3d, degree=5: 119 86
+3d, degree=5: 39 87
+3d, degree=5: 84 88
+3d, degree=5: 85 91
+3d, degree=5: 86 92
+3d, degree=5: 87 93
+3d, degree=5: 31 94
+3d, degree=5: 3 97
+3d, degree=5: 16 98
+3d, degree=5: 17 99
+3d, degree=5: 18 100
+3d, degree=5: 19 115
+3d, degree=5: 2 116
+3d, degree=5: 52 117
+3d, degree=5: 120 118
+3d, degree=5: 121 121
+3d, degree=5: 122 122
+3d, degree=5: 123 123
+3d, degree=5: 48 124
+3d, degree=5: 53 127
+3d, degree=5: 124 128
+3d, degree=5: 125 129
+3d, degree=5: 126 130
+3d, degree=5: 127 133
+3d, degree=5: 49 134
+3d, degree=5: 54 135
+3d, degree=5: 128 136
+3d, degree=5: 129 151
+3d, degree=5: 130 152
+3d, degree=5: 131 153
+3d, degree=5: 50 154
+3d, degree=5: 55 157
+3d, degree=5: 132 158
+3d, degree=5: 133 159
+3d, degree=5: 134 160
+3d, degree=5: 135 163
+3d, degree=5: 51 164
+3d, degree=5: 7 165
+3d, degree=5: 32 166
+3d, degree=5: 33 169
+3d, degree=5: 34 170
+3d, degree=5: 35 171
+3d, degree=5: 6 172

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.