]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Use new interfaces to GeometryInfo and QProjector where necessary. Furthermore, let...
authorleicht <leicht@0785d39b-7218-0410-832d-ea1e28bc413d>
Fri, 9 Feb 2007 07:13:14 +0000 (07:13 +0000)
committerleicht <leicht@0785d39b-7218-0410-832d-ea1e28bc413d>
Fri, 9 Feb 2007 07:13:14 +0000 (07:13 +0000)
git-svn-id: https://svn.dealii.org/trunk@14448 0785d39b-7218-0410-832d-ea1e28bc413d

18 files changed:
deal.II/deal.II/include/dofs/dof_accessor.templates.h
deal.II/deal.II/include/fe/fe.h
deal.II/deal.II/include/fe/fe_base.h
deal.II/deal.II/include/fe/fe_poly.templates.h
deal.II/deal.II/source/dofs/dof_accessor.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_data.cc
deal.II/deal.II/source/fe/fe_nedelec.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/mapping_cartesian.cc
deal.II/deal.II/source/fe/mapping_q.cc
deal.II/deal.II/source/fe/mapping_q1.cc

index 612dd8e571930525963eb242f80b23d96098a5bc..4660850f7a8082c238c68d25ad3259af2b8a192e 100644 (file)
@@ -481,9 +481,22 @@ DoFObjectAccessor<2,DH>::get_dof_indices (std::vector<unsigned int> &dof_indices
   for (unsigned int vertex=0; vertex<4; ++vertex)
     for (unsigned int d=0; d<dofs_per_vertex; ++d)
       *next++ = this->vertex_dof_index(vertex,d,fe_index);
+                                  // now copy dof numbers from the line. for
+                                  // lines with the wrong orientation (which
+                                  // might occur in 3d), we have already made
+                                  // sure that we're ok by picking the correct
+                                  // vertices (this happens automatically in
+                                  // the vertex() function). however, if the
+                                  // line is in wrong orientation, we look at
+                                  // it in flipped orientation and we will have
+                                  // to adjust the shape function indices that
+                                  // we see to correspond to the correct
+                                  // (face-local) ordering.
   for (unsigned int line=0; line<4; ++line)
     for (unsigned int d=0; d<dofs_per_line; ++d)
-      *next++ = this->line(line)->dof_index(d,fe_index);
+      *next++ = this->line(line)->dof_index(this->dof_handler->get_fe()[fe_index].
+                                           adjust_line_dof_index_for_line_orientation(d,
+                                                                                      this->line_orientation(line)),fe_index);
   for (unsigned int d=0; d<dofs_per_quad; ++d)
     *next++ = this->dof_index(d,fe_index);
 }
@@ -585,29 +598,42 @@ DoFObjectAccessor<3,DH>::get_dof_indices (std::vector<unsigned int> &dof_indices
   for (unsigned int vertex=0; vertex<8; ++vertex)
     for (unsigned int d=0; d<dofs_per_vertex; ++d)
       *next++ = this->vertex_dof_index(vertex,d,fe_index);
+                                  // now copy dof numbers from the line. for
+                                  // lines with the wrong orientation, we have
+                                  // already made sure that we're ok by picking
+                                  // the correct vertices (this happens
+                                  // automatically in the vertex()
+                                  // function). however, if the line is in
+                                  // wrong orientation, we look at it in
+                                  // flipped orientation and we will have to
+                                  // adjust the shape function indices that we
+                                  // see to correspond to the correct
+                                  // (cell-local) ordering.
   for (unsigned int line=0; line<12; ++line)
     for (unsigned int d=0; d<dofs_per_line; ++d)
-      *next++ = this->line(line)->dof_index(d,fe_index);
-  
+      *next++ = this->line(line)->dof_index(this->dof_handler->get_fe()[fe_index].
+                                           adjust_line_dof_index_for_line_orientation(d,
+                                                                                      this->line_orientation(line)),fe_index);
                                   // now copy dof numbers from the face. for
                                   // faces with the wrong orientation, we
                                   // have already made sure that we're ok by
                                   // picking the correct lines and vertices
                                   // (this happens automatically in the
-                                  // line() and vertex() functions. however,
+                                  // line() and vertex() functions). however,
                                   // if the face is in wrong orientation, we
                                   // look at it in flipped orientation and we
                                   // will have to adjust the shape function
                                   // indices that we see to correspond to the
-                                  // correct (cell-local) ordering.
+                                  // correct (cell-local) ordering. The same
+                                  // applies, if the face_rotation or
+                                  // face_orientation is non-standard
   for (unsigned int quad=0; quad<6; ++quad)
-    if (this->face_orientation(quad))
-      for (unsigned int d=0; d<dofs_per_quad; ++d)
-       *next++ = this->quad(quad)->dof_index(d,fe_index);
-    else
-      for (unsigned int d=0; d<dofs_per_quad; ++d)
-       *next++ = this->quad(quad)->dof_index(this->dof_handler->get_fe()[fe_index].
-                                             adjust_quad_dof_index_for_face_orientation(d),fe_index);
+    for (unsigned int d=0; d<dofs_per_quad; ++d)
+      *next++ = this->quad(quad)->dof_index(this->dof_handler->get_fe()[fe_index].
+                                             adjust_quad_dof_index_for_face_orientation(d,
+                                                                                        this->face_orientation(quad),
+                                                                                        this->face_flip(quad),
+                                                                                        this->face_rotation(quad)),fe_index);
   for (unsigned int d=0; d<dofs_per_hex; ++d)
     *next++ = this->dof_index(d,fe_index);
 }
index e3cf286baac8764a683df4e3a37fe596974431da..2c61f473a195e84f2063456e30fa937742049814 100644 (file)
@@ -1201,14 +1201,33 @@ class FiniteElement : public Subscriptor,
                                      * faces (quads) have to be permuted in
                                      * order to be combined with the correct
                                      * shape functions. Given a local dof @p
-                                     * index on a quad, return the local
-                                     * index, if the face has non-standard
-                                     * face_orientation. In 2D and 1D there
-                                     * is no need for permutation and
-                                     * consequently, and exception is thrown.
-                                     */
-    unsigned int adjust_quad_dof_index_for_face_orientation (const unsigned int index) const;
-
+                                     * index on a quad, return the local index,
+                                     * if the face has non-standard
+                                     * face_orientation, face_flip or
+                                     * face_rotation. In 2D and 1D there is no
+                                     * need for permutation and consequently
+                                     * an exception is thrown.
+                                     */
+    unsigned int adjust_quad_dof_index_for_face_orientation (const unsigned int index,
+                                                            const bool face_orientation,
+                                                            const bool face_flip,
+                                                            const bool face_rotation) const;
+
+                                    /**
+                                     * For lines with non-standard
+                                     * line_orientation in 3D, the dofs on
+                                     * lines have to be permuted in order to be
+                                     * combined with the correct shape
+                                     * functions. Given a local dof @p index on
+                                     * a line, return the local index, if the
+                                     * line has non-standard
+                                     * line_orientation. In 2D and 1D there is
+                                     * no need for permutation, so the given
+                                     * index is simply returned.
+                                     */
+    unsigned int adjust_line_dof_index_for_line_orientation (const unsigned int index,
+                                                            const bool line_orientation) const;
+    
                                     /**
                                      * Return in which of the vector
                                      * components of this finite
@@ -2079,8 +2098,35 @@ class FiniteElement : public Subscriptor,
                                      * i.e. <code>old_index + shift =
                                      * new_index</code>. In 2D and 1D there is
                                      * no need for permutation so the vector is
+                                     * empty. In 3D it has the size of <code>
+                                     * dofs_per_quad * 8 </code>, where 8 is
+                                     * the number of orientations, a face can
+                                     * be in (all comibinations of the three
+                                     * bool flags face_orientation, face_flip
+                                     * and face_rotation).
+                                     *
+                                     * The standard implementation fills this
+                                     * with zeros, i.e. no permuatation at
+                                     * all. Derived finite element classes have
+                                     * to fill this Table with the correct
+                                     * values.
+                                     */
+    Table<2,int> adjust_quad_dof_index_for_face_orientation_table;
+
+                                    /**
+                                     * For lines with non-standard
+                                     * line_orientation in 3D, the dofs on
+                                     * lines have to be permuted in
+                                     * order to be combined with the correct
+                                     * shape functions. Given a local dof @p
+                                     * index on a line, return the shift in the
+                                     * local index, if the line has
+                                     * non-standard line_orientation,
+                                     * i.e. <code>old_index + shift =
+                                     * new_index</code>. In 2D and 1D there is
+                                     * no need for permutation so the vector is
                                      * empty. In 3D it has the size of @p
-                                     * dofs_per_quad.
+                                     * dofs_per_line.
                                      *
                                      * The standard implementation fills this
                                      * with zeros, i.e. no permuatation at
@@ -2088,7 +2134,7 @@ class FiniteElement : public Subscriptor,
                                      * to fill this vector with the correct
                                      * values.
                                      */
-    std::vector<int> adjust_quad_dof_index_for_face_orientation_table;
+    std::vector<int> adjust_line_dof_index_for_line_orientation_table;
 
   private:
                                     /**
index 6eebc85d31044a816c41cf05bcf4264b23a8dac0..de5c14aae97c508e8b56ac39d09914bf6270ee4d 100644 (file)
@@ -557,7 +557,9 @@ class FiniteElementData
                                      */
     unsigned int face_to_cell_index (const unsigned int face_index,
                                     const unsigned int face,
-                                    const bool orientation = true) const;
+                                    const bool face_orientation = true,
+                                    const bool face_flip        = false,
+                                    const bool face_rotation    = false) const;
     
                                     /**
                                      * @deprecated This function is
index 450e1715a13bed67c4bd34800b8ad53da3e61eef..1f9c0d586acc86a326f554679b4b3d48c38ad852 100644 (file)
@@ -294,7 +294,10 @@ FE_Poly<POLY,dim>::fill_fe_face_values (const Mapping<dim>                   &ma
   
   const typename QProjector<dim>::DataSetDescriptor dsd;
   const typename QProjector<dim>::DataSetDescriptor offset
-    = dsd.face (face, cell->face_orientation(face),
+    = dsd.face (face,
+               cell->face_orientation(face),
+               cell->face_flip(face),
+               cell->face_rotation(face),
                quadrature.n_quadrature_points);
   
   const UpdateFlags flags(fe_data.update_once | fe_data.update_each);
@@ -345,8 +348,11 @@ FE_Poly<POLY,dim>::fill_fe_subface_values (const Mapping<dim>
 
   const typename QProjector<dim>::DataSetDescriptor dsd;
   const typename QProjector<dim>::DataSetDescriptor offset
-    = dsd.subface (face, subface, cell->face_orientation(face),
-                   quadrature.n_quadrature_points);
+    = dsd.subface (face, subface,
+                  cell->face_orientation(face),
+                  cell->face_flip(face),
+                  cell->face_rotation(face),
+                  quadrature.n_quadrature_points);
 
   const UpdateFlags flags(fe_data.update_once | fe_data.update_each);
 
index 78ad32b9693c9426c5d94e2083654feb6da9493e..de75f523cac18ba0ffd42e6d18ec1d6feb860ff5 100644 (file)
@@ -249,29 +249,42 @@ DoFCellAccessor<DoFHandler<3> >::update_cell_dof_indices_cache () const
   for (unsigned int vertex=0; vertex<8; ++vertex)
     for (unsigned int d=0; d<dofs_per_vertex; ++d)
       *next++ = vertex_dof_index(vertex,d);
+                                  // now copy dof numbers from the line. for
+                                  // lines with the wrong orientation, we have
+                                  // already made sure that we're ok by picking
+                                  // the correct vertices (this happens
+                                  // automatically in the vertex()
+                                  // function). however, if the line is in
+                                  // wrong orientation, we look at it in
+                                  // flipped orientation and we will have to
+                                  // adjust the shape function indices that we
+                                  // see to correspond to the correct
+                                  // (cell-local) ordering.
   for (unsigned int line=0; line<12; ++line)
     for (unsigned int d=0; d<dofs_per_line; ++d)
-      *next++ = this->line(line)->dof_index(d);
-
+      *next++ = this->line(line)->dof_index(this->dof_handler->get_fe().
+                                           adjust_line_dof_index_for_line_orientation(d,
+                                                                                      this->line_orientation(line)));
                                   // now copy dof numbers from the face. for
                                   // faces with the wrong orientation, we
                                   // have already made sure that we're ok by
                                   // picking the correct lines and vertices
                                   // (this happens automatically in the
-                                  // line() and vertex() functions. however,
+                                  // line() and vertex() functions). however,
                                   // if the face is in wrong orientation, we
                                   // look at it in flipped orientation and we
                                   // will have to adjust the shape function
                                   // indices that we see to correspond to the
-                                  // correct (cell-local) ordering.
+                                  // correct (cell-local) ordering. The same
+                                  // applies, if the face_rotation or
+                                  // face_orientation is non-standard
   for (unsigned int quad=0; quad<6; ++quad)
-    if (this->face_orientation(quad))
-      for (unsigned int d=0; d<dofs_per_quad; ++d)
-       *next++ = this->quad(quad)->dof_index(d);
-    else
-      for (unsigned int d=0; d<dofs_per_quad; ++d)
-       *next++ = this->quad(quad)->dof_index(this->dof_handler->get_fe().
-                                             adjust_quad_dof_index_for_face_orientation(d));
+    for (unsigned int d=0; d<dofs_per_quad; ++d)
+      *next++ = this->quad(quad)->dof_index(this->dof_handler->get_fe().
+                                           adjust_quad_dof_index_for_face_orientation(d,
+                                                                                      this->face_orientation(quad),
+                                                                                      this->face_flip(quad),
+                                                                                      this->face_rotation(quad)));
   for (unsigned int d=0; d<dofs_per_hex; ++d)
     *next++ = dof_index(d);
 }
index 0f02e477a7b89cc4fa6573b4c3fa096d4d346612..a1b0d8e4f3e55e13f6a008953e31b5805be47e2d 100644 (file)
@@ -115,8 +115,10 @@ FiniteElement<dim>::FiniteElement (
                FiniteElementData<dim> (fe_data),
                cached_primitivity(false),
                adjust_quad_dof_index_for_face_orientation_table (dim == 3 ?
-                                                                 this->dofs_per_quad : 0,
-                                                                 0),
+                                                                 this->dofs_per_quad : 0 ,
+                                                                 dim==3 ? 8 : 0),
+               adjust_line_dof_index_for_line_orientation_table (dim == 3 ?
+                                                                 this->dofs_per_line : 0),
                 system_to_base_table(this->dofs_per_cell),
                 face_system_to_base_table(this->dofs_per_face),                
                 component_to_base_table (this->components,
@@ -206,6 +208,7 @@ FiniteElement<dim>::FiniteElement (
                                   // changed by constructor of
                                   // derived class.
   first_block_of_base_table.resize(1,0);
+  adjust_quad_dof_index_for_face_orientation_table.fill(0);
 }
 
 
@@ -338,21 +341,27 @@ FiniteElement<dim>::component_to_block_index (const unsigned int index) const
 
 template <int dim>
 unsigned int
-FiniteElement<dim>::adjust_quad_dof_index_for_face_orientation (const unsigned int) const
+FiniteElement<dim>::adjust_quad_dof_index_for_face_orientation (const unsigned int index,
+                                                               const bool,
+                                                               const bool,
+                                                               const bool) const
 {
                                   // general template for 1D and 2D: not
                                   // implemented. in fact, the function
                                   // shouldn't even be called unless we are
                                   // in 3d, so throw an internal error
   Assert (false, ExcInternalError());
-  return deal_II_numbers::invalid_unsigned_int;
+  return index;
 }
 
 #if deal_II_dimension == 3
 
 template <>
 unsigned int
-FiniteElement<3>::adjust_quad_dof_index_for_face_orientation (const unsigned int index) const
+FiniteElement<3>::adjust_quad_dof_index_for_face_orientation (const unsigned int index,
+                                                             const bool face_orientation,
+                                                             const bool face_flip,
+                                                             const bool face_rotation) const
 {
                                   // adjust dofs on 3d faces if the face is
                                   // flipped. note that we query a table that
@@ -364,9 +373,41 @@ FiniteElement<3>::adjust_quad_dof_index_for_face_orientation (const unsigned int
                                   // the function should also not have been
                                   // called
   Assert (index<this->dofs_per_quad, ExcIndexRange(index,0,this->dofs_per_quad));
-  Assert (adjust_quad_dof_index_for_face_orientation_table.size()==this->dofs_per_quad,
+  Assert (adjust_quad_dof_index_for_face_orientation_table.n_elements()==8*this->dofs_per_quad,
          ExcInternalError());
-  return index+adjust_quad_dof_index_for_face_orientation_table[index];
+  return index+adjust_quad_dof_index_for_face_orientation_table(index,4*face_orientation+2*face_flip+face_rotation);
+}
+
+#endif
+
+
+
+template <int dim>
+unsigned int
+FiniteElement<dim>::adjust_line_dof_index_for_line_orientation (const unsigned int index,
+                                                               const bool) const
+{
+                                  // general template for 1D and 2D: do
+                                  // nothing. Do not throw an Assertion,
+                                  // however, in order to allow to call this
+                                  // function in 2D as well
+  return index;
+}
+
+#if deal_II_dimension == 3
+
+template <>
+unsigned int
+FiniteElement<3>::adjust_line_dof_index_for_line_orientation (const unsigned int index,
+                                                             const bool line_orientation) const
+{
+  Assert (index<this->dofs_per_line, ExcIndexRange(index,0,this->dofs_per_line));
+  Assert (adjust_line_dof_index_for_line_orientation_table.size()==this->dofs_per_line,
+         ExcInternalError());
+  if (line_orientation)
+    return index;
+  else
+    return index+adjust_line_dof_index_for_line_orientation_table[index];
 }
 
 #endif
index 34c68f8b0cee48acd6e7fe3dd7c7922fce84490f..ce9c2b20c9d6bc64f44795d4b61ea0f1c52757d3 100644 (file)
@@ -32,8 +32,9 @@
 
 #include <iostream>
 
-//TODO: implement the adjust_quad_dof_index_for_face_orientation_table field,
-//and write a test similar to bits/face_orientation_and_fe_q_01
+//TODO: implement the adjust_quad_dof_index_for_face_orientation_table and
+//adjust_line_dof_index_for_line_orientation_table fields, and write tests
+//similar to bits/face_orientation_and_fe_q_*
 
 
 DEAL_II_NAMESPACE_OPEN
@@ -686,8 +687,8 @@ FE_ABF<dim>::interpolate(
       double n_orient = (double) GeometryInfo<dim>::unit_normal_orientation[face];
       for (unsigned int fp=0; fp < n_face_points; ++fp)
        {
-         // TODO: Check what the face_orientation has to be in 3D
-         unsigned int k = QProjector<dim>::DataSetDescriptor::face (face, false, n_face_points);
+         // TODO: Check what the face_orientation, face_flip and face_rotation  have to be in 3D
+         unsigned int k = QProjector<dim>::DataSetDescriptor::face (face, false, false, false, n_face_points);
          for (unsigned int i=0; i<boundary_weights_abf.size(1); ++i)
            local_dofs[start_abf_dofs+i] += n_orient * boundary_weights_abf(k + fp, i) 
              * values[k + fp](GeometryInfo<dim>::unit_normal_direction[face]+offset);
@@ -746,8 +747,8 @@ FE_ABF<dim>::interpolate(
       double n_orient = (double) GeometryInfo<dim>::unit_normal_orientation[face];
       for (unsigned int fp=0; fp < n_face_points; ++fp)
        {
-         // TODO: Check what the face_orientation has to be in 3D
-         unsigned int k = QProjector<dim>::DataSetDescriptor::face (face, false, n_face_points);
+         // TODO: Check what the face_orientation, face_flip and face_rotation have to be in 3D
+         unsigned int k = QProjector<dim>::DataSetDescriptor::face (face, false, false, false, n_face_points);
          for (unsigned int i=0; i<boundary_weights_abf.size(1); ++i)
            local_dofs[start_abf_dofs+i] += n_orient * boundary_weights_abf(k + fp, i) 
              * values[GeometryInfo<dim>::unit_normal_direction[face]][k + fp];
index 7f6c9e04daeb771908cbe292d6c83300d53c04df..2457fdaaa1aefadbf8782fa522652661e6358035 100644 (file)
@@ -103,7 +103,9 @@ unsigned int
 FiniteElementData<dim>::
 face_to_cell_index (const unsigned int face_index,
                    const unsigned int face,
-                   const bool orientation) const
+                   const bool face_orientation,
+                   const bool face_flip,
+                   const bool face_rotation) const
 {
   Assert (face_index < this->dofs_per_face,
          ExcIndexRange(face_index, 0, this->dofs_per_face));
@@ -116,7 +118,10 @@ face_to_cell_index (const unsigned int face_index,
                                       // Vertex number on the face
       const unsigned int face_vertex = face_index / this->dofs_per_vertex;
       return face_index % this->dofs_per_vertex
-       + GeometryInfo<dim>::face_to_cell_vertices(face, face_vertex, orientation)
+       + GeometryInfo<dim>::face_to_cell_vertices(face, face_vertex,
+                                                  face_orientation,
+                                                  face_flip,
+                                                  face_rotation)
        * this->dofs_per_vertex;
     }
                                   // Else, DoF on a line?
@@ -127,7 +132,10 @@ face_to_cell_index (const unsigned int face_index,
                                       // Line number on the face
       const unsigned int face_line = index / this->dofs_per_line;
       return this->first_line_index + index % this->dofs_per_line
-       + GeometryInfo<dim>::face_to_cell_lines(face, face_line, orientation)
+       + GeometryInfo<dim>::face_to_cell_lines(face, face_line,
+                                               face_orientation,
+                                               face_flip,
+                                               face_rotation)
        * this->dofs_per_line;
     }
                                   // Else, DoF is on a quad
index b2d0aa8cfa3a6a1099e81fb8ffa92def905bd897..ee6842a65e26dba48d931e52afb9bc57be15a2f1 100644 (file)
@@ -24,6 +24,8 @@
 
 #include <sstream>
 
+//TODO: implement the adjust_line_dof_index_for_line_orientation_table field,
+//and write a test similar to bits/face_orientation_and_fe_q_02
 
 DEAL_II_NAMESPACE_OPEN
 
@@ -1130,7 +1132,10 @@ FE_Nedelec<dim>::fill_fe_face_values (const Mapping<dim>                   &mapp
                                   // faces are stored contiguously)
   const typename QProjector<dim>::DataSetDescriptor offset
     = (QProjector<dim>::DataSetDescriptor::
-       face (face, cell->face_orientation(face),
+       face (face,
+            cell->face_orientation(face),
+            cell->face_flip(face),
+            cell->face_rotation(face),
              quadrature.n_quadrature_points));
 
                                   // get the flags indicating the
@@ -1157,7 +1162,7 @@ FE_Nedelec<dim>::fill_fe_face_values (const Mapping<dim>                   &mapp
                                        // ways
       Assert (fe_data.shape_values[0].size() ==
               GeometryInfo<dim>::faces_per_cell * n_q_points *
-              (dim == 3 ? 2 : 1),
+              (dim == 3 ? 8 : 1),
               ExcInternalError());
       
       std::vector<Tensor<1,dim> > shape_values (n_q_points);
@@ -1190,7 +1195,7 @@ FE_Nedelec<dim>::fill_fe_face_values (const Mapping<dim>                   &mapp
                                        // ways
       Assert (fe_data.shape_gradients[0].size() ==
               GeometryInfo<dim>::faces_per_cell * n_q_points *
-              (dim == 3 ? 2 : 1),
+              (dim == 3 ? 8 : 1),
               ExcInternalError());
 
       std::vector<Tensor<2,dim> > shape_grads1 (n_q_points);
@@ -1276,8 +1281,11 @@ FE_Nedelec<dim>::fill_fe_subface_values (const Mapping<dim>                   &m
                                   // faces are stored contiguously)
   const typename QProjector<dim>::DataSetDescriptor offset
     = (QProjector<dim>::DataSetDescriptor::
-       subface (face, subface, cell->face_orientation(face),
-                 quadrature.n_quadrature_points));
+       subface (face, subface,
+               cell->face_orientation(face),
+               cell->face_flip(face),
+               cell->face_rotation(face),
+               quadrature.n_quadrature_points));
 
                                   // get the flags indicating the
                                   // fields that have to be filled
index ba4fc66431be4e736f517792ff11bc0283d2a179..d0c82ab304e7eb9aeba80cdf88e3d19df667db86 100644 (file)
@@ -536,7 +536,10 @@ FE_PolyTensor<POLY,dim>::fill_fe_face_values (
   
   const typename QProjector<dim>::DataSetDescriptor dsd;
   const typename QProjector<dim>::DataSetDescriptor offset
-    = dsd.face (face, cell->face_orientation(face),
+    = dsd.face (face,
+               cell->face_orientation(face),
+               cell->face_flip(face),
+               cell->face_rotation(face),
                n_q_points);
   
   const UpdateFlags flags(fe_data.update_once | fe_data.update_each);
@@ -717,8 +720,11 @@ FE_PolyTensor<POLY,dim>::fill_fe_subface_values (
 
   const typename QProjector<dim>::DataSetDescriptor dsd;
   const typename QProjector<dim>::DataSetDescriptor offset
-    = dsd.subface (face, subface, cell->face_orientation(face),
-                   n_q_points);
+    = dsd.subface (face, subface,
+                  cell->face_orientation(face),
+                  cell->face_flip(face),
+                  cell->face_rotation(face),
+                  n_q_points);
 
   const UpdateFlags flags(fe_data.update_once | fe_data.update_each);
 
index 9b4908e85e6e0426cca8cd1886c625ada32dc0ac..7de581d3167ec5c1823d1b019fe64455564d5d24 100644 (file)
@@ -810,18 +810,66 @@ template <>
 void
 FE_Q<3>::initialize_quad_dof_index_permutation ()
 {
-  Assert (adjust_quad_dof_index_for_face_orientation_table.size()==this->dofs_per_quad,
+  Assert (adjust_quad_dof_index_for_face_orientation_table.n_elements()==8*this->dofs_per_quad,
          ExcInternalError());
 
-  const unsigned int points = this->degree-1;
-  Assert(points*points==this->dofs_per_quad, ExcInternalError());
-               
+  const unsigned int n=this->degree-1;
+  Assert(n*n==this->dofs_per_quad, ExcInternalError());
+
+                                  // alias for the table to fill
+  Table<2,int> &data=this->adjust_quad_dof_index_for_face_orientation_table;
+  
+                                  // the dofs on a face are connected to a n x
+                                  // n matrix. for example, for degree==4 we
+                                  // have the following dofs on a quad
+
+                                  //  ___________
+                                  // |           |
+                                  // |  6  7  8  |
+                                  // |           |
+                                  // |  3  4  5  |
+                                  // |           |
+                                  // |  0  1  2  |
+                                  // |___________|
+                                  //
+                                  // we have dof_no=i+n*j with index i in
+                                  // x-direction and index j in y-direction
+                                  // running from 0 to n-1.  to extract i and j
+                                  // we can use i=dof_no%n and j=dof_no/n. i
+                                  // and j can then be used to construct the
+                                  // rotated and mirrored numbers.
+
+
   for (unsigned int local=0; local<this->dofs_per_quad; ++local)
                                     // face support points are in lexicographic
                                     // ordering with x running fastest. invert
                                     // that (y running fastest)
-    this->adjust_quad_dof_index_for_face_orientation_table[local]
-      = (local%points)*points + local/points - local;
+    {
+      unsigned int i=local%n,
+                  j=local/n;
+      
+                                      // face_orientation=false, face_flip=false, face_rotation=false
+      data(local,0)=j       + i      *n - local;
+                                      // face_orientation=false, face_flip=false, face_rotation=true
+      data(local,1)=(n-1-i) + j      *n - local;
+                                      // face_orientation=false, face_flip=true,  face_rotation=false
+      data(local,2)=(n-1-j) + (n-1-i)*n - local;
+                                      // face_orientation=false, face_flip=true,  face_rotation=true
+      data(local,3)=i       + (n-1-j)*n - local;
+                                      // face_orientation=true,  face_flip=false, face_rotation=false
+      data(local,4)=0;
+                                      // face_orientation=true,  face_flip=false, face_rotation=true
+      data(local,5)=j       + (n-1-i)*n - local;
+                                      // face_orientation=true,  face_flip=true,  face_rotation=false
+      data(local,6)=(n-1-i) + (n-1-j)*n - local;
+                                      // face_orientation=true,  face_flip=true,  face_rotation=true
+      data(local,7)=(n-1-j) + i      *n - local;
+    }
+
+                                  // aditionally initialize reordering of line
+                                  // dofs
+  for (unsigned int i=0; i<this->dofs_per_line; ++i)
+    this->adjust_line_dof_index_for_line_orientation_table[i]=this->dofs_per_line-1-i - i;
 }
 
 #endif
index e2faf68cf1ac1dcca4cf61efceed87de35e3da7e..0ebed3355eba384c4fb96762ff4b0f73819422c5 100644 (file)
@@ -16,8 +16,9 @@
 #include <cmath>
 #include <sstream>
 
-//TODO: implement the adjust_quad_dof_index_for_face_orientation_table field,
-//and write a test similar to bits/face_orientation_and_fe_q_01
+//TODO: implement the adjust_quad_dof_index_for_face_orientation_table and
+//adjust_line_dof_index_for_line_orientation_table fields, and write tests
+//similar to bits/face_orientation_and_fe_q_*
 
 
 DEAL_II_NAMESPACE_OPEN
index 859d86879ef8619400beae20b467cc058e9eb71e..7b89c2ac5d9598b80cf2b703405f6f1a9b77be17 100644 (file)
@@ -27,8 +27,9 @@
 #include <sstream>
 #include <iostream>
 
-//TODO: implement the adjust_quad_dof_index_for_face_orientation_table field,
-//and write a test similar to bits/face_orientation_and_fe_q_01
+//TODO: implement the adjust_quad_dof_index_for_face_orientation_table and
+//adjust_line_dof_index_for_line_orientation_table fields, and write tests
+//similar to bits/face_orientation_and_fe_q_*
 
 
 DEAL_II_NAMESPACE_OPEN
@@ -213,7 +214,7 @@ FE_RaviartThomas<dim>::initialize_support_points (const unsigned int deg)
        {
                                           // Enter the support point
                                           // into the vector
-         this->generalized_support_points[current] = faces.point(current);
+         this->generalized_support_points[current] = faces.point(current+QProjector<dim>::DataSetDescriptor::face(0,true,false,false,n_face_points));
        }
     }
   
index 957902c8f3409c9be60c15fd0d18e245a7941782..084ae9b768c58bd0b3dc6aaeeaf6cbf3b7f52964 100644 (file)
@@ -25,8 +25,9 @@
 
 #include <sstream>
 
-//TODO: implement the adjust_quad_dof_index_for_face_orientation_table field,
-//and write a test similar to bits/face_orientation_and_fe_q_01
+//TODO: implement the adjust_quad_dof_index_for_face_orientation_table and
+//adjust_line_dof_index_for_line_orientation_table fields, and write tests
+//similar to bits/face_orientation_and_fe_q_*
 
 
 DEAL_II_NAMESPACE_OPEN
@@ -328,7 +329,12 @@ FE_RaviartThomasNodal<dim>::initialize_support_points (const unsigned int deg)
       for (unsigned int k=0;
           k<this->dofs_per_face*GeometryInfo<dim>::faces_per_cell;
           ++k)
-       this->generalized_support_points[k] = faces.point(k);
+       this->generalized_support_points[k] = faces.point(k+QProjector<dim>
+                                                                                                                                         ::DataSetDescriptor::face(0,
+                                                                                                                                                                                                                true,
+                                                                                                                                                                                                                false,
+                                                                                                                                                                                                                false,
+                                                                                                                                                                                                                this->dofs_per_face));
 
       current = this->dofs_per_face*GeometryInfo<dim>::faces_per_cell;
     }
index ef70cb174b8e4c7de3369dd724ef56b0c5322111..2e688344402600c35bea20c802a70e745c5dfbfb 100644 (file)
@@ -1866,24 +1866,44 @@ FESystem<3>::initialize_quad_dof_index_permutation ()
 {
                                   // the array into which we want to write
                                   // should have the correct size already.
-  Assert (adjust_quad_dof_index_for_face_orientation_table.size()==this->dofs_per_quad,
+  Assert (adjust_quad_dof_index_for_face_orientation_table.n_elements()==8*this->dofs_per_quad,
          ExcInternalError());
                                   // to obtain the shifts for this composed
-                                  // element, concatenate the shift vectors of
+                                  // element, copy the shift information of
                                   // the base elements
   unsigned int index = 0;
   for (unsigned int b=0; b<n_base_elements();++b)
     {
-      const std::vector<int> &temp
+      const Table<2,int> &temp
        = this->base_element(b).adjust_quad_dof_index_for_face_orientation_table;
       for (unsigned int c=0; c<element_multiplicity(b); ++c)
        {
-         std::copy (temp.begin(), temp.end(),
-                    adjust_quad_dof_index_for_face_orientation_table.begin() + index);
-         index += temp.size();
+         for (unsigned int i=0; i<temp.size(0); ++i)
+           for (unsigned int j=0; j<8; ++j)
+             adjust_quad_dof_index_for_face_orientation_table(index+i,j)=temp(i,j);
+         index += temp.size(0);
        }
     }
   Assert (index == this->dofs_per_quad,
+         ExcInternalError());
+
+                                  // aditionally compose the permutation
+                                  // information for lines
+  Assert (adjust_line_dof_index_for_line_orientation_table.size()==this->dofs_per_line,
+         ExcInternalError());
+  index = 0;
+  for (unsigned int b=0; b<n_base_elements();++b)
+    {
+      const std::vector<int> &temp2
+       = this->base_element(b).adjust_line_dof_index_for_line_orientation_table;
+      for (unsigned int c=0; c<element_multiplicity(b); ++c)
+       {
+         std::copy(temp2.begin(), temp2.end(),
+                   adjust_line_dof_index_for_line_orientation_table.begin()+index);
+         index += temp2.size();
+       }
+    }
+  Assert (index == this->dofs_per_line,
          ExcInternalError());
 }
 
index 0e8094359b80d56106062416280ccd8f38d83692..5a114c3bc571ecc81b32f5052b1cb8e3665399d7 100644 (file)
@@ -205,11 +205,15 @@ MappingCartesian<dim>::compute_fill (const typename Triangulation<dim>::cell_ite
                                             // called from FEFaceValues
            QProjector<dim>::DataSetDescriptor::face (face_no,
                                                      cell->face_orientation(face_no),
+                                                     cell->face_flip(face_no),
+                                                     cell->face_rotation(face_no),
                                                      quadrature_points.size())
            :
                                             // 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())
           ));
 
index 42af4fedd7f464917d04e1e2acad49e9d8493459..3b0f604b6ddac912721eb9962b547516f0e75c13 100644 (file)
@@ -383,7 +383,10 @@ MappingQ<dim>::fill_fe_face_values (const typename Triangulation<dim>::cell_iter
   this->compute_fill_face (cell, face_no, false,
                            n_q_points,
                            QProjector<dim>::DataSetDescriptor::
-                           face (face_no, cell->face_orientation(face_no),
+                           face (face_no,
+                                cell->face_orientation(face_no),
+                                cell->face_flip(face_no),
+                                cell->face_rotation(face_no),
                                  n_q_points),
                            q.get_weights(),
                            *p_data,
@@ -446,6 +449,8 @@ MappingQ<dim>::fill_fe_subface_values (const typename Triangulation<dim>::cell_i
                            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),
                            q.get_weights(),
                            *p_data,
@@ -1023,12 +1028,17 @@ add_quad_support_points(const Triangulation<3>::cell_iterator &cell,
 
                                        // select the correct mappings
                                        // for the present face
-      const bool face_orientation = cell->face_orientation(face_no);
+      const bool face_orientation = cell->face_orientation(face_no),
+                face_flip        = cell->face_flip       (face_no),
+                face_rotation    = cell->face_rotation   (face_no);
 
                                        // some sanity checks up front
       for (unsigned int i=0; i<vertices_per_face; ++i)
         Assert(face->vertex_index(i)==cell->vertex_index(
-         GeometryInfo<3>::face_to_cell_vertices(face_no, i, face_orientation)),
+         GeometryInfo<3>::face_to_cell_vertices(face_no, i,
+                                                face_orientation,
+                                                face_flip,
+                                                face_rotation)),
          ExcInternalError());
 
                                       // indices of the lines that
@@ -1037,7 +1047,8 @@ add_quad_support_points(const Triangulation<3>::cell_iterator &cell,
                                       // face_to_cell_lines
       for (unsigned int i=0; i<lines_per_face; ++i)
         Assert(face->line(i)==cell->line(GeometryInfo<3>::face_to_cell_lines(
-         face_no, i, face_orientation)), ExcInternalError());
+         face_no, i, face_orientation, face_flip, face_rotation)),
+              ExcInternalError());
       
                                       // if face at boundary, then
                                       // ask boundary object to
@@ -1088,13 +1099,16 @@ add_quad_support_points(const Triangulation<3>::cell_iterator &cell,
              
                                               // sort the points into b
               for (unsigned int i=0; i<vertices_per_face; ++i)
-                b[i]=a[GeometryInfo<3>::face_to_cell_vertices(face_no, i, face_orientation)];
+                b[i]=a[GeometryInfo<3>::face_to_cell_vertices(face_no, i,
+                                                             face_orientation,
+                                                             face_flip,
+                                                             face_rotation)];
                      
               for (unsigned int i=0; i<lines_per_face; ++i)
                 for (unsigned int j=0; j<degree-1; ++j)
                   b[vertices_per_face+i*(degree-1)+j]=
                     a[vertices_per_cell + GeometryInfo<3>::face_to_cell_lines(
-                     face_no, i, face_orientation)*(degree-1)+j];
+                     face_no, i, face_orientation, face_flip, face_rotation)*(degree-1)+j];
 
                                               // Now b includes the
                                               // right order of
index e715a28f3a9de02d6166622495a879919822057d..991f94258a6e7cc344b60f27b9a98934af2d2924 100644 (file)
@@ -724,6 +724,8 @@ MappingQ1<dim>::fill_fe_face_values (const typename Triangulation<dim>::cell_ite
                     n_q_points,
                     DataSetDescriptor::face (face_no,
                                               cell->face_orientation(face_no),
+                                              cell->face_flip(face_no),
+                                              cell->face_rotation(face_no),
                                               n_q_points),
                     q.get_weights(),
                     data,
@@ -757,8 +759,10 @@ MappingQ1<dim>::fill_fe_subface_values (const typename Triangulation<dim>::cell_
   compute_fill_face (cell, face_no, true,
                     n_q_points,
                     DataSetDescriptor::subface (face_no, sub_no,
-                                                  cell->face_orientation(face_no),
-                                                  n_q_points),
+                                                cell->face_orientation(face_no),
+                                                cell->face_flip(face_no),
+                                                cell->face_rotation(face_no),
+                                                n_q_points),
                     q.get_weights(),
                     data,
                     quadrature_points,

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.