From 746d461344de8254e6ec62039458006e9a3676ad Mon Sep 17 00:00:00 2001 From: David Wells Date: Sat, 16 Jan 2016 13:00:50 -0500 Subject: [PATCH] Assign unique numbers to GMSH elements. GMSH will not properly load information from a .msh file if some element (geometry element, as in line, face, quadrilateral, hexahedron) indices are repeated. Partially addresses issue #814. --- include/deal.II/grid/grid_out.h | 98 +++++++++++++++++---------- source/grid/grid_out.cc | 114 ++++++++++++++++++-------------- tests/grid/grid_out_04.output | 2 +- 3 files changed, 130 insertions(+), 84 deletions(-) diff --git a/include/deal.II/grid/grid_out.h b/include/deal.II/grid/grid_out.h index bd939571a4..79a6648965 100644 --- a/include/deal.II/grid/grid_out.h +++ b/include/deal.II/grid/grid_out.h @@ -1302,8 +1302,18 @@ private: * printed which are on the boundary and which have a boundary indicator not * equal to zero, since the latter is the default for boundary faces. * - * Since cells and faces are continuously numbered, the @p starting_index - * for the numbering of the faces is passed also. + * Since, in GMSH, geometric elements are continuously numbered, this + * function requires a parameter @p next_element_index providing the next + * geometric element number. This index should have a numerical value equal + * to one more than the index previously used to write a geometric element + * to @p out. + * + * @returns The next unused geometric element index. + * + * @warning @p next_element_index should be (at least) one larger than the + * current number of triangulation elements (lines, cells, faces) that have + * been written to @p out. GMSH will not load the saved file correctly if + * there are repeated indices. * * This function unfortunately can not be included in the regular @p * write_msh function, since it needs special treatment for the case @@ -1313,26 +1323,30 @@ private: * compiling the function for dim==1. Bad luck. */ template - void write_msh_faces (const Triangulation &tria, - const unsigned int starting_index, - std::ostream &out) const; + unsigned int + write_msh_faces (const Triangulation &tria, + const unsigned int next_element_index, + std::ostream &out) const; /** * Declaration of the specialization of above function for 1d. Does nothing. */ - void write_msh_faces (const Triangulation<1,1> &tria, - const unsigned int starting_index, - std::ostream &out) const; + unsigned int + write_msh_faces (const Triangulation<1,1> &tria, + const unsigned int next_element_index, + std::ostream &out) const; /** * Declaration of the specialization of above function for 1d, 2sd. Does * nothing. */ - void write_msh_faces (const Triangulation<1,2> &tria, - const unsigned int starting_index, - std::ostream &out) const; - void write_msh_faces (const Triangulation<1,3> &tria, - const unsigned int starting_index, - std::ostream &out) const; + unsigned int + write_msh_faces (const Triangulation<1,2> &tria, + const unsigned int next_element_index, + std::ostream &out) const; + unsigned int + write_msh_faces (const Triangulation<1,3> &tria, + const unsigned int next_element_index, + std::ostream &out) const; @@ -1341,8 +1355,18 @@ private: * printed which are on the boundary and which have a boundary indicator not * equal to zero, since the latter is the default for boundary faces. * - * Since cells and faces are continuously numbered, the @p starting_index - * for the numbering of the lines is passed also. + * Since, in GMSH, geometric elements are continuously numbered, this + * function requires a parameter @p next_element_index providing the next + * geometric element number. This index should have a numerical value equal + * to one more than the index previously used to write a geometric element + * to @p out. + * + * @returns The next unused geometric element index. + * + * @warning @p next_element_index should be (at least) one larger than the + * current number of triangulation elements (lines, cells, faces) that have + * been written to @p out. GMSH will not load the saved file correctly if + * there are repeated indices. * * This function unfortunately can not be included in the regular @p * write_msh function, since it needs special treatment for the case @@ -1352,40 +1376,46 @@ private: * when compiling the function for dim==1/2. Bad luck. */ template - void write_msh_lines (const Triangulation &tria, - const unsigned int starting_index, - std::ostream &out) const; + unsigned int + write_msh_lines (const Triangulation &tria, + const unsigned int next_element_index, + std::ostream &out) const; /** * Declaration of the specialization of above function for 1d. Does nothing. */ - void write_msh_lines (const Triangulation<1,1> &tria, - const unsigned int starting_index, - std::ostream &out) const; + unsigned int + write_msh_lines (const Triangulation<1,1> &tria, + const unsigned int next_element_index, + std::ostream &out) const; /** * Declaration of the specialization of above function for 1d, 2sd. Does * nothing. */ - void write_msh_lines (const Triangulation<1,2> &tria, - const unsigned int starting_index, - std::ostream &out) const; - void write_msh_lines (const Triangulation<1,3> &tria, - const unsigned int starting_index, - std::ostream &out) const; + unsigned int + write_msh_lines (const Triangulation<1,2> &tria, + const unsigned int next_element_index, + std::ostream &out) const; + unsigned int + write_msh_lines (const Triangulation<1,3> &tria, + const unsigned int next_element_index, + std::ostream &out) const; /** * Declaration of the specialization of above function for 2d. Does nothing. */ - void write_msh_lines (const Triangulation<2,2> &tria, - const unsigned int starting_index, - std::ostream &out) const; + unsigned int + write_msh_lines (const Triangulation<2,2> &tria, + const unsigned int next_element_index, + std::ostream &out) const; /** * Declaration of the specialization of above function for 2d, 3sd. Does * nothing. */ - void write_msh_lines (const Triangulation<2,3> &tria, - const unsigned int starting_index, - std::ostream &out) const; + unsigned int + write_msh_lines (const Triangulation<2,3> &tria, + const unsigned int next_element_index, + std::ostream &out) const; /** * Write the grid information about faces to @p out. Only those faces are diff --git a/source/grid/grid_out.cc b/source/grid/grid_out.cc index 3d1efd1d4a..280558767e 100644 --- a/source/grid/grid_out.cc +++ b/source/grid/grid_out.cc @@ -1063,13 +1063,16 @@ void GridOut::write_msh (const Triangulation &tria, out << '\n'; } - // write faces and lines with - // non-zero boundary indicator - unsigned int next_index = tria.n_active_cells()+1; + // write faces and lines with non-zero boundary indicator + unsigned int next_element_index = tria.n_active_cells()+1; if (msh_flags.write_faces) - write_msh_faces (tria, next_index, out); + { + next_element_index = write_msh_faces (tria, next_element_index, out); + } if (msh_flags.write_lines) - write_msh_lines (tria, next_index, out); + { + next_element_index = write_msh_lines (tria, next_element_index, out); + } out << "$ENDELM\n"; @@ -2620,83 +2623,92 @@ unsigned int GridOut::n_boundary_lines (const Triangulation &tria -void GridOut::write_msh_faces (const Triangulation<1> &, - const unsigned int, - std::ostream &) const +unsigned int +GridOut::write_msh_faces (const Triangulation<1> &, + const unsigned int next_element_index, + std::ostream &) const { - return; + return next_element_index; } -void GridOut::write_msh_faces (const Triangulation<1,2> &, - const unsigned int, - std::ostream &) const +unsigned int +GridOut::write_msh_faces (const Triangulation<1,2> &, + const unsigned int next_element_index, + std::ostream &) const { - return; + return next_element_index; } -void GridOut::write_msh_faces (const Triangulation<1,3> &, - const unsigned int, - std::ostream &) const +unsigned int +GridOut::write_msh_faces (const Triangulation<1,3> &, + const unsigned int next_element_index, + std::ostream &) const { - return; + return next_element_index; } -void GridOut::write_msh_lines (const Triangulation<1> &, - const unsigned int, - std::ostream &) const +unsigned int +GridOut::write_msh_lines (const Triangulation<1> &, + const unsigned int next_element_index, + std::ostream &) const { - return; + return next_element_index; } -void GridOut::write_msh_lines (const Triangulation<1,2> &, - const unsigned int, - std::ostream &) const +unsigned int +GridOut::write_msh_lines (const Triangulation<1,2> &, + const unsigned int next_element_index, + std::ostream &) const { - return; + return next_element_index; } -void GridOut::write_msh_lines (const Triangulation<1,3> &, - const unsigned int, - std::ostream &) const +unsigned int +GridOut::write_msh_lines (const Triangulation<1,3> &, + const unsigned int next_element_index, + std::ostream &) const { - return; + return next_element_index; } -void GridOut::write_msh_lines (const Triangulation<2> &, - const unsigned int, - std::ostream &) const +unsigned int +GridOut::write_msh_lines (const Triangulation<2> &, + const unsigned int next_element_index, + std::ostream &) const { - return; + return next_element_index; } -void GridOut::write_msh_lines (const Triangulation<2,3> &, - const unsigned int, - std::ostream &) const +unsigned int +GridOut::write_msh_lines (const Triangulation<2,3> &, + const unsigned int next_element_index, + std::ostream &) const { - return; + return next_element_index; } template -void GridOut::write_msh_faces (const Triangulation &tria, - const unsigned int starting_index, - std::ostream &out) const +unsigned int +GridOut::write_msh_faces (const Triangulation &tria, + const unsigned int next_element_index, + std::ostream &out) const { + unsigned int current_element_index = next_element_index; typename Triangulation::active_face_iterator face, endf; - unsigned int index=starting_index; for (face=tria.begin_active_face(), endf=tria.end_face(); face != endf; ++face) if (face->at_boundary() && (face->boundary_id() != 0)) { - out << index << ' '; + out << current_element_index << ' '; switch (dim) { case 2: @@ -2718,16 +2730,19 @@ void GridOut::write_msh_faces (const Triangulation &tria, << face->vertex_index(GeometryInfo::ucd_to_deal[vertex])+1; out << '\n'; - ++index; + ++current_element_index; } + return current_element_index; } template -void GridOut::write_msh_lines (const Triangulation &tria, - const unsigned int starting_index, - std::ostream &out) const +unsigned int +GridOut::write_msh_lines (const Triangulation &tria, + const unsigned int next_element_index, + std::ostream &out) const { + unsigned int current_element_index = next_element_index; // save the user flags for lines so // we can use these flags to track // which ones we've already taken @@ -2739,7 +2754,6 @@ void GridOut::write_msh_lines (const Triangulation &tria, .clear_user_flags_line (); typename Triangulation::active_cell_iterator cell, endc; - unsigned int index=starting_index; for (cell=tria.begin_active(), endc=tria.end(); cell != endc; ++cell) @@ -2750,7 +2764,7 @@ void GridOut::write_msh_lines (const Triangulation &tria, && (cell->line(l)->user_flag_set() == false)) { - out << index << " 1 "; + out << current_element_index << " 1 "; out << static_cast(cell->line(l)->boundary_id()) << ' ' << static_cast(cell->line(l)->boundary_id()) @@ -2764,7 +2778,7 @@ void GridOut::write_msh_lines (const Triangulation &tria, // move on to the next line // but mark the current one // as taken care of - ++index; + ++current_element_index; cell->line(l)->set_user_flag(); } @@ -2772,6 +2786,8 @@ void GridOut::write_msh_lines (const Triangulation &tria, // flags for the lines const_cast&>(tria) .load_user_flags_line (line_flags); + + return current_element_index; } diff --git a/tests/grid/grid_out_04.output b/tests/grid/grid_out_04.output index 5403b23775..8c48ef77ee 100644 --- a/tests/grid/grid_out_04.output +++ b/tests/grid/grid_out_04.output @@ -27,5 +27,5 @@ $ELM 3 1 5 0 0 8 1 2 6 5 3 4 8 7 2 3 2 2 4 5 6 8 7 -2 1 1 1 2 1 3 +3 1 1 1 2 1 3 $ENDELM -- 2.39.5