From 8d03ad6a77b46bc1abe4f51f6804c0a5371f5003 Mon Sep 17 00:00:00 2001 From: bangerth Date: Tue, 15 Jul 2014 02:24:32 +0000 Subject: [PATCH] Address issue #228 (https://code.google.com/p/dealii/issues/detail?id=228): Teach GridReordering::reorder_cells() to use the vertex numbering that we have used every since deal.II 5.2. Remove the code for this from grid_generator.cc and instead call reorder_cells() from there with the flag set. git-svn-id: https://svn.dealii.org/trunk@33179 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/doc/news/changes.h | 11 ++ .../include/deal.II/grid/grid_reordering.h | 32 ++-- deal.II/source/grid/grid_generator.cc | 62 +------- deal.II/source/grid/grid_reordering.cc | 138 +++++++++++++++--- 4 files changed, 160 insertions(+), 83 deletions(-) diff --git a/deal.II/doc/news/changes.h b/deal.II/doc/news/changes.h index 41acf13069..211a2a0595 100644 --- a/deal.II/doc/news/changes.h +++ b/deal.II/doc/news/changes.h @@ -172,6 +172,17 @@ inconvenience this causes.

Specific improvements

    +
  1. New: The GridReordering::reorder_cells() function used a + numbering format for the vertices in a cell that was last used in + deal.II version 5.2. This format is still used internally, but + the function now also understands the numbering that has been + used in deal.II ever since. The choice is made by an additional + argument to the function that defaults to the old-style + format for backward compatibility. +
    + (Wolfgang Bangerth, 2014/07/14) +
  2. +
  3. New: There are now functions GridOut::write_vtk() and GridOut::write_vtu() that can write a mesh in VTK/VTU format. diff --git a/deal.II/include/deal.II/grid/grid_reordering.h b/deal.II/include/deal.II/grid/grid_reordering.h index 652a59ce98..e14d6097ff 100644 --- a/deal.II/include/deal.II/grid/grid_reordering.h +++ b/deal.II/include/deal.II/grid/grid_reordering.h @@ -34,9 +34,12 @@ DEAL_II_NAMESPACE_OPEN * 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 + * @note In contrast to the rest of the deal.II library, by default this class * uses the old deal.II numbering scheme, which was used up to deal.II - * version 5.2. That is, the vertex and face ordering in 2d is assumed + * version 5.2 (but the main function of this class takes a flag that + * specifies whether it should do an implicit conversion from the new + * to the old format before doing its work, and then back again after + * reordering). In this old format, the vertex and face ordering in 2d is assumed * to be * @verbatim * 2 @@ -73,7 +76,6 @@ DEAL_II_NAMESPACE_OPEN * |/ / | |/ * *-------* *-------* * @endverbatim - * * After calling the GridReordering::reorder_cells() function the * CellData is still in this old numbering scheme. Hence, for creating * a Triangulation based on the resulting CellData the @@ -495,9 +497,9 @@ DEAL_II_NAMESPACE_OPEN * * Prior to the implementation of the algorithms developed by Michael Anderson * and described above, we used a branch-and-cut algorithm initially - * implemented in 2000 by Wolfgang Bangerth. Although it is no longer used + * implemented in 2000 by Wolfgang Bangerth. Although it is no longer used, * here is how it works, and why it doesn't always work for large meshes since - * its run-time can exponential in bad cases. + * its run-time can be exponential in bad cases. * * The first observation is that although there are counterexamples, * problems are usually local. For example, in the second example @@ -662,8 +664,17 @@ public: * If a consistent reordering is not * possible in dim=3, the original * connectivity data is restored. + * + * @param original_cells An object that contains the data that describes + * the mesh. + * @param use_new_style_ordering If true, then use the standard + * ordering of vertices within a cell. If false (the default), then + * use the "old-style" ordering of vertices within cells used by + * deal.II before version 5.2 and as explained in the documentation + * of this class. */ - static void reorder_cells (std::vector > &original_cells); + static void reorder_cells (std::vector > &original_cells, + const bool use_new_style_ordering = false); /** * Grids generated by grid @@ -704,15 +715,18 @@ public: // declaration of explicit specializations template<> void -GridReordering<2>::reorder_cells (std::vector > &original_cells); +GridReordering<2>::reorder_cells (std::vector > &original_cells, + const bool); template<> void -GridReordering<2,3>::reorder_cells (std::vector > &original_cells); +GridReordering<2,3>::reorder_cells (std::vector > &original_cells, + const bool); template<> void -GridReordering<3>::reorder_cells (std::vector > &original_cells); +GridReordering<3>::reorder_cells (std::vector > &original_cells, + const bool); template<> void diff --git a/deal.II/source/grid/grid_generator.cc b/deal.II/source/grid/grid_generator.cc index 5233e55acf..39fa5409cf 100644 --- a/deal.II/source/grid/grid_generator.cc +++ b/deal.II/source/grid/grid_generator.cc @@ -44,58 +44,6 @@ DEAL_II_NAMESPACE_OPEN -// anonymous namespace for internal helper functions -namespace -{ - /** - * A set of three functions that - * reorder the data from the - * "current" to the "classic" - * format of vertex numbering of - * cells and faces. These functions - * do the reordering of their - * arguments in-place. - */ - void - reorder_compatibility (const std::vector > &, - const SubCellData &) - { - // nothing to do here: the format - // hasn't changed for 1d - } - - - void - reorder_compatibility (std::vector > &cells, - const SubCellData &) - { - for (unsigned int cell=0; cell > &cells, - SubCellData &subcelldata) - { - unsigned int tmp[GeometryInfo<3>::vertices_per_cell]; - for (unsigned int cell=0; cell::vertices_per_cell; ++i) - tmp[i] = cells[cell].vertices[i]; - for (unsigned int i=0; i::vertices_per_cell; ++i) - cells[cell].vertices[i] = tmp[GeometryInfo<3>::ucd_to_deal[i]]; - } - - // now points in boundary quads - std::vector >::iterator boundary_quad - = subcelldata.boundary_quads.begin(); - std::vector >::iterator end_quad - = subcelldata.boundary_quads.end(); - for (unsigned int quad_no=0; boundary_quad!=end_quad; ++boundary_quad, ++quad_no) - std::swap(boundary_quad->vertices[2], boundary_quad->vertices[3]); - } -} namespace GridGenerator { @@ -3480,12 +3428,12 @@ namespace GridGenerator GridTools::delete_duplicated_vertices (vertices, cells, subcell_data, considered_vertices); - // reorder_cells expects data in the "classic" format, transform - // the cell data before and after the call to that function - reorder_compatibility(cells, subcell_data); - GridReordering::reorder_cells(cells); + + // reorder the cells to ensure that they satisfy the convention for + // edge and face directions + GridReordering::reorder_cells(cells, true); result.clear (); - result.create_triangulation_compatibility (vertices, cells, subcell_data); + result.create_triangulation (vertices, cells, subcell_data); } diff --git a/deal.II/source/grid/grid_reordering.cc b/deal.II/source/grid/grid_reordering.cc index 9b478ad08c..07dcf6c947 100644 --- a/deal.II/source/grid/grid_reordering.cc +++ b/deal.II/source/grid/grid_reordering.cc @@ -32,7 +32,8 @@ DEAL_II_NAMESPACE_OPEN template<> void -GridReordering<1>::reorder_cells (std::vector > &) +GridReordering<1>::reorder_cells (std::vector > &, + const bool) { // there should not be much to do // in 1d... @@ -49,7 +50,8 @@ GridReordering<1>::invert_all_cells_of_negative_grid(const std::vector template<> void -GridReordering<1,2>::reorder_cells (std::vector > &) +GridReordering<1,2>::reorder_cells (std::vector > &, + const bool) { // there should not be much to do // in 1d... @@ -67,7 +69,8 @@ GridReordering<1,2>::invert_all_cells_of_negative_grid(const std::vector void -GridReordering<1,3>::reorder_cells (std::vector > &) +GridReordering<1,3>::reorder_cells (std::vector > &, + const bool) { // there should not be much to do // in 1d... @@ -614,28 +617,121 @@ namespace internal } // namespace internal +// anonymous namespace for internal helper functions +namespace +{ + /** + * A set of three functions that + * reorder the data from the + * "current" to the "classic" + * format of vertex numbering of + * cells and faces. These functions + * do the reordering of their + * arguments in-place. + */ + void + reorder_new_to_old_style (const std::vector > &) + { + // nothing to do here: the format + // hasn't changed for 1d + } + + + void + reorder_new_to_old_style (std::vector > &cells) + { + for (unsigned int cell=0; cell > &cells) + { + unsigned int tmp[GeometryInfo<3>::vertices_per_cell]; + for (unsigned int cell=0; cell::vertices_per_cell; ++i) + tmp[i] = cells[cell].vertices[i]; + for (unsigned int i=0; i::vertices_per_cell; ++i) + cells[cell].vertices[i] = tmp[GeometryInfo<3>::ucd_to_deal[i]]; + } + } + + + /** + * And now also in the opposite direction. + */ + void + reorder_old_to_new_style (const std::vector > &) + { + // nothing to do here: the format + // hasn't changed for 1d + } + + + void + reorder_old_to_new_style (std::vector > &cells) + { + // just invert the permutation: + reorder_new_to_old_style(cells); + } + + + void + reorder_old_to_new_style (std::vector > &cells) + { + // undo the ordering above + unsigned int tmp[GeometryInfo<3>::vertices_per_cell]; + for (unsigned int cell=0; cell::vertices_per_cell; ++i) + tmp[i] = cells[cell].vertices[i]; + for (unsigned int i=0; i::vertices_per_cell; ++i) + cells[cell].vertices[GeometryInfo<3>::ucd_to_deal[i]] = tmp[i]; + } + } +} template<> void -GridReordering<2>::reorder_cells (std::vector > &original_cells) +GridReordering<2>::reorder_cells (std::vector > &cells, + const bool use_new_style_ordering) { + // if necessary, convert to old-style format + if (use_new_style_ordering) + reorder_new_to_old_style(cells); + // check if grids are already // consistent. if so, do // nothing. if not, then do the // reordering - if (internal::GridReordering2d::is_consistent (original_cells)) - return; + if (!internal::GridReordering2d::is_consistent (cells)) + internal::GridReordering2d::GridReordering().reorient(cells); - internal::GridReordering2d::GridReordering().reorient(original_cells); + + // and convert back if necessary + if (use_new_style_ordering) + reorder_old_to_new_style(cells); } template<> void -GridReordering<2,3>::reorder_cells (std::vector > &original_cells) +GridReordering<2,3>::reorder_cells (std::vector > &cells, + const bool use_new_style_ordering) { - GridReordering<2>::reorder_cells(original_cells); + // if necessary, convert to old-style format + if (use_new_style_ordering) + reorder_new_to_old_style(cells); + + GridReordering<2>::reorder_cells(cells); + + + // and convert back if necessary + if (use_new_style_ordering) + reorder_old_to_new_style(cells); } @@ -1551,26 +1647,34 @@ namespace internal template<> void -GridReordering<3>::reorder_cells (std::vector > &incubes) +GridReordering<3>::reorder_cells (std::vector > &cells, + const bool use_new_style_ordering) { + Assert (cells.size() != 0, + ExcMessage("List of elements to orient must have at least one cell")); - Assert (incubes.size() != 0, - ExcMessage("List of elements to orient was of zero length")); + // if necessary, convert to old-style format + if (use_new_style_ordering) + reorder_new_to_old_style(cells); // create a backup to use if GridReordering // was not successful - std::vector > backup=incubes; + std::vector > backup=cells; // This does the real work - bool success= - internal::GridReordering3d::Orienter::orient_mesh (incubes); + const bool success= + internal::GridReordering3d::Orienter::orient_mesh (cells); // if reordering was not successful use - // original connectivity, otherwiese do + // original connectivity, otherwise do // nothing (i.e. use the reordered // connectivity) if (!success) - incubes=backup; + cells=backup; + + // and convert back if necessary + if (use_new_style_ordering) + reorder_old_to_new_style(cells); } -- 2.39.5