/**
- * This class reorders the vertices of cells such that they meet the
- * requirements of the Triangulation class when creating
- * grids. This class is mainly used when reading in grids from files
- * and converting them to deal.II triangulations.
+ * This class reorders the vertices of cells such that they meet the standard
+ * requirements of the Triangulation class when creating grids, i.e. all lines
+ * have a unique orientation with respect to all neighboring cells. This class
+ * is mainly used when reading in grids from files and converting them to
+ * deal.II triangulations.
*
* Note: In contrast to the rest of the deal.II library this class
* uses the old deal.II numbering scheme, which was used up to deal.II
* clockwise, and axially upward. However, if before joining the two
* ends of the string of cells, the string is twisted by 180 degrees,
* then no such orientation is possible any more, as can easily be
- * checked. In effect, some meshes cannot be used in deal.II,
- * unfortunately.
+ * checked. In effect, some meshes could not be used in deal.II.
+ * In order to overcome this problem, the <code>face_rotation</code>,
+ * <code>face_flip</code> and <code>line_orientation</code> flags have
+ * been introduced. With these, it is possible to treat all purely hexahedral
+ * meshes. However, in order to reduce the effect of possible bugs, it should
+ * still be tried to reorder a grid. Only if this procedure fails, the original
+ * connectivity information should be used.
*
*
* <h3>Examples of problems</h3>
* the general documentation of
* this class for dim=2 and 3
* and doing nothing for dim=1.
+ *
+ * If a consistent reordering is not
+ * possible in dim=3, the original
+ * connectivity data is restored.
*/
static void reorder_cells (std::vector<CellData<dim> > &original_cells);
* the inverse of the orientation
* required by deal.II.
*
- * In 3d this function checks
+ * In 2d and 3d this function checks
* whether all cells have
* negative or positiv
* measure/volume. In the former
* case, all cells are inverted.
- * It does nothing in 1 and 2d.
+ * It does nothing in 1d.
*
* The invertion of cells might
* also work when only a subset
- void Orienter::orient_mesh (std::vector<CellData<3> > &incubes)
+ bool Orienter::orient_mesh (std::vector<CellData<3> > &incubes)
{
Orienter orienter (incubes);
orienter.mesh.sanity_check ();
// Orient the mesh
- orienter.orient_edges ();
+
+ // if not successful, break here, else go
+ // on
+ if (!orienter.orient_edges ())
+ return false;
// Now we have a bunch of oriented
// edges int the structure we only
// internal structure back into
// their original location.
orienter.mesh.export_to_deal_format (incubes);
+ // reordering was successful
+ return true;
}
/**
* cube is a rotated Deal.II
* cube.
*/
- void Orienter::orient_edges ()
+ bool Orienter::orient_edges ()
{
// While there are still cubes
// to orient
// Cube doesn't
// have a
// contradiction
- AssertThrow(cell_is_consistent(cur_posn),
- ExcGridOrientError("Mesh is Unorientable"));
-
+ if (!cell_is_consistent(cur_posn))
+ return false;
+
// If we needed to
// orient any edges
// in the current
// (equivalence class
// of edges)
++cur_edge_group;
- }
+ }
+ return true;
}
Assert (incubes.size() != 0,
ExcMessage("List of elements to orient was of zero length"));
+
+ // create a backup to use if GridReordering
+ // was not successful
+ std::vector<CellData<3> > backup=incubes;
// This does the real work
- internal::GridReordering3d::Orienter::orient_mesh (incubes);
+ bool success=
+ internal::GridReordering3d::Orienter::orient_mesh (incubes);
+
+ // if reordering was not successful use
+ // original connectivity, otherwiese do
+ // nothing (i.e. use the reordered
+ // connectivity)
+ if (!success)
+ incubes=backup;
}