Skip to content

Commit ba5d5f5

Browse files
authored
Merge pull request #3396 from roystgnr/hole_ordering_fix
More MeshedHole fixes
2 parents 171d3cc + ed32833 commit ba5d5f5

File tree

4 files changed

+28
-14
lines changed

4 files changed

+28
-14
lines changed

src/mesh/mesh_triangle_holes.C

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,9 @@ RealGradient TriangulatorInterface::Hole::areavec() const
201201
// the division by 2 and the norm for the end.
202202
//
203203
// Your hole points had best be coplanar, but this should work
204-
// regardless of which plane they're in.
204+
// regardless of which plane they're in. If you're in the XY plane,
205+
// then the standard counter-clockwise hole point ordering gives you
206+
// a positive areavec(2);
205207

206208
RealGradient areavec = 0;
207209

@@ -210,7 +212,7 @@ RealGradient TriangulatorInterface::Hole::areavec() const
210212
const Point e_0im = this->point(i-1) - p0,
211213
e_0i = this->point(i) - p0;
212214

213-
areavec += e_0im.cross(e_0i);
215+
areavec += e_0i.cross(e_0im);
214216
}
215217

216218
return areavec;
@@ -648,13 +650,13 @@ TriangulatorInterface::MeshedHole::MeshedHole(const MeshBase & mesh,
648650
const Point e_0im = *hole_points[i-1] - p0,
649651
e_0i = *hole_points[i] - p0;
650652

651-
twice_this_area += e_0im.cross(e_0i)(2);
653+
twice_this_area += e_0i.cross(e_0im)(2);
652654
}
653655

654656
auto abs_twice_this_area = std::abs(twice_this_area);
655657

656-
if (((abs_twice_this_area == twice_this_area) && edge_type == 2) ||
657-
((abs_twice_this_area != twice_this_area) && edge_type == 1))
658+
if (((twice_this_area > 0) && edge_type == 2) ||
659+
((twice_this_area < 0) && edge_type == 1))
658660
++n_positive_areas;
659661
else
660662
++n_negative_areas;
@@ -700,7 +702,7 @@ TriangulatorInterface::MeshedHole::MeshedHole(const MeshBase & mesh,
700702
#endif
701703

702704
if (((twice_outer_area > 0) && outer_edge_type == 2) ||
703-
outer_edge_type == 1)
705+
((twice_outer_area < 0) && outer_edge_type == 1))
704706
{
705707
if (n_positive_areas > 1)
706708
{

src/mesh/poly2tri_triangulator.C

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,6 +1107,20 @@ bool Poly2TriTriangulator::insert_refinement_points()
11071107
// "to the left as viewed from the domain interior". We
11081108
// need to build the updated hole ordering "backwards".
11091109

1110+
// We should never see duplicate points when we add one
1111+
// to a hole; if we do then we did something wrong.
1112+
auto push_back_new_point = [&new_points](const Point & p) {
1113+
// O(1) assert in devel
1114+
libmesh_assert(new_points.empty() ||
1115+
new_points.back() != p);
1116+
#ifdef DEBUG
1117+
// O(N) asserts in dbg
1118+
for (auto old_p : new_points)
1119+
libmesh_assert_not_equal_to(old_p, p);
1120+
#endif
1121+
new_points.push_back(p);
1122+
};
1123+
11101124
for (auto point_it = arb.get_points().rbegin(),
11111125
point_end = arb.get_points().rend();
11121126
point_it != point_end;)
@@ -1117,7 +1131,7 @@ bool Poly2TriTriangulator::insert_refinement_points()
11171131
if (new_points.empty() ||
11181132
(point != new_points.back() &&
11191133
point != new_points.front()))
1120-
new_points.push_back(point);
1134+
push_back_new_point(point);
11211135

11221136
auto it = next_boundary_node.find(point);
11231137
while (it != next_boundary_node.end())
@@ -1128,7 +1142,7 @@ bool Poly2TriTriangulator::insert_refinement_points()
11281142
if (point_it != point_end &&
11291143
point == *point_it)
11301144
++point_it;
1131-
new_points.push_back(point);
1145+
push_back_new_point(point);
11321146
it = next_boundary_node.find(point);
11331147
}
11341148
}

src/mesh/triangulator_interface.C

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,7 @@ void TriangulatorInterface::elems_to_segments()
112112
}
113113

114114
// We'll steal the ordering calculation from
115-
// the MeshedHole code, but reverse the ordering since it's
116-
// to be used as an outer rather than an inner boundary.
115+
// the MeshedHole code
117116
const TriangulatorInterface::MeshedHole mh { _mesh, this->_bdy_ids };
118117

119118
// And now we're done with elements. Delete them lest they have
@@ -125,7 +124,6 @@ void TriangulatorInterface::elems_to_segments()
125124
// inside that boundary. Triangulator code doesn't like Steiner
126125
// points that aren't inside the triangulation domain, so we
127126
// need to get rid of them.
128-
129127
std::unordered_set<Node *> nodes_to_delete;
130128
if (!this->_bdy_ids.empty())
131129
{
@@ -139,10 +137,10 @@ void TriangulatorInterface::elems_to_segments()
139137
const std::size_t np = mh.n_points();
140138
for (auto i : make_range(np))
141139
{
142-
const Point pt = mh.point(np-i-1);
140+
const Point pt = mh.point(i);
143141
const dof_id_type id0 = libmesh_map_find(point_id_map, pt);
144142
nodes_to_delete.erase(_mesh.node_ptr(id0));
145-
const Point next_pt = mh.point((2*np-i-2)%np);
143+
const Point next_pt = mh.point((np+i+1)%np);
146144
const dof_id_type id1 = libmesh_map_find(point_id_map, next_pt);
147145
this->segments.emplace_back(id0, id1);
148146
}

tests/mesh/mesh_triangulation.C

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,7 @@ public:
904904

905905
// If refinement should have increased our element count, check it
906906
if (desired_area || area_func)
907-
CPPUNIT_ASSERT_LESS(mesh.n_elem(), n_original_elem); // n_elem+++
907+
CPPUNIT_ASSERT_GREATER(n_original_elem, mesh.n_elem()); // n_elem+++
908908
else
909909
CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), n_original_elem);
910910

0 commit comments

Comments
 (0)