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);
}
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);
}
* 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
* 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
* 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:
/**
*/
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
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);
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);
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);
}
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,
// changed by constructor of
// derived class.
first_block_of_base_table.resize(1,0);
+ adjust_quad_dof_index_for_face_orientation_table.fill(0);
}
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
// 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
#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
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);
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];
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));
// 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?
// 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
#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
// 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
// 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);
// 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);
// 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
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);
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);
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
#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
#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
{
// 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));
}
}
#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
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;
}
{
// 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());
}
// 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())
));
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,
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,
// 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
// 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
// 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
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,
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,