libMesh
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. More...
 
void destroy (triangulateio &t, IO_Type)
 Frees any memory which has been dynamically allocated by Triangle. More...
 
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. More...
 

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 65 of file mesh_triangle_wrapper.h.

65  {
66  INPUT = 0,
67  OUTPUT = 1,
68  BOTH = 2};

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 103 of file mesh_triangle_wrapper.C.

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

References libMesh::MeshBase::add_elem(), libMesh::MeshBase::add_point(), libMesh::BoundaryInfo::add_side(), libMesh::MeshBase::clear(), 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::PetscMatrix< libMesh::Number >::set_destroy_mat_on_exit(), and 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::LaspackLinearSolver< T >::adjoint_solve(), libMesh::PetscLinearSolver< Number >::adjoint_solve(), libMesh::SlepcEigenSolver< libMesh::Number >::attach_deflation_space(), libMesh::AdjointRefinementEstimator::estimate_error(), Biharmonic::init(), libMesh::DiagonalMatrix< T >::init(), libMesh::EigenSparseVector< T >::init(), libMesh::LaspackVector< T >::init(), libMesh::DistributedVector< T >::init(), libMesh::EpetraVector< T >::init(), libMesh::PetscVector< libMesh::Number >::init(), main(), libMesh::PetscVector< libMesh::Number >::PetscVector(), libMesh::QComposite< QSubCell >::QComposite(), OverlappingAlgebraicGhostingTest::run_ghosting_test(), OverlappingCouplingGhostingTest::run_sparsity_pattern_test(), libMesh::SlepcEigenSolver< libMesh::Number >::set_initial_space(), OverlappingFunctorTest::setUp(), libMesh::EigenSparseLinearSolver< T >::solve(), libMesh::LaspackLinearSolver< T >::solve(), libMesh::NoxNonlinearSolver< Number >::solve(), libMesh::AztecLinearSolver< T >::solve(), libMesh::TaoOptimizationSolver< T >::solve(), libMesh::NloptOptimizationSolver< T >::solve(), libMesh::PetscNonlinearSolver< Number >::solve(), libMesh::PetscLinearSolver< Number >::solve(), libMesh::SlepcEigenSolver< libMesh::Number >::solve_generalized(), libMesh::SlepcEigenSolver< libMesh::Number >::solve_standard(), libMesh::TriangleInterface::triangulate(), libMesh::LaspackMatrix< T >::update_sparsity_pattern(), and libMesh::EpetraMatrix< T >::update_sparsity_pattern().

libMesh::TriangleWrapper::BOTH
Definition: mesh_triangle_wrapper.h:68
libMesh::TRI3
Definition: enum_elem_type.h:39
libMesh::TRI6
Definition: enum_elem_type.h:40
libMesh::TriangleWrapper::INPUT
Definition: mesh_triangle_wrapper.h:66
libMesh::TriangleWrapper::OUTPUT
Definition: mesh_triangle_wrapper.h:67