libMesh
inf_elem_builder.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 #include "libmesh/libmesh_config.h"
19 
20 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
21 
22 // C++ includes
23 
24 // Local includes
25 #include "libmesh/inf_elem_builder.h"
26 #include "libmesh/libmesh_logging.h"
27 #include "libmesh/mesh_tools.h"
28 #include "libmesh/face_inf_quad4.h"
29 #include "libmesh/face_inf_quad6.h"
30 #include "libmesh/cell_inf_prism6.h"
31 #include "libmesh/cell_inf_prism12.h"
32 #include "libmesh/cell_inf_hex8.h"
33 #include "libmesh/cell_inf_hex16.h"
34 #include "libmesh/cell_inf_hex18.h"
35 #include "libmesh/mesh_base.h"
36 #include "libmesh/remote_elem.h"
37 
38 namespace libMesh
39 {
40 
41 const Point InfElemBuilder::build_inf_elem(bool be_verbose)
42 {
43  // determine origin automatically,
44  // works only if the mesh has no symmetry planes.
46  Point origin = (b_box.first + b_box.second) / 2;
47 
48  if (be_verbose && _mesh.processor_id() == 0)
49  {
50 #ifdef DEBUG
51  libMesh::out << " Determined origin for Infinite Elements:"
52  << std::endl
53  << " ";
55  libMesh::out << std::endl;
56 #endif
57  }
58 
59  // Call the protected implementation function with the
60  // automatically determined origin.
61  this->build_inf_elem(origin, false, false, false, be_verbose);
62 
63  // when finished with building the Ifems,
64  // it remains to prepare the mesh for use:
65  // find neighbors (again), partition (if needed)...
66  this->_mesh.prepare_for_use (/*skip_renumber =*/ false);
67 
68  return origin;
69 }
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
83  const InfElemOriginValue & origin_y,
84  const InfElemOriginValue & origin_z,
85  const bool x_sym,
86  const bool y_sym,
87  const bool z_sym,
88  const bool be_verbose,
89  std::vector<const Node *> * inner_boundary_nodes)
90 {
91  START_LOG("build_inf_elem()", "InfElemBuilder");
92 
93  // first determine the origin of the
94  // infinite elements. For this, the
95  // origin defaults to the given values,
96  // and may be overridden when the user
97  // provided values
98  Point origin(origin_x.second, origin_y.second, origin_z.second);
99 
100  // when only _one_ of the origin coordinates is _not_
101  // given, we have to determine it on our own
102  if ( !origin_x.first || !origin_y.first || !origin_z.first)
103  {
104  // determine origin
106  const Point auto_origin = (b_box.first+b_box.second)/2;
107 
108  // override default values, if necessary
109  if (!origin_x.first)
110  origin(0) = auto_origin(0);
111 #if LIBMESH_DIM > 1
112  if (!origin_y.first)
113  origin(1) = auto_origin(1);
114 #endif
115 #if LIBMESH_DIM > 2
116  if (!origin_z.first)
117  origin(2) = auto_origin(2);
118 #endif
119 
120  if (be_verbose)
121  {
122  libMesh::out << " Origin for Infinite Elements:" << std::endl;
123 
124  if (!origin_x.first)
125  libMesh::out << " determined x-coordinate" << std::endl;
126  if (!origin_y.first)
127  libMesh::out << " determined y-coordinate" << std::endl;
128  if (!origin_z.first)
129  libMesh::out << " determined z-coordinate" << std::endl;
130 
131  libMesh::out << " coordinates: ";
133  libMesh::out << std::endl;
134  }
135  }
136 
137  else if (be_verbose)
138 
139  {
140  libMesh::out << " Origin for Infinite Elements:" << std::endl;
141  libMesh::out << " coordinates: ";
143  libMesh::out << std::endl;
144  }
145 
146 
147 
148  // Now that we have the origin, check if the user provided an \p
149  // inner_boundary_nodes. If so, we pass a std::set to the actual
150  // implementation of the build_inf_elem(), so that we can convert
151  // this to the Node * vector
152  if (inner_boundary_nodes != nullptr)
153  {
154  // note that the std::set that we will get
155  // from build_inf_elem() uses the index of
156  // the element in this->_elements vector,
157  // and the second entry is the side index
158  // for this element. Therefore, we do _not_
159  // need to renumber nodes and elements
160  // prior to building the infinite elements.
161  //
162  // However, note that this method here uses
163  // node id's... Do we need to renumber?
164 
165 
166  // Form the list of faces of elements which finally
167  // will tell us which nodes should receive boundary
168  // conditions (to form the std::vector<const Node *>)
169  std::set<std::pair<dof_id_type,
170  unsigned int>> inner_faces;
171 
172 
173  // build infinite elements
174  this->build_inf_elem(origin,
175  x_sym, y_sym, z_sym,
176  be_verbose,
177  &inner_faces);
178 
179  if (be_verbose)
180  {
181  this->_mesh.print_info();
182  libMesh::out << "Data pre-processing:" << std::endl
183  << " convert the <int,int> list to a Node * list..."
184  << std::endl;
185  }
186 
187  // First use a std::vector<dof_id_type> that holds
188  // the global node numbers. Then sort this vector,
189  // so that it can be made unique (no multiple occurrence
190  // of a node), and then finally insert the Node * in
191  // the vector inner_boundary_nodes.
192  //
193  // Reserve memory for the vector<> with
194  // 4 times the size of the number of elements in the
195  // std::set. This is a good bet for Quad4 face elements.
196  // For higher-order elements, this probably _has_ to lead
197  // to additional allocations...
198  // Practice has to show how this affects performance.
199  std::vector<dof_id_type> inner_boundary_node_numbers;
200  inner_boundary_node_numbers.reserve(4*inner_faces.size());
201 
202  // Now transform the set of pairs to a list of (possibly
203  // duplicate) global node numbers.
204  for (const auto & p : inner_faces)
205  {
206  // build a full-ordered side element to get _all_ the base nodes
207  std::unique_ptr<Elem> side(this->_mesh.elem_ref(p.first).build_side_ptr(p.second));
208 
209  // insert all the node numbers in inner_boundary_node_numbers
210  for (const Node & node : side->node_ref_range())
211  inner_boundary_node_numbers.push_back(node.id());
212  }
213 
214 
215  // inner_boundary_node_numbers now still holds multiple entries of
216  // node numbers. So first sort, then unique the vector.
217  // Note that \p std::unique only puts the new ones in
218  // front, while to leftovers are not deleted. Instead,
219  // it returns a pointer to the end of the unique range.
220  //TODO:[BSK] int_ibn_size_before is not the same type as unique_size!
221 #ifndef NDEBUG
222  const std::size_t ibn_size_before = inner_boundary_node_numbers.size();
223 #endif
224  std::sort (inner_boundary_node_numbers.begin(), inner_boundary_node_numbers.end());
225  auto unique_end =
226  std::unique (inner_boundary_node_numbers.begin(), inner_boundary_node_numbers.end());
227 
228  std::size_t unique_size = std::distance(inner_boundary_node_numbers.begin(), unique_end);
229  libmesh_assert_less_equal (unique_size, ibn_size_before);
230 
231  // Finally, create const Node * in the inner_boundary_nodes
232  // vector. Reserve, not resize (otherwise, the push_back
233  // would append the interesting nodes, while nullptr-nodes
234  // live in the resize'd area...
235  inner_boundary_nodes->reserve (unique_size);
236  inner_boundary_nodes->clear();
237 
238  for (const auto & dof : as_range(inner_boundary_node_numbers.begin(), unique_end))
239  {
240  const Node * node = this->_mesh.node_ptr(dof);
241  inner_boundary_nodes->push_back(node);
242  }
243 
244  if (be_verbose)
245  libMesh::out << " finished identifying " << unique_size
246  << " target nodes." << std::endl;
247  }
248 
249  else
250 
251  {
252  // There are no inner boundary nodes, so simply build the infinite elements
253  this->build_inf_elem(origin, x_sym, y_sym, z_sym, be_verbose);
254  }
255 
256 
257  STOP_LOG("build_inf_elem()", "InfElemBuilder");
258 
259  // when finished with building the Ifems,
260  // it remains to prepare the mesh for use:
261  // find neighbors again, partition (if needed)...
262  this->_mesh.prepare_for_use (/*skip_renumber =*/ false);
263 
264  return origin;
265 }
266 
267 
268 
269 
270 
271 
272 
273 
274 
275 // The actual implementation of building elements.
277  const bool x_sym,
278  const bool y_sym,
279  const bool z_sym,
280  const bool be_verbose,
281  std::set<std::pair<dof_id_type,
282  unsigned int>> * inner_faces)
283 {
284  if (be_verbose)
285  {
286 #ifdef DEBUG
287  libMesh::out << " Building Infinite Elements:" << std::endl;
288  libMesh::out << " updating element neighbor tables..." << std::endl;
289 #else
290  libMesh::out << " Verbose mode disabled in non-debug mode." << std::endl;
291 #endif
292  }
293 
294 
295  // update element neighbors
296  this->_mesh.find_neighbors();
297 
298  LOG_SCOPE("build_inf_elem()", "InfElemBuilder");
299 
300  // A set for storing element number, side number pairs.
301  // pair.first == element number, pair.second == side number
302  std::set<std::pair<dof_id_type,unsigned int>> faces;
303  std::set<std::pair<dof_id_type,unsigned int>> ofaces;
304 
305  // A set for storing node numbers on the outer faces.
306  std::set<dof_id_type> onodes;
307 
308  // The distance to the farthest point in the mesh from the origin
309  Real max_r=0.;
310 
311  // The index of the farthest point in the mesh from the origin
312  int max_r_node = -1;
313 
314 #ifdef DEBUG
315  if (be_verbose)
316  {
317  libMesh::out << " collecting boundary sides";
318  if (x_sym || y_sym || z_sym)
319  libMesh::out << ", skipping sides in symmetry planes..." << std::endl;
320  else
321  libMesh::out << "..." << std::endl;
322  }
323 #endif
324 
325  // Iterate through all elements and sides, collect indices of all active
326  // boundary sides in the faces set. Skip sides which lie in symmetry planes.
327  // Later, sides of the inner boundary will be sorted out.
328  for (const auto & elem : _mesh.active_element_ptr_range())
329  for (auto s : elem->side_index_range())
330  if (elem->neighbor_ptr(s) == nullptr)
331  {
332  // note that it is safe to use the Elem::side() method,
333  // which gives a non-full-ordered element
334  std::unique_ptr<Elem> side(elem->build_side_ptr(s));
335 
336  // bool flags for symmetry detection
337  bool sym_side=false;
338  bool on_x_sym=true;
339  bool on_y_sym=true;
340  bool on_z_sym=true;
341 
342 
343  // Loop over the nodes to check whether they are on the symmetry planes,
344  // and therefore sufficient to use a non-full-ordered side element
345  for (const Node & node : side->node_ref_range())
346  {
347  const dof_id_type node_id = node.id();
348  const Point dist_from_origin =
349  this->_mesh.point(node_id) - origin;
350 
351  if (x_sym)
352  if (std::abs(dist_from_origin(0)) > 1.e-3)
353  on_x_sym=false;
354 
355  if (y_sym)
356  if (std::abs(dist_from_origin(1)) > 1.e-3)
357  on_y_sym=false;
358 
359  if (z_sym)
360  if (std::abs(dist_from_origin(2)) > 1.e-3)
361  on_z_sym=false;
362 
363  // if (x_sym)
364  // if (std::abs(dist_from_origin(0)) > 1.e-6)
365  // on_x_sym=false;
366 
367  // if (y_sym)
368  // if (std::abs(dist_from_origin(1)) > 1.e-6)
369  // on_y_sym=false;
370 
371  // if (z_sym)
372  // if (std::abs(dist_from_origin(2)) > 1.e-6)
373  // on_z_sym=false;
374 
375  //find the node most distant from origin
376 
377  Real r = dist_from_origin.norm();
378  if (r > max_r)
379  {
380  max_r = r;
381  max_r_node=node_id;
382  }
383 
384  }
385 
386  sym_side = (x_sym && on_x_sym) || (y_sym && on_y_sym) || (z_sym && on_z_sym);
387 
388  if (!sym_side)
389  faces.insert( std::make_pair(elem->id(), s) );
390 
391  } // neighbor(s) == nullptr
392 
393 
394 
395 
396 
397 
398  // If a boundary side has one node on the outer boundary,
399  // all points of this side are on the outer boundary.
400  // Start with the node most distant from origin, which has
401  // to be on the outer boundary, then recursively find all
402  // sides and nodes connected to it. Found sides are moved
403  // from faces to ofaces, nodes are collected in onodes.
404  // Here, the search is done iteratively, because, depending on
405  // the mesh, a very high level of recursion might be necessary.
406  if (max_r_node >= 0)
407  // include the possibility of the 1st element being most far away.
408  // Only the case of no outer boundary is to be excluded.
409  onodes.insert(max_r_node);
410 
411 
412  {
413  auto face_it = faces.begin();
414  auto face_end = faces.end();
415  unsigned int facesfound=0;
416  while (face_it != face_end) {
417  std::pair<dof_id_type, unsigned int> p = *face_it;
418 
419  // This has to be a full-ordered side element,
420  // since we need the correct n_nodes,
421  std::unique_ptr<Elem> side(this->_mesh.elem_ref(p.first).build_side_ptr(p.second));
422 
423  bool found=false;
424  for (const Node & node : side->node_ref_range())
425  if (onodes.count(node.id()))
426  {
427  found=true;
428  break;
429  }
430 
431  // If a new oface is found, include its nodes in onodes
432  if (found)
433  {
434  for (const Node & node : side->node_ref_range())
435  onodes.insert(node.id());
436 
437  ofaces.insert(p);
438  face_it = faces.erase(face_it); // increment is done here
439 
440  facesfound++;
441  }
442 
443  else
444  ++face_it; // increment is done here
445 
446  // If at least one new oface was found in this cycle,
447  // do another search cycle.
448  if (facesfound>0 && face_it == faces.end())
449  {
450  facesfound = 0;
451  face_it = faces.begin();
452  }
453  }
454  }
455 
456 
457 #ifdef DEBUG
458  if (be_verbose)
459  libMesh::out << " found "
460  << faces.size()
461  << " inner and "
462  << ofaces.size()
463  << " outer boundary faces"
464  << std::endl;
465 #endif
466 
467  // When the user provided a non-null pointer to
468  // inner_faces, that implies he wants to have
469  // this std::set. For now, simply copy the data.
470  if (inner_faces != nullptr)
471  *inner_faces = faces;
472 
473  // free memory, clear our local variable, no need
474  // for it any more.
475  faces.clear();
476 
477 
478  // outer_nodes maps onodes to their duplicates
479  std::map<dof_id_type, Node *> outer_nodes;
480 
481  // We may need to pick our own object ids in parallel
482  dof_id_type old_max_node_id = _mesh.max_node_id();
483  dof_id_type old_max_elem_id = _mesh.max_elem_id();
484 
485  // Likewise with our unique_ids
486 #ifdef LIBMESH_ENABLE_UNIQUE_ID
487  unique_id_type old_max_unique_id = _mesh.parallel_max_unique_id();
488 #endif
489 
490  // for each boundary node, add an outer_node with
491  // double distance from origin.
492  for (const auto & dof : onodes)
493  {
494  Point p = (Point(this->_mesh.point(dof)) * 2) - origin;
495  if (_mesh.is_serial())
496  {
497  // Add with a default id in serial
498  outer_nodes[dof]=this->_mesh.add_point(p);
499  }
500  else
501  {
502  // Pick a unique id in parallel
503  Node & bnode = _mesh.node_ref(dof);
504  dof_id_type new_id = bnode.id() + old_max_node_id;
505  Node * new_node =
506  this->_mesh.add_point(p, new_id,
507  bnode.processor_id());
508 #ifdef LIBMESH_ENABLE_UNIQUE_ID
509  new_node->set_unique_id() = old_max_unique_id + bnode.id();
510 #endif
511  outer_nodes[dof] = new_node;
512  }
513  }
514 
515 
516 #ifdef DEBUG
517  // for verbose, remember n_elem
518  dof_id_type n_conventional_elem = this->_mesh.n_elem();
519 #endif
520 
521 
522  // build Elems based on boundary side type
523  for (auto & p : ofaces)
524  {
525  Elem & belem = this->_mesh.elem_ref(p.first);
526 
527  // build a full-ordered side element to get the base nodes
528  std::unique_ptr<Elem> side(belem.build_side_ptr(p.second));
529 
530  // create cell depending on side type, assign nodes,
531  // use braces to force scope.
532  bool is_higher_order_elem = false;
533 
534  Elem * el;
535  switch(side->type())
536  {
537  // 3D infinite elements
538  // TRIs
539  case TRI3:
540  el=new InfPrism6;
541  break;
542 
543  case TRI6:
544  el=new InfPrism12;
545  is_higher_order_elem = true;
546  break;
547 
548  // QUADs
549  case QUAD4:
550  el=new InfHex8;
551  break;
552 
553  case QUAD8:
554  el=new InfHex16;
555  is_higher_order_elem = true;
556  break;
557 
558  case QUAD9:
559  el=new InfHex18;
560 
561  // the method of assigning nodes (which follows below)
562  // omits in the case of QUAD9 the bubble node; therefore
563  // we assign these first by hand here.
564  el->set_node(16) = side->node_ptr(8);
565  el->set_node(17) = outer_nodes[side->node_id(8)];
566  is_higher_order_elem=true;
567  break;
568 
569  // 2D infinite elements
570  case EDGE2:
571  el=new InfQuad4;
572  break;
573 
574  case EDGE3:
575  el=new InfQuad6;
576  el->set_node(4) = side->node_ptr(2);
577  break;
578 
579  // 1D infinite elements not supported
580  default:
581  libMesh::out << "InfElemBuilder::build_inf_elem(Point, bool, bool, bool, bool): "
582  << "invalid face element "
583  << std::endl;
584  continue;
585  }
586 
587  const unsigned int n_base_vertices = side->n_vertices();
588 
589  // On a distributed mesh, manually assign unique ids to the new
590  // element, and make sure any RemoteElem neighbor links are set.
591  if (!_mesh.is_serial())
592  {
593  el->processor_id() = belem.processor_id();
594 
595  // We'd better not have elements with more than 6 sides
596  libmesh_assert_less_equal(el->n_sides(), 6);
597  el->set_id (belem.id() * 6 + p.second + old_max_elem_id);
598 
599 #ifdef LIBMESH_ENABLE_UNIQUE_ID
600  el->set_unique_id() = old_max_unique_id + old_max_node_id + belem.id();
601 #endif
602 
603  // If we have a remote neighbor on a boundary element side
604  if (belem.dim() > 1)
605  for (auto s : belem.side_index_range())
606  if (belem.neighbor_ptr(s) == remote_elem)
607  {
608  // Find any corresponding infinite element side
609  std::unique_ptr<const Elem> remote_side(belem.build_side_ptr(s));
610 
611  for (auto inf_s : el->side_index_range())
612  {
613  // The base side 0 shares all vertices but isn't
614  // remote
615  if (!inf_s)
616  continue;
617 
618  // But another side, one which shares enough
619  // vertices to show it's the same side, is.
620  unsigned int n_shared_vertices = 0;
621  for (unsigned int i = 0; i != n_base_vertices; ++i)
622  for (auto & node : remote_side->node_ref_range())
623  if (side->node_ptr(i) == &node &&
624  el->is_node_on_side(i,inf_s))
625  ++n_shared_vertices;
626 
627  if (n_shared_vertices + 1 >= belem.dim())
628  {
629  el->set_neighbor
630  (inf_s, const_cast<RemoteElem *>(remote_elem));
631  break;
632  }
633  }
634  }
635  }
636 
637  // assign vertices to the new infinite element
638  for (unsigned int i=0; i<n_base_vertices; i++)
639  {
640  el->set_node(i ) = side->node_ptr(i);
641  el->set_node(i+n_base_vertices) = outer_nodes[side->node_id(i)];
642  }
643 
644 
645  // when this is a higher order element,
646  // assign also the nodes in between
647  if (is_higher_order_elem)
648  {
649  // n_safe_base_nodes is the number of nodes in \p side
650  // that may be safely assigned using below for loop.
651  // Actually, n_safe_base_nodes is _identical_ with el->n_vertices(),
652  // since for QUAD9, the 9th node was already assigned above
653  const unsigned int n_safe_base_nodes = el->n_vertices();
654 
655  for (unsigned int i=n_base_vertices; i<n_safe_base_nodes; i++)
656  {
657  el->set_node(i+n_base_vertices) = side->node_ptr(i);
658  el->set_node(i+n_safe_base_nodes) =
659  outer_nodes[side->node_id(i)];
660  }
661  }
662 
663 
664  // add infinite element to mesh
665  this->_mesh.add_elem(el);
666  } // for
667 
668 
669 #ifdef DEBUG
671 
672  if (be_verbose)
673  libMesh::out << " added "
674  << this->_mesh.n_elem() - n_conventional_elem
675  << " infinite elements and "
676  << onodes.size()
677  << " nodes to the mesh"
678  << std::endl
679  << std::endl;
680 #endif
681 }
682 
683 } // namespace libMesh
684 
685 
686 
687 
688 
689 #endif // LIBMESH_ENABLE_INFINITE_ELEMENTS
libMesh::dof_id_type
uint8_t dof_id_type
Definition: id_types.h:67
libMesh::InfElemBuilder::build_inf_elem
const Point build_inf_elem(const bool be_verbose=false)
Build infinite elements atop a volume-based mesh, determine origin automatically.
Definition: inf_elem_builder.C:41
libMesh::Elem::is_node_on_side
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
libMesh::Elem::build_side_ptr
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i, bool proxy=true)=0
libMesh::unique_id_type
uint8_t unique_id_type
Definition: id_types.h:86
libMesh::MeshBase::is_serial
virtual bool is_serial() const
Definition: mesh_base.h:159
libMesh::MeshBase::libmesh_assert_valid_parallel_ids
virtual void libmesh_assert_valid_parallel_ids() const
Verify id and processor_id consistency of our elements and nodes containers.
Definition: mesh_base.h:1297
libMesh::MeshBase::point
virtual const Point & point(const dof_id_type i) const =0
libMesh::BoundingBox
Defines a Cartesian bounding box by the two corner extremum.
Definition: bounding_box.h:40
libMesh::MeshBase::active_element_ptr_range
virtual SimpleRange< element_iterator > active_element_ptr_range()=0
libMesh::MeshBase::n_elem
virtual dof_id_type n_elem() const =0
libMesh::DofObject::set_id
dof_id_type & set_id()
Definition: dof_object.h:776
libMesh::MeshBase::elem_ref
virtual const Elem & elem_ref(const dof_id_type i) const
Definition: mesh_base.h:521
libMesh::MeshBase::max_elem_id
virtual dof_id_type max_elem_id() const =0
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::Elem::dim
virtual unsigned short dim() const =0
libMesh::InfElemBuilder::InfElemOriginValue
std::pair< bool, double > InfElemOriginValue
Useful typedef.
Definition: inf_elem_builder.h:65
libMesh::TypeVector::write_unformatted
void write_unformatted(std::ostream &out, const bool newline=true) const
Unformatted print to the stream out.
Definition: type_vector.C:65
libMesh::Elem::set_neighbor
void set_neighbor(const unsigned int i, Elem *n)
Assigns n as the neighbor.
Definition: elem.h:2105
libMesh::InfPrism6
The InfPrism6 is an infinite element in 3D composed of 6 nodes.
Definition: cell_inf_prism6.h:57
libMesh::MeshBase::node_ptr
virtual const Node * node_ptr(const dof_id_type i) const =0
libMesh::DofObject::set_unique_id
unique_id_type & set_unique_id()
Definition: dof_object.h:797
libMesh::MeshBase::max_node_id
virtual dof_id_type max_node_id() const =0
libMesh::InfHex18
The InfHex18 is an infinite element in 3D composed of 18 nodes.
Definition: cell_inf_hex18.h:70
libMesh::DofObject::processor_id
processor_id_type processor_id() const
Definition: dof_object.h:829
libMesh::InfQuad4
The INFQUAD4 is an infinite element in 2D composed of 4 nodes.
Definition: face_inf_quad4.h:52
libMesh::MeshTools::create_bounding_box
libMesh::BoundingBox create_bounding_box(const MeshBase &mesh)
The same functionality as the deprecated MeshTools::bounding_box().
Definition: mesh_tools.C:389
std::abs
MetaPhysicL::DualNumber< T, D > abs(const MetaPhysicL::DualNumber< T, D > &in)
libMesh::ParallelObject::processor_id
processor_id_type processor_id() const
Definition: parallel_object.h:106
libMesh::QUAD4
Definition: enum_elem_type.h:41
libMesh::Point
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
libMesh::TRI3
Definition: enum_elem_type.h:39
libMesh::Elem::n_vertices
virtual unsigned int n_vertices() const =0
libMesh::Node
A Node is like a Point, but with more information.
Definition: node.h:52
libMesh::as_range
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
Definition: simple_range.h:57
libMesh::Elem::set_node
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:2059
libMesh::MeshBase::node_ref
virtual const Node & node_ref(const dof_id_type i) const
Definition: mesh_base.h:451
libMesh::InfPrism12
The InfPrism12 is an infinite element in 3D composed of 12 nodes.
Definition: cell_inf_prism12.h:61
libMesh::TRI6
Definition: enum_elem_type.h:40
distance
Real distance(const Point &p)
Definition: subdomains_ex3.C:50
libMesh::InfElemBuilder::_mesh
MeshBase & _mesh
Reference to the mesh we're building infinite elements for.
Definition: inf_elem_builder.h:130
libMesh::MeshBase::add_elem
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
libMesh::MeshBase::print_info
void print_info(std::ostream &os=libMesh::out) const
Prints relevant information about the mesh.
Definition: mesh_base.C:585
libMesh::DofObject::id
dof_id_type id() const
Definition: dof_object.h:767
libMesh::EDGE3
Definition: enum_elem_type.h:36
libMesh::Elem::side_index_range
IntRange< unsigned short > side_index_range() const
Definition: elem.h:2188
libMesh::Elem
This is the base class from which all geometric element types are derived.
Definition: elem.h:100
libMesh::InfHex8
The InfHex8 is an infinite element in 3D composed of 8 nodes.
Definition: cell_inf_hex8.h:55
libMesh::QUAD9
Definition: enum_elem_type.h:43
libMesh::MeshBase::add_point
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
Add a new Node at Point p to the end of the vertex array, with processor_id procid.
libMesh::MeshBase::parallel_max_unique_id
virtual unique_id_type parallel_max_unique_id() const =0
libMesh::Elem::neighbor_ptr
const Elem * neighbor_ptr(unsigned int i) const
Definition: elem.h:2085
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::MeshBase::prepare_for_use
void prepare_for_use(const bool skip_renumber_nodes_and_elements=false, const bool skip_find_neighbors=false)
Prepare a newly ecreated (or read) mesh for use.
Definition: mesh_base.C:318
libMesh::Elem::n_sides
virtual unsigned int n_sides() const =0
libMesh::InfQuad6
The INFQUAD6 is an infinite element in 2D composed of 6 nodes.
Definition: face_inf_quad6.h:53
libMesh::TypeVector::norm
auto norm() const -> decltype(std::norm(T()))
Definition: type_vector.h:955
libMesh::out
OStreamProxy out
libMesh::MeshBase::find_neighbors
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true)=0
Locate element face (edge in 2D) neighbors.
libMesh::remote_elem
const RemoteElem * remote_elem
Definition: remote_elem.C:57
libMesh::EDGE2
Definition: enum_elem_type.h:35
libMesh::QUAD8
Definition: enum_elem_type.h:42
libMesh::InfHex16
The InfHex16 is an infinite element in 3D composed of 16 nodes.
Definition: cell_inf_hex16.h:70