1#include <libmesh/boundary_info.h>
2#include <libmesh/elem.h>
3#include <libmesh/mesh.h>
4#include <libmesh/mesh_generation.h>
5#include <libmesh/mesh_modification.h>
6#include <libmesh/mesh_triangle_holes.h>
7#include <libmesh/mesh_triangle_interface.h>
8#include <libmesh/parallel_implementation.h>
9#include <libmesh/parsed_function.h>
10#include <libmesh/point.h>
11#include <libmesh/poly2tri_triangulator.h>
36#ifdef LIBMESH_HAVE_POLY2TRI
47# ifdef LIBMESH_ENABLE_AMR
75#ifdef LIBMESH_HAVE_TRIANGLE
82# ifdef LIBMESH_ENABLE_AMR
115#ifdef LIBMESH_ENABLE_EXCEPTIONS
119 bool threw_desired_exception =
false;
124 std::regex msg_regex(re);
125 CPPUNIT_ASSERT(std::regex_search(e.what(), msg_regex));
126 threw_desired_exception =
true;
128 catch (CppUnit::Exception & e) {
132 CPPUNIT_ASSERT_MESSAGE(
"Unexpected exception type thrown",
false);
134 CPPUNIT_ASSERT(threw_desired_exception);
146 std::vector<TriangulatorInterface::PolygonHole> polyholes;
149 polyholes.emplace_back(center,
radius, 2);
151 polyholes.emplace_back(center,
radius, 3);
153 polyholes.emplace_back(center,
radius, 4);
155 polyholes.emplace_back(center,
radius, 5);
157 polyholes.emplace_back(center,
radius, 6);
159 for (
int i=0; i != 5; ++i)
161 const int n_sides = i+2;
164 const Real computed_area = hole.
area();
165 const Real theta =
pi/n_sides;
166 const Real half_side_length =
radius*std::cos(theta);
168 const Real area = n_sides * apothem * half_side_length;
176#ifdef LIBMESH_HAVE_TRIANGLE
191 std::vector<TriangulatorInterface::PolygonHole> polyholes;
193 auto check_corners = [center,
radius]
197 CPPUNIT_ASSERT_EQUAL(np, hole.n_points());
201 const Real xin = center(0) +
radius * .99 * std::cos(theta);
202 const Real xout = center(0) +
radius * 1.01 * std::cos(theta);
203 const Real yin = center(1) +
radius * .99 * std::sin(theta);
204 const Real yout = center(1) +
radius * 1.01 * std::sin(theta);
206 CPPUNIT_ASSERT(hole.contains(
Point(xin, yin)));
207 CPPUNIT_ASSERT(!hole.contains(
Point(xout, yout)));
212 check_corners(triangle, 3);
214 check_corners(diamond, 4);
216 check_corners(hexagon, 6);
219 {{1,0}, {{0,-1},{2,-1},{2,1},{1.75,-.5},{1.5,1},{1.25,-.5},
220 {1,1},{.75,-.5},{.5,1},{.25,-.5},{0,1}}};
222 CPPUNIT_ASSERT(jaggy.contains({.1,-.3}));
223 CPPUNIT_ASSERT(jaggy.contains({.5,.9}));
224 CPPUNIT_ASSERT(jaggy.contains({.9,-.3}));
225 CPPUNIT_ASSERT(jaggy.contains({1,0}));
226 CPPUNIT_ASSERT(jaggy.contains({1.1,-.4}));
227 CPPUNIT_ASSERT(jaggy.contains({1.5,.9}));
228 CPPUNIT_ASSERT(jaggy.contains({1.9,-.3}));
230 CPPUNIT_ASSERT(jaggy.contains({1.9,-.5}));
231 CPPUNIT_ASSERT(jaggy.contains({1.6,-.5}));
232 CPPUNIT_ASSERT(jaggy.contains({1.1,-.5}));
233 CPPUNIT_ASSERT(jaggy.contains({.5,-.5}));
234 CPPUNIT_ASSERT(jaggy.contains({.2,-.5}));
236 CPPUNIT_ASSERT(!jaggy.contains({.1,.7}));
237 CPPUNIT_ASSERT(!jaggy.contains({.5,1.1}));
238 CPPUNIT_ASSERT(!jaggy.contains({.9,.7}));
239 CPPUNIT_ASSERT(!jaggy.contains({1,-1.1}));
240 CPPUNIT_ASSERT(!jaggy.contains({1.1,.8}));
241 CPPUNIT_ASSERT(!jaggy.contains({1.5,1.1}));
242 CPPUNIT_ASSERT(!jaggy.contains({1.9,.9}));
244 CPPUNIT_ASSERT(!jaggy.contains({1.9,1}));
245 CPPUNIT_ASSERT(!jaggy.contains({1.4,1}));
246 CPPUNIT_ASSERT(!jaggy.contains({.9,1}));
247 CPPUNIT_ASSERT(!jaggy.contains({.4,1}));
248 CPPUNIT_ASSERT(!jaggy.contains({-.2,1}));
249 CPPUNIT_ASSERT(!jaggy.contains({-.2,0}));
250 CPPUNIT_ASSERT(!jaggy.contains({1.2,0}));
253 {{1,0}, {{-.25,-1},{2,-1},{2,1},{1.75,1},{1.75,-.5},{1.5,-.5},
254 {1.5,1},{1.25,1},{1.25,-.5},{1,-.5},{1,1},{.75,1},
255 {.75,-.5},{.5,-.5},{.5,1},{.25,1},{.25,-.5},{0,-.5},
258 CPPUNIT_ASSERT(square_jaggy.contains({-.1,-.3}));
259 CPPUNIT_ASSERT(square_jaggy.contains({.4,.9}));
260 CPPUNIT_ASSERT(square_jaggy.contains({.9,-.3}));
261 CPPUNIT_ASSERT(square_jaggy.contains({.9,0}));
262 CPPUNIT_ASSERT(square_jaggy.contains({1.1,-.6}));
263 CPPUNIT_ASSERT(square_jaggy.contains({1.4,.9}));
264 CPPUNIT_ASSERT(square_jaggy.contains({1.9,-.3}));
266 CPPUNIT_ASSERT(!square_jaggy.contains({.1,-.3}));
267 CPPUNIT_ASSERT(!square_jaggy.contains({.6,.9}));
268 CPPUNIT_ASSERT(!square_jaggy.contains({1.1,-.3}));
269 CPPUNIT_ASSERT(!square_jaggy.contains({1.1,0}));
270 CPPUNIT_ASSERT(!square_jaggy.contains({1.1,-1.6}));
271 CPPUNIT_ASSERT(!square_jaggy.contains({1.6,.9}));
272 CPPUNIT_ASSERT(!square_jaggy.contains({2.1,-.3}));
274 CPPUNIT_ASSERT(square_jaggy.contains({-.1,-.5}));
275 CPPUNIT_ASSERT(square_jaggy.contains({.3,-.5}));
276 CPPUNIT_ASSERT(square_jaggy.contains({.9,-.5}));
277 CPPUNIT_ASSERT(square_jaggy.contains({1.3,-.5}));
278 CPPUNIT_ASSERT(square_jaggy.contains({1.9,-.5}));
280 CPPUNIT_ASSERT(!square_jaggy.contains({-.3,1}));
281 CPPUNIT_ASSERT(!square_jaggy.contains({.2,1}));
282 CPPUNIT_ASSERT(!square_jaggy.contains({.6,1}));
283 CPPUNIT_ASSERT(!square_jaggy.contains({1.1,1}));
284 CPPUNIT_ASSERT(!square_jaggy.contains({1.6,1}));
285 CPPUNIT_ASSERT(!square_jaggy.contains({2.1,1}));
307 perturbed(
Point(0,4.e-16), std::sqrt(2_R)/2, 4);
309 {{0,0}, {{100,0},{100,100},{0,100},{-100,100},
310 {-100,0},{-100,-100},{0,-100},{100,-100}}};
313 CPPUNIT_ASSERT(outer_bdy.contains(perturbed.
point(i)));
325 for (
const auto & elem :
mesh.element_ptr_range())
327 CPPUNIT_ASSERT_EQUAL(elem->type(),
TRI3);
331 (elem->point(1) - elem->point(0)).cross
332 (elem->point(2) - elem->point(0));
334 CPPUNIT_ASSERT_GREATER(
Real(0), cross_prod(2));
336 bool found_triangle =
false;
337 for (
const auto & node : elem->node_ref_range())
339 const Point & point = node;
340 if (point ==
Point(0,0))
342 found_triangle =
true;
343 CPPUNIT_ASSERT((elem->point(0) ==
Point(0,0) &&
344 elem->point(1) ==
Point(1,0) &&
345 elem->point(2) ==
Point(0,1)) ||
346 (elem->point(1) ==
Point(0,0) &&
347 elem->point(2) ==
Point(1,0) &&
348 elem->point(0) ==
Point(0,1)) ||
349 (elem->point(2) ==
Point(0,0) &&
350 elem->point(0) ==
Point(1,0) &&
351 elem->point(1) ==
Point(0,1)));
353 if (point ==
Point(1,2))
355 found_triangle =
true;
356 CPPUNIT_ASSERT((elem->point(0) ==
Point(0,1) &&
357 elem->point(1) ==
Point(1,0) &&
358 elem->point(2) ==
Point(1,2)) ||
359 (elem->point(1) ==
Point(0,1) &&
360 elem->point(2) ==
Point(1,0) &&
361 elem->point(0) ==
Point(1,2)) ||
362 (elem->point(2) ==
Point(0,1) &&
363 elem->point(0) ==
Point(1,0) &&
364 elem->point(1) ==
Point(1,2)));
367 CPPUNIT_ASSERT(found_triangle);
378 const Real hsq2 = std::sqrt(2) / 2.0;
382 for (
const auto & elem :
mesh.element_ptr_range())
385 CPPUNIT_ASSERT_EQUAL(elem->type(),
TRI6);
387 for (
const auto & i_side :
make_range(elem->n_sides()))
390 if (elem->neighbor_ptr(i_side) ==
nullptr)
392 const Point & side_pt_0 = *(elem->node_ptr(i_side));
393 const Point & side_pt_1 = *(elem->node_ptr((i_side + 1) % 3));
394 const Point & side_pt_2 = *(elem->node_ptr(i_side + 3));
395 const bool x_sign = (side_pt_0(0) == 1 || side_pt_1(0) == 1);
396 const bool y_sign = (side_pt_0(1) == 1 || side_pt_1(1) == 1);
397 const Point ref_side_pt_2 =
Point (x_sign ? hsq2 : -hsq2, y_sign ? hsq2 : -hsq2);
398 CPPUNIT_ASSERT_EQUAL(ref_side_pt_2, side_pt_2);
435 int interpolate_boundary_points,
437 Real expected_total_area = 1.5,
438 Real desired_area = 1000)
454 CPPUNIT_ASSERT_EQUAL(
mesh.
n_elem(), n_expected_elem);
457 for (
const auto & elem :
mesh.active_local_element_ptr_range())
459 CPPUNIT_ASSERT_EQUAL(elem->level(), 0u);
460 CPPUNIT_ASSERT_EQUAL(elem->type(),
TRI3);
462 area += elem->volume();
472 const std::vector<Point> & expected_centers)
474 std::vector<bool> found_centers(expected_centers.size(),
false);
476 for (
const auto & elem :
mesh.element_ptr_range())
478 CPPUNIT_ASSERT_EQUAL(elem->type(),
TRI3);
482 (elem->point(1) - elem->point(0)).cross
483 (elem->point(2) - elem->point(0));
485 CPPUNIT_ASSERT_GREATER(
Real(0), cross_prod(2));
488 Point center = elem->vertex_average();
490 bool found_mine =
false;
493 Point possible = expected_centers[i];
498 found_centers[i] =
true;
501 CPPUNIT_ASSERT(found_mine);
506 for (
auto found_it : found_centers)
507 CPPUNIT_ASSERT(found_it);
525 const std::vector<TriangulatorInterface::Hole*> holes { &diamond };
533 Real r2p2o6 = (std::sqrt(2_R)+2)/6;
534 Real r2p4o6 = (std::sqrt(2_R)+4)/6;
536 std::vector <Point> expected_centers
537 { {r2p2o6,r2p2o6}, {r2p2o6,-r2p2o6},
538 {-r2p2o6,r2p2o6}, {-r2p2o6,-r2p2o6},
539 {0,r2p4o6}, {r2p4o6, 0},
540 {0,-r2p4o6}, {-r2p4o6, 0}
571 diamond(
Point(0,4.e-16),
572 std::sqrt(2_R)/2, 4);
573 const std::vector<TriangulatorInterface::Hole*> holes { &diamond };
581 const Real r2p200o6 = (std::sqrt(2_R)+200)/6,
582 r2p400o6 = (std::sqrt(2_R)+400)/6;
584 std::vector <Point> expected_centers
585 { {r2p400o6,100./3}, {-r2p400o6,100./3},
586 {r2p400o6,-100./3}, {-r2p400o6,-100./3},
587 {100./3,r2p400o6}, {-100./3,r2p400o6},
588 {100./3,-r2p400o6}, {-100./3,-r2p400o6},
589 {r2p200o6,r2p200o6}, {-r2p200o6,r2p200o6},
590 {r2p200o6,-r2p200o6}, {-r2p200o6,-r2p200o6},
626 left_diamond(
Point(-100,4.e-16),
627 std::sqrt(2_R)/2, 4),
628 right_diamond(
Point(100,-4.e-16),
629 std::sqrt(2_R)/2, 4);
630 const std::vector<TriangulatorInterface::Hole*> holes
631 { &left_diamond, &right_diamond };
639 const Real r2p200o6 = (std::sqrt(2_R)+200)/6,
640 r2p400o6 = (std::sqrt(2_R)+400)/6;
642 std::vector <Point> expected_centers
644 {100+r2p400o6,100./3}, {100+r2p400o6,-100./3},
645 {100+100./3,r2p400o6}, {100-100./3,r2p400o6},
646 {100+100./3,-r2p400o6}, {100-100./3,-r2p400o6},
647 {100+r2p200o6,r2p200o6}, {100-r2p200o6,r2p200o6},
648 {100+r2p200o6,-r2p200o6}, {100-r2p200o6,-r2p200o6},
650 {-100-r2p400o6,100./3}, {-100-r2p400o6,-100./3},
651 {-100-100./3,r2p400o6}, {-100+100./3,r2p400o6},
652 {-100-100./3,-r2p400o6}, {-100+100./3,-r2p400o6},
653 {-100-r2p200o6,r2p200o6}, {-100+r2p200o6,r2p200o6},
654 {-100-r2p200o6,-r2p200o6}, {-100+r2p200o6,-r2p200o6},
656 {0,100./3}, {0,-100./3}
681 CPPUNIT_ASSERT_EQUAL(centerhole.n_points(), 8u);
682 CPPUNIT_ASSERT_EQUAL(centerhole.area(),
Real(1));
683 Point inside = centerhole.inside();
684 CPPUNIT_ASSERT_EQUAL(inside(0),
Real(20));
685 CPPUNIT_ASSERT_EQUAL(inside(1),
Real(20));
687 const std::vector<TriangulatorInterface::Hole*> holes { ¢erhole };
695 std::vector <Point> expected_centers
696 { {-0.5,
Real(2)/3}, {0,
Real(5)/6},
700 {-0.5, -
Real(2)/3}, {0, -
Real(5)/6},
702 {-
Real(2)/3, -0.5}, {-
Real(5)/6, 0},
706 for (
auto & p : expected_centers)
713#ifdef LIBMESH_ENABLE_AMR
727 const Point center{20,20};
735 CPPUNIT_ASSERT_EQUAL(centerhole.n_points(), 8u);
736 Point inside = centerhole.inside();
737 CPPUNIT_ASSERT_EQUAL(inside(0),
Real(20));
738 CPPUNIT_ASSERT_EQUAL(inside(1),
Real(20));
740 const std::vector<TriangulatorInterface::Hole*> holes { ¢erhole };
752 std::map<std::pair<Real, Real>,
Point> outer_midpoints
753 {{{19, 19}, {20, 19}},
754 {{21, 19}, {21, 20}},
755 {{21, 21}, {20, 21}},
759 for (
const auto & elem :
mesh.active_local_element_ptr_range())
760 for (
const auto n :
make_range(elem->n_sides()))
762 if (elem->neighbor_ptr(n))
766 outer_midpoints.find(std::make_pair(elem->point(n)(0),
768 if (it != outer_midpoints.end())
770 const Point error = it->second - elem->point(n+3);
776 const Point radius1 = elem->point(n) - center;
780 const Point radius2 = elem->point((n+1)%3) - center;
784 const Point radius3 = elem->point(n+3) - center;
803 triangulator.
segments = {{0,2},{2,1},{1,3},{3,0}};
820 edge13->set_node(1, node3);
823 edge02->set_node(1, node2);
826 edge30->set_node(1, node0);
829 edge21->set_node(1, node1);
832 if (elem_type ==
EDGE3)
835 edge13->set_node(2, node4);
837 edge02->set_node(2, node5);
839 edge30->set_node(2, node6);
841 edge21->set_node(2, node7);
851 const Real hsq2 = std::sqrt(2) / 2.0;
863 edge021->set_node(1, node2);
864 edge021->set_node(2, node1);
867 edge243->set_node(1, node4);
868 edge243->set_node(2, node3);
871 edge465->set_node(1, node6);
872 edge465->set_node(2, node5);
875 edge607->set_node(1, node0);
876 edge607->set_node(2, node7);
899 edge45->set_node(1, node5);
900 edge45->subdomain_id() = 1;
903 edge56->set_node(1, node6);
904 edge56->subdomain_id() = 1;
907 edge67->set_node(1, node7);
908 edge67->subdomain_id() = 1;
911 edge78->set_node(1, node8);
912 edge78->subdomain_id() = 1;
915 edge84->set_node(1, node4);
916 edge84->subdomain_id() = 1;
918 if (elem_type ==
EDGE3)
921 edge45->set_node(2, node9);
923 edge56->set_node(2, node10);
925 edge67->set_node(2, node11);
927 edge78->set_node(2, node12);
929 edge84->set_node(2, node13);
936 std::set<std::size_t> bdy_ids {0};
943#ifdef LIBMESH_HAVE_TRIANGLE
1004#ifdef LIBMESH_ENABLE_AMR
1051#ifdef LIBMESH_HAVE_POLY2TRI
1180 bool saw_curved_element =
false;
1181 for (
const auto & elem :
mesh.element_ptr_range())
1183 CPPUNIT_ASSERT_EQUAL(elem->type(),
TRI7);
1185 const Point & x0 = elem->point(0);
1186 const Point & x1 = elem->point(1);
1187 const Point & x2 = elem->point(2);
1188 const Point & x3 = elem->point(3);
1189 const Point & x4 = elem->point(4);
1190 const Point & x5 = elem->point(5);
1191 const Point & x6 = elem->point(6);
1193 const Point expected =
1194 (
Real(-1)/9) * (x0 + x1 + x2) +
1195 (
Real( 4)/9) * (x3 + x4 + x5);
1196 const Point straight = (x0 + x1 + x2) /
Real(3);
1207 saw_curved_element =
true;
1211 CPPUNIT_ASSERT(saw_curved_element);
1217#ifdef LIBMESH_ENABLE_EXCEPTIONS
1238 edgeAB->set_node(1, vB);
1239 edgeAB->set_node(2, mAB);
1243 edgeBC->set_node(1, vC);
1244 edgeBC->set_node(2, mBC);
1248 edgeCA->set_node(1, vA);
1249 edgeCA->set_node(2, mCA);
1257 bool threw_desired_exception =
false;
1262 const std::regex msg_regex(
"tangled quadratic triangle");
1263 CPPUNIT_ASSERT(std::regex_search(e.what(), msg_regex));
1264 threw_desired_exception =
true;
1266 catch (CppUnit::Exception & e) {
1270 CPPUNIT_ASSERT_MESSAGE(
"Unexpected exception type thrown",
false);
1272 CPPUNIT_ASSERT(threw_desired_exception);
1277#ifdef LIBMESH_ENABLE_AMR
1329 edge13->set_node(1, node3);
1332 edge02->set_node(1, node2);
1335 edge30->set_node(1, node0);
1361 edge01->set_node(1, node1);
1364 edge12->set_node(1, node2);
1367 edge20->set_node(1, node0);
1371 edge34->set_node(1, node4);
1374 edge45->set_node(1, node5);
1377 edge53->set_node(1, node3);
1402 tri012->set_node(1, node1);
1403 tri012->set_node(2, node2);
1406 tri345->set_node(1, node4);
1407 tri345->set_node(2, node5);
1437 const std::vector<TriangulatorInterface::Hole*> * holes,
1438 Real expected_total_area,
1440 Real desired_area = 0.1,
1457 if (desired_area || area_func)
1458 CPPUNIT_ASSERT_GREATER(n_original_elem,
mesh.
n_elem());
1460 CPPUNIT_ASSERT_EQUAL(
mesh.
n_elem(), n_original_elem);
1463 for (
const auto & elem :
mesh.active_local_element_ptr_range())
1465 CPPUNIT_ASSERT_EQUAL(elem->level(), 0u);
1466 CPPUNIT_ASSERT_EQUAL(elem->type(),
TRI3);
1468 const Real my_area = elem->volume();
1471 if (desired_area != 0)
1472 CPPUNIT_ASSERT_LESSEQUAL(desired_area, my_area);
1474 if (area_func !=
nullptr)
1475 for (
auto v :
make_range(elem->n_vertices()))
1477 const Real local_desired_area =
1478 (*area_func)(elem->point(v));
1479 CPPUNIT_ASSERT_LESSEQUAL(local_desired_area, my_area);
1521#ifdef LIBMESH_HAVE_FPARSER
1535 const std::vector<TriangulatorInterface::Hole*> holes { &diamond };
1550 Real total_area = 1.5;
1560 std::vector<TriangulatorInterface::AffineHole> hole_data;
1562 hole_data.reserve(M*N);
1563 std::vector<TriangulatorInterface::Hole*> holes;
1568 hole_data.emplace_back(diamond, 0, shift);
1569 holes.push_back(&hole_data.back());
1570 total_area -= hole_data.back().area();
1591 const std::vector<TriangulatorInterface::Hole*> holes { &diamond };
1603 int n_outer_sides = std::count_if(side_bcs.begin(), side_bcs.end(),
1604 [](
auto t){return std::get<2>(t) == 0;});
1605 CPPUNIT_ASSERT_GREATER(4, n_outer_sides);
1606 int n_hole_sides = std::count_if(side_bcs.begin(), side_bcs.end(),
1607 [](
auto t){return std::get<2>(t) == 1;});
1608 CPPUNIT_ASSERT_EQUAL(n_hole_sides, 4);
1631 const std::vector<TriangulatorInterface::Hole*> holes { &diamond };
1640#ifdef LIBMESH_HAVE_FPARSER
1643 const std::vector<TriangulatorInterface::Hole*> holes { &diamond };
void testPoly2TriRefined()
CPPUNIT_TEST(testPoly2TriNonUniformRefined)
LIBMESH_CPPUNIT_TEST_SUITE(MeshTriangulationTest)
The goal of this test is to verify proper operation of the interfaces to triangulation libraries.
void testPoly2TriInterp2()
void testPoly2TriHolesRefined()
CPPUNIT_TEST(testTriangleHalfDomain)
void testTriangleEdge3ToTri6()
CPPUNIT_TEST(testPoly2TriEdge3s)
void testPoly2TriMeshedHoles()
void testEdge3Mesh(MeshBase &mesh)
void testPoly2TriHolesNonUniformRefined()
void testTriangulatorInterp(UnstructuredMesh &mesh, TriangulatorInterface &triangulator, int interpolate_boundary_points, dof_id_type n_expected_elem, Real expected_total_area=1.5, Real desired_area=1000)
CPPUNIT_TEST(testTriangleEdges)
CPPUNIT_TEST(testPoly2TriHolePerturbed)
void testEdge3ToTri6Base(MeshBase &mesh, TriangulatorInterface &triangulator)
void testTriangleHoleArea()
void testTriangleInterp2()
CPPUNIT_TEST(testPoly2TriEdge3ToTri6)
void testPoly2TriRoundHole()
void testPoly2TriHalfDomainEdge3()
void testTriangleInterp()
void testPoly2TriBad2DMultiBoundary()
CPPUNIT_TEST(testPoly2TriInterp)
CPPUNIT_TEST(testPoly2TriHolesInteriorRefined)
void testPoly2TriHolesExtraRefined()
void testTriangleMeshedHoles()
void testPoly2TriEdge3s()
CPPUNIT_TEST(testPoly2TriNonRefined)
void testTriangleHoleContains()
void testPoly2TriSegments()
CPPUNIT_TEST(testTriangleInterp)
void testEdgesMesh(MeshBase &mesh, ElemType elem_type)
void testPoly2TriHalfDomain()
CPPUNIT_TEST(testPoly2TriEdge3ToTri6FlipThrows)
void testTriangleRoundHole()
CPPUNIT_TEST(testPoly2TriHolesInteriorExtraRefined)
CPPUNIT_TEST(testPoly2TriBadEdges)
CPPUNIT_TEST(testPoly2TriBad1DMultiBoundary)
void testTriangulatorHoles(MeshBase &mesh, TriangulatorInterface &triangulator)
void testTriangulatorBase(MeshBase &mesh, TriangulatorInterface &triangulator)
void testPoly2TriEdge3ToTri6FlipThrows()
void testFoundCenters(const MeshBase &mesh, const std::vector< Point > &expected_centers)
CPPUNIT_TEST(testPoly2TriBad2DMultiBoundary)
void testTriangulatorSegments(MeshBase &mesh, TriangulatorInterface &triangulator)
CPPUNIT_TEST(testTriangleRoundHole)
void testPoly2TriExtraRefined()
void testTriangulatorRoundHole(MeshBase &mesh, TriangulatorInterface &triangulator)
void testPoly2TriEdgesRefined()
CPPUNIT_TEST(testPoly2TriHoles)
void testExceptionBase(MeshBase &mesh, TriangulatorInterface &triangulator, const char *re)
void testPoly2TriNonRefined()
CPPUNIT_TEST(testTriangleSegments)
CPPUNIT_TEST(testPoly2TriHolesInterpRefined)
void testPoly2TriBadEdges()
CPPUNIT_TEST(testTriangleEdge3ToTri6)
void testPoly2TriRefinementBase(UnstructuredMesh &mesh, const std::vector< TriangulatorInterface::Hole * > *holes, Real expected_total_area, dof_id_type n_original_elem, Real desired_area=0.1, FunctionBase< Real > *area_func=nullptr)
CPPUNIT_TEST(testTriangleMeshedHoles)
CPPUNIT_TEST(testPoly2TriHolesExtraRefined)
void testPoly2TriHolePerturbed()
void testHalfDomain(MeshBase &mesh, TriangulatorInterface &triangulator, ElemType elem_type)
void testPoly2TriInterp()
void testPoly2TriHolesInteriorExtraRefined()
void testTriangulator(MeshBase &mesh, TriangulatorInterface &triangulator)
void testTriangleHalfDomain()
CPPUNIT_TEST(testTriangleInterp2)
void testPoly2TriEdge3ToTri7CenterFixup()
void testPoly2TriHolesInterpRefined()
CPPUNIT_TEST(testPoly2TriRefined)
void testTriangulatorTrapMesh(UnstructuredMesh &mesh)
void testHoleContainsRayDegeneracies()
void testPoly2TriNonUniformRefined()
void testPoly2TriHolesInteriorRefined()
void testTriangulatorHolePerturbed(MeshBase &mesh, TriangulatorInterface &triangulator)
void testPoly2TriHoleTangentPerturbed()
void testPoly2TriHolesInteriorRefinedBase(dof_id_type n_original_elem, Real desired_area)
void testPoly2TriEdge3ToTri6()
CPPUNIT_TEST(testPoly2TriSegments)
CPPUNIT_TEST(testPoly2Tri)
void testTriangulatorHoleTangentPerturbed(MeshBase &mesh, TriangulatorInterface &triangulator)
CPPUNIT_TEST(testTriangleHoleContains)
CPPUNIT_TEST(testTriangle)
void commonSettings(TriangulatorInterface &triangulator)
CPPUNIT_TEST(testPoly2TriHolesRefined)
CPPUNIT_TEST(testPoly2TriEdgesRefined)
CPPUNIT_TEST(testTriangleHoleArea)
CPPUNIT_TEST(testPoly2TriMeshedHoles)
CPPUNIT_TEST(testHoleContainsRayDegeneracies)
CPPUNIT_TEST(testPoly2TriHolesNonUniformRefined)
CPPUNIT_TEST(testPoly2TriHoleTangentPerturbed)
CPPUNIT_TEST(testPoly2TriEdge3ToTri7CenterFixup)
CPPUNIT_TEST(testTriangleHoles)
CPPUNIT_TEST(testPoly2TriEdges)
CPPUNIT_TEST(testPoly2TriExtraRefined)
CPPUNIT_TEST(testPoly2TriHalfDomainEdge3)
CPPUNIT_TEST(testPoly2TriRoundHole)
void testPoly2TriBad1DMultiBoundary()
CPPUNIT_TEST(testPoly2TriInterp2)
void testTriangulatorMeshedHoles(MeshBase &mesh, TriangulatorInterface &triangulator)
CPPUNIT_TEST(testPoly2TriHalfDomain)
void testTriangleSegments()
void max(const T &r, T &o, Request &req) const
std::vector< BCTuple > build_side_list(BCTupleSortBy sort_by=BCTupleSortBy::ELEM_ID) const
virtual Node *& set_node(const unsigned int i)
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Base class for functors that can be evaluated at a point and (optionally) time.
A class to represent the internal "this should never happen" errors, to be thrown by "libmesh_error()...
This is the MeshBase class.
virtual const Node & node_ref(const dof_id_type i) const
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
virtual dof_id_type n_elem() const =0
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
Prepare a newly created (or read) mesh for use.
virtual dof_id_type n_nodes() const =0
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
Add a new Node at Point p to the end of the vertex array, with processor_id procid.
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
const Parallel::Communicator & comm() const
A Function generated (via FParser) by parsing a mathematical expression.
A Point defines a location in LIBMESH_DIM dimensional Real space.
A C++ interface between LibMesh and the poly2tri library, with custom code for Steiner point insertio...
virtual void set_refine_boundary_allowed(bool refine_bdy_allowed) override
Set whether or not the triangulation is allowed to refine the mesh boundary when refining the interio...
virtual void set_desired_area_function(FunctionBase< Real > *desired) override
Set a function giving desired triangle area as a function of position.
virtual void triangulate() override
Internally, this calls the poly2tri triangulation code in a loop, inserting our owner Steiner points ...
A C++ interface between LibMesh and the Triangle library written by J.R.
Another concrete instantiation of the hole, this one should be sufficiently general for most non-poly...
An abstract class for defining a 2-dimensional hole.
virtual bool refine_boundary_allowed() const
Get whether or not the triangulation is allowed to refine the mesh boundary when refining the interio...
Real area() const
Return the area of the hole.
virtual void set_refine_boundary_allowed(bool refine_bdy_allowed)
Set whether or not a triangulator is allowed to refine the hole boundary when refining the mesh inter...
Another concrete instantiation of the hole, as general as ArbitraryHole, but based on an existing 1D ...
A concrete instantiation of the Hole class that describes polygonal (triangular, square,...
virtual Point point(const unsigned int n) const override
Return the nth point defining the hole.
virtual unsigned int n_points() const override
The number of geometric points which define the hole.
void set_outer_boundary_ids(std::set< std::size_t > bdy_ids)
A set of ids to allow on the outer boundary loop: interpreted as boundary ids of 2D elements and/or s...
Real & minimum_angle()
Sets and/or gets the minimum desired angle.
TriangulationType & triangulation_type()
Sets and/or gets the desired triangulation type.
virtual void triangulate()=0
This is the main public interface for this function.
@ PSLG
Triangulate the interior of a Planar Straight Line Graph, which is defined implicitly by the order of...
bool & smooth_after_generating()
Sets/gets flag which tells whether to do two steps of Laplace mesh smoothing after generating the gri...
void set_verify_hole_boundaries(bool v)
Verifying that hole boundaries don't cross the outer boundary or each other is something like O(N_bdy...
std::vector< std::pair< unsigned int, unsigned int > > segments
When constructing a PSLG, if the node numbers do not define the desired boundary segments implicitly ...
void attach_hole_list(const std::vector< Hole * > *holes)
Attaches a vector of Hole* pointers which will be meshed around.
Real & desired_area()
Sets and/or gets the desired triangle area.
ElemType & elem_type()
Sets and/or gets the desired element type.
void set_fixup_tri7_center_nodes(bool v)
For TRI7 elements, after boundary mid-edge nodes have been snapped to a curved boundary in increase_t...
void set_interpolate_boundary_points(int n_points)
Complicated setter, for compatibility with insert_extra_points()
bool absolute_fuzzy_equals(const TypeVector< T > &rhs, Real tol=TOLERANCE) const
bool relative_fuzzy_equals(const TypeVector< T > &rhs, Real tol=TOLERANCE) const
The UnstructuredMesh class is derived from the MeshBase class.
Communicator * TestCommWorld
CPPUNIT_TEST_SUITE_REGISTRATION(MeshTriangulationTest)
The libMesh namespace provides an interface to certain functionality in the library.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
ElemType
Defines an enum for geometric element types.
static constexpr Real TOLERANCE
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...