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_netgen_interface.h> 6 #include <libmesh/mesh_tetgen_interface.h> 7 #include <libmesh/mesh_tet_interface.h> 8 #include <libmesh/mesh_tools.h> 9 #include <libmesh/parallel_implementation.h> 29 (
mesh, xmin, xmax, ymin, ymax, zmin, zmax, flip_tris);
32 return (xmax-xmin)*(ymax-ymin)*(zmax-zmin)/6;
47 #ifdef LIBMESH_HAVE_NETGEN 49 CPPUNIT_TEST( testNetGen );
50 CPPUNIT_TEST( testNetGenError );
51 CPPUNIT_TEST( testNetGenTets );
52 CPPUNIT_TEST( testNetGenFlippedTris );
53 CPPUNIT_TEST( testNetGenNonOriented );
54 CPPUNIT_TEST( testNetGenHole );
56 #ifdef LIBMESH_ENABLE_AMR 57 CPPUNIT_TEST( testNetGenSphereShell );
72 #ifdef LIBMESH_HAVE_TETGEN 81 CPPUNIT_TEST_SUITE_END();
93 Real expected_volume = 0)
95 #ifdef LIBMESH_ENABLE_EXCEPTIONS 99 bool threw_desired_exception =
false;
101 this->testTetInterfaceBase(
mesh, tetinterface, expected_n_elem,
102 expected_n_nodes, expected_volume);
105 std::regex msg_regex(re);
106 CPPUNIT_ASSERT(std::regex_search(e.what(), msg_regex));
107 threw_desired_exception =
true;
109 catch (CppUnit::Exception & e) {
113 CPPUNIT_ASSERT_MESSAGE(
"Unexpected exception type thrown",
false);
115 CPPUNIT_ASSERT(threw_desired_exception);
124 Real expected_volume = 0)
129 CPPUNIT_ASSERT_EQUAL(
mesh.
n_elem(), expected_n_elem);
132 CPPUNIT_ASSERT_EQUAL(
mesh.
n_nodes(), expected_n_nodes);
134 if (expected_volume != 0)
139 for (
const auto & elem :
mesh.element_ptr_range())
141 CPPUNIT_ASSERT_EQUAL(elem->type(),
TET4);
144 CPPUNIT_ASSERT(!elem->is_flipped());
152 for (
const auto & elem :
mesh.element_ptr_range())
154 for (
auto s : elem->side_index_range())
156 auto neigh = elem->neighbor_ptr(s);
166 auto side = elem->side_ptr(s);
167 auto normal = (side->point(1) - side->point(0)).cross
168 (side->point(2) - side->point(0));
170 if (normal * side->vertex_average() > 0)
183 std::unique_ptr<UnstructuredMesh> holemesh =
184 std::make_unique<Mesh>(*TestCommWorld);
187 -2, 2, -2, 2, -2, 2);
189 const Real hole_volume =
190 build_octahedron(*holemesh,
false, -1, 1, -1, 1, -1, 1);
193 std::make_unique<std::vector<std::unique_ptr<UnstructuredMesh>>>();
195 holes->push_back(std::move(holemesh));
199 const Real expected_volume =
201 this->testTetInterfaceBase(
mesh, triangulator, 32, 14,
206 #ifdef LIBMESH_ENABLE_AMR 210 std::unique_ptr<UnstructuredMesh> holemesh =
211 std::make_unique<Mesh>(*TestCommWorld);
218 std::make_unique<std::vector<std::unique_ptr<UnstructuredMesh>>>();
220 holes->push_back(std::move(holemesh));
229 this->testTetInterfaceBase(
mesh, triangulator);
236 bool flip_tris =
false,
237 bool flip_some_tris =
false)
241 const Real expected_volume =
242 build_octahedron(
mesh, flip_tris, -1, 1, -1, 1, -0.1, 0.1);
246 for (
auto elem :
mesh.element_ptr_range())
248 Point center = elem->vertex_average();
249 if ((center(0) > 0 &&
260 this->testTetInterfaceBase(
mesh, triangulator, 4,
267 bool flip_tris =
false)
269 const Real expected_volume =
270 build_octahedron(
mesh, flip_tris, -1, 1, -1, 1, -0.1, 0.1);
273 for (
auto elem :
mesh.element_ptr_range())
275 Point center = elem->vertex_average();
283 this->testExceptionBase(
"element with a null neighbor",
mesh, triangulator,
301 auto add_tet = [&
mesh](std::array<dof_id_type,4> nodes)
320 this->testTetInterfaceBase(
mesh, triangulator, 4,
325 #ifdef LIBMESH_HAVE_TETGEN 332 testTrisToTets(
mesh, tet_tet);
342 testTrisToTetsError(
mesh, tet_tet);
368 #endif // LIBMESH_HAVE_TETGEN 371 #ifdef LIBMESH_HAVE_NETGEN 382 testTrisToTets(
mesh, net_tet);
393 testTrisToTetsError(
mesh, net_tet);
403 testTetsToTets(
mesh, net_tet);
414 testTrisToTets(
mesh, net_tet,
true);
425 testTrisToTets(
mesh, net_tet,
true,
true);
436 testHole(
mesh, net_tet);
441 #ifdef LIBMESH_ENABLE_AMR 448 testSphereShell(
mesh, net_tet);
558 #endif // LIBMESH_HAVE_NETGEN Class TetGenMeshInterface provides an interface for tetrahedralization of meshes using the TetGen lib...
void testBcids(UnstructuredMesh &mesh)
virtual Node *& set_node(const unsigned int i)
bool has_boundary_id(const Node *const node, const boundary_id_type id) const
Real & desired_volume()
Sets and/or gets the desired tetrahedron volume.
Class NetGenMeshInterface provides an interface for tetrahedralization of meshes using the NetGen lib...
void testTrisToTetsError(UnstructuredMesh &mesh, MeshTetInterface &triangulator, bool flip_tris=false)
libMesh::Parallel::Communicator * TestCommWorld
static constexpr Real TOLERANCE
void set_verbosity(unsigned int v)
Sets a verbosity level, defaulting to 0 (print nothing), to be set as high as 100 (print everything)...
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.
CPPUNIT_TEST_SUITE_REGISTRATION(MeshTetTest)
The libMesh namespace provides an interface to certain functionality in the library.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
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.
This is the MeshBase class.
void testSphereShell(UnstructuredMesh &mesh, MeshTetInterface &triangulator)
std::size_t n_boundary_ids() const
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 testTetsToTets(MeshBase &mesh, MeshTetInterface &triangulator)
void testNetGenSphereShell()
virtual void delete_elem(Elem *e)=0
Removes element e from the mesh.
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
The UnstructuredMesh class is derived from the MeshBase class.
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)
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
void testNetGenFlippedTris()
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.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
A class to represent the internal "this should never happen" errors, to be thrown by "libmesh_error()...
void testNetGenNonOriented()
virtual void triangulate()=0
This is the main public interface for this function.
void testHole(UnstructuredMesh &mesh, MeshTetInterface &triangulator)
virtual dof_id_type n_elem() const =0
virtual const Node * node_ptr(const dof_id_type i) const =0
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
A Point defines a location in LIBMESH_DIM dimensional Real space.
void unset_is_prepared()
Tells this we have done some operation where we should no longer consider ourself prepared...
virtual dof_id_type n_nodes() const =0
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)
Class MeshTetInterface provides an abstract interface for tetrahedralization of meshes by subclasses...
void testTrisToTets(UnstructuredMesh &mesh, MeshTetInterface &triangulator, bool flip_tris=false, bool flip_some_tris=false)