19 #include "libmesh/libmesh_config.h" 21 #ifdef LIBMESH_HAVE_TRIANGLE 24 #include "libmesh/mesh_triangle_interface.h" 25 #include "libmesh/unstructured_mesh.h" 26 #include "libmesh/face_tri3.h" 27 #include "libmesh/face_tri6.h" 28 #include "libmesh/mesh_generation.h" 29 #include "libmesh/mesh_smoother_laplace.h" 30 #include "libmesh/boundary_info.h" 31 #include "libmesh/mesh_triangle_holes.h" 32 #include "libmesh/mesh_triangle_wrapper.h" 33 #include "libmesh/enum_elem_type.h" 34 #include "libmesh/enum_to_string.h" 61 const bool have_holes = ((
_holes !=
nullptr) && (!
_holes->empty()));
81 TriangleWrapper::triangulateio initial;
82 TriangleWrapper::triangulateio
final;
83 TriangleWrapper::triangulateio voronoi;
90 initial.numberofpoints =
_mesh.
n_nodes() + n_hole_points;
91 initial.pointlist =
static_cast<REAL*
>(std::malloc(initial.numberofpoints * 2 *
sizeof(REAL)));
97 initial.numberofsegments = initial.numberofpoints;
101 initial.numberofsegments = this->segments.size() + n_hole_points;
105 initial.numberofsegments = n_hole_points;
108 if (initial.numberofsegments > 0)
110 initial.segmentlist =
static_cast<int *
> (std::malloc(initial.numberofsegments * 2 *
sizeof(
int)));
112 initial.segmentmarkerlist =
static_cast<int *
> (std::malloc(initial.numberofsegments *
sizeof(
int)));
120 unsigned int hole_offset=0;
123 for (
const auto & hole : *
_holes)
125 for (
unsigned int ctr=0, h=0, i=0, hsism=hole->segment_indices().size()-1; i<hsism; ++i)
127 unsigned int begp = hole_offset + hole->segment_indices()[i];
128 unsigned int endp = hole->segment_indices()[i+1];
130 for (; h<endp; ctr+=2, ++h)
132 Point p = hole->point(h);
134 const unsigned int index0 = 2*hole_offset+ctr;
135 const unsigned int index1 = 2*hole_offset+ctr+1;
138 initial.pointlist[index0] = p(0);
139 initial.pointlist[index1] = p(1);
142 initial.segmentlist[index0] = hole_offset+h;
143 initial.segmentlist[index1] = (h == endp - 1) ? begp : hole_offset + h + 1;
146 initial.segmentmarkerlist[hole_offset+h] = 1;
151 hole_offset += hole->n_points();
156 std::vector<unsigned int> libmesh_id_to_pointlist_index(
_mesh.
max_node_id());
159 for (
auto & node :
_mesh.node_ptr_range())
164 initial.pointlist[index] = (*node)(0);
165 initial.pointlist[index+1] = (*node)(1);
166 libmesh_id_to_pointlist_index[node->id()] = ctr/2;
175 initial.segmentlist[index] = hole_offset+n;
176 initial.segmentlist[index+1] = (n==
_mesh.
n_nodes()-1) ? hole_offset : hole_offset+n+1;
178 initial.segmentmarkerlist[hole_offset + n] = (*_markers)[n];
188 for (std::size_t ctr=0, s=0, ss=this->
segments.size(); s<ss; ctr+=2, ++s)
190 const unsigned int index0 = 2*hole_offset+ctr;
191 const unsigned int index1 = 2*hole_offset+ctr+1;
193 initial.segmentlist[index0] = hole_offset +
194 libmesh_id_to_pointlist_index[this->
segments[s].first];
195 initial.segmentlist[index1] = hole_offset +
196 libmesh_id_to_pointlist_index[this->segments[s].second];
198 initial.segmentmarkerlist[hole_offset + s] = (*_markers)[s];
206 initial.numberofholes =
_holes->size();
207 initial.holelist =
static_cast<REAL*
>(std::malloc(initial.numberofholes * 2 *
sizeof(REAL)));
208 for (std::size_t i=0, ctr=0, hs=
_holes->size(); i<hs; ++i, ctr+=2)
210 Point inside_point = (*_holes)[i]->inside();
211 initial.holelist[ctr] = inside_point(0);
212 initial.holelist[ctr+1] = inside_point(1);
218 initial.numberofregions =
_regions->size();
219 initial.regionlist =
static_cast<REAL*
>(std::malloc(initial.numberofregions * 4 *
sizeof(REAL)));
220 for (std::size_t i=0, ctr=0, rs=
_regions->size(); i<rs; ++i, ctr+=4)
222 Point inside_point = (*_regions)[i]->inside();
223 initial.regionlist[ctr] = inside_point(0);
224 initial.regionlist[ctr+1] = inside_point(1);
225 initial.regionlist[ctr+2] = (*_regions)[i]->attribute();
226 initial.regionlist[ctr+3] = (*_regions)[i]->max_area();
250 std::ostringstream flags;
279 libmesh_error_msg(
"ERROR: INVALID_TRIANGULATION_TYPE selected!");
282 libmesh_error_msg(
"Unrecognized _triangulation_type");
330 TriangleWrapper::triangulate(const_cast<char *>(flags.str().c_str()),
343 TriangleWrapper::triangulate(const_cast<char *>(flags.str().c_str()),
389 #endif // LIBMESH_HAVE_TRIANGLE virtual void triangulate() override
Internally, this calls Triangle's triangulate routine.
void insert_any_extra_boundary_points()
Helper function to add extra points (midpoints of initial segments) to a PSLG triangulation.
static constexpr Real TOLERANCE
const std::vector< int > * _markers
Boundary markers.
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.
Real _minimum_angle
Minimum angle in triangles.
const std::vector< Region * > * _regions
A pointer to a vector of Regions*s.
std::string _extra_flags
Additional flags to be passed to triangle.
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true, const bool assert_valid=true) override
Other functions from MeshBase requiring re-definition.
UnstructuredMesh & _mesh
Reference to the mesh which is to be created by triangle.
The libMesh namespace provides an interface to certain functionality in the library.
virtual void smooth() override
Redefinition of the smooth function from the base class.
Real _desired_area
The desired area for the elements in the resulting mesh.
Does nothing, used as a "null" value.
void elems_to_segments()
Helper function to create PSLG segments from our other boundary-defining options (1D mesh edges...
This class defines the data structures necessary for Laplace smoothing.
ElemType _elem_type
The type of elements to generate.
bool _quiet
Flag which tells if we want to suppress stdout outputs.
The UnstructuredMesh class is derived from the MeshBase class.
void copy_tri_to_mesh(const triangulateio &triangle_data_input, UnstructuredMesh &mesh_output, const ElemType type, const triangulateio *voronoi=nullptr)
Copies triangulation data computed by triangle from a triangulateio object to a LibMesh mesh...
const std::vector< Hole * > * _holes
A pointer to a vector of Hole*s.
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
void set_mesh_dimension(unsigned char d)
Resets the logical dimension of the mesh.
void increase_triangle_order()
Helper function to upconvert Tri3 to any higher order triangle type if requested via _elem_type...
First generate a convex hull from the set of points passed in, and then triangulate this set of point...
unsigned int total_hole_points()
Helper function to count points in and verify holes.
std::string enum_to_string(const T e)
Triangulate the interior of a Planar Straight Line Graph, which is defined implicitly by the order of...
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 nodes_to_segments(dof_id_type max_node_id)
Helper function to create PSLG segments from our node ordering, up to the maximum node id...
bool _smooth_after_generating
Flag which tells whether we should smooth the mesh after it is generated.
void destroy(triangulateio &t, IO_Type)
Frees any memory which has been dynamically allocated by Triangle.
virtual dof_id_type max_node_id() const =0
TriangulationType _triangulation_type
The type of triangulation to perform: choices are: convex hull PSLG.
A Point defines a location in LIBMESH_DIM dimensional Real space.
virtual dof_id_type n_nodes() const =0
TriangleInterface(UnstructuredMesh &mesh)
The constructor.