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
 
UniquePtr< ReplicatedMesh_inside_mesh_2D
 
UniquePtr< ReplicatedMesh_outside_mesh_2D
 
UniquePtr< ReplicatedMesh_inside_mesh_3D
 
UniquePtr< ReplicatedMesh_outside_mesh_3D
 
Parallel::Communicator _comm_self
 
UniquePtr< TriangleInterface_triangle_inside
 
UniquePtr< TriangleInterface_triangle_outside
 
UniquePtr< TetGenMeshInterface_tetgen_inside
 
UniquePtr< 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 59 of file elem_cutter.h.

Constructor & Destructor Documentation

libMesh::ElemCutter::ElemCutter ( )

Constructor.

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

Definition at line 41 of file elem_cutter.C.

References _comm_self, _inside_mesh_2D, _inside_mesh_3D, _outside_mesh_2D, _outside_mesh_3D, _tetgen_inside, _tetgen_outside, _triangle_inside, and _triangle_outside.

42 {
43  _inside_mesh_2D.reset (new ReplicatedMesh(_comm_self,2)); _triangle_inside.reset (new TriangleInterface (*_inside_mesh_2D));
44  _outside_mesh_2D.reset (new ReplicatedMesh(_comm_self,2)); _triangle_outside.reset (new TriangleInterface (*_outside_mesh_2D));
45 
46  _inside_mesh_3D.reset (new ReplicatedMesh(_comm_self,3)); _tetgen_inside.reset (new TetGenMeshInterface (*_inside_mesh_3D));
47  _outside_mesh_3D.reset (new ReplicatedMesh(_comm_self,3)); _tetgen_outside.reset (new TetGenMeshInterface (*_outside_mesh_3D));
48 
49  cut_cntr = 0;
50 }
UniquePtr< ReplicatedMesh > _outside_mesh_3D
Definition: elem_cutter.h:159
UniquePtr< ReplicatedMesh > _inside_mesh_3D
Definition: elem_cutter.h:158
UniquePtr< TriangleInterface > _triangle_outside
Definition: elem_cutter.h:164
UniquePtr< ReplicatedMesh > _inside_mesh_2D
Definition: elem_cutter.h:156
UniquePtr< ReplicatedMesh > _outside_mesh_2D
Definition: elem_cutter.h:157
UniquePtr< TetGenMeshInterface > _tetgen_outside
Definition: elem_cutter.h:166
UniquePtr< TetGenMeshInterface > _tetgen_inside
Definition: elem_cutter.h:165
UniquePtr< TriangleInterface > _triangle_inside
Definition: elem_cutter.h:163
Parallel::Communicator _comm_self
Definition: elem_cutter.h:161
libMesh::ElemCutter::~ElemCutter ( )

Destructor.

Definition at line 54 of file elem_cutter.C.

55 {}

Member Function Documentation

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

cutting algorithm in 1D.

Definition at line 211 of file elem_cutter.C.

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

213 {
214  libmesh_not_implemented();
215 }
void libMesh::ElemCutter::cut_2D ( const Elem elem,
const std::vector< Real > &  vertex_distance_func 
)
protected

cutting algorithm in 2D.

Definition at line 219 of file elem_cutter.C.

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

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

221 {
222 #ifndef LIBMESH_HAVE_TRIANGLE
223 
224  // current implementation requires triangle!
225  libMesh::err << "ERROR: current libMesh ElemCutter 2D implementation requires\n"
226  << " the \"triangle\" library!\n"
227  << std::endl;
228  libmesh_not_implemented();
229 
230 #else // OK, LIBMESH_HAVE_TRIANGLE
231 
232  std::cout << "Inside cut face element!\n";
233 
236 
237  _inside_mesh_2D->clear();
238  _outside_mesh_2D->clear();
239 
240  for (unsigned int v=0; v<elem.n_vertices(); v++)
241  {
242  if (vertex_distance_func[v] >= 0.)
243  _outside_mesh_2D->add_point (elem.point(v));
244 
245  if (vertex_distance_func[v] <= 0.)
246  _inside_mesh_2D->add_point (elem.point(v));
247  }
248 
249  for (std::vector<Point>::const_iterator it=_intersection_pts.begin();
250  it != _intersection_pts.end(); ++it)
251  {
252  _inside_mesh_2D->add_point(*it);
253  _outside_mesh_2D->add_point(*it);
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  {
287  _inside_elem.clear(); _outside_elem.clear();
288 
289  MeshBase::const_element_iterator
290  it = _inside_mesh_2D->elements_begin(),
291  end = _inside_mesh_2D->elements_end();
292 
293  for (; it!=end; ++it)
294  _inside_elem.push_back (*it);
295 
296  it = _outside_mesh_2D->elements_begin();
297  end = _outside_mesh_2D->elements_end();
298 
299  for (; it!=end; ++it)
300  _outside_elem.push_back (*it);
301  }
302 
303 #endif
304 }
OStreamProxy err
UniquePtr< TriangleInterface > _triangle_outside
Definition: elem_cutter.h:164
UniquePtr< ReplicatedMesh > _inside_mesh_2D
Definition: elem_cutter.h:156
std::vector< Point > _intersection_pts
Definition: elem_cutter.h:168
const class libmesh_nullptr_t libmesh_nullptr
IterBase * end
Also have a polymorphic pointer to the end object, this prevents iterating past the end...
UniquePtr< ReplicatedMesh > _outside_mesh_2D
Definition: elem_cutter.h:157
libmesh_assert(j)
std::vector< Elem const * > _inside_elem
Definition: elem_cutter.h:153
std::vector< Elem const * > _outside_elem
Definition: elem_cutter.h:154
UniquePtr< TriangleInterface > _triangle_inside
Definition: elem_cutter.h:163
void libMesh::ElemCutter::cut_3D ( const Elem elem,
const std::vector< Real > &  vertex_distance_func 
)
protected

cutting algorithm in 3D.

Definition at line 308 of file elem_cutter.C.

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

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

310 {
311 #ifndef LIBMESH_HAVE_TETGEN
312 
313  // current implementation requires tetgen!
314  libMesh::err << "ERROR: current libMesh ElemCutter 3D implementation requires\n"
315  << " the \"tetgen\" library!\n"
316  << std::endl;
317  libmesh_not_implemented();
318 
319 #else // OK, LIBMESH_HAVE_TETGEN
320 
321  std::cout << "Inside cut cell element!\n";
322 
325 
326  _inside_mesh_3D->clear();
327  _outside_mesh_3D->clear();
328 
329  for (unsigned int v=0; v<elem.n_vertices(); v++)
330  {
331  if (vertex_distance_func[v] >= 0.)
332  _outside_mesh_3D->add_point (elem.point(v));
333 
334  if (vertex_distance_func[v] <= 0.)
335  _inside_mesh_3D->add_point (elem.point(v));
336  }
337 
338  for (std::vector<Point>::const_iterator it=_intersection_pts.begin();
339  it != _intersection_pts.end(); ++it)
340  {
341  _inside_mesh_3D->add_point(*it);
342  _outside_mesh_3D->add_point(*it);
343  }
344 
345 
346  // Triangulate!
347  _tetgen_inside->triangulate_pointset();
348  //_inside_mesh_3D->print_info();
349  _tetgen_outside->triangulate_pointset();
350  //_outside_mesh_3D->print_info();
351 
352 
353  // (below generates some horribly expensive meshes,
354  // but seems immune to the 0 volume problem).
355  // _tetgen_inside->pointset_convexhull();
356  // _inside_mesh_3D->find_neighbors();
357  // _inside_mesh_3D->print_info();
358  // _tetgen_inside->triangulate_conformingDelaunayMesh (1.e3, 100.);
359  // _inside_mesh_3D->print_info();
360 
361  // _tetgen_outside->pointset_convexhull();
362  // _outside_mesh_3D->find_neighbors();
363  // _outside_mesh_3D->print_info();
364  // _tetgen_outside->triangulate_conformingDelaunayMesh (1.e3, 100.);
365  // _outside_mesh_3D->print_info();
366 
367  std::ostringstream name;
368 
369  name << "cut_cell_"
370  << cut_cntr++
371  << ".dat";
372  _inside_mesh_3D->write ("in_" + name.str());
373  _outside_mesh_3D->write ("out_" + name.str());
374 
375  // finally, add the elements to our lists.
376  {
377  _inside_elem.clear(); _outside_elem.clear();
378 
379  MeshBase::const_element_iterator
380  it = _inside_mesh_3D->elements_begin(),
381  end = _inside_mesh_3D->elements_end();
382 
383  for (; it!=end; ++it)
384  if ((*it)->volume() > std::numeric_limits<Real>::epsilon())
385  _inside_elem.push_back (*it);
386 
387  it = _outside_mesh_3D->elements_begin();
388  end = _outside_mesh_3D->elements_end();
389 
390  for (; it!=end; ++it)
391  if ((*it)->volume() > std::numeric_limits<Real>::epsilon())
392  _outside_elem.push_back (*it);
393  }
394 
395 #endif
396 }
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:39
OStreamProxy err
UniquePtr< ReplicatedMesh > _outside_mesh_3D
Definition: elem_cutter.h:159
UniquePtr< ReplicatedMesh > _inside_mesh_3D
Definition: elem_cutter.h:158
std::vector< Point > _intersection_pts
Definition: elem_cutter.h:168
const class libmesh_nullptr_t libmesh_nullptr
IterBase * end
Also have a polymorphic pointer to the end object, this prevents iterating past the end...
libmesh_assert(j)
UniquePtr< TetGenMeshInterface > _tetgen_outside
Definition: elem_cutter.h:166
std::vector< Elem const * > _inside_elem
Definition: elem_cutter.h:153
UniquePtr< TetGenMeshInterface > _tetgen_inside
Definition: elem_cutter.h:165
std::vector< Elem const * > _outside_elem
Definition: elem_cutter.h:154
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 156 of file elem_cutter.C.

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

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

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

References _inside_elem.

116  { return _inside_elem; }
std::vector< Elem const * > _inside_elem
Definition: elem_cutter.h:153
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 std::max(), std::min(), and 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 (std::vector<Real>::const_iterator it=vertex_distance_func.begin();
99  it!=vertex_distance_func.end(); ++it)
100  {
101  vmin = std::min (vmin, *it);
102  vmax = std::max (vmax, *it);
103  }
104 
105  // if the distance function changes sign, we're cut.
106  return (vmin*vmax < 0.);
107 }
long double max(long double a, double b)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
long double min(long double a, double b)
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 (std::vector<Real>::const_iterator it=vertex_distance_func.begin();
65  it!=vertex_distance_func.end(); ++it)
66  if (*it > 0.) return false;
67 
68  // if the distance function is nonpositive, we are outside
69  return true;
70 }
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 (std::vector<Real>::const_iterator it=vertex_distance_func.begin();
80  it!=vertex_distance_func.end(); ++it)
81  if (*it < 0.) return false;
82 
83  // if the distance function is nonnegative, we are outside
84  return true;
85 }
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 111 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().

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

References _outside_elem, cut_1D(), cut_2D(), cut_3D(), and find_intersection_points().

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

Member Data Documentation

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

Definition at line 161 of file elem_cutter.h.

Referenced by ElemCutter().

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

Definition at line 153 of file elem_cutter.h.

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

UniquePtr<ReplicatedMesh> libMesh::ElemCutter::_inside_mesh_2D
protected

Definition at line 156 of file elem_cutter.h.

Referenced by cut_2D(), and ElemCutter().

UniquePtr<ReplicatedMesh> libMesh::ElemCutter::_inside_mesh_3D
protected

Definition at line 158 of file elem_cutter.h.

Referenced by cut_3D(), and ElemCutter().

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

Definition at line 168 of file elem_cutter.h.

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

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

Definition at line 154 of file elem_cutter.h.

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

UniquePtr<ReplicatedMesh> libMesh::ElemCutter::_outside_mesh_2D
protected

Definition at line 157 of file elem_cutter.h.

Referenced by cut_2D(), and ElemCutter().

UniquePtr<ReplicatedMesh> libMesh::ElemCutter::_outside_mesh_3D
protected

Definition at line 159 of file elem_cutter.h.

Referenced by cut_3D(), and ElemCutter().

UniquePtr<TetGenMeshInterface> libMesh::ElemCutter::_tetgen_inside
protected

Definition at line 165 of file elem_cutter.h.

Referenced by cut_3D(), and ElemCutter().

UniquePtr<TetGenMeshInterface> libMesh::ElemCutter::_tetgen_outside
protected

Definition at line 166 of file elem_cutter.h.

Referenced by cut_3D(), and ElemCutter().

UniquePtr<TriangleInterface> libMesh::ElemCutter::_triangle_inside
protected

Definition at line 163 of file elem_cutter.h.

Referenced by cut_2D(), and ElemCutter().

UniquePtr<TriangleInterface> libMesh::ElemCutter::_triangle_outside
protected

Definition at line 164 of file elem_cutter.h.

Referenced by cut_2D(), and ElemCutter().


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