libMesh
Loading...
Searching...
No Matches
Public Member Functions | List of all members
MeshTetTest Class Reference
Inheritance diagram for MeshTetTest:
[legend]

Public Member Functions

 LIBMESH_CPPUNIT_TEST_SUITE (MeshTetTest)
 The goal of this test is to verify proper operation of the interfaces to tetrahedralization libraries.
 
 CPPUNIT_TEST (testNetGen)
 
 CPPUNIT_TEST (testNetGenError)
 
 CPPUNIT_TEST (testNetGenTets)
 
 CPPUNIT_TEST (testNetGenFlippedTris)
 
 CPPUNIT_TEST (testNetGenNonOriented)
 
 CPPUNIT_TEST (testNetGenHole)
 
 CPPUNIT_TEST (testNetGenQuadratic)
 
 CPPUNIT_TEST (testNetGenQuadraticCurved)
 
 CPPUNIT_TEST (testNetGenTet14)
 
 CPPUNIT_TEST (testNetGenTet14Curved)
 
 CPPUNIT_TEST (testNetGenSphereShell)
 
 CPPUNIT_TEST_SUITE_END ()
 
void setUp ()
 
void tearDown ()
 
void testExceptionBase (const char *re, MeshBase &mesh, MeshTetInterface &tetinterface, dof_id_type expected_n_elem=DofObject::invalid_id, dof_id_type expected_n_nodes=DofObject::invalid_id, Real expected_volume=0)
 
void testTetInterfaceBase (MeshBase &mesh, MeshTetInterface &triangulator, dof_id_type expected_n_elem=DofObject::invalid_id, dof_id_type expected_n_nodes=DofObject::invalid_id, Real expected_volume=0)
 
void testBcids (UnstructuredMesh &mesh)
 
void testHole (UnstructuredMesh &mesh, MeshTetInterface &triangulator)
 
void testSphereShell (UnstructuredMesh &mesh, MeshTetInterface &triangulator)
 
void testTrisToTets (UnstructuredMesh &mesh, MeshTetInterface &triangulator, bool flip_tris=false, bool flip_some_tris=false)
 
void testTrisToTetsError (UnstructuredMesh &mesh, MeshTetInterface &triangulator, bool flip_tris=false)
 
void testTetsToTets (MeshBase &mesh, MeshTetInterface &triangulator)
 
void testTetGen ()
 
void testTetGenError ()
 
void testNetGen ()
 
void testNetGenError ()
 
void testNetGenTets ()
 
void testNetGenFlippedTris ()
 
void testNetGenNonOriented ()
 
void testNetGenHole ()
 
void testNetGenQuadratic ()
 
void testNetGenTet14 ()
 
void testNetGenQuadraticCurved ()
 
void testNetGenTet14Curved ()
 
void testNetGenSphereShell ()
 

Detailed Description

Definition at line 40 of file mesh_tet_test.C.

Member Function Documentation

◆ CPPUNIT_TEST() [1/11]

MeshTetTest::CPPUNIT_TEST ( testNetGen  )

◆ CPPUNIT_TEST() [2/11]

MeshTetTest::CPPUNIT_TEST ( testNetGenError  )

◆ CPPUNIT_TEST() [3/11]

MeshTetTest::CPPUNIT_TEST ( testNetGenFlippedTris  )

◆ CPPUNIT_TEST() [4/11]

MeshTetTest::CPPUNIT_TEST ( testNetGenHole  )

◆ CPPUNIT_TEST() [5/11]

MeshTetTest::CPPUNIT_TEST ( testNetGenNonOriented  )

◆ CPPUNIT_TEST() [6/11]

MeshTetTest::CPPUNIT_TEST ( testNetGenQuadratic  )

◆ CPPUNIT_TEST() [7/11]

MeshTetTest::CPPUNIT_TEST ( testNetGenQuadraticCurved  )

◆ CPPUNIT_TEST() [8/11]

MeshTetTest::CPPUNIT_TEST ( testNetGenSphereShell  )

◆ CPPUNIT_TEST() [9/11]

MeshTetTest::CPPUNIT_TEST ( testNetGenTet14  )

◆ CPPUNIT_TEST() [10/11]

MeshTetTest::CPPUNIT_TEST ( testNetGenTet14Curved  )

◆ CPPUNIT_TEST() [11/11]

MeshTetTest::CPPUNIT_TEST ( testNetGenTets  )

◆ CPPUNIT_TEST_SUITE_END()

MeshTetTest::CPPUNIT_TEST_SUITE_END ( )

◆ LIBMESH_CPPUNIT_TEST_SUITE()

MeshTetTest::LIBMESH_CPPUNIT_TEST_SUITE ( MeshTetTest  )

The goal of this test is to verify proper operation of the interfaces to tetrahedralization libraries.

◆ setUp()

void MeshTetTest::setUp ( )
inline

Definition at line 90 of file mesh_tet_test.C.

90{}

◆ tearDown()

void MeshTetTest::tearDown ( )
inline

Definition at line 92 of file mesh_tet_test.C.

92{}

◆ testBcids()

void MeshTetTest::testBcids ( UnstructuredMesh mesh)
inline

Definition at line 155 of file mesh_tet_test.C.

156 {
158 for (const auto & elem : mesh.element_ptr_range())
159 {
160 for (auto s : elem->side_index_range())
161 {
162 auto neigh = elem->neighbor_ptr(s);
163
164 if (neigh)
165 {
166 CPPUNIT_ASSERT_EQUAL(bi.n_boundary_ids(elem, s), 0u);
167 continue;
168 }
169
170 CPPUNIT_ASSERT_EQUAL(bi.n_boundary_ids(elem, s), 1u);
171
172 auto side = elem->side_ptr(s);
173 auto normal = (side->point(1) - side->point(0)).cross
174 (side->point(2) - side->point(0));
175 // Outer faces, in these tests
176 if (normal * side->vertex_average() > 0)
177 CPPUNIT_ASSERT(bi.has_boundary_id(elem, s, 0));
178 // Inner faces, with one-hole tests
179 else
180 CPPUNIT_ASSERT(bi.has_boundary_id(elem, s, 1));
181 }
182 }
183 }
The BoundaryInfo class contains information relevant to boundary conditions including storing faces,...
std::size_t n_boundary_ids() const
bool has_boundary_id(const Node *const node, const boundary_id_type id) const
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition mesh_base.h:170
MeshBase & mesh

References libMesh::MeshBase::get_boundary_info(), libMesh::BoundaryInfo::has_boundary_id(), mesh, and libMesh::BoundaryInfo::n_boundary_ids().

Referenced by testNetGen(), testNetGenFlippedTris(), testNetGenHole(), testNetGenNonOriented(), testNetGenQuadratic(), testNetGenQuadraticCurved(), testNetGenSphereShell(), testNetGenTet14(), testNetGenTet14Curved(), and testNetGenTets().

◆ testExceptionBase()

void MeshTetTest::testExceptionBase ( const char *  re,
MeshBase mesh,
MeshTetInterface tetinterface,
dof_id_type  expected_n_elem = DofObject::invalid_id,
dof_id_type  expected_n_nodes = DofObject::invalid_id,
Real  expected_volume = 0 
)
inline

Definition at line 94 of file mesh_tet_test.C.

100 {
101#ifdef LIBMESH_ENABLE_EXCEPTIONS
102 // We can't just CPPUNIT_ASSERT_THROW, because we want to make
103 // sure we were thrown from the right place with the right error
104 // message!
105 bool threw_desired_exception = false;
106 try {
107 this->testTetInterfaceBase(mesh, tetinterface, expected_n_elem,
108 expected_n_nodes, expected_volume);
109 }
110 catch (libMesh::LogicError & e) {
111 std::regex msg_regex(re);
112 CPPUNIT_ASSERT(std::regex_search(e.what(), msg_regex));
113 threw_desired_exception = true;
114 }
115 catch (CppUnit::Exception & e) {
116 throw e;
117 }
118 catch (...) {
119 CPPUNIT_ASSERT_MESSAGE("Unexpected exception type thrown", false);
120 }
121 CPPUNIT_ASSERT(threw_desired_exception);
122#endif
123 }
void testTetInterfaceBase(MeshBase &mesh, MeshTetInterface &triangulator, dof_id_type expected_n_elem=DofObject::invalid_id, dof_id_type expected_n_nodes=DofObject::invalid_id, Real expected_volume=0)
A class to represent the internal "this should never happen" errors, to be thrown by "libmesh_error()...

References testTetInterfaceBase().

Referenced by testTrisToTetsError().

◆ testHole()

void MeshTetTest::testHole ( UnstructuredMesh mesh,
MeshTetInterface triangulator 
)
inline

Definition at line 186 of file mesh_tet_test.C.

188 {
189 std::unique_ptr<UnstructuredMesh> holemesh =
190 std::make_unique<Mesh>(*TestCommWorld);
191
193 -2, 2, -2, 2, -2, 2);
194
195 const Real hole_volume =
196 build_octahedron(*holemesh, false, -1, 1, -1, 1, -1, 1);
197
198 auto holes =
199 std::make_unique<std::vector<std::unique_ptr<UnstructuredMesh>>>();
200
201 holes->push_back(std::move(holemesh));
202
203 triangulator.attach_hole_list(std::move(holes));
204
205 const Real expected_volume =
206 MeshTools::volume(mesh) - hole_volume;
207 this->testTetInterfaceBase(mesh, triangulator, 32, 14,
208 expected_volume);
209 }
void attach_hole_list(std::unique_ptr< std::vector< std::unique_ptr< UnstructuredMesh > > > holes)
Attaches a vector of Mesh pointers defining holes which will be meshed around.
void build_cube(UnstructuredMesh &mesh, const unsigned int nx=0, const unsigned int ny=0, const unsigned int nz=0, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const Real zmin=0., const Real zmax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
Builds a (elements) cube.
Real volume(const MeshBase &mesh, unsigned int dim=libMesh::invalid_uint)
Find the total volume of a mesh (interpreting that as area for dim = 2, or total arc length for dim =...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

References libMesh::MeshTetInterface::attach_hole_list(), libMesh::MeshTools::Generation::build_cube(), mesh, libMesh::Real, TestCommWorld, testTetInterfaceBase(), and libMesh::MeshTools::volume().

Referenced by testNetGenHole().

◆ testNetGen()

void MeshTetTest::testNetGen ( )
inline

Definition at line 378 of file mesh_tet_test.C.

379 {
380 LOG_UNIT_TEST;
381
382 Mesh mesh(*TestCommWorld);
383 NetGenMeshInterface net_tet(mesh);
384
385 // This should give no output for our correctly-set-up inputs
386 net_tet.set_verbosity(50);
387
388 testTrisToTets(mesh, net_tet);
390 }
void testTrisToTets(UnstructuredMesh &mesh, MeshTetInterface &triangulator, bool flip_tris=false, bool flip_some_tris=false)
void testBcids(UnstructuredMesh &mesh)
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition mesh.h:51
Class NetGenMeshInterface provides an interface for tetrahedralization of meshes using the NetGen lib...

References mesh, libMesh::MeshTetInterface::set_verbosity(), testBcids(), TestCommWorld, and testTrisToTets().

◆ testNetGenError()

void MeshTetTest::testNetGenError ( )
inline

Definition at line 393 of file mesh_tet_test.C.

394 {
395 LOG_UNIT_TEST;
396
397 Mesh mesh(*TestCommWorld);
398 NetGenMeshInterface net_tet(mesh);
399 testTrisToTetsError(mesh, net_tet);
400 }
void testTrisToTetsError(UnstructuredMesh &mesh, MeshTetInterface &triangulator, bool flip_tris=false)

References mesh, TestCommWorld, and testTrisToTetsError().

◆ testNetGenFlippedTris()

void MeshTetTest::testNetGenFlippedTris ( )
inline

Definition at line 414 of file mesh_tet_test.C.

415 {
416 LOG_UNIT_TEST;
417
418 Mesh mesh(*TestCommWorld);
419 NetGenMeshInterface net_tet(mesh);
420 testTrisToTets(mesh, net_tet, true);
422 }

References mesh, testBcids(), TestCommWorld, and testTrisToTets().

◆ testNetGenHole()

void MeshTetTest::testNetGenHole ( )
inline

Definition at line 436 of file mesh_tet_test.C.

437 {
438 LOG_UNIT_TEST;
439
440 Mesh mesh(*TestCommWorld);
441 NetGenMeshInterface net_tet(mesh);
442 testHole(mesh, net_tet);
444 }
void testHole(UnstructuredMesh &mesh, MeshTetInterface &triangulator)

References mesh, testBcids(), TestCommWorld, and testHole().

◆ testNetGenNonOriented()

void MeshTetTest::testNetGenNonOriented ( )
inline

Definition at line 425 of file mesh_tet_test.C.

426 {
427 LOG_UNIT_TEST;
428
429 Mesh mesh(*TestCommWorld);
430 NetGenMeshInterface net_tet(mesh);
431 testTrisToTets(mesh, net_tet, true, true);
433 }

References mesh, testBcids(), TestCommWorld, and testTrisToTets().

◆ testNetGenQuadratic()

void MeshTetTest::testNetGenQuadratic ( )
inline

Definition at line 447 of file mesh_tet_test.C.

448 {
449 LOG_UNIT_TEST;
450
451 Mesh mesh(*TestCommWorld);
452 NetGenMeshInterface net_tet(mesh);
453 net_tet.elem_type() = TET10;
454
455 const Real expected_volume =
456 build_octahedron(mesh, false, -1, 1, -1, 1, -0.1, 0.1);
457
458 net_tet.triangulate();
459
460 LIBMESH_ASSERT_FP_EQUAL(MeshTools::volume(mesh),
461 expected_volume,
463
464 for (const auto & elem : mesh.element_ptr_range())
465 {
466 CPPUNIT_ASSERT_EQUAL(elem->type(), TET10);
467 CPPUNIT_ASSERT_EQUAL(elem->n_nodes(), 10u);
468 CPPUNIT_ASSERT(!elem->is_flipped());
469 }
470
471 // Boundary ids should survive the increase to second order
473 }
static constexpr Real TOLERANCE

References libMesh::MeshTetInterface::elem_type(), mesh, libMesh::Real, testBcids(), TestCommWorld, libMesh::TET10, libMesh::TOLERANCE, libMesh::NetGenMeshInterface::triangulate(), and libMesh::MeshTools::volume().

◆ testNetGenQuadraticCurved()

void MeshTetTest::testNetGenQuadraticCurved ( )
inline

Definition at line 505 of file mesh_tet_test.C.

506 {
507 LOG_UNIT_TEST;
508
509 Mesh mesh(*TestCommWorld);
510 NetGenMeshInterface net_tet(mesh);
511 net_tet.elem_type() = TET10;
512
513 // Build TRI3 octahedron then upconvert to TRI6 with geometric midpoints.
514 build_octahedron(mesh, false, -1, 1, -1, 1, -0.1, 0.1);
517
518 // Perturb every TRI6 midpoint outward to simulate a curved boundary.
519 // Key by sorted pair of corner positions (same scheme as record_and_strip).
520 const Real eps = 0.05;
521 std::map<std::pair<Point,Point>, Point> expected;
522
523 for (const auto & elem : mesh.element_ptr_range())
524 {
525 libmesh_assert_equal_to(elem->type(), TRI6);
526 for (auto e : make_range(3u))
527 {
528 const Point & pa = elem->point(e);
529 const Point & pb = elem->point((e+1)%3);
530 auto key = pa < pb ? std::make_pair(pa, pb)
531 : std::make_pair(pb, pa);
532 if (expected.count(key))
533 continue;
534
535 // Perturb midpoint radially outward via mutable Point & ref.
536 Point & mid = elem->point(e+3);
537 mid += eps * mid.unit();
538 expected[key] = mid;
539 }
540 }
541
542 net_tet.triangulate();
543
544 // For every boundary face of the resulting TET10 mesh, verify that edge
545 // midpoints match the perturbed positions — not geometric averages.
546 unsigned int n_checked = 0;
547 for (const auto & elem : mesh.element_ptr_range())
548 for (auto s : elem->side_index_range())
549 {
550 if (elem->neighbor_ptr(s)) continue;
551
552 auto side = elem->build_side_ptr(s); // TRI6, nodes into mesh
553 for (auto e : make_range(3u))
554 {
555 const Point & pa = side->point(e);
556 const Point & pb = side->point((e+1)%3);
557 auto key = pa < pb ? std::make_pair(pa, pb)
558 : std::make_pair(pb, pa);
559 auto it = expected.find(key);
560 if (it == expected.end())
561 continue;
562 const Point & exp = it->second;
563 const Point & got = side->point(e+3);
564 LIBMESH_ASSERT_FP_EQUAL(exp(0), got(0), TOLERANCE);
565 LIBMESH_ASSERT_FP_EQUAL(exp(1), got(1), TOLERANCE);
566 LIBMESH_ASSERT_FP_EQUAL(exp(2), got(2), TOLERANCE);
567 ++n_checked;
568 }
569 }
570
571 CPPUNIT_ASSERT_GREATER(0u, n_checked);
572
573 // Boundary ids should survive the increase to second order, even with
574 // perturbed (curved) boundary midpoints
576 }
void all_second_order(const bool full_ordered=true)
Calls the range-based version of this function with a range consisting of all elements in the mesh.
Definition mesh_base.C:1803
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.
Definition mesh_base.C:824
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
TypeVector< T > unit() const
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...
Definition int_range.h:176

References libMesh::MeshBase::all_second_order(), libMesh::MeshTetInterface::elem_type(), libMesh::make_range(), mesh, libMesh::MeshBase::prepare_for_use(), libMesh::Real, testBcids(), TestCommWorld, libMesh::TET10, libMesh::TOLERANCE, libMesh::TRI6, libMesh::NetGenMeshInterface::triangulate(), and libMesh::TypeVector< T >::unit().

◆ testNetGenSphereShell()

void MeshTetTest::testNetGenSphereShell ( )
inline

Definition at line 666 of file mesh_tet_test.C.

667 {
668 LOG_UNIT_TEST;
669
670 Mesh mesh(*TestCommWorld);
671 NetGenMeshInterface net_tet(mesh);
672 testSphereShell(mesh, net_tet);
674 }
void testSphereShell(UnstructuredMesh &mesh, MeshTetInterface &triangulator)

References mesh, testBcids(), TestCommWorld, and testSphereShell().

◆ testNetGenTet14()

void MeshTetTest::testNetGenTet14 ( )
inline

Definition at line 476 of file mesh_tet_test.C.

477 {
478 LOG_UNIT_TEST;
479
480 Mesh mesh(*TestCommWorld);
481 NetGenMeshInterface net_tet(mesh);
482 net_tet.elem_type() = TET14;
483
484 const Real expected_volume =
485 build_octahedron(mesh, false, -1, 1, -1, 1, -0.1, 0.1);
486
487 net_tet.triangulate();
488
489 LIBMESH_ASSERT_FP_EQUAL(MeshTools::volume(mesh),
490 expected_volume,
492
493 for (const auto & elem : mesh.element_ptr_range())
494 {
495 CPPUNIT_ASSERT_EQUAL(elem->type(), TET14);
496 CPPUNIT_ASSERT_EQUAL(elem->n_nodes(), 14u);
497 CPPUNIT_ASSERT(!elem->is_flipped());
498 }
499
500 // Boundary ids should survive the increase to complete order
502 }

References libMesh::MeshTetInterface::elem_type(), mesh, libMesh::Real, testBcids(), TestCommWorld, libMesh::TET14, libMesh::TOLERANCE, libMesh::NetGenMeshInterface::triangulate(), and libMesh::MeshTools::volume().

◆ testNetGenTet14Curved()

void MeshTetTest::testNetGenTet14Curved ( )
inline

Definition at line 579 of file mesh_tet_test.C.

580 {
581 LOG_UNIT_TEST;
582
583 Mesh mesh(*TestCommWorld);
584 NetGenMeshInterface net_tet(mesh);
585 net_tet.elem_type() = TET14;
586
587 // Build TRI3 octahedron then upconvert to TRI7 (edge mids + centroid).
588 build_octahedron(mesh, false, -1, 1, -1, 1, -0.1, 0.1);
591
592 const Real eps = 0.05;
593 std::map<std::pair<Point,Point>, Point> expected_mid;
594 std::map<std::array<Point,3>, Point> expected_cen;
595
596 for (const auto & elem : mesh.element_ptr_range())
597 {
598 libmesh_assert_equal_to(elem->type(), TRI7);
599 for (auto e : make_range(3u))
600 {
601 const Point & pa = elem->point(e);
602 const Point & pb = elem->point((e+1)%3);
603 auto key = pa < pb ? std::make_pair(pa, pb)
604 : std::make_pair(pb, pa);
605 if (!expected_mid.count(key))
606 {
607 Point & mid = elem->point(e+3);
608 mid += eps * mid.unit();
609 expected_mid[key] = mid;
610 }
611 }
612 // Perturb the face-centroid node (index 6) radially outward.
613 std::array<Point,3> corners =
614 {elem->point(0), elem->point(1), elem->point(2)};
615 std::sort(corners.begin(), corners.end());
616 Point & cen = elem->point(6);
617 cen += eps * cen.unit();
618 expected_cen[corners] = cen;
619 }
620
621 net_tet.triangulate();
622
623 unsigned int n_mid = 0, n_cen = 0;
624 for (const auto & elem : mesh.element_ptr_range())
625 for (auto s : elem->side_index_range())
626 {
627 if (elem->neighbor_ptr(s)) continue;
628 auto side = elem->build_side_ptr(s);
629 CPPUNIT_ASSERT_EQUAL(side->type(), TRI7);
630 for (auto e : make_range(3u))
631 {
632 const Point & pa = side->point(e);
633 const Point & pb = side->point((e+1)%3);
634 auto key = pa < pb ? std::make_pair(pa, pb)
635 : std::make_pair(pb, pa);
636 auto it = expected_mid.find(key);
637 if (it == expected_mid.end()) continue;
638 const Point & exp = it->second;
639 const Point & got = side->point(e+3);
640 LIBMESH_ASSERT_FP_EQUAL(exp(0), got(0), TOLERANCE);
641 LIBMESH_ASSERT_FP_EQUAL(exp(1), got(1), TOLERANCE);
642 LIBMESH_ASSERT_FP_EQUAL(exp(2), got(2), TOLERANCE);
643 ++n_mid;
644 }
645 std::array<Point,3> corners =
646 {side->point(0), side->point(1), side->point(2)};
647 std::sort(corners.begin(), corners.end());
648 auto it = expected_cen.find(corners);
649 if (it == expected_cen.end()) continue;
650 const Point & exp = it->second;
651 const Point & got = side->point(6);
652 LIBMESH_ASSERT_FP_EQUAL(exp(0), got(0), TOLERANCE);
653 LIBMESH_ASSERT_FP_EQUAL(exp(1), got(1), TOLERANCE);
654 LIBMESH_ASSERT_FP_EQUAL(exp(2), got(2), TOLERANCE);
655 ++n_cen;
656 }
657
658 CPPUNIT_ASSERT_GREATER(0u, n_mid);
659 CPPUNIT_ASSERT_GREATER(0u, n_cen);
660
662 }
virtual void all_complete_order()
Calls the range-based version of this function with a range consisting of all elements in the mesh.
Definition mesh_base.C:1808

References libMesh::MeshBase::all_complete_order(), libMesh::MeshTetInterface::elem_type(), libMesh::make_range(), mesh, libMesh::MeshBase::prepare_for_use(), libMesh::Real, testBcids(), TestCommWorld, libMesh::TET14, libMesh::TOLERANCE, libMesh::TRI7, libMesh::NetGenMeshInterface::triangulate(), and libMesh::TypeVector< T >::unit().

◆ testNetGenTets()

void MeshTetTest::testNetGenTets ( )
inline

Definition at line 403 of file mesh_tet_test.C.

404 {
405 LOG_UNIT_TEST;
406
407 Mesh mesh(*TestCommWorld);
408 NetGenMeshInterface net_tet(mesh);
409 testTetsToTets(mesh, net_tet);
411 }
void testTetsToTets(MeshBase &mesh, MeshTetInterface &triangulator)

References mesh, testBcids(), TestCommWorld, and testTetsToTets().

◆ testSphereShell()

void MeshTetTest::testSphereShell ( UnstructuredMesh mesh,
MeshTetInterface triangulator 
)
inline

Definition at line 213 of file mesh_tet_test.C.

215 {
216 std::unique_ptr<UnstructuredMesh> holemesh =
217 std::make_unique<Mesh>(*TestCommWorld);
218
219 MeshTools::Generation::build_sphere (*holemesh, 1, 2, TET4);
220
222
223 auto holes =
224 std::make_unique<std::vector<std::unique_ptr<UnstructuredMesh>>>();
225
226 holes->push_back(std::move(holemesh));
227
228 triangulator.attach_hole_list(std::move(holes));
229
230 // Netgen can't seem to triangulate this without inserting points,
231 // so let MeshNetgenInterface know that we're allowed to insert
232 // points
233 triangulator.desired_volume() = 1000;
234
235 this->testTetInterfaceBase(mesh, triangulator);
236 }
Real & desired_volume()
Sets and/or gets the desired tetrahedron volume.
void build_sphere(UnstructuredMesh &mesh, const Real radius=1, const unsigned int n_refinements=2, const ElemType type=INVALID_ELEM, const unsigned int n_smooth=2, const bool flat=true)
Fills mesh with a mesh discretizing a ball (||x||<= radius) or sphere (||x|| = radius) domain.

References libMesh::MeshTetInterface::attach_hole_list(), libMesh::MeshTools::Generation::build_sphere(), libMesh::MeshTetInterface::desired_volume(), mesh, TestCommWorld, testTetInterfaceBase(), and libMesh::TET4.

Referenced by testNetGenSphereShell().

◆ testTetGen()

void MeshTetTest::testTetGen ( )
inline

Definition at line 332 of file mesh_tet_test.C.

333 {
334 LOG_UNIT_TEST;
335
336 Mesh mesh(*TestCommWorld);
337 TetGenMeshInterface tet_tet(mesh);
338 testTrisToTets(mesh, tet_tet);
339 }
Class TetGenMeshInterface provides an interface for tetrahedralization of meshes using the TetGen lib...

References mesh, TestCommWorld, and testTrisToTets().

◆ testTetGenError()

void MeshTetTest::testTetGenError ( )
inline

Definition at line 342 of file mesh_tet_test.C.

343 {
344 LOG_UNIT_TEST;
345
346 Mesh mesh(*TestCommWorld);
347 TetGenMeshInterface tet_tet(mesh);
348 testTrisToTetsError(mesh, tet_tet);
349 }

References mesh, TestCommWorld, and testTrisToTetsError().

◆ testTetInterfaceBase()

void MeshTetTest::testTetInterfaceBase ( MeshBase mesh,
MeshTetInterface triangulator,
dof_id_type  expected_n_elem = DofObject::invalid_id,
dof_id_type  expected_n_nodes = DofObject::invalid_id,
Real  expected_volume = 0 
)
inline

Definition at line 126 of file mesh_tet_test.C.

131 {
132 triangulator.triangulate();
133
134 if (expected_n_elem != DofObject::invalid_id)
135 CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), expected_n_elem);
136
137 if (expected_n_nodes != DofObject::invalid_id)
138 CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(), expected_n_nodes);
139
140 if (expected_volume != 0)
141 LIBMESH_ASSERT_FP_EQUAL(MeshTools::volume(mesh),
142 expected_volume,
144
145 for (const auto & elem : mesh.element_ptr_range())
146 {
147 CPPUNIT_ASSERT_EQUAL(elem->type(), TET4);
148
149 // Make sure we're not getting any inverted elements
150 CPPUNIT_ASSERT(!elem->is_flipped());
151 }
152 }
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition dof_object.h:473
virtual dof_id_type n_elem() const =0
virtual dof_id_type n_nodes() const =0
virtual void triangulate()=0
This is the main public interface for this function.

References libMesh::DofObject::invalid_id, mesh, libMesh::MeshBase::n_elem(), libMesh::MeshBase::n_nodes(), libMesh::TET4, libMesh::TOLERANCE, libMesh::MeshTetInterface::triangulate(), and libMesh::MeshTools::volume().

Referenced by testExceptionBase(), testHole(), testSphereShell(), testTetsToTets(), and testTrisToTets().

◆ testTetsToTets()

void MeshTetTest::testTetsToTets ( MeshBase mesh,
MeshTetInterface triangulator 
)
inline

Definition at line 295 of file mesh_tet_test.C.

297 {
298 // An asymmetric octahedron, so we hopefully have an unambiguous
299 // choice of shortest diagonal for a Delaunay algorithm to pick.
300 mesh.add_point(Point(0,0,-0.1), 0);
301 mesh.add_point(Point(1,0,0), 1);
302 mesh.add_point(Point(0,1,0), 2);
303 mesh.add_point(Point(-1,0,0), 3);
304 mesh.add_point(Point(0,-1,0), 4);
305 mesh.add_point(Point(0,0,0.1), 5);
306
307 auto add_tet = [&mesh](std::array<dof_id_type,4> nodes)
308 {
309 auto elem = mesh.add_elem(Elem::build(TET4));
310 elem->set_node(0, mesh.node_ptr(nodes[0]));
311 elem->set_node(1, mesh.node_ptr(nodes[1]));
312 elem->set_node(2, mesh.node_ptr(nodes[2]));
313 elem->set_node(3, mesh.node_ptr(nodes[3]));
314 };
315
316 // Split along a different diagonal to start
317 add_tet({1,3,4,5});
318 add_tet({1,3,5,2});
319 add_tet({1,3,2,0});
320 add_tet({1,3,0,4});
321
323
324 const Real expected_volume = MeshTools::volume(mesh);
325
326 this->testTetInterfaceBase(mesh, triangulator, /* n_elem = */ 4,
327 /* n_nodes = */ 6, expected_volume);
328 }
virtual Node *& set_node(const unsigned int i)
Definition elem.h:2567
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition elem.C:442
virtual const Node * node_ptr(const dof_id_type i) 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.

References libMesh::MeshBase::add_elem(), libMesh::MeshBase::add_point(), libMesh::Elem::build(), mesh, libMesh::MeshBase::node_ptr(), libMesh::MeshBase::prepare_for_use(), libMesh::Real, libMesh::Elem::set_node(), testTetInterfaceBase(), libMesh::TET4, and libMesh::MeshTools::volume().

Referenced by testNetGenTets().

◆ testTrisToTets()

void MeshTetTest::testTrisToTets ( UnstructuredMesh mesh,
MeshTetInterface triangulator,
bool  flip_tris = false,
bool  flip_some_tris = false 
)
inline

Definition at line 240 of file mesh_tet_test.C.

244 {
245 // An asymmetric octahedron, so we hopefully have an unambiguous
246 // choice of shortest diagonal for a Delaunay algorithm to pick.
247 const Real expected_volume =
248 build_octahedron(mesh, flip_tris, -1, 1, -1, 1, -0.1, 0.1);
249
250 // Flip a couple tri, breaking the mesh in a way we can fix
251 if (flip_some_tris)
252 for (auto elem : mesh.element_ptr_range())
253 {
254 Point center = elem->vertex_average();
255 if ((center(0) > 0 &&
256 center(1) > 0 &&
257 center(2) > 0) ||
258 (center(0) < 0 &&
259 center(1) < 0 &&
260 center(2) < 0))
261 elem->flip(&mesh.get_boundary_info());
262
264 }
265
266 this->testTetInterfaceBase(mesh, triangulator, /* n_elem = */ 4,
267 /* n_nodes = */ 6, expected_volume);
268 }
void unset_is_prepared()
Tells this we have done some operation where we should no longer consider ourself prepared.
Definition mesh_base.C:1070

References libMesh::MeshBase::get_boundary_info(), mesh, libMesh::Real, testTetInterfaceBase(), and libMesh::MeshBase::unset_is_prepared().

Referenced by testNetGen(), testNetGenFlippedTris(), testNetGenNonOriented(), and testTetGen().

◆ testTrisToTetsError()

void MeshTetTest::testTrisToTetsError ( UnstructuredMesh mesh,
MeshTetInterface triangulator,
bool  flip_tris = false 
)
inline

Definition at line 271 of file mesh_tet_test.C.

274 {
275 const Real expected_volume =
276 build_octahedron(mesh, flip_tris, -1, 1, -1, 1, -0.1, 0.1);
277
278 // Remove one tri, breaking the mesh
279 for (auto elem : mesh.element_ptr_range())
280 {
281 Point center = elem->vertex_average();
282 if (center(0) > 0 &&
283 center(1) > 0 &&
284 center(2) > 0)
285 mesh.delete_elem(elem);
286 }
288
289 this->testExceptionBase("element with a null neighbor", mesh, triangulator,
290 /* n_elem = */ 4, /* n_nodes = */ 6,
291 expected_volume);
292 }
void testExceptionBase(const char *re, MeshBase &mesh, MeshTetInterface &tetinterface, dof_id_type expected_n_elem=DofObject::invalid_id, dof_id_type expected_n_nodes=DofObject::invalid_id, Real expected_volume=0)
virtual void delete_elem(Elem *e)=0
Removes element e from the mesh.

References libMesh::MeshBase::delete_elem(), mesh, libMesh::MeshBase::prepare_for_use(), libMesh::Real, and testExceptionBase().

Referenced by testNetGenError(), and testTetGenError().


The documentation for this class was generated from the following file: