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()),
390 #endif // LIBMESH_HAVE_TRIANGLE virtual void triangulate() override
Internally, this calls Triangle's triangulate routine.
virtual void smooth() override
Redefinition of the smooth function from the base class.
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 ecreated (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.
UnstructuredMesh & _mesh
Reference to the mesh which is to be created by triangle.
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true) override
Other functions from MeshBase requiring re-definition.
The libMesh namespace provides an interface to certain functionality in the library.
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.