#include <mesh_tetgen_support.h>
TetGenMeshInterface (UnstructuredMesh &mesh)
~TetGenMeshInterface ()
void triangulate_pointset ()
void pointset_convexhull ()
void triangulate_conformingDelaunayMesh (const double quality_constraint, const double volume_constraint)
void triangulate_conformingDelaunayMesh_carvehole (const std::vector< Node * > &holes, const double quality_constraint, const double volume_constraint)
int get_node_index (const Node *inode)
Class TetGenMeshInterface provides an interface for tetrahedrization of meshes using the TetGen library. For information about TetGen cf. TetGen home page.
Definition at line 223 of file mesh_tetgen_support.h.
Definition at line 275 of file mesh_tetgen_support.C.
:
_mesh (mesh)
{
}
Definition at line 235 of file mesh_tetgen_support.h.
{};
Definition at line 379 of file mesh_tetgen_support.C.
References _mesh, DofObject::id(), MeshBase::n_nodes(), and MeshBase::node().
{
// This is NO elegant solution! (A linear search of the nodes.)
unsigned int node_id;
node_id = inode->id();
for (unsigned int i=0; i<this->_mesh.n_nodes(); ++i)
if (this->_mesh.node(i).id() == node_id)
return i;
std::cerr << 'Error! Node not found in the mesh!' << std::endl;
libmesh_error();
return 0;
}
Definition at line 327 of file mesh_tetgen_support.C.
References _mesh, MeshBase::add_elem(), MeshBase::delete_elem(), MeshBase::elements_begin(), MeshBase::elements_end(), TetGenWrapper::get_numberoftrifaces(), TetGenWrapper::get_triface_node(), Elem::n_nodes(), MeshBase::n_nodes(), MeshBase::node_ptr(), MeshBase::nodes_begin(), MeshBase::nodes_end(), TetGenWrapper::run_tetgen(), Elem::set_node(), TetGenWrapper::set_node(), TetGenWrapper::set_pointlist(), and TetGenWrapper::set_switches().
{
// class tetgen_wrapper allows library access on a basic level:
TetGen_access tetgen_wrapper;
// fill input structure with point set data:
tetgen_wrapper.set_pointlist(this->_mesh.n_nodes());
int index = 0;
MeshBase::node_iterator it = this->_mesh.nodes_begin();
const MeshBase::node_iterator end = this->_mesh.nodes_end();
for ( ; it != end; ++it)
tetgen_wrapper.set_node(index++, (**it)(0), (**it)(1), (**it)(2));
// run TetGen triangulation method:
tetgen_wrapper.set_switches('Q'); // TetGen switches: triangulation, Convex hull, Quiet mode
tetgen_wrapper.run_tetgen();
unsigned int num_elements = tetgen_wrapper.get_numberoftrifaces();
// Delete *all* old elements
{
MeshBase::element_iterator it = this->_mesh.elements_begin();
const MeshBase::element_iterator end = this->_mesh.elements_end();
for ( ; it != end; ++it)
this->_mesh.delete_elem (*it);
}
// Add the 2D elements which comprise the convex hull back to the mesh.
// Vector that temporarily holds the node labels defining element.
unsigned long int node_labels[3];
for (unsigned int i=0; i<num_elements; ++i)
{
Elem* elem = new Tri3;
// Get node labels associated with this element
for (unsigned int j=0; j<elem->n_nodes(); ++j)
node_labels[j] = tetgen_wrapper.get_triface_node(i,j);
// Associate nodes with this element
for (unsigned int j=0; j<elem->n_nodes(); j++)
elem->set_node(j) = this->_mesh.node_ptr( node_labels[j] );
// Finally, add this element to the mesh.
this->_mesh.add_elem(elem);
}
}
Definition at line 397 of file mesh_tetgen_support.C.
References _mesh, MeshBase::elem(), MeshBase::n_elem(), Elem::n_neighbors(), Elem::neighbor(), and triangulate_conformingDelaunayMesh_carvehole().
{
// >>> libmesh_assert usage of TRI3 hull elements (no other elements! => mesh.all_tri() )
// thorough check of hull integrity:
// loop over hull with breadth-first search:
std::set< Elem *> visited;
std::vector< Elem *> current;
// Initialize the current vector with element 0
current.push_back(this->_mesh.elem(0));
while (!current.empty())
{
Elem* elem = current.back();
libmesh_assert (elem != NULL);
// Attempt to insert this element into the visited set.
visited.insert(elem);
// Remove the last element from the vector.
current.pop_back();
// Loop over the element's neighbors
for (unsigned int i=0; i<elem->n_neighbors(); ++i)
{
// Attempt to find this element's neighbor in the visited set.
// If not found, insert this neighbor into the current vector.
if (visited.find(elem->neighbor(i)) == visited.end())
current.push_back(elem->neighbor(i));
}
}
if (visited.size() != this->_mesh.n_elem())
{
std::cerr << 'triangulate: hull not connected: element(s) not reached by others.;
libmesh_error();
}
// start triangulation method with empty holes list:
std::vector< Node *> noholes;
triangulate_conformingDelaunayMesh_carvehole(noholes, quality_constraint, volume_constraint);
}
Definition at line 445 of file mesh_tetgen_support.C.
References _mesh, MeshBase::add_elem(), MeshBase::add_point(), MeshBase::elements_begin(), MeshBase::elements_end(), TetGenWrapper::get_element_node(), Elem::get_node(), TetGenWrapper::get_numberofpoints(), TetGenWrapper::get_numberoftetrahedra(), TetGenWrapper::get_output_node(), MeshBase::n_elem(), Elem::n_neighbors(), Elem::n_nodes(), MeshBase::n_nodes(), Elem::neighbor(), MeshBase::node_ptr(), MeshBase::nodes_begin(), MeshBase::nodes_end(), TetGenWrapper::run_tetgen(), TetGenWrapper::set_facet_polygonlist(), TetGenWrapper::set_facetlist(), TetGenWrapper::set_hole(), Elem::set_node(), TetGenWrapper::set_node(), TetGenWrapper::set_pointlist(), TetGenWrapper::set_polygon_vertexlist(), TetGenWrapper::set_switches(), TetGenWrapper::set_vertex(), libMeshEnums::TRI3, and Elem::type().
Referenced by triangulate_conformingDelaunayMesh().
{
// Check mesh for validity: Must be composed of all TRI3 elements,
// also it must be convex so each element must have non-NULL neighbors.
{
MeshBase::element_iterator it = this->_mesh.elements_begin();
const MeshBase::element_iterator end = this->_mesh.elements_end();
for (; it != end ; ++it)
{
Elem* elem = *it;
// Check for proper element type
if (elem->type() != TRI3)
{
std::cerr << 'ERROR: Some of the elements in the original mesh were not TRI3!' << std::endl;
libmesh_error();
}
for (unsigned int i=0; i<elem->n_neighbors(); ++i)
{
if (elem->neighbor(i) == NULL)
{
std::cerr << 'ERROR: Non-convex hull, cannot be tetrahedralized.' << std::endl;
libmesh_error();
}
}
}
}
// >>> fill input structure with point set data:
// class tetgen_wrapper allows library access on a basic level:
TetGen_access tetgen_wrapper;
tetgen_wrapper.set_pointlist(this->_mesh.n_nodes());
{
int index = 0;
MeshBase::node_iterator it = this->_mesh.nodes_begin();
const MeshBase::node_iterator end = this->_mesh.nodes_end();
for ( ; it != end; ++it)
tetgen_wrapper.set_node(index++, (**it)(0), (**it)(1), (**it)(2));
}
// >>> fill input structure 'tetgenio' with facet data:
int facet_num = this->_mesh.n_elem();
// allocate memory in 'tetgenio' structure:
tetgen_wrapper.set_facetlist(facet_num, holes.size());
{
int insertnum = 0;
MeshBase::element_iterator it = this->_mesh.elements_begin();
const MeshBase::element_iterator end = this->_mesh.elements_end();
for (; it != end ; ++it)
{
tetgen_wrapper.set_facet_polygonlist(insertnum, 1);
tetgen_wrapper.set_polygon_vertexlist(insertnum, 0, 3);
Elem* elem = *it;
for (unsigned int j=0; j<elem->n_nodes(); ++j)
tetgen_wrapper.set_vertex(insertnum, // facet number
0, // polygon (always 0)
j, // vertex in tetgen input
this->get_node_index(elem->get_node(j)));
insertnum++;
}
}
// fill hole list (if there are holes):
if (holes.size() > 0)
{
std::vector< Node *>::const_iterator ihole;
int hole_index = 0;
for (ihole=holes.begin(); ihole!=holes.end(); ++ihole)
tetgen_wrapper.set_hole(hole_index++, (**ihole)(0), (**ihole)(1), (**ihole)(2));
}
// >>> run TetGen triangulation method:
// assemble switches:
std::ostringstream oss; // string holding switches
oss << 'pQ';
if (quality_constraint != 0)
oss << 'q' << std::fixed << quality_constraint;
if (volume_constraint != 0)
oss << 'a' << std::fixed << volume_constraint;
std::string params = oss.str();
tetgen_wrapper.set_switches(params); // TetGen switches: Piecewise linear complex, Quiet mode
tetgen_wrapper.run_tetgen();
// => nodes:
unsigned int old_nodesnum = this->_mesh.n_nodes();
REAL x=0., y=0., z=0.;
const unsigned int num_nodes = tetgen_wrapper.get_numberofpoints();
// Add additional nodes to the nodes vector.
for (unsigned int i=old_nodesnum; i<=num_nodes; i++)
{
tetgen_wrapper.get_output_node(i, x,y,z);
this->_mesh.add_point ( Point(x,y,z) );
}
// => tetrahedra:
const unsigned int num_elements = tetgen_wrapper.get_numberoftetrahedra();
// Vector that temporarily holds the node labels defining element.
unsigned long int node_labels[4];
for (unsigned int i=0; i<num_elements; i++)
{
//_elements[firstnumber+i] = new Tet4; // TetGen only supports Tet4 elements.
Elem* elem = new Tet4;
// Fill up the the node_labels vector
for (unsigned int j=0; j<elem->n_nodes(); j++)
node_labels[j] = tetgen_wrapper.get_element_node(i,j);
// Associate nodes with this element
for (unsigned int j=0; j<elem->n_nodes(); j++)
elem->set_node(j) = this->_mesh.node_ptr( node_labels[j] );
// Finally, add this element to the mesh
this->_mesh.add_elem(elem);
}
}
Definition at line 282 of file mesh_tetgen_support.C.
References _mesh, MeshBase::add_elem(), TetGenWrapper::get_element_node(), TetGenWrapper::get_numberoftetrahedra(), Elem::n_nodes(), MeshBase::n_nodes(), MeshBase::node_ptr(), MeshBase::nodes_begin(), MeshBase::nodes_end(), TetGenWrapper::run_tetgen(), Elem::set_node(), TetGenWrapper::set_node(), TetGenWrapper::set_pointlist(), and TetGenWrapper::set_switches().
{
// class tetgen_wrapper allows library access on a basic level:
TetGen_access tetgen_wrapper;
// fill input structure with point set data:
tetgen_wrapper.set_pointlist( this->_mesh.n_nodes() );
{
int index = 0;
MeshBase::node_iterator it = this->_mesh.nodes_begin();
const MeshBase::node_iterator end = this->_mesh.nodes_end();
for ( ; it != end; ++it)
tetgen_wrapper.set_node(index++, (**it)(0), (**it)(1), (**it)(2));
}
// run TetGen triangulation method:
tetgen_wrapper.set_switches('Q'); // TetGen switches: triangulation, Quiet mode
tetgen_wrapper.run_tetgen();
// save elements to mesh structure, nodes will not be changed:
const unsigned int num_elements = tetgen_wrapper.get_numberoftetrahedra();
// Vector that temporarily holds the node labels defining element.
unsigned long int node_labels[4];
for (unsigned int i=0; i<num_elements; ++i)
{
Elem* elem = new Tet4;
// Get the nodes associated with this element
for (unsigned int j=0; j<elem->n_nodes(); ++j)
node_labels[j] = tetgen_wrapper.get_element_node(i,j);
// Associate the nodes with this element
for (unsigned int j=0; j<elem->n_nodes(); ++j)
elem->set_node(j) = this->_mesh.node_ptr( node_labels[j] );
// Finally, add this element to the mesh.
this->_mesh.add_elem(elem);
}
}
Definition at line 277 of file mesh_tetgen_support.h.
Referenced by get_node_index(), pointset_convexhull(), triangulate_conformingDelaunayMesh(), triangulate_conformingDelaunayMesh_carvehole(), and triangulate_pointset().
Generated automatically by Doxygen for libMesh from the source code.