* the exact order of the
* children is laid down in the
* documentation of the
- * Triangulation class.
- * However, it must be noted that
- * this class and function only
- * deals with faces in standard
- * orientation. In 3d, faces can
- * exist in two orientations,
- * though, and if a face is in
- * the wrong orientation, then
- * this function may not give you
- * what you want. You can inquire
- * about the face orientation
- * using the
- * <tt>cell->face_orientation</tt>
- * function, and the function to
- * ask for a neighbor's cell
- * behind a given face and
- * subface is
- * <tt>cell->neighbor_child_on_subface</tt>.
- * The latter function, in
- * contrast to the present one,
- * also takes into account the
- * actual orientation of the
- * faces of a cell and will
- * return the correct result in
- * all cases.
+ * Triangulation class. Through
+ * the <tt>face_orientation</tt>
+ * argument this function handles
+ * faces oriented in both, the
+ * standard and non-standard
+ * orientation.
+ * <tt>face_orientation</tt>
+ * defaults to <tt>true</tt>
+ * (standard orientation) and has
+ * no effect in 2d.
*/
static unsigned int child_cell_on_face (const unsigned int face,
- const unsigned int subface);
+ const unsigned int subface,
+ const bool face_orientation = true);
/**
* Map line vertex number to cell
* face <tt>face</tt>, e.g.
* <tt>GeometryInfo<2>::face_to_cell_vertices(2,0)=3</tt>.
*
+ * Through the
+ * <tt>face_orientation</tt>
+ * argument this function handles
+ * faces oriented in both, the
+ * standard or non-standard
+ * orientation.
+ * <tt>face_orientation</tt>
+ * defaults to <tt>true</tt>
+ * (standard orientation) and has
+ * no effect in 2d.
+ *
* As the children of a cell are
* ordered according to the
* vertices of the cell, this
* a suggestive name.
*/
static unsigned int face_to_cell_vertices (const unsigned int face,
- const unsigned int vertex);
+ const unsigned int vertex,
+ const bool face_orientation = true);
/**
* Map face line number to cell
* <tt>face</tt>, e.g.
* <tt>GeometryInfo<3>::face_to_cell_lines(3,1)=5</tt>.
*
+ * Through the
+ * <tt>face_orientation</tt>
+ * argument this function handles
+ * faces oriented in both, the
+ * standard and non-standard
+ * orientation.
+ * <tt>face_orientation</tt>
+ * defaults to <tt>true</tt>
+ * (standard orientation).
+ *
* This function is useful and
* implemented for
* <tt>dim=3</tt>, only.
*/
static unsigned int face_to_cell_lines (const unsigned int face,
- const unsigned int line);
+ const unsigned int line,
+ const bool face_orientation = true);
/**
* Return the position of the
lines_per_face = GeometryInfo<3>::lines_per_face,
vertices_per_cell = GeometryInfo<3>::vertices_per_cell;
- // mapping of faces to vertex
- // indices for properly oriented
- // faces is given by
- // GeometryInfo<3>::face_to_cell_vertices
- //
- // same if the face is in opposite
- // orientation
- static const unsigned int face_to_cell_vertices2
- [faces_per_cell][vertices_per_face]={{0,3,2,1},
- {4,7,6,5},
- {0,4,5,1},
- {1,2,6,5},
- {3,7,6,2},
- {0,3,7,4}};
-
static const StraightBoundary<3> straight_boundary;
// used if face quad at boundary or
// entirely in the interior of the
// some sanity checks up front
for (unsigned int i=0; i<vertices_per_face; ++i)
- Assert(face->vertex_index(i)==
- cell->vertex_index(face_orientation ?
- GeometryInfo<3>::face_to_cell_vertices(face_no, i) :
- face_to_cell_vertices2[face_no][i]),
- ExcInternalError());
-
+ Assert(face->vertex_index(i)==cell->vertex_index(
+ GeometryInfo<3>::face_to_cell_vertices(face_no, i, face_orientation)),
+ ExcInternalError());
// indices of the lines that
- // bound a properly oriented
- // face are given by
- // GeometryInfo<3>::
- // face_to_cell_lines(face_no, line_no)
- //
- // same for faces in wrong
- // orientation is given by
+ // bound a face are given by
// GeometryInfo<3>::
- // face_to_cell_lines(face_no, 3-line_no)
+ // face_to_cell_lines
for (unsigned int i=0; i<lines_per_face; ++i)
- Assert(face->line(i)==
- cell->line(face_orientation ?
- GeometryInfo<3>::face_to_cell_lines(face_no, i) :
- GeometryInfo<3>::face_to_cell_lines(face_no, 3-i)),
- ExcInternalError());
+ Assert(face->line(i)==cell->line(GeometryInfo<3>::face_to_cell_lines(
+ face_no, i, face_orientation)), 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[face_orientation ?
- GeometryInfo<3>::face_to_cell_vertices(face_no, i) :
- face_to_cell_vertices2[face_no][i]];
+ b[i]=a[GeometryInfo<3>::face_to_cell_vertices(face_no, i, face_orientation)];
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+
- (face_orientation ?
- GeometryInfo<3>::face_to_cell_lines(face_no, i) :
- GeometryInfo<3>::face_to_cell_lines(face_no, 3-i))*(degree-1)+j];
+ a[vertices_per_cell + GeometryInfo<3>::face_to_cell_lines(
+ face_no, i, face_orientation)*(degree-1)+j];
// Now b includes the
// right order of
template <>
unsigned int
GeometryInfo<1>::child_cell_on_face (const unsigned int face,
- const unsigned int subface)
+ const unsigned int subface,
+ const bool)
{
Assert (face<faces_per_cell, ExcIndexRange(face, 0, faces_per_cell));
Assert (subface==subfaces_per_face, ExcIndexRange(subface, 0, 1));
template <>
unsigned int
GeometryInfo<2>::child_cell_on_face (const unsigned int face,
- const unsigned int subface)
+ const unsigned int subface,
+ const bool)
{
Assert (face<faces_per_cell, ExcIndexRange(face, 0, faces_per_cell));
Assert (subface<subfaces_per_face, ExcIndexRange(subface, 0, subfaces_per_face));
template <>
unsigned int
GeometryInfo<3>::child_cell_on_face (const unsigned int face,
- const unsigned int subface)
+ const unsigned int subface,
+ const bool face_orientation)
{
Assert (face<faces_per_cell, ExcIndexRange(face, 0, faces_per_cell));
Assert (subface<subfaces_per_face, ExcIndexRange(subface, 0, subfaces_per_face));
-
+ static const unsigned int
+ flip[GeometryInfo<3>::subfaces_per_face] = { 0, 3, 2, 1 };
static const unsigned
subcells[faces_per_cell][subfaces_per_face] = {{0, 1, 2, 3},
{4, 5, 6, 7},
{1, 5, 6, 2},
{3, 2, 6, 7},
{0, 4, 7, 3}};
- return subcells[face][subface];
+ return face_orientation ? subcells[face][subface] : subcells[face][flip[subface]];
}
template <>
unsigned int
GeometryInfo<3>::face_to_cell_lines (const unsigned int face,
- const unsigned int line)
+ const unsigned int line,
+ const bool face_orientation)
{
Assert (face<faces_per_cell, ExcIndexRange(face, 0, faces_per_cell));
Assert (line<lines_per_face, ExcIndexRange(line, 0, lines_per_face));
{2,10, 6,11},
{8, 7,11, 3}};
- return lines[face][line];
+ return face_orientation ? lines[face][line] : lines[face][3-line];
}
inline
unsigned int
GeometryInfo<dim>::face_to_cell_vertices (const unsigned int face,
- const unsigned int vertex)
+ const unsigned int vertex,
+ const bool face_orientation)
{
- return child_cell_on_face(face, vertex);
+ return child_cell_on_face(face, vertex, face_orientation);
}
new_hexes[GeometryInfo<dim>::child_cell_on_face(f,s)]
->set_face_orientation(f, hex->face_orientation(f));
+#ifdef DEBUG
+ // check consistency
+ // against
+ // GeometryInfo<3>::child_cell_on_face
+ for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+ for (unsigned int s=0; s<GeometryInfo<dim>::subfaces_per_face; ++s)
+ Assert(hex->face(f)->child(s)==hex->child(
+ GeometryInfo<dim>::child_cell_on_face(
+ f, s, hex->face_orientation(f)))->face(f), ExcInternalError());
+#endif
/////////////////////////////////
// now the only thing still
&&
hex->face_orientation(face));
- static const unsigned int
- child_switch_table[GeometryInfo<dim>::subfaces_per_face]
- = { 0, 3, 2, 1 };
-
for (unsigned int c=0;
c<GeometryInfo<dim>::subfaces_per_face; ++c)
{
neighbor_cells[face][c]
= neighbor->child(GeometryInfo<dim>::
- child_cell_on_face(nb_nb,
- orient ?
- c :
- child_switch_table[c]));
+ child_cell_on_face(nb_nb, c, orient));
Assert (neighbor_cells[face][c].state() ==
IteratorState::valid,
= (this->neighbor(face)->face_orientation(neighbor_neighbor) ==
this->face_orientation(face));
const unsigned int neighbor_child_index
- = (GeometryInfo<3>::
- child_cell_on_face(neighbor_neighbor,
- (face_orientations_match ?
- subface :
- subface_translation[subface])));
+ = GeometryInfo<3>::child_cell_on_face(neighbor_neighbor, subface,
+ face_orientations_match);
const TriaIterator<3,CellAccessor<3> > neighbor_child=
this->neighbor(face)->child(neighbor_child_index);