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> 32 CPPUNIT_TEST( testTriangleHoleArea );
33 CPPUNIT_TEST( testTriangleHoleContains );
35 #ifdef LIBMESH_HAVE_POLY2TRI 36 CPPUNIT_TEST( testPoly2Tri );
37 CPPUNIT_TEST( testPoly2TriHalfDomain );
38 CPPUNIT_TEST( testPoly2TriHalfDomainEdge3 );
39 CPPUNIT_TEST( testPoly2TriInterp );
40 CPPUNIT_TEST( testPoly2TriInterp2 );
41 CPPUNIT_TEST( testPoly2TriHoles );
42 CPPUNIT_TEST( testPoly2TriMeshedHoles );
43 CPPUNIT_TEST( testPoly2TriEdge3ToTri6 );
44 # ifdef LIBMESH_ENABLE_AMR 45 CPPUNIT_TEST( testPoly2TriRoundHole );
47 CPPUNIT_TEST( testPoly2TriEdges );
48 CPPUNIT_TEST( testPoly2TriEdge3s );
49 CPPUNIT_TEST( testPoly2TriBadEdges );
50 CPPUNIT_TEST( testPoly2TriBad1DMultiBoundary );
51 CPPUNIT_TEST( testPoly2TriBad2DMultiBoundary );
52 CPPUNIT_TEST( testPoly2TriEdgesRefined );
53 CPPUNIT_TEST( testPoly2TriSegments );
54 CPPUNIT_TEST( testPoly2TriRefined );
55 CPPUNIT_TEST( testPoly2TriNonRefined );
56 CPPUNIT_TEST( testPoly2TriExtraRefined );
57 CPPUNIT_TEST( testPoly2TriHolesRefined );
58 CPPUNIT_TEST( testPoly2TriHolesInterpRefined );
59 CPPUNIT_TEST( testPoly2TriHolesInteriorRefined );
60 CPPUNIT_TEST( testPoly2TriHolesInteriorExtraRefined );
62 CPPUNIT_TEST( testPoly2TriHolesExtraRefined );
64 CPPUNIT_TEST( testPoly2TriNonUniformRefined );
65 CPPUNIT_TEST( testPoly2TriHolesNonUniformRefined );
68 #ifdef LIBMESH_HAVE_TRIANGLE 69 CPPUNIT_TEST( testTriangle );
70 CPPUNIT_TEST( testTriangleHalfDomain );
71 CPPUNIT_TEST( testTriangleInterp );
72 CPPUNIT_TEST( testTriangleInterp2 );
73 CPPUNIT_TEST( testTriangleHoles );
74 CPPUNIT_TEST( testTriangleMeshedHoles );
75 # ifdef LIBMESH_ENABLE_AMR 76 CPPUNIT_TEST( testTriangleRoundHole );
78 CPPUNIT_TEST( testTriangleEdges );
79 CPPUNIT_TEST( testTriangleSegments );
80 CPPUNIT_TEST( testTriangleEdge3ToTri6 );
83 CPPUNIT_TEST_SUITE_END();
108 #ifdef LIBMESH_ENABLE_EXCEPTIONS 112 bool threw_desired_exception =
false;
114 this->testTriangulatorBase(
mesh, triangulator);
117 std::regex msg_regex(re);
118 CPPUNIT_ASSERT(std::regex_search(e.what(), msg_regex));
119 threw_desired_exception =
true;
121 catch (CppUnit::Exception & e) {
125 CPPUNIT_ASSERT_MESSAGE(
"Unexpected exception type thrown",
false);
127 CPPUNIT_ASSERT(threw_desired_exception);
139 std::vector<TriangulatorInterface::PolygonHole> polyholes;
142 polyholes.emplace_back(center,
radius, 2);
144 polyholes.emplace_back(center,
radius, 3);
146 polyholes.emplace_back(center,
radius, 4);
148 polyholes.emplace_back(center,
radius, 5);
150 polyholes.emplace_back(center,
radius, 6);
152 for (
int i=0; i != 5; ++i)
154 const int n_sides = i+2;
157 const Real computed_area = hole.
area();
158 const Real theta =
pi/n_sides;
159 const Real half_side_length =
radius*std::cos(theta);
161 const Real area = n_sides * apothem * half_side_length;
169 #ifdef LIBMESH_HAVE_TRIANGLE 171 TriangleInterface::PolygonHole square(center,
radius, 4);
184 std::vector<TriangulatorInterface::PolygonHole> polyholes;
186 auto check_corners = [center,
radius]
190 CPPUNIT_ASSERT_EQUAL(np, hole.n_points());
194 const Real xin = center(0) +
radius * .99 * std::cos(theta);
195 const Real xout = center(0) +
radius * 1.01 * std::cos(theta);
196 const Real yin = center(1) +
radius * .99 * std::sin(theta);
197 const Real yout = center(1) +
radius * 1.01 * std::sin(theta);
199 CPPUNIT_ASSERT(hole.contains(
Point(xin, yin)));
200 CPPUNIT_ASSERT(!hole.contains(
Point(xout, yout)));
205 check_corners(triangle, 3);
207 check_corners(diamond, 4);
209 check_corners(hexagon, 6);
212 {{1,0}, {{0,-1},{2,-1},{2,1},{1.75,-.5},{1.5,1},{1.25,-.5},
213 {1,1},{.75,-.5},{.5,1},{.25,-.5},{0,1}}};
215 CPPUNIT_ASSERT(jaggy.contains({.1,-.3}));
216 CPPUNIT_ASSERT(jaggy.contains({.5,.9}));
217 CPPUNIT_ASSERT(jaggy.contains({.9,-.3}));
218 CPPUNIT_ASSERT(jaggy.contains({1,0}));
219 CPPUNIT_ASSERT(jaggy.contains({1.1,-.4}));
220 CPPUNIT_ASSERT(jaggy.contains({1.5,.9}));
221 CPPUNIT_ASSERT(jaggy.contains({1.9,-.3}));
223 CPPUNIT_ASSERT(jaggy.contains({1.9,-.5}));
224 CPPUNIT_ASSERT(jaggy.contains({1.6,-.5}));
225 CPPUNIT_ASSERT(jaggy.contains({1.1,-.5}));
226 CPPUNIT_ASSERT(jaggy.contains({.5,-.5}));
227 CPPUNIT_ASSERT(jaggy.contains({.2,-.5}));
229 CPPUNIT_ASSERT(!jaggy.contains({.1,.7}));
230 CPPUNIT_ASSERT(!jaggy.contains({.5,1.1}));
231 CPPUNIT_ASSERT(!jaggy.contains({.9,.7}));
232 CPPUNIT_ASSERT(!jaggy.contains({1,-1.1}));
233 CPPUNIT_ASSERT(!jaggy.contains({1.1,.8}));
234 CPPUNIT_ASSERT(!jaggy.contains({1.5,1.1}));
235 CPPUNIT_ASSERT(!jaggy.contains({1.9,.9}));
237 CPPUNIT_ASSERT(!jaggy.contains({1.9,1}));
238 CPPUNIT_ASSERT(!jaggy.contains({1.4,1}));
239 CPPUNIT_ASSERT(!jaggy.contains({.9,1}));
240 CPPUNIT_ASSERT(!jaggy.contains({.4,1}));
241 CPPUNIT_ASSERT(!jaggy.contains({-.2,1}));
242 CPPUNIT_ASSERT(!jaggy.contains({-.2,0}));
243 CPPUNIT_ASSERT(!jaggy.contains({1.2,0}));
246 {{1,0}, {{-.25,-1},{2,-1},{2,1},{1.75,1},{1.75,-.5},{1.5,-.5},
247 {1.5,1},{1.25,1},{1.25,-.5},{1,-.5},{1,1},{.75,1},
248 {.75,-.5},{.5,-.5},{.5,1},{.25,1},{.25,-.5},{0,-.5},
251 CPPUNIT_ASSERT(square_jaggy.contains({-.1,-.3}));
252 CPPUNIT_ASSERT(square_jaggy.contains({.4,.9}));
253 CPPUNIT_ASSERT(square_jaggy.contains({.9,-.3}));
254 CPPUNIT_ASSERT(square_jaggy.contains({.9,0}));
255 CPPUNIT_ASSERT(square_jaggy.contains({1.1,-.6}));
256 CPPUNIT_ASSERT(square_jaggy.contains({1.4,.9}));
257 CPPUNIT_ASSERT(square_jaggy.contains({1.9,-.3}));
259 CPPUNIT_ASSERT(!square_jaggy.contains({.1,-.3}));
260 CPPUNIT_ASSERT(!square_jaggy.contains({.6,.9}));
261 CPPUNIT_ASSERT(!square_jaggy.contains({1.1,-.3}));
262 CPPUNIT_ASSERT(!square_jaggy.contains({1.1,0}));
263 CPPUNIT_ASSERT(!square_jaggy.contains({1.1,-1.6}));
264 CPPUNIT_ASSERT(!square_jaggy.contains({1.6,.9}));
265 CPPUNIT_ASSERT(!square_jaggy.contains({2.1,-.3}));
267 CPPUNIT_ASSERT(square_jaggy.contains({-.1,-.5}));
268 CPPUNIT_ASSERT(square_jaggy.contains({.3,-.5}));
269 CPPUNIT_ASSERT(square_jaggy.contains({.9,-.5}));
270 CPPUNIT_ASSERT(square_jaggy.contains({1.3,-.5}));
271 CPPUNIT_ASSERT(square_jaggy.contains({1.9,-.5}));
273 CPPUNIT_ASSERT(!square_jaggy.contains({-.3,1}));
274 CPPUNIT_ASSERT(!square_jaggy.contains({.2,1}));
275 CPPUNIT_ASSERT(!square_jaggy.contains({.6,1}));
276 CPPUNIT_ASSERT(!square_jaggy.contains({1.1,1}));
277 CPPUNIT_ASSERT(!square_jaggy.contains({1.6,1}));
278 CPPUNIT_ASSERT(!square_jaggy.contains({2.1,1}));
285 commonSettings(triangulator);
290 for (
const auto & elem :
mesh.element_ptr_range())
292 CPPUNIT_ASSERT_EQUAL(elem->type(),
TRI3);
296 (elem->point(1) - elem->point(0)).cross
297 (elem->point(2) - elem->point(0));
299 CPPUNIT_ASSERT_GREATER(
Real(0), cross_prod(2));
301 bool found_triangle =
false;
302 for (
const auto & node : elem->node_ref_range())
304 const Point & point = node;
305 if (point ==
Point(0,0))
307 found_triangle =
true;
308 CPPUNIT_ASSERT((elem->point(0) ==
Point(0,0) &&
309 elem->point(1) ==
Point(1,0) &&
310 elem->point(2) ==
Point(0,1)) ||
311 (elem->point(1) ==
Point(0,0) &&
312 elem->point(2) ==
Point(1,0) &&
313 elem->point(0) ==
Point(0,1)) ||
314 (elem->point(2) ==
Point(0,0) &&
315 elem->point(0) ==
Point(1,0) &&
316 elem->point(1) ==
Point(0,1)));
318 if (point ==
Point(1,2))
320 found_triangle =
true;
321 CPPUNIT_ASSERT((elem->point(0) ==
Point(0,1) &&
322 elem->point(1) ==
Point(1,0) &&
323 elem->point(2) ==
Point(1,2)) ||
324 (elem->point(1) ==
Point(0,1) &&
325 elem->point(2) ==
Point(1,0) &&
326 elem->point(0) ==
Point(1,2)) ||
327 (elem->point(2) ==
Point(0,1) &&
328 elem->point(0) ==
Point(1,0) &&
329 elem->point(1) ==
Point(1,2)));
332 CPPUNIT_ASSERT(found_triangle);
339 commonSettings(triangulator);
343 const Real hsq2 = std::sqrt(2) / 2.0;
347 for (
const auto & elem :
mesh.element_ptr_range())
350 CPPUNIT_ASSERT_EQUAL(elem->type(),
TRI6);
352 for (
const auto & i_side :
make_range(elem->n_sides()))
355 if (elem->neighbor_ptr(i_side) ==
nullptr)
357 const Point & side_pt_0 = *(elem->node_ptr(i_side));
358 const Point & side_pt_1 = *(elem->node_ptr((i_side + 1) % 3));
359 const Point & side_pt_2 = *(elem->node_ptr(i_side + 3));
360 const bool x_sign = (side_pt_0(0) == 1 || side_pt_1(0) == 1);
361 const bool y_sign = (side_pt_0(1) == 1 || side_pt_1(1) == 1);
362 const Point ref_side_pt_2 =
Point (x_sign ? hsq2 : -hsq2, y_sign ? hsq2 : -hsq2);
363 CPPUNIT_ASSERT_EQUAL(ref_side_pt_2, side_pt_2);
381 this->testTriangulatorBase(
mesh, triangulator);
400 int interpolate_boundary_points,
402 Real expected_total_area = 1.5,
403 Real desired_area = 1000)
405 commonSettings(triangulator);
408 testTriangulatorTrapMesh(
mesh);
419 CPPUNIT_ASSERT_EQUAL(
mesh.
n_elem(), n_expected_elem);
422 for (
const auto & elem :
mesh.active_local_element_ptr_range())
424 CPPUNIT_ASSERT_EQUAL(elem->level(), 0u);
425 CPPUNIT_ASSERT_EQUAL(elem->type(),
TRI3);
427 area += elem->volume();
437 const std::vector<Point> & expected_centers)
439 std::vector<bool> found_centers(expected_centers.size(),
false);
441 for (
const auto & elem :
mesh.element_ptr_range())
443 CPPUNIT_ASSERT_EQUAL(elem->type(),
TRI3);
447 (elem->point(1) - elem->point(0)).cross
448 (elem->point(2) - elem->point(0));
450 CPPUNIT_ASSERT_GREATER(
Real(0), cross_prod(2));
453 Point center = elem->vertex_average();
455 bool found_mine =
false;
458 Point possible = expected_centers[i];
463 found_centers[i] =
true;
466 CPPUNIT_ASSERT(found_mine);
471 for (
auto found_it : found_centers)
472 CPPUNIT_ASSERT(found_it);
486 commonSettings(triangulator);
490 const std::vector<TriangulatorInterface::Hole*> holes { &diamond };
498 Real r2p2o6 = (std::sqrt(2_R)+2)/6;
499 Real r2p4o6 = (std::sqrt(2_R)+4)/6;
501 std::vector <Point> expected_centers
502 { {r2p2o6,r2p2o6}, {r2p2o6,-r2p2o6},
503 {-r2p2o6,r2p2o6}, {-r2p2o6,-r2p2o6},
504 {0,r2p4o6}, {r2p4o6, 0},
505 {0,-r2p4o6}, {-r2p4o6, 0}
508 testFoundCenters(
mesh, expected_centers);
522 commonSettings(triangulator);
530 CPPUNIT_ASSERT_EQUAL(centerhole.n_points(), 8u);
531 CPPUNIT_ASSERT_EQUAL(centerhole.area(),
Real(1));
532 Point inside = centerhole.inside();
533 CPPUNIT_ASSERT_EQUAL(inside(0),
Real(20));
534 CPPUNIT_ASSERT_EQUAL(inside(1),
Real(20));
536 const std::vector<TriangulatorInterface::Hole*> holes { ¢erhole };
544 std::vector <Point> expected_centers
545 { {-0.5,
Real(2)/3}, {0,
Real(5)/6},
549 {-0.5, -
Real(2)/3}, {0, -
Real(5)/6},
551 {-
Real(2)/3, -0.5}, {-
Real(5)/6, 0},
555 for (
auto & p : expected_centers)
558 testFoundCenters(
mesh, expected_centers);
562 #ifdef LIBMESH_ENABLE_AMR 572 commonSettings(triangulator);
576 const Point center{20,20};
584 CPPUNIT_ASSERT_EQUAL(centerhole.n_points(), 8u);
585 Point inside = centerhole.inside();
586 CPPUNIT_ASSERT_EQUAL(inside(0),
Real(20));
587 CPPUNIT_ASSERT_EQUAL(inside(1),
Real(20));
589 const std::vector<TriangulatorInterface::Hole*> holes { ¢erhole };
601 std::map<std::pair<Real, Real>,
Point> outer_midpoints
602 {{{19, 19}, {20, 19}},
603 {{21, 19}, {21, 20}},
604 {{21, 21}, {20, 21}},
608 for (
const auto & elem :
mesh.active_local_element_ptr_range())
609 for (
const auto n :
make_range(elem->n_sides()))
611 if (elem->neighbor_ptr(n))
615 outer_midpoints.find(std::make_pair(elem->point(n)(0),
617 if (it != outer_midpoints.end())
619 const Point error = it->second - elem->point(n+3);
625 const Point radius1 = elem->point(n) - center;
629 const Point radius2 = elem->point((n+1)%3) - center;
633 const Point radius3 = elem->point(n+3) - center;
639 #endif // LIBMESH_ENABLE_AMR 652 triangulator.
segments = {{0,2},{2,1},{1,3},{3,0}};
654 this->testTriangulatorBase(
mesh, triangulator);
669 edge13->set_node(1, node3);
672 edge02->set_node(1, node2);
675 edge30->set_node(1, node0);
678 edge21->set_node(1, node1);
681 if (elem_type ==
EDGE3)
684 edge13->set_node(2, node4);
686 edge02->set_node(2, node5);
688 edge30->set_node(2, node6);
690 edge21->set_node(2, node7);
700 const Real hsq2 = std::sqrt(2) / 2.0;
712 edge021->set_node(1, node2);
713 edge021->set_node(2, node1);
716 edge243->set_node(1, node4);
717 edge243->set_node(2, node3);
720 edge465->set_node(1, node6);
721 edge465->set_node(2, node5);
724 edge607->set_node(1, node0);
725 edge607->set_node(2, node7);
748 edge45->set_node(1, node5);
749 edge45->subdomain_id() = 1;
752 edge56->set_node(1, node6);
753 edge56->subdomain_id() = 1;
756 edge67->set_node(1, node7);
757 edge67->subdomain_id() = 1;
760 edge78->set_node(1, node8);
761 edge78->subdomain_id() = 1;
764 edge84->set_node(1, node4);
765 edge84->subdomain_id() = 1;
767 if (elem_type ==
EDGE3)
770 edge45->set_node(2, node9);
772 edge56->set_node(2, node10);
774 edge67->set_node(2, node11);
776 edge78->set_node(2, node12);
778 edge84->set_node(2, node13);
783 testEdgesMesh(
mesh, elem_type);
785 std::set<std::size_t> bdy_ids {0};
788 this->testTriangulatorBase(
mesh, triangulator);
792 #ifdef LIBMESH_HAVE_TRIANGLE 799 testTriangulator(
mesh, triangle);
819 testTriangulatorInterp(
mesh, triangle, 1, 6);
829 testTriangulatorInterp(
mesh, triangle, 2, 10);
839 testTriangulatorHoles(
mesh, triangle);
849 testTriangulatorMeshedHoles(
mesh, triangle);
853 #ifdef LIBMESH_ENABLE_AMR 860 testTriangulatorRoundHole(
mesh, triangle);
862 #endif // LIBMESH_ENABLE_AMR 873 this->testTriangulatorBase(
mesh, triangulator);
882 testTriangulatorSegments(
mesh, triangle);
894 this->testEdge3ToTri6Base(
mesh, triangulator);
897 #endif // LIBMESH_HAVE_TRIANGLE 900 #ifdef LIBMESH_HAVE_POLY2TRI 907 testTriangulator(
mesh, p2t_tri);
937 testTriangulatorInterp(
mesh, p2t_tri, 1, 6);
947 testTriangulatorInterp(
mesh, p2t_tri, 2, 10);
957 testTriangulatorHoles(
mesh, p2t_tri);
967 testTriangulatorMeshedHoles(
mesh, p2t_tri);
979 this->testEdge3ToTri6Base(
mesh, triangulator);
983 #ifdef LIBMESH_ENABLE_AMR 990 testTriangulatorRoundHole(
mesh, p2t_tri);
992 #endif // LIBMESH_ENABLE_AMR 1003 this->testTriangulatorBase(
mesh, triangulator);
1015 this->testTriangulatorBase(
mesh, triangulator);
1035 edge13->set_node(1, node3);
1038 edge02->set_node(1, node2);
1041 edge30->set_node(1, node0);
1045 testExceptionBase(
mesh, triangulator,
"Bad edge topology");
1067 edge01->set_node(1, node1);
1070 edge12->set_node(1, node2);
1073 edge20->set_node(1, node0);
1077 edge34->set_node(1, node4);
1080 edge45->set_node(1, node5);
1083 edge53->set_node(1, node3);
1087 testExceptionBase(
mesh, triangulator,
"multiple loops of Edge");
1108 tri012->set_node(1, node1);
1109 tri012->set_node(2, node2);
1112 tri345->set_node(1, node4);
1113 tri345->set_node(2, node5);
1117 testExceptionBase(
mesh, triangulator,
"cannot choose one");
1128 testPoly2TriRefinementBase(
mesh,
nullptr, 1.5, 14);
1138 testTriangulatorSegments(
mesh, p2t_tri);
1141 void testPoly2TriRefinementBase
1143 const std::vector<TriangulatorInterface::Hole*> * holes,
1144 Real expected_total_area,
1146 Real desired_area = 0.1,
1151 commonSettings(triangulator);
1163 if (desired_area || area_func)
1164 CPPUNIT_ASSERT_GREATER(n_original_elem,
mesh.
n_elem());
1166 CPPUNIT_ASSERT_EQUAL(
mesh.
n_elem(), n_original_elem);
1169 for (
const auto & elem :
mesh.active_local_element_ptr_range())
1171 CPPUNIT_ASSERT_EQUAL(elem->level(), 0u);
1172 CPPUNIT_ASSERT_EQUAL(elem->type(),
TRI3);
1174 const Real my_area = elem->volume();
1177 if (desired_area != 0)
1178 CPPUNIT_ASSERT_LESSEQUAL(desired_area, my_area);
1180 if (area_func !=
nullptr)
1181 for (
auto v :
make_range(elem->n_vertices()))
1183 const Real local_desired_area =
1184 (*area_func)(elem->point(v));
1185 CPPUNIT_ASSERT_LESSEQUAL(local_desired_area, my_area);
1201 testTriangulatorTrapMesh(
mesh);
1202 testPoly2TriRefinementBase(
mesh,
nullptr, 1.5, 15);
1210 testTriangulatorTrapMesh(
mesh);
1212 testPoly2TriRefinementBase(
mesh,
nullptr, 1.5, 2, 0);
1221 testTriangulatorTrapMesh(
mesh);
1222 testPoly2TriRefinementBase(
mesh,
nullptr, 1.5, 150, 0.01);
1227 #ifdef LIBMESH_HAVE_FPARSER 1230 testTriangulatorTrapMesh(
mesh);
1231 testPoly2TriRefinementBase(
mesh,
nullptr, 1.5, 150, 0, &var_area);
1232 #endif // LIBMESH_HAVE_FPARSER 1241 const std::vector<TriangulatorInterface::Hole*> holes { &diamond };
1244 testTriangulatorTrapMesh(
mesh);
1245 testPoly2TriRefinementBase(
mesh, &holes, 1.25, 13);
1253 testTriangulatorTrapMesh(
mesh);
1256 Real total_area = 1.5;
1266 std::vector<TriangulatorInterface::AffineHole> hole_data;
1268 hole_data.reserve(M*N);
1269 std::vector<TriangulatorInterface::Hole*> holes;
1274 hole_data.emplace_back(diamond, 0, shift);
1275 holes.push_back(&hole_data.back());
1276 total_area -= hole_data.back().area();
1283 testTriangulatorInterp(
mesh, p2t_tri, 4, 0, total_area, 0.03_R);
1286 void testPoly2TriHolesInteriorRefinedBase
1297 const std::vector<TriangulatorInterface::Hole*> holes { &diamond };
1302 testTriangulatorTrapMesh(
mesh);
1303 testPoly2TriRefinementBase(
mesh, &holes, 1.25, n_original_elem, desired_area);
1309 int n_outer_sides = std::count_if(side_bcs.begin(), side_bcs.end(),
1310 [](
auto t){
return std::get<2>(t) == 0;});
1311 CPPUNIT_ASSERT_GREATER(4, n_outer_sides);
1312 int n_hole_sides = std::count_if(side_bcs.begin(), side_bcs.end(),
1313 [](
auto t){
return std::get<2>(t) == 1;});
1314 CPPUNIT_ASSERT_EQUAL(n_hole_sides, 4);
1321 testPoly2TriHolesInteriorRefinedBase(25, 0.05);
1329 testPoly2TriHolesInteriorRefinedBase(60, 0.02);
1337 const std::vector<TriangulatorInterface::Hole*> holes { &diamond };
1340 testTriangulatorTrapMesh(
mesh);
1341 testPoly2TriRefinementBase(
mesh, &holes, 1.25, 125, 0.01);
1346 #ifdef LIBMESH_HAVE_FPARSER 1349 const std::vector<TriangulatorInterface::Hole*> holes { &diamond };
1353 testTriangulatorTrapMesh(
mesh);
1354 testPoly2TriRefinementBase(
mesh, &holes, 1.25, 150, 0, &var_area);
1355 #endif // LIBMESH_HAVE_FPARSER 1359 #endif // LIBMESH_HAVE_POLY2TRI void testTriangleHoleArea()
void testPoly2TriEdge3s()
void testTriangulatorTrapMesh(UnstructuredMesh &mesh)
ElemType
Defines an enum for geometric element types.
virtual Node *& set_node(const unsigned int i)
void testPoly2TriHolesNonUniformRefined()
virtual void triangulate()=0
This is the main public interface for this function.
auto norm() const -> decltype(std::norm(T()))
void testTriangleInterp2()
void testPoly2TriHolesInteriorExtraRefined()
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...
void testPoly2TriHolesExtraRefined()
A Function generated (via FParser) by parsing a mathematical expression.
void testPoly2TriHolesInterpRefined()
void testPoly2TriEdge3ToTri6()
void testPoly2TriBad1DMultiBoundary()
libMesh::Parallel::Communicator * TestCommWorld
static constexpr Real TOLERANCE
An abstract class for defining a 2-dimensional hole.
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...
void testTriangleEdge3ToTri6()
void testTriangleInterp()
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
Prepare a newly ecreated (or read) mesh for use.
void testTriangulatorSegments(MeshBase &mesh, TriangulatorInterface &triangulator)
Real area() const
Return the area of the hole.
const Parallel::Communicator & comm() const
void set_interpolate_boundary_points(int n_points)
Complicated setter, for compatibility with insert_extra_points()
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...
The libMesh namespace provides an interface to certain functionality in the library.
ElemType & elem_type()
Sets and/or gets the desired element type.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
void testTriangulatorHoles(MeshBase &mesh, TriangulatorInterface &triangulator)
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.
void testPoly2TriEdgesRefined()
void testHalfDomain(MeshBase &mesh, TriangulatorInterface &triangulator, ElemType elem_type)
This is the MeshBase class.
void build_side_list(std::vector< dof_id_type > &element_id_list, std::vector< unsigned short int > &side_list, std::vector< boundary_id_type > &bc_id_list) const
Creates a list of element numbers, sides, and ids for those sides.
void testTriangleRoundHole()
TriangulationType & triangulation_type()
Sets and/or gets the desired triangulation type.
void testPoly2TriNonRefined()
void testPoly2TriHalfDomain()
void testPoly2TriInterp2()
void testEdge3ToTri6Base(MeshBase &mesh, TriangulatorInterface &triangulator)
void commonSettings(TriangulatorInterface &triangulator)
auto norm_sq() const -> decltype(std::norm(T()))
void testPoly2TriNonUniformRefined()
void attach_hole_list(const std::vector< Hole *> *holes)
Attaches a vector of Hole* pointers which will be meshed around.
virtual void set_desired_area_function(FunctionBase< Real > *desired) override
Set a function giving desired triangle area as a function of position.
The UnstructuredMesh class is derived from the MeshBase class.
void testPoly2TriExtraRefined()
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Real & minimum_angle()
Sets and/or gets the minimum desired angle.
void testPoly2TriSegments()
void testTriangleHalfDomain()
CPPUNIT_TEST_SUITE_REGISTRATION(MeshTriangulationTest)
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)
bool absolute_fuzzy_equals(const TypeVector< T > &rhs, Real tol=TOLERANCE) const
void testPoly2TriMeshedHoles()
void testTriangleHoleContains()
virtual bool refine_boundary_allowed() const
Get whether or not the triangulation is allowed to refine the mesh boundary when refining the interio...
virtual void triangulate() override
Internally, this calls the poly2tri triangulation code in a loop, inserting our owner Steiner points ...
Real & desired_area()
Sets and/or gets the desired triangle area.
Triangulate the interior of a Planar Straight Line Graph, which is defined implicitly by the order of...
void testPoly2TriRoundHole()
void testPoly2TriBad2DMultiBoundary()
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
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 testTriangulatorRoundHole(MeshBase &mesh, TriangulatorInterface &triangulator)
void max(const T &r, T &o, Request &req) const
A class to represent the internal "this should never happen" errors, to be thrown by "libmesh_error()...
Another concrete instantiation of the hole, as general as ArbitraryHole, but based on an existing 1D ...
void testPoly2TriHolesRefined()
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...
A concrete instantiation of the Hole class that describes polygonal (triangular, square, pentagonal, ...) holes.
void testTriangulatorBase(MeshBase &mesh, TriangulatorInterface &triangulator)
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...
void testPoly2TriBadEdges()
void testTriangulator(MeshBase &mesh, TriangulatorInterface &triangulator)
void testEdgesMesh(MeshBase &mesh, ElemType elem_type)
Another concrete instantiation of the hole, this one should be sufficiently general for most non-poly...
void testPoly2TriHalfDomainEdge3()
virtual const Node & node_ref(const dof_id_type i) const
A C++ interface between LibMesh and the poly2tri library, with custom code for Steiner point insertio...
void testTriangleSegments()
void testEdge3Mesh(MeshBase &mesh)
virtual dof_id_type n_elem() const =0
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
A C++ interface between LibMesh and the Triangle library written by J.R.
void testTriangulatorMeshedHoles(MeshBase &mesh, TriangulatorInterface &triangulator)
void testPoly2TriInterp()
A Point defines a location in LIBMESH_DIM dimensional Real space.
void testPoly2TriRefined()
void testPoly2TriHolesInteriorRefined()
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
void testTriangleMeshedHoles()
virtual dof_id_type n_nodes() const =0
void testExceptionBase(MeshBase &mesh, TriangulatorInterface &triangulator, const char *re)
bool & smooth_after_generating()
Sets/gets flag which tells whether to do two steps of Laplace mesh smoothing after generating the gri...
void testFoundCenters(const MeshBase &mesh, const std::vector< Point > &expected_centers)