CArl
Code Arlequin / C++ implementation
carl::Intersection_Tools Class Reference

Class with a series of methods to find the intersections between libMesh's elements, using CGAL internally. More...

#include <intersection_tools.h>

Public Member Functions

 Intersection_Tools (const libMesh::Elem *elem_C, double Min_Inter_Volume=1E-21, bool bDoPerf_log=false)
 Constructor with a pre-defined coupling element. It preallocates most objects and build the decomposition mappings. More...
 
 Intersection_Tools (double Min_Inter_Volume=1E-21, bool bDoPerf_log=false)
 Constructor preallocating most objects and building the decomposition mappings. More...
 
const libMesh::Elem * FindFirstIntersection (const libMesh::Elem *Query_elem, std::unique_ptr< libMesh::PointLocatorBase > &point_locator, bool bGuaranteeQueryIsInMesh=false)
 Find an element from a mesh intersecting Query_elem, using the mesh's libMesh::PointLocatorBase. More...
 
bool FindAllIntersection (const libMesh::Elem *Query_elem, std::unique_ptr< libMesh::PointLocatorBase > &point_locator, std::set< unsigned int > &Intersecting_elems)
 Find all elements from the mesh intersecting Query_elem, using the mesh's libMesh::PointLocatorBase. More...
 
bool libMesh_exact_do_intersect (const libMesh::Elem *elem_A, const libMesh::Elem *elem_B)
 Determinate if two elements intersect. More...
 
bool libMesh_exact_intersection (const libMesh::Elem *elem_A, const libMesh::Elem *elem_B, std::set< Point_3 > &points_out, bool bCreateNewNefForA=true, bool bConvertPoints=true, bool bTestNeeded=true)
 Build the intersection between two elements. More...
 
bool libMesh_exact_do_intersect_inside_coupling (const libMesh::Elem *elem_A, const libMesh::Elem *elem_B, bool bCreateNewNefForA=true)
 Determinate if two elements intersect inside the coupling region. More...
 
bool libMesh_exact_intersection_inside_coupling (const libMesh::Elem *elem_A, const libMesh::Elem *elem_B, std::set< libMesh::Point > &points_out, bool bCreateNewNefForA=true, bool bConvertPoints=true, bool bTestNeeded=false)
 Build the intersection between two elements intersect inside the coupling region. More...
 
void libmesh_set_coupling_nef_polyhedron (const libMesh::Elem *elem_C)
 Set the Nef polyhedron for the coupling mesh element. More...
 
void convert_elem_to_exact_points (const libMesh::Elem *elem_input, std::vector< ExactPoint_3 > &points_output)
 Convert an libMesh element to a list of CGAL exact points. More...
 
void convert_exact_points_to_Nef (std::vector< ExactPoint_3 >::const_iterator it_begin, std::vector< ExactPoint_3 >::const_iterator it_end, Nef_Polyhedron &nef_out)
 Convert an CGAL exact point set to a CGAL Nef polyhedron. More...
 

Protected Member Functions

void set_element_indexes ()
 Build the tetrahedron and triangle decomposition mappings. More...
 
bool elements_do_intersect (std::vector< ExactPoint_3 > &elem_C_points, std::vector< std::vector< unsigned int > > &elem_C_tetras, std::vector< std::vector< unsigned int > > &elem_C_triangles, std::vector< ExactPoint_3 > &elem_D_points, std::vector< std::vector< unsigned int > > &elem_D_tetras, std::vector< std::vector< unsigned int > > &elem_D_triangles)
 Determinate if two elements intersect, using their points and decompositions. More...
 

Protected Attributes

Nef_Polyhedron m_nef_A
 Nef polyhedrons for the elements. More...
 
Nef_Polyhedron m_nef_B
 
Nef_Polyhedron m_nef_I
 
Nef_Polyhedron m_nef_C
 
Nef_Polyhedron m_nef_I_AC
 Nef polyhedron used to save the intersection between m_nef_A and m_nef_C, reducing the number of intersection operations. More...
 
std::vector< ExactPoint_3m_exact_points_A
 CGAL Exact point vectors. More...
 
std::vector< ExactPoint_3m_exact_points_B
 
std::vector< ExactPoint_3m_exact_points_C
 
ExactPolyhedron m_dummyPoly
 Intersection polyhedron. More...
 
CGAL::Convex_hull_traits_3< ExactKernelExactHullTraits
 CGAL ExactKernel's convex hull traits. More...
 
Kernel_to_ExactKernel ConvertInexactToExact
 Convert inexact CGAL constructs to exact constructs. More...
 
ExactKernel_to_Kernel ConvertExactToInexact
 Convert exact CGAL constructs to inexact constructs. More...
 
ExactTetrahedron m_test_tetra
 
ExactTriangle_3 m_test_triangle
 
double m_Min_Inter_Volume
 Minimal volume cutoff for the intersections. More...
 
bool MASTER_bPerfLog_intersection_tools
 Do performance log? Default: false. More...
 
libMesh::PerfLog m_perf_log
 libMesh::PerfLog object. More...
 
std::vector< std::vector< unsigned int > > m_TET_tetrahedrons
 Vertex indices for a TET* element tetrahedron. More...
 
std::vector< std::vector< unsigned int > > m_TET_triangles
 Vertex indices for a TET* element surface triangles. More...
 
std::vector< std::vector< unsigned int > > m_TET_edges
 Vertex indices for a TET* element edges (not used!) More...
 
std::vector< std::vector< unsigned int > > m_HEX_tetrahedrons
 Vertex indices for a HEX* element tetrahedron decomposition. More...
 
std::vector< std::vector< unsigned int > > m_HEX_triangles
 Vertex indices for a HEX* element surface triangles decomposition. More...
 
std::vector< std::vector< unsigned int > > m_HEX_edges
 Vertex indices for a HEX* element edges (not used!) More...
 
std::vector< std::vector< unsigned int > > * m_elem_C_tetrahedrons
 Pointer for the appropriate tetrahedron vertex index list (useless!) More...
 
std::vector< std::vector< unsigned int > > * m_elem_C_triangles
 Pointer for the appropriate triangle vertex index list (useless!) More...
 

Detailed Description

Class with a series of methods to find the intersections between libMesh's elements, using CGAL internally.

Definition at line 25 of file intersection_tools.h.

Constructor & Destructor Documentation

carl::Intersection_Tools::Intersection_Tools ( const libMesh::Elem *  elem_C,
double  Min_Inter_Volume = 1E-21,
bool  bDoPerf_log = false 
)
inline

Constructor with a pre-defined coupling element. It preallocates most objects and build the decomposition mappings.

Definition at line 114 of file intersection_tools.h.

114  :
115  m_Min_Inter_Volume { Min_Inter_Volume },
117  m_perf_log { libMesh::PerfLog("Intersection tools", MASTER_bPerfLog_intersection_tools) }
118  {
119  m_exact_points_A.resize(8);
120  m_exact_points_B.resize(8);
121  m_exact_points_C.resize(8);
122 
123  m_dummyPoly.reserve(8,18,12);
124 
126 
127  this->set_element_indexes();
128 
129  m_elem_C_tetrahedrons = NULL;
130  m_elem_C_triangles = NULL;
131  };
double m_Min_Inter_Volume
Minimal volume cutoff for the intersections.
void set_element_indexes()
Build the tetrahedron and triangle decomposition mappings.
std::vector< ExactPoint_3 > m_exact_points_B
std::vector< ExactPoint_3 > m_exact_points_A
CGAL Exact point vectors.
void libmesh_set_coupling_nef_polyhedron(const libMesh::Elem *elem_C)
Set the Nef polyhedron for the coupling mesh element.
bool MASTER_bPerfLog_intersection_tools
Do performance log? Default: false.
ExactPolyhedron m_dummyPoly
Intersection polyhedron.
std::vector< std::vector< unsigned int > > * m_elem_C_tetrahedrons
Pointer for the appropriate tetrahedron vertex index list (useless!)
std::vector< ExactPoint_3 > m_exact_points_C
libMesh::PerfLog m_perf_log
libMesh::PerfLog object.
std::vector< std::vector< unsigned int > > * m_elem_C_triangles
Pointer for the appropriate triangle vertex index list (useless!)
carl::Intersection_Tools::Intersection_Tools ( double  Min_Inter_Volume = 1E-21,
bool  bDoPerf_log = false 
)
inline

Constructor preallocating most objects and building the decomposition mappings.

Definition at line 135 of file intersection_tools.h.

135  :
136  m_Min_Inter_Volume { Min_Inter_Volume },
138  m_perf_log { libMesh::PerfLog("Intersection tools", MASTER_bPerfLog_intersection_tools) }
139  {
140  m_exact_points_A.resize(8);
141  m_exact_points_B.resize(8);
142  m_exact_points_C.resize(8);
143 
144  m_dummyPoly.reserve(8,18,12);
145 
146  m_nef_C.clear(Nef_Polyhedron::EMPTY);
147 
148  this->set_element_indexes();
149 
150  m_elem_C_tetrahedrons = NULL;
151  m_elem_C_triangles = NULL;
152  };
double m_Min_Inter_Volume
Minimal volume cutoff for the intersections.
void set_element_indexes()
Build the tetrahedron and triangle decomposition mappings.
std::vector< ExactPoint_3 > m_exact_points_B
std::vector< ExactPoint_3 > m_exact_points_A
CGAL Exact point vectors.
bool MASTER_bPerfLog_intersection_tools
Do performance log? Default: false.
ExactPolyhedron m_dummyPoly
Intersection polyhedron.
std::vector< std::vector< unsigned int > > * m_elem_C_tetrahedrons
Pointer for the appropriate tetrahedron vertex index list (useless!)
std::vector< ExactPoint_3 > m_exact_points_C
libMesh::PerfLog m_perf_log
libMesh::PerfLog object.
std::vector< std::vector< unsigned int > > * m_elem_C_triangles
Pointer for the appropriate triangle vertex index list (useless!)

Member Function Documentation

void carl::Intersection_Tools::convert_elem_to_exact_points ( const libMesh::Elem *  elem_input,
std::vector< ExactPoint_3 > &  points_output 
)

Convert an libMesh element to a list of CGAL exact points.

Definition at line 636 of file intersection_tools.cpp.

638 {
639  libMesh::Point dummyPoint;
640  for(unsigned int iii = 0; iii < elem_input->n_nodes(); ++iii)
641  {
642  dummyPoint = elem_input->point(iii);
643  points_output[iii] = ExactPoint_3( dummyPoint(0),
644  dummyPoint(1),
645  dummyPoint(2));
646  }
647 }
ExactKernel::Point_3 ExactPoint_3
Definition: CGAL_typedefs.h:94
void carl::Intersection_Tools::convert_exact_points_to_Nef ( std::vector< ExactPoint_3 >::const_iterator  it_begin,
std::vector< ExactPoint_3 >::const_iterator  it_end,
Nef_Polyhedron nef_out 
)

Convert an CGAL exact point set to a CGAL Nef polyhedron.

Definition at line 649 of file intersection_tools.cpp.

652 {
653  CGAL::convex_hull_3(it_begin,it_end,m_dummyPoly,ExactHullTraits);
654  nef_out = Nef_Polyhedron(m_dummyPoly);
655 }
CGAL::Nef_polyhedron_3< ExactKernel, CGAL::SNC_indexed_items > Nef_Polyhedron
CGAL::Convex_hull_traits_3< ExactKernel > ExactHullTraits
CGAL ExactKernel's convex hull traits.
ExactPolyhedron m_dummyPoly
Intersection polyhedron.
bool carl::Intersection_Tools::elements_do_intersect ( std::vector< ExactPoint_3 > &  elem_C_points,
std::vector< std::vector< unsigned int > > &  elem_C_tetras,
std::vector< std::vector< unsigned int > > &  elem_C_triangles,
std::vector< ExactPoint_3 > &  elem_D_points,
std::vector< std::vector< unsigned int > > &  elem_D_tetras,
std::vector< std::vector< unsigned int > > &  elem_D_triangles 
)
protected

Determinate if two elements intersect, using their points and decompositions.

CGAL's "do_intersect" methods are not compatible with generic polyhedrons - at most, we can determinate if a triangle intersects a tetrahedron. To determinate if two elements A and B intersect, we must then decompose them into these geometrical objects, and test the intersections pairwise. This method takes the elements' points and decompositions into tetrahedrons and triangles and test each tetrahedron / triangle pair for intersections.

Definition at line 84 of file intersection_tools.cpp.

91 {
92  bool bElemIntersect = false;
93 
94  // Test intersections between C's tetrahedrons and D's triangles
95  for(unsigned int jjj = 0; jjj < elem_D_triangles.size(); ++jjj)
96  {
97  std::vector<unsigned int> & work_triangle = elem_D_triangles[jjj];
98  m_test_triangle = ExactTriangle_3(elem_D_points[work_triangle[0]],
99  elem_D_points[work_triangle[1]],
100  elem_D_points[work_triangle[2]]);
101 
102  for(unsigned int iii = 0; iii < elem_C_tetras.size(); ++iii)
103  {
104  std::vector<unsigned int> & work_tetra = elem_C_tetras[iii];
105  m_test_tetra = ExactTetrahedron( elem_C_points[work_tetra[0]],
106  elem_C_points[work_tetra[1]],
107  elem_C_points[work_tetra[2]],
108  elem_C_points[work_tetra[3]]);
109 
110  bElemIntersect = CGAL::do_intersect(m_test_triangle,m_test_tetra);
111 
112  if(bElemIntersect)
113  {
114  // Found intersection!
115  break;
116  }
117  }
118 
119  if(bElemIntersect)
120  {
121  // Found intersection!
122  break;
123  }
124  }
125 
126  if(!bElemIntersect)
127  {
128  // Test intersections between D's tetrahedrons and C's triangles
129  for(unsigned int jjj = 0; jjj < elem_C_triangles.size(); ++jjj)
130  {
131  std::vector<unsigned int> & work_triangle = elem_C_triangles[jjj];
132  m_test_triangle = ExactTriangle_3(elem_C_points[work_triangle[0]],
133  elem_C_points[work_triangle[1]],
134  elem_C_points[work_triangle[2]]);
135 
136  for(unsigned int iii = 0; iii < elem_D_tetras.size(); ++iii)
137  {
138  std::vector<unsigned int> & work_tetra = elem_D_tetras.at(iii);
139  m_test_tetra = ExactTetrahedron( elem_D_points[work_tetra[0]],
140  elem_D_points[work_tetra[1]],
141  elem_D_points[work_tetra[2]],
142  elem_D_points[work_tetra[3]]);
143 
144  bElemIntersect = CGAL::do_intersect(m_test_triangle,m_test_tetra);
145 
146  if(bElemIntersect)
147  {
148  // Found intersection!
149  break;
150  }
151  }
152 
153  if(bElemIntersect)
154  {
155  // Found intersection!
156  break;
157  }
158  }
159  }
160  return bElemIntersect;
161 }
ExactKernel::Triangle_3 ExactTriangle_3
Definition: CGAL_typedefs.h:95
ExactTetrahedron m_test_tetra
ExactTriangle_3 m_test_triangle
CGAL::Tetrahedron_3< ExactKernel > ExactTetrahedron
bool carl::Intersection_Tools::FindAllIntersection ( const libMesh::Elem *  Query_elem,
std::unique_ptr< libMesh::PointLocatorBase > &  point_locator,
std::set< unsigned int > &  Intersecting_elems 
)

Find all elements from the mesh intersecting Query_elem, using the mesh's libMesh::PointLocatorBase.

Definition at line 200 of file intersection_tools.cpp.

204 {
205  libMesh::PointLocatorBase& locator = *point_locator.get();
206 
207  // Clear output
208  Intersecting_elems.clear();
209 
210  // Search each vertex
211  unsigned int elem_nb_nodes = Query_elem->n_nodes();
212  libMesh::Point dummyPoint;
213 
214  int nbOfInters = 0;
215 
216  // Just to be sure, check if one of the points intersect the mesh
217  for(unsigned int iii = 0; iii < elem_nb_nodes; ++iii)
218  {
219  dummyPoint = Query_elem->point(iii);
220  const libMesh::Elem * Patch_elem = locator(Query_elem->point(iii));
221 
222  if(Patch_elem != NULL)
223  {
224  Intersecting_elems.insert(Patch_elem->id());
225  ++nbOfInters;
226  }
227  }
228 
229  return nbOfInters != 0;
230 };
const libMesh::Elem * carl::Intersection_Tools::FindFirstIntersection ( const libMesh::Elem *  Query_elem,
std::unique_ptr< libMesh::PointLocatorBase > &  point_locator,
bool  bGuaranteeQueryIsInMesh = false 
)

Find an element from a mesh intersecting Query_elem, using the mesh's libMesh::PointLocatorBase.

By default, a test is done to be sure that the query element does indeed intersect the tested mesh. The test can be bypassed using the flag bGuaranteeQueryIsInMesh.

Definition at line 163 of file intersection_tools.cpp.

167 {
168  libMesh::PointLocatorBase& locator = *point_locator.get();
169  if(!bGuaranteeQueryIsInMesh)
170  {
171  // Then we are sure that the query element is inside the mesh, only
172  // one search needed
173  }
174  else
175  {
176  // Better check all the vertices ...
177  unsigned int elem_nb_nodes = Query_elem->n_nodes();
178  libMesh::Point dummyPoint;
179  bool bInsideTheMesh = true;
180 
181  // Just to be sure, check if one of the points intersect the mesh
182  for(unsigned int iii = 0; iii < elem_nb_nodes; ++iii)
183  {
184  dummyPoint = Query_elem->point(iii);
185  const libMesh::Elem * Patch_elem = locator(Query_elem->point(iii));
186 
187  if(Patch_elem == NULL)
188  {
189  bInsideTheMesh = false;
190  break;
191  }
192  }
193 
194  homemade_assert_msg(bInsideTheMesh, "Query element is not fully inside tested mesh!\n");
195  }
196 
197  return locator(Query_elem->point(0));
198 };
#define homemade_assert_msg(asserted, msg)
Definition: common_header.h:63
bool carl::Intersection_Tools::libMesh_exact_do_intersect ( const libMesh::Elem *  elem_A,
const libMesh::Elem *  elem_B 
)

Determinate if two elements intersect.

Serves as a frontend for the private Intersection_Tools::elements_do_intersect method.

Definition at line 232 of file intersection_tools.cpp.

235 {
236  // The booleans
237  bool bBboxIntersect = false;
238  bool bElemIntersect = false;
239 
240  unsigned int n_nodes_A = elem_A->n_nodes();
241  unsigned int n_nodes_B = elem_B->n_nodes();
242 
243  // First, convert both elements to CGAL exact point vectors
246 
247  // Fast check: bounding boxes
248  std::vector<ExactPoint_3>::const_iterator exact_points_A_begin = m_exact_points_A.begin();
249  std::vector<ExactPoint_3>::const_iterator exact_points_B_begin = m_exact_points_B.begin();
250 
251  Bbox_3 exact_bbox_A = CGAL::bbox_3(exact_points_A_begin,exact_points_A_begin + n_nodes_A);
252  Bbox_3 exact_bbox_B = CGAL::bbox_3(exact_points_B_begin,exact_points_B_begin + n_nodes_B);
253 
254  bBboxIntersect = CGAL::do_intersect(exact_bbox_A,exact_bbox_B);
255 
256  if(bBboxIntersect)
257  {
258  // Bbox intersect, test intersection between tetrahedrons and triangles
259 
260  // Pointers that will depend on the element type;
261  std::vector<std::vector<unsigned int> > * elem_A_tetras = NULL;
262  std::vector<std::vector<unsigned int> > * elem_A_triangles = NULL;
263 
264  std::vector<std::vector<unsigned int> > * elem_B_tetras = NULL;
265  std::vector<std::vector<unsigned int> > * elem_B_triangles = NULL;
266 
267  if(elem_A->type() == libMesh::TET4)
268  {
269  // Use tetrahedron geometry
270  elem_A_tetras = &m_TET_tetrahedrons;
271  elem_A_triangles = &m_TET_triangles;
272  }
273  else if(elem_A->type() == libMesh::HEX8)
274  {
275  // Use hexaedron geometry
276  elem_A_tetras = &m_HEX_tetrahedrons;
277  elem_A_triangles = &m_HEX_triangles;
278  }
279  else
280  {
281  homemade_error_msg("Unsupported element type! Must be either TET4 or HEX8");
282  }
283 
284  if(elem_B->type() == libMesh::TET4)
285  {
286  // Use tetrahedron geometry
287  elem_B_tetras = &m_TET_tetrahedrons;
288  elem_B_triangles = &m_TET_triangles;
289  }
290  else if(elem_B->type() == libMesh::HEX8)
291  {
292  // Use hexaedron geometry
293  elem_B_tetras = &m_HEX_tetrahedrons;
294  elem_B_triangles = &m_HEX_triangles;
295  }
296  else
297  {
298  homemade_error_msg("Unsupported element type! Must be either TET4 or HEX8");
299  }
300 
301  bElemIntersect = this->elements_do_intersect(m_exact_points_A, *elem_A_tetras, *elem_A_triangles,
302  m_exact_points_B, *elem_B_tetras, *elem_B_triangles);
303  }
304  else
305  {
306  bElemIntersect = false;
307  }
308 
309  return bElemIntersect;
310 }
#define homemade_error_msg(msg)
Definition: common_header.h:73
std::vector< std::vector< unsigned int > > m_HEX_tetrahedrons
Vertex indices for a HEX* element tetrahedron decomposition.
std::vector< ExactPoint_3 > m_exact_points_B
std::vector< ExactPoint_3 > m_exact_points_A
CGAL Exact point vectors.
std::vector< std::vector< unsigned int > > m_HEX_triangles
Vertex indices for a HEX* element surface triangles decomposition.
CGAL::Bbox_3 Bbox_3
void convert_elem_to_exact_points(const libMesh::Elem *elem_input, std::vector< ExactPoint_3 > &points_output)
Convert an libMesh element to a list of CGAL exact points.
std::vector< std::vector< unsigned int > > m_TET_triangles
Vertex indices for a TET* element surface triangles.
bool elements_do_intersect(std::vector< ExactPoint_3 > &elem_C_points, std::vector< std::vector< unsigned int > > &elem_C_tetras, std::vector< std::vector< unsigned int > > &elem_C_triangles, std::vector< ExactPoint_3 > &elem_D_points, std::vector< std::vector< unsigned int > > &elem_D_tetras, std::vector< std::vector< unsigned int > > &elem_D_triangles)
Determinate if two elements intersect, using their points and decompositions.
std::vector< std::vector< unsigned int > > m_TET_tetrahedrons
Vertex indices for a TET* element tetrahedron.
bool carl::Intersection_Tools::libMesh_exact_do_intersect_inside_coupling ( const libMesh::Elem *  elem_A,
const libMesh::Elem *  elem_B,
bool  bCreateNewNefForA = true 
)

Determinate if two elements intersect inside the coupling region.

This method uses CGAL's Nef polyhedrons. The boolean flag "bCreateNewNefForA" is used to avoid re-building the elem_A's Nef polyhedron.

Definition at line 397 of file intersection_tools.cpp.

400 {
401  bool bElemIntersect = true;
402 
403  // Assert if C was built
404  homemade_assert_msg(!m_nef_C.is_empty(), "Coupling restriction element was not set yet!\n");
405 
406  // Test the intersection beforehand. This also generates the exact
407  // points needed.
408  bElemIntersect = libMesh_exact_do_intersect(elem_A,elem_B);
409 
410  if(bElemIntersect)
411  {
412  // Generate the Nef polyhedrons
413  unsigned int n_nodes_A = elem_A->n_nodes();
414  unsigned int n_nodes_B = elem_B->n_nodes();
415 
416  std::vector<ExactPoint_3>::const_iterator exact_points_A_begin = m_exact_points_A.begin();
417  std::vector<ExactPoint_3>::const_iterator exact_points_B_begin = m_exact_points_B.begin();
418 
419  if(bCreateNewNefForA)
420  {
421  // A was updated, must also update A*C
422  convert_exact_points_to_Nef( exact_points_A_begin,
423  exact_points_A_begin + n_nodes_A,
424  m_nef_A);
426  }
427  else
428  {
429  homemade_assert_msg(!m_nef_I_AC.is_empty(), "Intersection base is empty!\n");
430  }
431  convert_exact_points_to_Nef( exact_points_B_begin,
432  exact_points_B_begin + n_nodes_B,
433  m_nef_B);
434 
435  // Intersect them
437 
438  if(!m_nef_I.is_empty() && m_nef_I.number_of_volumes() > 1)
439  {
440  // Intersection exists!
441  bElemIntersect = true;
442  }
443  else
444  {
445  bElemIntersect = false;
446  }
447  }
448 
449  return bElemIntersect;
450 }
std::vector< ExactPoint_3 > m_exact_points_B
std::vector< ExactPoint_3 > m_exact_points_A
CGAL Exact point vectors.
Nef_Polyhedron m_nef_I_AC
Nef polyhedron used to save the intersection between m_nef_A and m_nef_C, reducing the number of inte...
bool libMesh_exact_do_intersect(const libMesh::Elem *elem_A, const libMesh::Elem *elem_B)
Determinate if two elements intersect.
#define homemade_assert_msg(asserted, msg)
Definition: common_header.h:63
Nef_Polyhedron m_nef_A
Nef polyhedrons for the elements.
void convert_exact_points_to_Nef(std::vector< ExactPoint_3 >::const_iterator it_begin, std::vector< ExactPoint_3 >::const_iterator it_end, Nef_Polyhedron &nef_out)
Convert an CGAL exact point set to a CGAL Nef polyhedron.
bool carl::Intersection_Tools::libMesh_exact_intersection ( const libMesh::Elem *  elem_A,
const libMesh::Elem *  elem_B,
std::set< Point_3 > &  points_out,
bool  bCreateNewNefForA = true,
bool  bConvertPoints = true,
bool  bTestNeeded = true 
)

Build the intersection between two elements.

Definition at line 312 of file intersection_tools.cpp.

318 {
319  bool bElemIntersect = true;
320 
321  if(bTestNeeded)
322  {
323  // Test the intersection beforehand
324  m_perf_log.push("Test intersection","Exact intersection construction");
325  bElemIntersect = libMesh_exact_do_intersect(elem_A,elem_B);
326  m_perf_log.pop("Test intersection","Exact intersection construction");
327  }
328  else if(bConvertPoints)
329  {
330  // Test already made somewhere else, but we need to set up the exact
331  // points.
332  m_perf_log.push("Point conversion to exact","Exact intersection construction");
333  if(bCreateNewNefForA)
334  {
336  }
338  m_perf_log.pop("Point conversion to exact","Exact intersection construction");
339  }
340 
341  if(bElemIntersect)
342  {
343  // Generate the Nef polyhedrons
344  unsigned int n_nodes_A = elem_A->n_nodes();
345  unsigned int n_nodes_B = elem_B->n_nodes();
346 
347  std::vector<ExactPoint_3>::const_iterator exact_points_A_begin = m_exact_points_A.begin();
348  std::vector<ExactPoint_3>::const_iterator exact_points_B_begin = m_exact_points_B.begin();
349 
350  m_perf_log.push("Nef polyhedron construction","Exact intersection construction");
351  if(bCreateNewNefForA)
352  {
353  convert_exact_points_to_Nef( exact_points_A_begin,
354  exact_points_A_begin + n_nodes_A,
355  m_nef_A);
356  }
357  else
358  {
359  homemade_assert_msg(!m_nef_A.is_empty(), "Intersection base is empty!\n");
360  }
361 
362  convert_exact_points_to_Nef( exact_points_B_begin,
363  exact_points_B_begin + n_nodes_B,
364  m_nef_B);
365 
366  m_perf_log.pop("Nef polyhedron construction","Exact intersection construction");
367 
368  // Intersect them
369  m_perf_log.push("Nef polyhedron intersection","Exact intersection construction");
371  m_perf_log.pop("Nef polyhedron intersection","Exact intersection construction");
372 
373  m_perf_log.push("Point set output","Exact intersection construction");
374  if(!m_nef_I.is_empty())
375  {
376  // Intersection exists! Create output
377  bElemIntersect = true;
378 
379  points_out.clear();
380  for(Nef_Polyhedron::Vertex_const_iterator it_vertex = m_nef_I.vertices_begin();
381  it_vertex != m_nef_I.vertices_end();
382  ++it_vertex)
383  {
384  points_out.insert(ConvertExactToInexact(it_vertex->point()));
385  }
386  }
387  else
388  {
389  bElemIntersect = false;
390  }
391  m_perf_log.pop("Point set output","Exact intersection construction");
392  }
393 
394  return bElemIntersect;
395 }
ExactKernel_to_Kernel ConvertExactToInexact
Convert exact CGAL constructs to inexact constructs.
std::vector< ExactPoint_3 > m_exact_points_B
std::vector< ExactPoint_3 > m_exact_points_A
CGAL Exact point vectors.
void convert_elem_to_exact_points(const libMesh::Elem *elem_input, std::vector< ExactPoint_3 > &points_output)
Convert an libMesh element to a list of CGAL exact points.
bool libMesh_exact_do_intersect(const libMesh::Elem *elem_A, const libMesh::Elem *elem_B)
Determinate if two elements intersect.
#define homemade_assert_msg(asserted, msg)
Definition: common_header.h:63
Nef_Polyhedron m_nef_A
Nef polyhedrons for the elements.
libMesh::PerfLog m_perf_log
libMesh::PerfLog object.
void convert_exact_points_to_Nef(std::vector< ExactPoint_3 >::const_iterator it_begin, std::vector< ExactPoint_3 >::const_iterator it_end, Nef_Polyhedron &nef_out)
Convert an CGAL exact point set to a CGAL Nef polyhedron.
bool carl::Intersection_Tools::libMesh_exact_intersection_inside_coupling ( const libMesh::Elem *  elem_A,
const libMesh::Elem *  elem_B,
std::set< libMesh::Point > &  points_out,
bool  bCreateNewNefForA = true,
bool  bConvertPoints = true,
bool  bTestNeeded = false 
)

Build the intersection between two elements intersect inside the coupling region.

This method uses CGAL's Nef polyhedrons. The boolean flag "bCreateNewNefForA" is used to avoid re-building the elem_A's Nef polyhedron. If the boolean flag "bConvertPoints" is set to true, the elements points are converted to CGAL's exact points. When the boolean flag "bTestNeeded" is set to true, a preliminary intersection test is done.

Definition at line 452 of file intersection_tools.cpp.

458 {
459  bool bElemIntersect = true;
460 
461  // Assert if C was built
462  homemade_assert_msg(!m_nef_C.is_empty(), "Coupling restriction element was not set yet!\n");
463 
464  // Dummy CGAL point
465  Point_3 dummy_CGAL_point;
466  libMesh::Point dummy_libMesh_point;
467 
468  std::vector<double> bbox_dims(6,0);
469  double inter_vol = 0;
470 
471  if(bTestNeeded)
472  {
473  // Test the intersection beforehand
474  m_perf_log.push("Test intersection","Exact intersection construction inside coupling");
475  bElemIntersect = libMesh_exact_do_intersect(elem_A,elem_B);
476  m_perf_log.pop("Test intersection","Exact intersection construction inside coupling");
477  }
478  else if(bConvertPoints)
479  {
480  // Test already made somewhere else, but we need to set up the exact
481  // points.
482  m_perf_log.push("Point conversion to exact","Exact intersection construction inside coupling");
485  m_perf_log.pop("Point conversion to exact","Exact intersection construction inside coupling");
486  }
487 
488  if(bElemIntersect)
489  {
490  // Generate the Nef polyhedrons
491  unsigned int n_nodes_A = elem_A->n_nodes();
492  unsigned int n_nodes_B = elem_B->n_nodes();
493 
494  std::vector<ExactPoint_3>::const_iterator exact_points_A_begin = m_exact_points_A.begin();
495  std::vector<ExactPoint_3>::const_iterator exact_points_B_begin = m_exact_points_B.begin();
496 
497  m_perf_log.push("Nef polyhedron construction","Exact intersection construction inside coupling");
498  if(bCreateNewNefForA)
499  {
500  // Then we need to build a new nef polyhedron
501  convert_exact_points_to_Nef( exact_points_A_begin,
502  exact_points_A_begin + n_nodes_A,
503  m_nef_A);
505  }
506  else
507  {
508  homemade_assert_msg(!m_nef_I_AC.is_empty(), "Intersection base is empty!\n");
509  }
510 
511  convert_exact_points_to_Nef( exact_points_B_begin,
512  exact_points_B_begin + n_nodes_B,
513  m_nef_B);
514  m_perf_log.pop("Nef polyhedron construction","Exact intersection construction inside coupling");
515 
516  // Intersect them
517  m_perf_log.push("Nef polyhedron intersection","Exact intersection construction inside coupling");
518 
520 
521  m_perf_log.pop("Nef polyhedron intersection","Exact intersection construction inside coupling");
522 
523  m_perf_log.push("Point set output","Exact intersection construction inside coupling");
524 
525  if( !m_nef_I.is_empty() &&
526  m_nef_I.number_of_volumes() > 1 &&
527  m_nef_I.number_of_vertices() > 3 &&
528  m_nef_I.number_of_facets() > 1)
529  {
530  // Intersection exists! Extract points!
531  points_out.clear();
532  bElemIntersect = true;
533 
534  for(Nef_Polyhedron::Vertex_const_iterator it_vertex = m_nef_I.vertices_begin();
535  it_vertex != m_nef_I.vertices_end();
536  ++it_vertex)
537  {
538  dummy_CGAL_point = ConvertExactToInexact(it_vertex->point());
539  points_out.insert(libMesh::Point(dummy_CGAL_point.x(),dummy_CGAL_point.y(),dummy_CGAL_point.z()));
540  }
541 
542  // Sometimes, CGAL will generate a very small volume, which follow
543  // the "if" conditions above, but results in a point or facet when
544  // converted to inexact values. The checks below test for it.
545  std::set<libMesh::Point>::const_iterator it_set = points_out.begin();
546  dummy_libMesh_point = *it_set;
547 
548  bbox_dims[0] = dummy_libMesh_point(0);
549  bbox_dims[1] = dummy_libMesh_point(0);
550  bbox_dims[2] = dummy_libMesh_point(1);
551  bbox_dims[3] = dummy_libMesh_point(1);
552  bbox_dims[4] = dummy_libMesh_point(2);
553  bbox_dims[5] = dummy_libMesh_point(2);
554  ++it_set;
555 
556  for(; it_set != points_out.end(); ++it_set)
557  {
558  dummy_libMesh_point = *it_set;
559  if(bbox_dims[0] > dummy_libMesh_point(0)) // Min x
560  bbox_dims[0] = dummy_libMesh_point(0);
561  if(bbox_dims[1] < dummy_libMesh_point(0)) // Max x
562  bbox_dims[1] = dummy_libMesh_point(0);
563  if(bbox_dims[2] > dummy_libMesh_point(1)) // Min y
564  bbox_dims[2] = dummy_libMesh_point(1);
565  if(bbox_dims[3] < dummy_libMesh_point(1)) // Max y
566  bbox_dims[3] = dummy_libMesh_point(1);
567  if(bbox_dims[4] > dummy_libMesh_point(2)) // Min z
568  bbox_dims[4] = dummy_libMesh_point(2);
569  if(bbox_dims[5] < dummy_libMesh_point(2)) // Max z
570  bbox_dims[5] = dummy_libMesh_point(2);
571 
572 // it_set->print();
573 // std::cout << std::endl;
574  }
575 
576  inter_vol = std::abs((bbox_dims[1] - bbox_dims[0]) * (bbox_dims[3] - bbox_dims[2]) * (bbox_dims[5] - bbox_dims[4]));
577 // std::cout << " -> Volume = " << inter_vol << std::endl;
578  if(points_out.size() < 4 || inter_vol < m_Min_Inter_Volume )
579  {
580  // Invalid intersection!
581  bElemIntersect = false;
582 
583  std::set<libMesh::Point>::const_iterator it_set = points_out.begin();
584 // std::cout << " -> Volume = " << inter_vol << std::endl;
585  for(; it_set != points_out.end(); ++it_set)
586  {
587 // it_set->print();
588 // std::cout << std::endl;
589  }
590 
591  }
592  }
593  else
594  {
595  bElemIntersect = false;
596  }
597 
598  m_perf_log.pop("Point set output","Exact intersection construction inside coupling");
599  }
600 
601  return bElemIntersect;
602 }
double m_Min_Inter_Volume
Minimal volume cutoff for the intersections.
ExactKernel_to_Kernel ConvertExactToInexact
Convert exact CGAL constructs to inexact constructs.
std::vector< ExactPoint_3 > m_exact_points_B
Kernel::Point_3 Point_3
std::vector< ExactPoint_3 > m_exact_points_A
CGAL Exact point vectors.
Nef_Polyhedron m_nef_I_AC
Nef polyhedron used to save the intersection between m_nef_A and m_nef_C, reducing the number of inte...
void convert_elem_to_exact_points(const libMesh::Elem *elem_input, std::vector< ExactPoint_3 > &points_output)
Convert an libMesh element to a list of CGAL exact points.
bool libMesh_exact_do_intersect(const libMesh::Elem *elem_A, const libMesh::Elem *elem_B)
Determinate if two elements intersect.
#define homemade_assert_msg(asserted, msg)
Definition: common_header.h:63
Nef_Polyhedron m_nef_A
Nef polyhedrons for the elements.
libMesh::PerfLog m_perf_log
libMesh::PerfLog object.
void convert_exact_points_to_Nef(std::vector< ExactPoint_3 >::const_iterator it_begin, std::vector< ExactPoint_3 >::const_iterator it_end, Nef_Polyhedron &nef_out)
Convert an CGAL exact point set to a CGAL Nef polyhedron.
void carl::Intersection_Tools::libmesh_set_coupling_nef_polyhedron ( const libMesh::Elem *  elem_C)

Set the Nef polyhedron for the coupling mesh element.

Definition at line 604 of file intersection_tools.cpp.

605 {
606  unsigned int n_nodes_C = elem_C->n_nodes();
607 
608  // First, convert the element to a CGAL exact point vector
610 
611  // Second, convert to Nef
612  std::vector<ExactPoint_3>::const_iterator exact_points_C_begin = m_exact_points_C.begin();
613  convert_exact_points_to_Nef( exact_points_C_begin,
614  exact_points_C_begin + n_nodes_C,
615  m_nef_C);
616 
617  // And, finally, associate the tetra and triangle tables to it
618  if(elem_C->type() == libMesh::TET4)
619  {
620  // Use tetrahedron geometry
623  }
624  else if(elem_C->type() == libMesh::HEX8)
625  {
626  // Use hexaedron geometry
629  }
630  else
631  {
632  homemade_error_msg("Unsupported element type! Must be either TET4 or HEX8");
633  }
634 }
#define homemade_error_msg(msg)
Definition: common_header.h:73
std::vector< std::vector< unsigned int > > m_HEX_tetrahedrons
Vertex indices for a HEX* element tetrahedron decomposition.
std::vector< std::vector< unsigned int > > m_HEX_triangles
Vertex indices for a HEX* element surface triangles decomposition.
void convert_elem_to_exact_points(const libMesh::Elem *elem_input, std::vector< ExactPoint_3 > &points_output)
Convert an libMesh element to a list of CGAL exact points.
std::vector< std::vector< unsigned int > > m_TET_triangles
Vertex indices for a TET* element surface triangles.
std::vector< std::vector< unsigned int > > * m_elem_C_tetrahedrons
Pointer for the appropriate tetrahedron vertex index list (useless!)
std::vector< ExactPoint_3 > m_exact_points_C
void convert_exact_points_to_Nef(std::vector< ExactPoint_3 >::const_iterator it_begin, std::vector< ExactPoint_3 >::const_iterator it_end, Nef_Polyhedron &nef_out)
Convert an CGAL exact point set to a CGAL Nef polyhedron.
std::vector< std::vector< unsigned int > > * m_elem_C_triangles
Pointer for the appropriate triangle vertex index list (useless!)
std::vector< std::vector< unsigned int > > m_TET_tetrahedrons
Vertex indices for a TET* element tetrahedron.
void carl::Intersection_Tools::set_element_indexes ( )
protected

Build the tetrahedron and triangle decomposition mappings.

CGAL's "do_intersect" methods are not compatible with generic polyhedrons - at most, we can determinate if a triangle intersects a tetrahedron. To determinate if two elements A and B intersect, we must then decompose them into these geometrical objects, and test the intersections pairwise. The Intersection_Tools::set_element_indexes method fills the vectors "m_XYZ_tetrahedrons" and "m_XYZ_triangles" with a mapping between an TET or HEX element and these decompositions.

Definition at line 13 of file intersection_tools.cpp.

14 {
15  m_TET_tetrahedrons.resize(1,std::vector<unsigned int>(4,0));
16  m_TET_triangles.resize(4,std::vector<unsigned int>(3,0));
17  m_TET_edges.resize(6,std::vector<unsigned int>(2,0));
18 
19  m_HEX_tetrahedrons.resize(5,std::vector<unsigned int>(4,0));
20  m_HEX_triangles.resize(12,std::vector<unsigned int>(3,0));
21  m_HEX_edges.resize(12,std::vector<unsigned int>(2,0));
22 
23  // Set up tetra tetrahedrons (...)
24  m_TET_tetrahedrons[0] = {0, 1, 2, 3};
25 
26  // Set up tetra triangles
27  m_TET_triangles[0] = {0, 1, 2};
28  m_TET_triangles[1] = {1, 2, 3};
29  m_TET_triangles[2] = {0, 1, 3};
30  m_TET_triangles[3] = {0, 2, 3};
31 
32  // Set up tetra edges
33  m_TET_edges[0] = {0, 1};
34  m_TET_edges[1] = {0, 2};
35  m_TET_edges[2] = {0, 3};
36  m_TET_edges[3] = {1, 3};
37  m_TET_edges[4] = {3, 2};
38  m_TET_edges[5] = {2, 1};
39 
40  // Set up hex tetrahedrons
41  m_HEX_tetrahedrons[0] = {0, 1, 3, 4};
42  m_HEX_tetrahedrons[1] = {5, 1, 4, 6};
43  m_HEX_tetrahedrons[2] = {7, 3, 4, 6};
44  m_HEX_tetrahedrons[3] = {2, 6, 1, 3};
45 
46  m_HEX_tetrahedrons[4] = {1, 4, 6, 3};
47 
48  // Set up hex triangles
49  m_HEX_triangles[0] = {0, 1, 2};
50  m_HEX_triangles[1] = {0, 3, 2};
51 
52  m_HEX_triangles[2] = {0, 1, 5};
53  m_HEX_triangles[3] = {0, 4, 5};
54 
55  m_HEX_triangles[4] = {0, 3, 7};
56  m_HEX_triangles[5] = {0, 4, 7};
57 
58  m_HEX_triangles[6] = {6, 5, 4};
59  m_HEX_triangles[7] = {6, 7, 4};
60 
61  m_HEX_triangles[8] = {6, 5, 1};
62  m_HEX_triangles[9] = {6, 2, 1};
63 
64  m_HEX_triangles[10] = {6, 7, 3};
65  m_HEX_triangles[11] = {6, 2, 3};
66 
67  // Set up hex edges
68  m_HEX_edges[0] = {0, 1};
69  m_HEX_edges[1] = {1, 2};
70  m_HEX_edges[2] = {2, 3};
71  m_HEX_edges[3] = {3, 0};
72 
73  m_HEX_edges[4] = {4, 5};
74  m_HEX_edges[5] = {5, 6};
75  m_HEX_edges[6] = {6, 7};
76  m_HEX_edges[7] = {7, 4};
77 
78  m_HEX_edges[8] = {0, 4};
79  m_HEX_edges[9] = {1, 5};
80  m_HEX_edges[10] = {2, 6};
81  m_HEX_edges[11] = {3, 7};
82 }
std::vector< std::vector< unsigned int > > m_HEX_edges
Vertex indices for a HEX* element edges (not used!)
std::vector< std::vector< unsigned int > > m_TET_edges
Vertex indices for a TET* element edges (not used!)
std::vector< std::vector< unsigned int > > m_HEX_tetrahedrons
Vertex indices for a HEX* element tetrahedron decomposition.
std::vector< std::vector< unsigned int > > m_HEX_triangles
Vertex indices for a HEX* element surface triangles decomposition.
std::vector< std::vector< unsigned int > > m_TET_triangles
Vertex indices for a TET* element surface triangles.
std::vector< std::vector< unsigned int > > m_TET_tetrahedrons
Vertex indices for a TET* element tetrahedron.

Member Data Documentation

ExactKernel_to_Kernel carl::Intersection_Tools::ConvertExactToInexact
protected

Convert exact CGAL constructs to inexact constructs.

Definition at line 51 of file intersection_tools.h.

Kernel_to_ExactKernel carl::Intersection_Tools::ConvertInexactToExact
protected

Convert inexact CGAL constructs to exact constructs.

Definition at line 50 of file intersection_tools.h.

CGAL::Convex_hull_traits_3<ExactKernel> carl::Intersection_Tools::ExactHullTraits
protected

CGAL ExactKernel's convex hull traits.

Definition at line 47 of file intersection_tools.h.

ExactPolyhedron carl::Intersection_Tools::m_dummyPoly
protected

Intersection polyhedron.

Definition at line 45 of file intersection_tools.h.

std::vector<std::vector<unsigned int> >* carl::Intersection_Tools::m_elem_C_tetrahedrons
protected

Pointer for the appropriate tetrahedron vertex index list (useless!)

Definition at line 77 of file intersection_tools.h.

std::vector<std::vector<unsigned int> >* carl::Intersection_Tools::m_elem_C_triangles
protected

Pointer for the appropriate triangle vertex index list (useless!)

Definition at line 78 of file intersection_tools.h.

std::vector<ExactPoint_3> carl::Intersection_Tools::m_exact_points_A
protected

CGAL Exact point vectors.

Definition at line 41 of file intersection_tools.h.

std::vector<ExactPoint_3> carl::Intersection_Tools::m_exact_points_B
protected

Definition at line 42 of file intersection_tools.h.

std::vector<ExactPoint_3> carl::Intersection_Tools::m_exact_points_C
protected

Definition at line 43 of file intersection_tools.h.

std::vector<std::vector<unsigned int> > carl::Intersection_Tools::m_HEX_edges
protected

Vertex indices for a HEX* element edges (not used!)

Definition at line 75 of file intersection_tools.h.

std::vector<std::vector<unsigned int> > carl::Intersection_Tools::m_HEX_tetrahedrons
protected

Vertex indices for a HEX* element tetrahedron decomposition.

Definition at line 73 of file intersection_tools.h.

std::vector<std::vector<unsigned int> > carl::Intersection_Tools::m_HEX_triangles
protected

Vertex indices for a HEX* element surface triangles decomposition.

Definition at line 74 of file intersection_tools.h.

double carl::Intersection_Tools::m_Min_Inter_Volume
protected

Minimal volume cutoff for the intersections.

Definition at line 57 of file intersection_tools.h.

Nef_Polyhedron carl::Intersection_Tools::m_nef_A
protected

Nef polyhedrons for the elements.

Definition at line 30 of file intersection_tools.h.

Nef_Polyhedron carl::Intersection_Tools::m_nef_B
protected

Definition at line 31 of file intersection_tools.h.

Nef_Polyhedron carl::Intersection_Tools::m_nef_C
protected

Definition at line 33 of file intersection_tools.h.

Nef_Polyhedron carl::Intersection_Tools::m_nef_I
protected

Definition at line 32 of file intersection_tools.h.

Nef_Polyhedron carl::Intersection_Tools::m_nef_I_AC
protected

Nef polyhedron used to save the intersection between m_nef_A and m_nef_C, reducing the number of intersection operations.

Definition at line 38 of file intersection_tools.h.

libMesh::PerfLog carl::Intersection_Tools::m_perf_log
protected

libMesh::PerfLog object.

Definition at line 61 of file intersection_tools.h.

ExactTetrahedron carl::Intersection_Tools::m_test_tetra
protected

Definition at line 54 of file intersection_tools.h.

ExactTriangle_3 carl::Intersection_Tools::m_test_triangle
protected

Definition at line 55 of file intersection_tools.h.

std::vector<std::vector<unsigned int> > carl::Intersection_Tools::m_TET_edges
protected

Vertex indices for a TET* element edges (not used!)

Definition at line 71 of file intersection_tools.h.

std::vector<std::vector<unsigned int> > carl::Intersection_Tools::m_TET_tetrahedrons
protected

Vertex indices for a TET* element tetrahedron.

Definition at line 69 of file intersection_tools.h.

std::vector<std::vector<unsigned int> > carl::Intersection_Tools::m_TET_triangles
protected

Vertex indices for a TET* element surface triangles.

Definition at line 70 of file intersection_tools.h.

bool carl::Intersection_Tools::MASTER_bPerfLog_intersection_tools
protected

Do performance log? Default: false.

Definition at line 60 of file intersection_tools.h.


The documentation for this class was generated from the following files: