From: Wolfgang Bangerth Date: Tue, 12 Dec 2023 06:49:23 +0000 (-0700) Subject: Provide some context to an exception. X-Git-Tag: relicensing~252^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F16342%2Fhead;p=dealii.git Provide some context to an exception. While there, clean up and document better. --- diff --git a/include/deal.II/grid/tria.h b/include/deal.II/grid/tria.h index 1183900c22..40b326e65e 100644 --- a/include/deal.II/grid/tria.h +++ b/include/deal.II/grid/tria.h @@ -3982,12 +3982,6 @@ public: int, << "You tried to do something on level " << arg1 << ", but this level is empty."); - /** - * Exception - * - * @ingroup Exceptions - */ - DeclException0(ExcNonOrientableTriangulation); /** * Exception diff --git a/source/grid/tria.cc b/source/grid/tria.cc index de285dca22..1f5a80ec70 100644 --- a/source/grid/tria.cc +++ b/source/grid/tria.cc @@ -12662,7 +12662,7 @@ void Triangulation::create_triangulation( orientation. To determine if 2 neighbors have the same or opposite orientation we use - a table of truth. Its entries are indexes by the local indices of the + a truth table. Its entries are indexed by the local indices of the common face. For example if two elements share a face, and this face is face 0 for element 0 and face 1 for element 1, then table(0,1) will tell whether the orientation are the same (true) or opposite (false). @@ -12672,7 +12672,7 @@ void Triangulation::create_triangulation( in 1D and 2D to generate the table. Assuming that a surface respects the standard orientation for 2d meshes, - the tables of truth are symmetric and their true values are the following + the truth tables are symmetric and their true values are the following - 1D curves: (0,1) - 2D surface: (0,1),(0,2),(1,3),(2,3) @@ -12690,18 +12690,18 @@ void Triangulation::create_triangulation( { case 1: { - bool values[][2] = {{false, true}, {true, false}}; + const bool values[][2] = {{false, true}, {true, false}}; for (const unsigned int i : GeometryInfo::face_indices()) for (const unsigned int j : GeometryInfo::face_indices()) - correct(i, j) = (values[i][j]); + correct(i, j) = values[i][j]; break; } case 2: { - bool values[][4] = {{false, true, true, false}, - {true, false, false, true}, - {true, false, false, true}, - {false, true, true, false}}; + const bool values[][4] = {{false, true, true, false}, + {true, false, false, true}, + {true, false, false, true}, + {false, true, true, false}}; for (const unsigned int i : GeometryInfo::face_indices()) for (const unsigned int j : GeometryInfo::face_indices()) correct(i, j) = (values[i][j]); @@ -12715,57 +12715,62 @@ void Triangulation::create_triangulation( std::list this_round, next_round; active_cell_iterator neighbor; + // Start with the first cell and (arbitrarily) decide that its + // direction flag should be 'true': this_round.push_back(begin_active()); begin_active()->set_direction_flag(true); begin_active()->set_user_flag(); while (this_round.size() > 0) { - for (typename std::list::iterator cell = - this_round.begin(); - cell != this_round.end(); - ++cell) + for (const auto &cell : this_round) { - for (const unsigned int i : (*cell)->face_indices()) + for (const unsigned int i : cell->face_indices()) { - if (!((*cell)->face(i)->at_boundary())) + if (cell->face(i)->at_boundary() == false) { - neighbor = (*cell)->neighbor(i); + // Consider the i'th neighbor of a cell for + // which we have already set the direction: + neighbor = cell->neighbor(i); - unsigned int cf = (*cell)->face_index(i); - unsigned int j = 0; - while (neighbor->face_index(j) != cf) - { - ++j; - } + const unsigned int nb_of_nb = + cell->neighbor_of_neighbor(i); - - // If we already saw this guy, check that everything is - // fine + // If we already saw this neighboring cell, + // check that everything is fine: if (neighbor->user_flag_set()) { - // If we have visited this guy, then the ordering and - // the orientation should agree - Assert(!(correct(i, j) ^ - (neighbor->direction_flag() == - (*cell)->direction_flag())), - ExcNonOrientableTriangulation()); + Assert( + !(correct(i, nb_of_nb) ^ + (neighbor->direction_flag() == + cell->direction_flag())), + ExcMessage( + "The triangulation you are trying to create is not orientable.")); } else { - next_round.push_back(neighbor); - neighbor->set_user_flag(); - if ((correct(i, j) ^ (neighbor->direction_flag() == - (*cell)->direction_flag()))) + // We had not seen this cell yet. Set its + // orientation flag (if necessary), mark it + // as treated via the user flag, and push it + // onto the list of cells to start work from + // the next time around: + if (correct(i, nb_of_nb) ^ + (neighbor->direction_flag() == + cell->direction_flag())) neighbor->set_direction_flag( !neighbor->direction_flag()); + neighbor->set_user_flag(); + next_round.push_back(neighbor); } } } } // Before we quit let's check that if the triangulation is - // disconnected that we still get all cells + // disconnected that we still get all cells by starting + // again from the first cell we haven't treated yet -- that + // is, the first cell of the next disconnected component we + // had not yet touched. if (next_round.empty()) for (const auto &cell : this->active_cell_iterators()) if (cell->user_flag_set() == false) @@ -12776,7 +12781,8 @@ void Triangulation::create_triangulation( break; } - this_round = next_round; + // Go on to the next round: + next_round.swap(this_round); next_round.clear(); } clear_user_flags();