libMesh
Loading...
Searching...
No Matches
Enumerations | Functions
libMesh::TriangleWrapper Namespace Reference

A special namespace for wrapping the standard Triangle API, as well as some helper functions for initializing/destroying the structs triangle uses to communicate. More...

Enumerations

enum  IO_Type { INPUT = 0 , OUTPUT = 1 , BOTH = 2 }
 

Functions

void init (triangulateio &t)
 Initializes the fields of t to nullptr/0 as necessary.
 
void destroy (triangulateio &t, IO_Type)
 Frees any memory which has been dynamically allocated by Triangle.
 
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.
 

Detailed Description

A special namespace for wrapping the standard Triangle API, as well as some helper functions for initializing/destroying the structs triangle uses to communicate.

Author
John W. Peterson
Date
2011

Namespace that wraps the Triangle mesh generator's API.

Enumeration Type Documentation

◆ IO_Type

Enumerator
INPUT 
OUTPUT 
BOTH 

Definition at line 57 of file mesh_triangle_wrapper.h.

Function Documentation

◆ copy_tri_to_mesh()

void libMesh::TriangleWrapper::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.

This routine is used internally by the MeshTools::Generation::build_delaunay_square(...) and MeshTools::Generation::build_delaunay_square_with_hole(...) routines.

Definition at line 105 of file mesh_triangle_wrapper.C.

109{
110 // Transfer the information into the LibMesh mesh.
111 mesh_output.clear();
112
113 // Make sure the new Mesh will be 2D
114 mesh_output.set_mesh_dimension(2);
115
116 // Node information
117 for (int i=0, c=0; c<triangle_data_input.numberofpoints; i+=2, ++c)
118 {
119 // Specify ID when adding point, otherwise, if this is DistributedMesh,
120 // it might add points with a non-sequential numbering...
121 mesh_output.add_point( Point(triangle_data_input.pointlist[i],
122 triangle_data_input.pointlist[i+1]),
123 /*id=*/c);
124 }
125
126 // Element information
127 for (int i=0; i<triangle_data_input.numberoftriangles; ++i)
128 {
129 switch (type)
130 {
131 case TRI3:
132 {
133 Elem * elem = mesh_output.add_elem(Elem::build(TRI3));
134
135 for (unsigned int n=0; n<3; ++n)
136 elem->set_node(n, mesh_output.node_ptr(triangle_data_input.trianglelist[i*3 + n]));
137
138 // use the first attribute to set the subdomain ID
139 if (triangle_data_input.triangleattributelist)
140 elem->subdomain_id() =
141 std::round(triangle_data_input.
142 triangleattributelist[i * triangle_data_input.numberoftriangleattributes]);
143 break;
144 }
145
146 case TRI6:
147 {
148 Elem * elem = mesh_output.add_elem(Elem::build(TRI6));
149
150 // Triangle number TRI6 nodes in a different way to libMesh
151 elem->set_node(0, mesh_output.node_ptr(triangle_data_input.trianglelist[i*6 + 0]));
152 elem->set_node(1, mesh_output.node_ptr(triangle_data_input.trianglelist[i*6 + 1]));
153 elem->set_node(2, mesh_output.node_ptr(triangle_data_input.trianglelist[i*6 + 2]));
154 elem->set_node(3, mesh_output.node_ptr(triangle_data_input.trianglelist[i*6 + 5]));
155 elem->set_node(4, mesh_output.node_ptr(triangle_data_input.trianglelist[i*6 + 3]));
156 elem->set_node(5, mesh_output.node_ptr(triangle_data_input.trianglelist[i*6 + 4]));
157
158 // use the first attribute to set the subdomain ID
159 if (triangle_data_input.triangleattributelist)
160 elem->subdomain_id() =
161 std::round(triangle_data_input.
162 triangleattributelist[i * triangle_data_input.numberoftriangleattributes]);
163 break;
164 }
165
166 default:
167 libmesh_error_msg("ERROR: Unrecognized triangular element type == " << Utility::enum_to_string(type));
168 }
169 }
170
171 // Note: If the input mesh was a parallel one, calling
172 // prepare_for_use() now will re-parallelize it by a call to
173 // delete_remote_elements()... We do not actually want to
174 // reparallelize it here though: the triangulate() function may
175 // still do some Mesh smoothing. The main thing needed (for
176 // smoothing) is the neighbor information, so let's just find
177 // neighbors...
178 //mesh_output.prepare_for_use(/*skip_renumber =*/false);
179 mesh_output.find_neighbors();
180
181 // set boundary info
182 if (voronoi && triangle_data_input.edgemarkerlist)
183 {
184 BoundaryInfo & boundary_info = mesh_output.get_boundary_info();
185 for (int e=0; e<triangle_data_input.numberofedges; ++e)
186 {
187 if (triangle_data_input.edgemarkerlist[e] != 0)
188 {
189 int p1 = triangle_data_input.edgelist[e + e];
190 int p2 = triangle_data_input.edgelist[e + e + 1];
191 int elem_id = voronoi->edgelist[e + e];
192 unsigned short int s;
193 if (p1 == triangle_data_input.trianglelist[elem_id*3] &&
194 p2 == triangle_data_input.trianglelist[elem_id*3 + 1])
195 s = 0;
196 else if (p1 == triangle_data_input.trianglelist[elem_id*3 + 1] &&
197 p2 == triangle_data_input.trianglelist[elem_id*3 + 2])
198 s = 1;
199 else if (p1 == triangle_data_input.trianglelist[elem_id*3 + 2] &&
200 p2 == triangle_data_input.trianglelist[elem_id*3])
201 s = 2;
202 else
203 libmesh_error_msg("ERROR: finding element errors for boundary edges.");
204
205 boundary_info.add_side(elem_id, s, triangle_data_input.edgemarkerlist[e]);
206 }
207 }
208 }
209}
This is the base class from which all geometric element types are derived.
Definition elem.h:96
virtual Node *& set_node(const unsigned int i)
Definition elem.h:2567
subdomain_id_type subdomain_id() const
Definition elem.h:2591
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition mesh_base.h:170
virtual const Node * node_ptr(const dof_id_type i) const =0
void set_mesh_dimension(unsigned char d)
Resets the logical dimension of the mesh.
Definition mesh_base.h:423
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 void clear()
Deletes all the element and node data that is currently stored.
Definition mesh_base.C:1036
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
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.

References libMesh::MeshBase::add_elem(), libMesh::MeshBase::add_point(), libMesh::BoundaryInfo::add_side(), libMesh::Elem::build(), libMesh::MeshBase::clear(), libMesh::Utility::enum_to_string(), libMesh::UnstructuredMesh::find_neighbors(), libMesh::MeshBase::get_boundary_info(), libMesh::MeshBase::node_ptr(), libMesh::MeshBase::set_mesh_dimension(), libMesh::Elem::set_node(), libMesh::Elem::subdomain_id(), libMesh::TRI3, and libMesh::TRI6.

Referenced by libMesh::TriangleInterface::triangulate().

◆ destroy()

void libMesh::TriangleWrapper::destroy ( triangulateio &  t,
IO_Type   
)

Frees any memory which has been dynamically allocated by Triangle.

Note
Triangle does not free any memory itself.
It is always safe to call free on a nullptr.
Triangle does shallow-copy (for example) the holelist pointer from the input to output struct without performing a deep copy of the holelist itself. Therefore, double-free will occur without additional care!

Referenced by libMesh::TriangleInterface::triangulate().

◆ init()

void libMesh::TriangleWrapper::init ( triangulateio &  t)

Initializes the fields of t to nullptr/0 as necessary.

This is helpful for preventing the access of uninitialized memory when working with C, which has no constructors or destructors.

Referenced by libMesh::TriangleInterface::triangulate().