From: wolf Date: Tue, 7 Jun 2005 17:46:34 +0000 (+0000) Subject: Use a proper data structure instead of signed integers and arithmetic X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d686377c0b5c3c328da45e6f950f130026ebb9a6;p=dealii-svn.git Use a proper data structure instead of signed integers and arithmetic on them to denote edge orientations. git-svn-id: https://svn.dealii.org/trunk@10845 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/deal.II/include/grid/grid_reordering_internal.h b/deal.II/deal.II/include/grid/grid_reordering_internal.h index cdae2caaa9..dda3c016c6 100644 --- a/deal.II/deal.II/include/grid/grid_reordering_internal.h +++ b/deal.II/deal.II/include/grid/grid_reordering_internal.h @@ -395,6 +395,74 @@ namespace internal */ namespace GridReordering3d { + /** + * A structure indicating the + * direction of an edge. In the + * implementation file, we define + * three objects, + * unoriented_edge, + * forward_edge, and + * backward_edge, that + * denote whether an edge has + * already been oriented, whether + * it is in standard orientation, + * or whether it has reverse + * direction. The state that each + * of these objects encode is + * stored in the + * orientation member + * variable -- we would really + * need only three such values, + * which we pick in the + * implementation file, and make + * sure when we compare such + * objects that only these three + * special values are actually + * used. + * + * The reason for this way of + * implementing things is as + * follows. Usually, such a + * property would be implemented + * as an enum. However, in the + * previous implementation, a + * signed integer was used with + * unoriented=0, forward=+1, and + * backward=-1. A number of + * operations, such as equality + * of ordered edges were mapped + * to checking whether the + * product of two edge + * orientations equals +1. Such + * arithmetic isn't always + * portable and sometimes flagged + * when using -ftrapv with + * gcc. Using this class instead + * makes sure that there isn't + * going to be any arithmetic + * going on on edge orientations, + * just comparisons for equality + * or inequality. + * + * @author Wolfgang Bangerth, 2005 + */ + struct EdgeOrientation + { + /** + * A value indicating the orientation. + */ + char orientation; + + /** + * Comparison operator. + */ + bool operator == (const EdgeOrientation &edge_orientation) const; + + /** + * Comparison operator. + */ + bool operator != (const EdgeOrientation &edge_orientation) const; + }; /** * During building the @@ -460,13 +528,13 @@ namespace internal /** * Whether the edge has not - * already been oriented (0), + * already been oriented, * points from node 0 to node - * 1 (1), or the reverse - * (-1). The initial state of - * this flag is zero. + * 1, or the reverse. + * The initial state of + * this flag is unoriented. */ - signed short int orientation_flag; + EdgeOrientation orientation_flag; /** * Used to determine which @@ -536,7 +604,7 @@ namespace internal * (1) or node 1 is the base * (-1). */ - signed int local_orientation_flags[GeometryInfo<3>::lines_per_cell]; + EdgeOrientation local_orientation_flags[GeometryInfo<3>::lines_per_cell]; /** * An internal flag used to diff --git a/deal.II/deal.II/source/grid/grid_reordering.cc b/deal.II/deal.II/source/grid/grid_reordering.cc index e286a2533b..bfc03e0f6f 100644 --- a/deal.II/deal.II/source/grid/grid_reordering.cc +++ b/deal.II/deal.II/source/grid/grid_reordering.cc @@ -20,9 +20,6 @@ #include -//TODO[WB]: this file uses signed integers in weird ways, for edge and face orientations. these uses should be fixed by proper use of an enum - - #if deal_II_dimension == 1 void GridReordering<1>::reorder_cells (const std::vector > &) @@ -586,6 +583,31 @@ namespace internal char *, << "Grid Orientation Error: " << arg1); + const EdgeOrientation unoriented_edge = {'u'}; + const EdgeOrientation forward_edge = {'f'}; + const EdgeOrientation backward_edge = {'b'}; + + inline + bool + EdgeOrientation:: + operator == (const EdgeOrientation &edge_orientation) const + { + Assert ((orientation == 'u') || (orientation == 'f') || (orientation == 'b'), + ExcInternalError()); + return orientation == edge_orientation.orientation; + } + + + + inline + bool + EdgeOrientation:: + operator != (const EdgeOrientation &edge_orientation) const + { + return ! (*this == edge_orientation); + } + + namespace ElementInfo { @@ -619,16 +641,16 @@ namespace internal * the edge -1 means the end * of the edge. */ - static const int edge_to_node_orient[8][3] = + static const EdgeOrientation edge_to_node_orient[8][3] = { - { 1, 1, 1}, - {-1, 1, 1}, - {-1,-1, 1}, - { 1,-1, 1}, - { 1, 1,-1}, - {-1, 1,-1}, - {-1,-1,-1}, - { 1,-1,-1} + {forward_edge,forward_edge,forward_edge}, + {backward_edge,forward_edge,forward_edge}, + {backward_edge,backward_edge,forward_edge}, + {forward_edge,backward_edge,forward_edge}, + {forward_edge,forward_edge,backward_edge}, + {backward_edge,forward_edge,backward_edge}, + {backward_edge,backward_edge,backward_edge}, + {forward_edge,backward_edge,backward_edge} }; /** @@ -680,7 +702,7 @@ namespace internal Edge::Edge (const unsigned int n0, const unsigned int n1) : - orientation_flag (0), + orientation_flag (unoriented_edge), group (deal_II_numbers::invalid_unsigned_int) { nodes[0] = n0; @@ -694,7 +716,7 @@ namespace internal for (unsigned int i=0; i::lines_per_cell; ++i) { edges[i] = deal_II_numbers::invalid_unsigned_int; - local_orientation_flags[i] = 1; + local_orientation_flags[i] = forward_edge; } for (unsigned int i=0; i::vertices_per_cell; ++i) @@ -756,21 +778,24 @@ namespace internal const unsigned int ge1 = c.edges[e1]; const unsigned int ge2 = c.edges[e2]; - const int or0 = ElementInfo::edge_to_node_orient[local_node_num][0] * - c.local_orientation_flags[e0]; - const int or1 = ElementInfo::edge_to_node_orient[local_node_num][1] * - c.local_orientation_flags[e1]; - const int or2 = ElementInfo::edge_to_node_orient[local_node_num][2] * - c.local_orientation_flags[e2]; + const EdgeOrientation or0 = ElementInfo::edge_to_node_orient[local_node_num][0] == + c.local_orientation_flags[e0] ? + forward_edge : backward_edge; + const EdgeOrientation or1 = ElementInfo::edge_to_node_orient[local_node_num][1] == + c.local_orientation_flags[e1] ? + forward_edge : backward_edge; + const EdgeOrientation or2 = ElementInfo::edge_to_node_orient[local_node_num][2] == + c.local_orientation_flags[e2] ? + forward_edge : backward_edge; // Make sure that edges agree // what the current node should // be. - Assert ((edge_list[ge0].nodes[or0 == 1 ? 0 : 1] == - edge_list[ge1].nodes[or1 == 1 ? 0 : 1]) + Assert ((edge_list[ge0].nodes[or0 == forward_edge ? 0 : 1] == + edge_list[ge1].nodes[or1 == forward_edge ? 0 : 1]) && - (edge_list[ge1].nodes[or1 == 1 ? 0 : 1] == - edge_list[ge2].nodes[or2 == 1 ? 0 : 1]), + (edge_list[ge1].nodes[or1 == forward_edge ? 0 : 1] == + edge_list[ge2].nodes[or2 == forward_edge ? 0 : 1]), ExcMessage ("This message does not satisfy the internal " "consistency check")); } @@ -805,7 +830,8 @@ namespace internal ++edge_num) { unsigned int gl_edge_num = 0; - signed int l_edge_orient = 1; + EdgeOrientation l_edge_orient = forward_edge; + // Construct the // CheapEdge const unsigned int @@ -835,7 +861,7 @@ namespace internal // from hash_map gl_edge_num = edge_map[cur_edge]; if (edge_list[gl_edge_num].nodes[0] != node0) - l_edge_orient = -1; + l_edge_orient = backward_edge; } // set edge number to // edgenum @@ -1019,7 +1045,7 @@ namespace internal { for (unsigned int i=0; i<12; ++i) if (mesh.edge_list[mesh.cell_list[cell_num].edges[i]].orientation_flag - == 0) + == unoriented_edge) return false; return true; } @@ -1041,28 +1067,30 @@ namespace internal // orientation is first // encountered in the group // it is stored in this - signed int value = 0; + EdgeOrientation value = unoriented_edge; // Loop over all parallel // edges for (unsigned int i=4*group; i<4*(group+1); ++i) { // If the edge has // orientation - if ((c.local_orientation_flags[i] != 0) + if ((c.local_orientation_flags[i] != + unoriented_edge) && - (mesh.edge_list[c.edges[i]].orientation_flag != 0)) + (mesh.edge_list[c.edges[i]].orientation_flag != + unoriented_edge)) { - const signed int this_edge_direction + const EdgeOrientation this_edge_direction = (c.local_orientation_flags[i] == mesh.edge_list[c.edges[i]].orientation_flag ? - +1 : -1); + forward_edge : backward_edge); // If we haven't // seen an oriented // edge before, // then store its // value: - if (value == 0) + if (value == unoriented_edge) value = this_edge_direction; else // If we have @@ -1091,7 +1119,8 @@ namespace internal // search for the unoriented // side while ((edge<12) && - (mesh.edge_list[c.edges[edge]].orientation_flag != 0)) + (mesh.edge_list[c.edges[edge]].orientation_flag != + unoriented_edge)) ++edge; // if we found none then return @@ -1108,7 +1137,8 @@ namespace internal // of the edges in the group // should be un-oriented for (unsigned int j = edge_group*4; j