libMesh
Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
libMesh::ElemCutter Class Reference

This class implements cutting a single element into a collection of subelements. More...

#include <elem_cutter.h>

Public Member Functions

 ElemCutter ()
 Constructor. More...
 
 ~ElemCutter ()
 Destructor. More...
 
bool is_inside (const Elem &elem, const std::vector< Real > &vertex_distance_func) const
 
bool is_outside (const Elem &elem, const std::vector< Real > &vertex_distance_func) const
 
bool is_cut (const Elem &elem, const std::vector< Real > &vertex_distance_func) const
 
void operator() (const Elem &elem_in, const std::vector< Real > &vertex_distance_func)
 This function implements cutting an element by a signed distance function. More...
 
const std::vector< Elem const * > & inside_elements () const
 
const std::vector< Elem const * > & outside_elements () const
 

Protected Member Functions

void find_intersection_points (const Elem &elem, const std::vector< Real > &vertex_distance_func)
 Finds the points where the cutting surface intersects the element edges. More...
 
void cut_1D (const Elem &elem, const std::vector< Real > &vertex_distance_func)
 cutting algorithm in 1D. More...
 
void cut_2D (const Elem &elem, const std::vector< Real > &vertex_distance_func)
 cutting algorithm in 2D. More...
 
void cut_3D (const Elem &elem, const std::vector< Real > &vertex_distance_func)
 cutting algorithm in 3D. More...
 

Protected Attributes

std::vector< Elem const * > _inside_elem
 
std::vector< Elem const * > _outside_elem
 
Parallel::Communicator _comm_self
 
std::unique_ptr< ReplicatedMesh_inside_mesh_2D
 
std::unique_ptr< TriangleInterface_triangle_inside
 
std::unique_ptr< ReplicatedMesh_outside_mesh_2D
 
std::unique_ptr< TriangleInterface_triangle_outside
 
std::unique_ptr< ReplicatedMesh_inside_mesh_3D
 
std::unique_ptr< TetGenMeshInterface_tetgen_inside
 
std::unique_ptr< ReplicatedMesh_outside_mesh_3D
 
std::unique_ptr< TetGenMeshInterface_tetgen_outside
 
std::vector< Point_intersection_pts
 

Detailed Description

This class implements cutting a single element into a collection of subelements.

This class depends on libmesh's Triangle and Tetgen interfaces, the former of which is only defined if libmesh is configured with –disable-strict-lgpl.

Author
Benjamin S. Kirk
Date
2013 Subdivides a single element using a mesh generator.

Definition at line 61 of file elem_cutter.h.

Constructor & Destructor Documentation

◆ ElemCutter()

libMesh::ElemCutter::ElemCutter ( )

Constructor.

Initializes pointer data without requiring a full ReplicatedMesh in this header file.

Definition at line 40 of file elem_cutter.C.

40  :
41  _inside_mesh_2D(std::make_unique<ReplicatedMesh>(_comm_self,2)),
42  _triangle_inside(std::make_unique<TriangleInterface>(*_inside_mesh_2D)),
43  _outside_mesh_2D(std::make_unique<ReplicatedMesh>(_comm_self,2)),
44  _triangle_outside(std::make_unique<TriangleInterface>(*_outside_mesh_2D)),
45  _inside_mesh_3D(std::make_unique<ReplicatedMesh>(_comm_self,3)),
46  _tetgen_inside(std::make_unique<TetGenMeshInterface>(*_inside_mesh_3D)),
47  _outside_mesh_3D(std::make_unique<ReplicatedMesh>(_comm_self,3)),
48  _tetgen_outside(std::make_unique<TetGenMeshInterface>(*_outside_mesh_3D))
49 {
50  cut_cntr = 0;
51 }
std::unique_ptr< ReplicatedMesh > _inside_mesh_3D
Definition: elem_cutter.h:166
std::unique_ptr< ReplicatedMesh > _inside_mesh_2D
Definition: elem_cutter.h:160
std::unique_ptr< TriangleInterface > _triangle_outside
Definition: elem_cutter.h:164
std::unique_ptr< ReplicatedMesh > _outside_mesh_3D
Definition: elem_cutter.h:169
std::unique_ptr< TriangleInterface > _triangle_inside
Definition: elem_cutter.h:161
std::unique_ptr< TetGenMeshInterface > _tetgen_inside
Definition: elem_cutter.h:167
std::unique_ptr< TetGenMeshInterface > _tetgen_outside
Definition: elem_cutter.h:170
std::unique_ptr< ReplicatedMesh > _outside_mesh_2D
Definition: elem_cutter.h:163
Parallel::Communicator _comm_self
Definition: elem_cutter.h:158

◆ ~ElemCutter()

libMesh::ElemCutter::~ElemCutter ( )
default

Destructor.

Member Function Documentation

◆ cut_1D()

void libMesh::ElemCutter::cut_1D ( const Elem elem,
const std::vector< Real > &  vertex_distance_func 
)
protected

cutting algorithm in 1D.

Definition at line 212 of file elem_cutter.C.

Referenced by operator()().

214 {
215  libmesh_not_implemented();
216 }

◆ cut_2D()

void libMesh::ElemCutter::cut_2D ( const Elem elem,
const std::vector< Real > &  vertex_distance_func 
)
protected

cutting algorithm in 2D.

Definition at line 220 of file elem_cutter.C.

References _inside_elem, _inside_mesh_2D, _intersection_pts, _outside_elem, _outside_mesh_2D, _triangle_inside, _triangle_outside, libMesh::err, libMesh::libmesh_assert(), libMesh::make_range(), libMesh::Elem::n_vertices(), and libMesh::Elem::point().

Referenced by operator()().

222 {
223 #ifndef LIBMESH_HAVE_TRIANGLE
224 
225  // current implementation requires triangle!
226  libMesh::err << "ERROR: current libMesh ElemCutter 2D implementation requires\n"
227  << " the \"triangle\" library!\n"
228  << std::endl;
229  libmesh_not_implemented();
230 
231 #else // OK, LIBMESH_HAVE_TRIANGLE
232 
233  // std::cout << "Inside cut face element!\n";
234 
235  libmesh_assert (_inside_mesh_2D.get() != nullptr);
236  libmesh_assert (_outside_mesh_2D.get() != nullptr);
237 
238  _inside_mesh_2D->clear();
239  _outside_mesh_2D->clear();
240 
241  for (auto v : make_range(elem.n_vertices()))
242  {
243  if (vertex_distance_func[v] >= 0.)
244  _outside_mesh_2D->add_point (elem.point(v));
245 
246  if (vertex_distance_func[v] <= 0.)
247  _inside_mesh_2D->add_point (elem.point(v));
248  }
249 
250  for (const auto & pt : _intersection_pts)
251  {
252  _inside_mesh_2D->add_point(pt);
253  _outside_mesh_2D->add_point(pt);
254  }
255 
256 
257  // Customize the variables for the triangulation
258  // we will be cutting reference cell, and want as few triangles
259  // as possible, so jack this up larger than the area we will be
260  // triangulating so we are governed only by accurately defining
261  // the boundaries.
262  _triangle_inside->desired_area() = 100.;
263  _triangle_outside->desired_area() = 100.;
264 
265  // allow for small angles
266  _triangle_inside->minimum_angle() = 5.;
267  _triangle_outside->minimum_angle() = 5.;
268 
269  // Turn off Laplacian mesh smoothing after generation.
270  _triangle_inside->smooth_after_generating() = false;
271  _triangle_outside->smooth_after_generating() = false;
272 
273  // Triangulate!
274  _triangle_inside->triangulate();
275  _triangle_outside->triangulate();
276 
277  // std::ostringstream name;
278 
279  // name << "cut_face_"
280  // << cut_cntr++
281  // << ".dat";
282  // _inside_mesh_2D->write ("in_" + name.str());
283  // _outside_mesh_2D->write ("out_" + name.str());
284 
285  // finally, add the elements to our lists.
286  _inside_elem.clear();
287  _outside_elem.clear();
288 
289  for (const auto & el : _inside_mesh_2D->element_ptr_range())
290  _inside_elem.push_back (el);
291 
292  for (const auto & el : _outside_mesh_2D->element_ptr_range())
293  _outside_elem.push_back (el);
294 
295 #endif
296 }
OStreamProxy err
std::unique_ptr< ReplicatedMesh > _inside_mesh_2D
Definition: elem_cutter.h:160
std::vector< Point > _intersection_pts
Definition: elem_cutter.h:172
std::unique_ptr< TriangleInterface > _triangle_outside
Definition: elem_cutter.h:164
std::vector< Elem const * > _inside_elem
Definition: elem_cutter.h:155
std::unique_ptr< TriangleInterface > _triangle_inside
Definition: elem_cutter.h:161
libmesh_assert(ctx)
std::vector< Elem const * > _outside_elem
Definition: elem_cutter.h:156
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:134
std::unique_ptr< ReplicatedMesh > _outside_mesh_2D
Definition: elem_cutter.h:163

◆ cut_3D()

void libMesh::ElemCutter::cut_3D ( const Elem elem,
const std::vector< Real > &  vertex_distance_func 
)
protected

cutting algorithm in 3D.

Definition at line 300 of file elem_cutter.C.

References _inside_elem, _inside_mesh_3D, _intersection_pts, _outside_elem, _outside_mesh_3D, _tetgen_inside, _tetgen_outside, libMesh::err, libMesh::libmesh_assert(), libMesh::make_range(), libMesh::Elem::n_vertices(), libMesh::Quality::name(), and libMesh::Elem::point().

Referenced by operator()().

302 {
303 #ifndef LIBMESH_HAVE_TETGEN
304 
305  // current implementation requires tetgen!
306  libMesh::err << "ERROR: current libMesh ElemCutter 3D implementation requires\n"
307  << " the \"tetgen\" library!\n"
308  << std::endl;
309  libmesh_not_implemented();
310 
311 #else // OK, LIBMESH_HAVE_TETGEN
312 
313  // std::cout << "Inside cut cell element!\n";
314 
315  libmesh_assert (_inside_mesh_3D.get() != nullptr);
316  libmesh_assert (_outside_mesh_3D.get() != nullptr);
317 
318  _inside_mesh_3D->clear();
319  _outside_mesh_3D->clear();
320 
321  for (auto v : make_range(elem.n_vertices()))
322  {
323  if (vertex_distance_func[v] >= 0.)
324  _outside_mesh_3D->add_point (elem.point(v));
325 
326  if (vertex_distance_func[v] <= 0.)
327  _inside_mesh_3D->add_point (elem.point(v));
328  }
329 
330  for (const auto & pt : _intersection_pts)
331  {
332  _inside_mesh_3D->add_point(pt);
333  _outside_mesh_3D->add_point(pt);
334  }
335 
336 
337  // Triangulate!
338  _tetgen_inside->triangulate_pointset();
339  //_inside_mesh_3D->print_info();
340  _tetgen_outside->triangulate_pointset();
341  //_outside_mesh_3D->print_info();
342 
343 
344  // (below generates some horribly expensive meshes,
345  // but seems immune to the 0 volume problem).
346  // _tetgen_inside->pointset_convexhull();
347  // _inside_mesh_3D->find_neighbors();
348  // _inside_mesh_3D->print_info();
349  // _tetgen_inside->triangulate_conformingDelaunayMesh (1.e3, 100.);
350  // _inside_mesh_3D->print_info();
351 
352  // _tetgen_outside->pointset_convexhull();
353  // _outside_mesh_3D->find_neighbors();
354  // _outside_mesh_3D->print_info();
355  // _tetgen_outside->triangulate_conformingDelaunayMesh (1.e3, 100.);
356  // _outside_mesh_3D->print_info();
357 
358  std::ostringstream name;
359 
360  name << "cut_cell_"
361  << cut_cntr++
362  << ".dat";
363  _inside_mesh_3D->write ("in_" + name.str());
364  _outside_mesh_3D->write ("out_" + name.str());
365 
366  // finally, add the elements to our lists.
367  _inside_elem.clear();
368  _outside_elem.clear();
369 
370  for (const auto & el : _inside_mesh_3D->element_ptr_range())
371  if (el->volume() > std::numeric_limits<Real>::epsilon())
372  _inside_elem.push_back (el);
373 
374  for (const auto & el : _outside_mesh_3D->element_ptr_range())
375  if (el->volume() > std::numeric_limits<Real>::epsilon())
376  _outside_elem.push_back (el);
377 
378 #endif
379 }
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
OStreamProxy err
std::unique_ptr< ReplicatedMesh > _inside_mesh_3D
Definition: elem_cutter.h:166
std::vector< Point > _intersection_pts
Definition: elem_cutter.h:172
std::vector< Elem const * > _inside_elem
Definition: elem_cutter.h:155
std::unique_ptr< ReplicatedMesh > _outside_mesh_3D
Definition: elem_cutter.h:169
libmesh_assert(ctx)
std::unique_ptr< TetGenMeshInterface > _tetgen_inside
Definition: elem_cutter.h:167
std::unique_ptr< TetGenMeshInterface > _tetgen_outside
Definition: elem_cutter.h:170
std::vector< Elem const * > _outside_elem
Definition: elem_cutter.h:156
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:134

◆ find_intersection_points()

void libMesh::ElemCutter::find_intersection_points ( const Elem elem,
const std::vector< Real > &  vertex_distance_func 
)
protected

Finds the points where the cutting surface intersects the element edges.

Definition at line 155 of file elem_cutter.C.

References _intersection_pts, libMesh::Elem::build_edge_ptr(), libMesh::Elem::edge_index_range(), libMesh::Elem::get_node_index(), libMesh::Elem::is_vertex(), libMesh::libmesh_assert(), and libMesh::Real.

Referenced by operator()().

157 {
158  _intersection_pts.clear();
159 
160  for (auto e : elem.edge_index_range())
161  {
162  std::unique_ptr<const Elem> edge (elem.build_edge_ptr(e));
163 
164  // find the element nodes el0, el1 that map
165  unsigned int
166  el0 = elem.get_node_index(edge->node_ptr(0)),
167  el1 = elem.get_node_index(edge->node_ptr(1));
168 
169  libmesh_assert (elem.is_vertex(el0));
170  libmesh_assert (elem.is_vertex(el1));
171  libmesh_assert_less (el0, vertex_distance_func.size());
172  libmesh_assert_less (el1, vertex_distance_func.size());
173 
174  const Real
175  d0 = vertex_distance_func[el0],
176  d1 = vertex_distance_func[el1];
177 
178  // if this edge has a 0 crossing
179  if (d0*d1 < 0.)
180  {
181  libmesh_assert_not_equal_to (d0, d1);
182 
183  // then find d_star in [0,1], the
184  // distance from el0 to el1 where the 0 lives.
185  const Real d_star = d0 / (d0 - d1);
186 
187 
188  // Prevent adding nodes trivially close to existing
189  // nodes.
190  const Real endpoint_tol = 0.01;
191 
192  if ( (d_star > endpoint_tol) &&
193  (d_star < (1.-endpoint_tol)) )
194  {
195  const Point x_star = (edge->point(0)*(1-d_star) +
196  edge->point(1)*d_star);
197 
198  /*
199  std::cout << "adding cut point (d_star, x_star) = "
200  << d_star << " , " << x_star << std::endl;
201  */
202 
203  _intersection_pts.push_back (x_star);
204  }
205  }
206  }
207 }
std::vector< Point > _intersection_pts
Definition: elem_cutter.h:172
libmesh_assert(ctx)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

◆ inside_elements()

const std::vector<Elem const *>& libMesh::ElemCutter::inside_elements ( ) const
inline
Returns
A list of general element pieces considered inside the cutting surface. These are subelements whose geometric union defines the spatial domain of the inside portion of the cut element.

Definition at line 117 of file elem_cutter.h.

References _inside_elem.

118  { return _inside_elem; }
std::vector< Elem const * > _inside_elem
Definition: elem_cutter.h:155

◆ is_cut()

bool libMesh::ElemCutter::is_cut ( const Elem elem,
const std::vector< Real > &  vertex_distance_func 
) const
Returns
true if the element is cut by the interface defined implicitly by the vertex values of the signed vertex_distance_func.

Definition at line 89 of file elem_cutter.C.

References libMesh::Real.

Referenced by operator()().

91 {
92  libmesh_assert_equal_to (elem.n_vertices(), vertex_distance_func.size());
93 
94  Real
95  vmin = vertex_distance_func.front(),
96  vmax = vmin;
97 
98  for (const auto & val : vertex_distance_func)
99  {
100  vmin = std::min (vmin, val);
101  vmax = std::max (vmax, val);
102  }
103 
104  // if the distance function changes sign, we're cut.
105  return (vmin*vmax < 0.);
106 }
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

◆ is_inside()

bool libMesh::ElemCutter::is_inside ( const Elem elem,
const std::vector< Real > &  vertex_distance_func 
) const
Returns
true if the element is completely inside the interface defined implicitly by the vertex values of the signed vertex_distance_func.

Definition at line 59 of file elem_cutter.C.

Referenced by operator()().

61 {
62  libmesh_assert_equal_to (elem.n_vertices(), vertex_distance_func.size());
63 
64  for (const auto & val : vertex_distance_func)
65  if (val > 0.)
66  return false;
67 
68  // if the distance function is nonpositive, we are outside
69  return true;
70 }

◆ is_outside()

bool libMesh::ElemCutter::is_outside ( const Elem elem,
const std::vector< Real > &  vertex_distance_func 
) const
Returns
true if the element is completely outside the interface defined implicitly by the vertex values of the signed vertex_distance_func.

Definition at line 74 of file elem_cutter.C.

Referenced by operator()().

76 {
77  libmesh_assert_equal_to (elem.n_vertices(), vertex_distance_func.size());
78 
79  for (const auto & val : vertex_distance_func)
80  if (val < 0.)
81  return false;
82 
83  // if the distance function is nonnegative, we are outside
84  return true;
85 }

◆ operator()()

void libMesh::ElemCutter::operator() ( const Elem elem_in,
const std::vector< Real > &  vertex_distance_func 
)

This function implements cutting an element by a signed distance function.

The input array vertex_distance_func contains the vertex values of a signed distance function, from which the cutting interface is inferred from the 0 level set. If all vertex values are positive, the element is outside the cutting surface and is not cut. Likewise if all vertex values are negative, the element is inside the cutting surface and is not cut.

Definition at line 110 of file elem_cutter.C.

References _inside_elem, _outside_elem, cut_1D(), cut_2D(), cut_3D(), libMesh::Elem::dim(), find_intersection_points(), is_cut(), is_inside(), is_outside(), libMesh::libmesh_assert(), and libMesh::Elem::n_vertices().

113 {
114  libmesh_assert_equal_to (vertex_distance_func.size(), elem.n_vertices());
115 
116  _inside_elem.clear();
117  _outside_elem.clear();
118 
119  // check for quick return?
120  {
121  // completely outside?
122  if (this->is_outside(elem, vertex_distance_func))
123  {
124  //std::cout << "element completely outside\n";
125  _outside_elem.push_back(& elem);
126  return;
127  }
128 
129  // completely inside?
130  else if (this->is_inside(elem, vertex_distance_func))
131  {
132  //std::cout << "element completely inside\n";
133  _inside_elem.push_back(&elem);
134  return;
135  }
136 
137  libmesh_assert (this->is_cut (elem, vertex_distance_func));
138  }
139 
140  // we now know we are in a cut element, find the intersecting points.
141  this->find_intersection_points (elem, vertex_distance_func);
142 
143  // and then dispatch the proper method
144  switch (elem.dim())
145  {
146  case 1: this->cut_1D(elem, vertex_distance_func); break;
147  case 2: this->cut_2D(elem, vertex_distance_func); break;
148  case 3: this->cut_3D(elem, vertex_distance_func); break;
149  default: libmesh_error_msg("Invalid element dimension: " << elem.dim());
150  }
151 }
void find_intersection_points(const Elem &elem, const std::vector< Real > &vertex_distance_func)
Finds the points where the cutting surface intersects the element edges.
Definition: elem_cutter.C:155
void cut_1D(const Elem &elem, const std::vector< Real > &vertex_distance_func)
cutting algorithm in 1D.
Definition: elem_cutter.C:212
bool is_cut(const Elem &elem, const std::vector< Real > &vertex_distance_func) const
Definition: elem_cutter.C:89
void cut_2D(const Elem &elem, const std::vector< Real > &vertex_distance_func)
cutting algorithm in 2D.
Definition: elem_cutter.C:220
std::vector< Elem const * > _inside_elem
Definition: elem_cutter.h:155
void cut_3D(const Elem &elem, const std::vector< Real > &vertex_distance_func)
cutting algorithm in 3D.
Definition: elem_cutter.C:300
libmesh_assert(ctx)
bool is_outside(const Elem &elem, const std::vector< Real > &vertex_distance_func) const
Definition: elem_cutter.C:74
bool is_inside(const Elem &elem, const std::vector< Real > &vertex_distance_func) const
Definition: elem_cutter.C:59
std::vector< Elem const * > _outside_elem
Definition: elem_cutter.h:156

◆ outside_elements()

const std::vector<Elem const *>& libMesh::ElemCutter::outside_elements ( ) const
inline
Returns
A list of general element pieces considered outside the cutting surface. These are subelements whose geometric union defines the spatial domain of the outside portion of the cut element.

Definition at line 125 of file elem_cutter.h.

References _outside_elem.

126  { return _outside_elem; }
std::vector< Elem const * > _outside_elem
Definition: elem_cutter.h:156

Member Data Documentation

◆ _comm_self

Parallel::Communicator libMesh::ElemCutter::_comm_self
protected

Definition at line 158 of file elem_cutter.h.

◆ _inside_elem

std::vector<Elem const *> libMesh::ElemCutter::_inside_elem
protected

Definition at line 155 of file elem_cutter.h.

Referenced by cut_2D(), cut_3D(), inside_elements(), and operator()().

◆ _inside_mesh_2D

std::unique_ptr<ReplicatedMesh> libMesh::ElemCutter::_inside_mesh_2D
protected

Definition at line 160 of file elem_cutter.h.

Referenced by cut_2D().

◆ _inside_mesh_3D

std::unique_ptr<ReplicatedMesh> libMesh::ElemCutter::_inside_mesh_3D
protected

Definition at line 166 of file elem_cutter.h.

Referenced by cut_3D().

◆ _intersection_pts

std::vector<Point> libMesh::ElemCutter::_intersection_pts
protected

Definition at line 172 of file elem_cutter.h.

Referenced by cut_2D(), cut_3D(), and find_intersection_points().

◆ _outside_elem

std::vector<Elem const *> libMesh::ElemCutter::_outside_elem
protected

Definition at line 156 of file elem_cutter.h.

Referenced by cut_2D(), cut_3D(), operator()(), and outside_elements().

◆ _outside_mesh_2D

std::unique_ptr<ReplicatedMesh> libMesh::ElemCutter::_outside_mesh_2D
protected

Definition at line 163 of file elem_cutter.h.

Referenced by cut_2D().

◆ _outside_mesh_3D

std::unique_ptr<ReplicatedMesh> libMesh::ElemCutter::_outside_mesh_3D
protected

Definition at line 169 of file elem_cutter.h.

Referenced by cut_3D().

◆ _tetgen_inside

std::unique_ptr<TetGenMeshInterface> libMesh::ElemCutter::_tetgen_inside
protected

Definition at line 167 of file elem_cutter.h.

Referenced by cut_3D().

◆ _tetgen_outside

std::unique_ptr<TetGenMeshInterface> libMesh::ElemCutter::_tetgen_outside
protected

Definition at line 170 of file elem_cutter.h.

Referenced by cut_3D().

◆ _triangle_inside

std::unique_ptr<TriangleInterface> libMesh::ElemCutter::_triangle_inside
protected

Definition at line 161 of file elem_cutter.h.

Referenced by cut_2D().

◆ _triangle_outside

std::unique_ptr<TriangleInterface> libMesh::ElemCutter::_triangle_outside
protected

Definition at line 164 of file elem_cutter.h.

Referenced by cut_2D().


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