libMesh
elem.h
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 
19 
20 #ifndef LIBMESH_ELEM_H
21 #define LIBMESH_ELEM_H
22 
23 // Local includes
24 #include "libmesh/libmesh_common.h"
25 #include "libmesh/bounding_box.h"
26 #include "libmesh/dof_object.h"
27 #include "libmesh/id_types.h"
28 #include "libmesh/reference_counted_object.h"
29 #include "libmesh/node.h"
30 #include "libmesh/enum_elem_type.h" // INVALID_ELEM
31 #include "libmesh/auto_ptr.h" // deprecated
32 #include "libmesh/multi_predicates.h"
33 #include "libmesh/pointer_to_pointer_iter.h"
34 #include "libmesh/int_range.h"
35 #include "libmesh/simple_range.h"
36 #include "libmesh/variant_filter_iterator.h"
37 #include "libmesh/hashword.h" // Used in compute_key() functions
38 
39 #ifdef LIBMESH_FORWARD_DECLARE_ENUMS
40 namespace libMesh
41 {
42 enum ElemQuality : int;
43 enum IOPackage : int;
44 enum Order : int;
45 }
46 #else
47 #include "libmesh/enum_elem_quality.h"
48 #include "libmesh/enum_io_package.h"
49 #include "libmesh/enum_order.h"
50 #endif
51 
52 // C++ includes
53 #include <algorithm>
54 #include <cstddef>
55 #include <iostream>
56 #include <limits.h> // CHAR_BIT
57 #include <set>
58 #include <vector>
59 #include <memory>
60 
61 namespace libMesh
62 {
63 
64 // Forward declarations
65 class MeshBase;
66 class MeshRefinement;
67 class Elem;
68 #ifdef LIBMESH_ENABLE_PERIODIC
69 class PeriodicBoundaries;
70 class PointLocatorBase;
71 #endif
72 
73 
101 class Elem : public ReferenceCountedObject<Elem>,
102  public DofObject
103 {
104 protected:
105 
112  Elem (const unsigned int n_nodes,
113  const unsigned int n_sides,
114  Elem * parent,
115  Elem ** elemlinkdata,
116  Node ** nodelinkdata);
117 
118 public:
119 
129  Elem (Elem &&) = delete;
130  Elem (const Elem &) = delete;
131  Elem & operator= (const Elem &) = delete;
132  Elem & operator= (Elem &&) = delete;
133 
137  virtual ~Elem();
138 
142  const Point & point (const unsigned int i) const;
143 
148  Point & point (const unsigned int i);
149 
154  virtual Point master_point (const unsigned int i) const = 0;
155 
159  dof_id_type node_id (const unsigned int i) const;
160 
165  unsigned int local_node (const dof_id_type i) const;
166 
171  unsigned int get_node_index (const Node * node_ptr) const;
172 
176  const Node * const * get_nodes () const;
177 
181  const Node * node_ptr (const unsigned int i) const;
182 
186  Node * node_ptr (const unsigned int i);
187 
191  const Node & node_ref (const unsigned int i) const;
192 
196  Node & node_ref (const unsigned int i);
197 
201  virtual Node * & set_node (const unsigned int i);
202 
206  class NodeRefIter;
207  class ConstNodeRefIter;
208 
217 
219 
224 
230 
246 
255  const Elem * reference_elem () const;
256 
262  virtual dof_id_type key (const unsigned int s) const = 0;
263 
270  virtual dof_id_type key () const;
271 
278  bool operator == (const Elem & rhs) const;
279 
289  const Elem * neighbor_ptr (unsigned int i) const;
290 
294  Elem * neighbor_ptr (unsigned int i);
295 
299  typedef Elem * const * NeighborPtrIter;
300  typedef const Elem * const * ConstNeighborPtrIter;
301 
311 
313 
314 #ifdef LIBMESH_ENABLE_PERIODIC
315 
321  const Elem * topological_neighbor (const unsigned int i,
322  const MeshBase & mesh,
323  const PointLocatorBase & point_locator,
324  const PeriodicBoundaries * pb) const;
325 
332  Elem * topological_neighbor (const unsigned int i,
333  MeshBase & mesh,
334  const PointLocatorBase & point_locator,
335  const PeriodicBoundaries * pb);
336 
341  bool has_topological_neighbor (const Elem * elem,
342  const MeshBase & mesh,
343  const PointLocatorBase & point_locator,
344  const PeriodicBoundaries * pb) const;
345 #endif
346 
350  void set_neighbor (const unsigned int i, Elem * n);
351 
356  bool has_neighbor (const Elem * elem) const;
357 
362  Elem * child_neighbor (Elem * elem);
363 
368  const Elem * child_neighbor (const Elem * elem) const;
369 
375  bool on_boundary () const;
376 
381  bool is_semilocal (const processor_id_type my_pid) const;
382 
388  unsigned int which_neighbor_am_i(const Elem * e) const;
389 
406  unsigned int which_side_am_i(const Elem * e) const;
407 
418  virtual unsigned int which_node_am_i(unsigned int side,
419  unsigned int side_node) const = 0;
420 
425  bool contains_vertex_of(const Elem * e) const;
426 
432  bool contains_edge_of(const Elem * e) const;
433 
450  void find_point_neighbors(const Point & p,
451  std::set<const Elem *> & neighbor_set) const;
452 
458  void find_point_neighbors(std::set<const Elem *> & neighbor_set) const;
459 
465  void find_point_neighbors(std::set<const Elem *> & neighbor_set,
466  const Elem * start_elem) const;
467 
471  void find_point_neighbors(std::set<Elem *> & neighbor_set,
472  Elem * start_elem);
473 
479  void find_edge_neighbors(const Point & p1,
480  const Point & p2,
481  std::set<const Elem *> & neighbor_set) const;
482 
491  void find_edge_neighbors(std::set<const Elem *> & neighbor_set) const;
492 
498  void find_interior_neighbors(std::set<const Elem *> & neighbor_set) const;
499 
504  void find_interior_neighbors(std::set<Elem *> & neighbor_set);
505 
513  void remove_links_to_me ();
514 
522  void make_links_to_me_remote ();
523 
530  void make_links_to_me_local (unsigned int n);
531 
543  virtual bool is_remote () const
544  { return false; }
545 
550  virtual void connectivity(const unsigned int sc,
551  const IOPackage iop,
552  std::vector<dof_id_type> & conn) const = 0;
553 
559  void write_connectivity (std::ostream & out,
560  const IOPackage iop) const;
561 
566  virtual ElemType type () const = 0;
567 
571  virtual unsigned short dim () const = 0;
572 
577  static const unsigned int type_to_n_nodes_map[INVALID_ELEM];
578 
582  virtual unsigned int n_nodes () const = 0;
583 
588  static const unsigned int max_n_nodes = 27;
589 
595 
601  virtual unsigned int n_nodes_in_child (unsigned int /*c*/) const
602  { return this->n_nodes(); }
603 
608  static const unsigned int type_to_n_sides_map[INVALID_ELEM];
609 
615  virtual unsigned int n_sides () const = 0;
616 
622 
632  unsigned int n_neighbors () const
633  { return this->n_sides(); }
634 
639  virtual unsigned int n_vertices () const = 0;
640 
645  virtual unsigned int n_edges () const = 0;
646 
652 
657  static const unsigned int type_to_n_edges_map[INVALID_ELEM];
658 
663  virtual unsigned int n_faces () const = 0;
664 
669  virtual unsigned int n_children () const = 0;
670 
674  virtual bool is_vertex(const unsigned int i) const = 0;
675 
682  virtual unsigned int is_vertex_on_child (unsigned int /*c*/,
683  unsigned int n) const
684  { return this->is_vertex(n); }
685 
690  virtual bool is_vertex_on_parent(unsigned int c,
691  unsigned int n) const;
692 
696  virtual bool is_edge(const unsigned int i) const = 0;
697 
701  virtual bool is_face(const unsigned int i) const = 0;
702 
707  virtual bool is_node_on_side(const unsigned int n,
708  const unsigned int s) const = 0;
709 
713  virtual std::vector<unsigned int> nodes_on_side(const unsigned int /*s*/) const = 0;
714 
719  virtual bool is_node_on_edge(const unsigned int n,
720  const unsigned int e) const = 0;
721 
725  virtual bool is_edge_on_side(const unsigned int e,
726  const unsigned int s) const = 0;
727 
732  virtual unsigned int opposite_side(const unsigned int s) const;
733 
739  virtual unsigned int opposite_node(const unsigned int n,
740  const unsigned int s) const;
741 
747  virtual unsigned int n_sub_elem () const = 0;
748 
763  virtual std::unique_ptr<Elem> side_ptr (unsigned int i) = 0;
764  std::unique_ptr<const Elem> side_ptr (unsigned int i) const;
765 
781  virtual void side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) = 0;
782  void side_ptr (std::unique_ptr<const Elem> & side, const unsigned int i) const;
783 
805  virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i, bool proxy=true) = 0;
806  std::unique_ptr<const Elem> build_side_ptr (const unsigned int i, bool proxy=true) const;
807 
823  virtual void build_side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) = 0;
824  void build_side_ptr (std::unique_ptr<const Elem> & side, const unsigned int i) const;
825 
839  virtual std::unique_ptr<Elem> build_edge_ptr (const unsigned int i) = 0;
840  std::unique_ptr<const Elem> build_edge_ptr (const unsigned int i) const;
841 
847  virtual Order default_order () const = 0;
848 
856  virtual Point centroid () const;
857 
861  virtual Real hmin () const;
862 
866  virtual Real hmax () const;
867 
871  virtual Real volume () const;
872 
883  virtual BoundingBox loose_bounding_box () const;
884 
889  virtual Real quality (const ElemQuality q) const;
890 
899  virtual std::pair<Real,Real> qual_bounds (const ElemQuality) const
900  { libmesh_not_implemented(); return std::make_pair(0.,0.); }
901 
917  virtual bool contains_point (const Point & p, Real tol=TOLERANCE) const;
918 
923  virtual bool close_to_point(const Point & p, Real tol) const;
924 
925 private:
932  bool point_test(const Point & p, Real box_tol, Real map_tol) const;
933 
934 public:
939  virtual bool has_affine_map () const { return false; }
940 
945  virtual bool is_linear () const { return false; }
946 
950  void print_info (std::ostream & os=libMesh::out) const;
951 
955  std::string get_info () const;
956 
963  bool active () const;
964 
970  bool ancestor () const;
971 
976  bool subactive () const;
977 
982  bool has_children () const;
983 
988  bool has_ancestor_children () const;
989 
995  bool is_ancestor_of(const Elem * descendant) const;
996 
1001  const Elem * parent () const;
1002 
1007  Elem * parent ();
1008 
1013  void set_parent (Elem * p);
1014 
1022  const Elem * top_parent () const;
1023 
1038  const Elem * interior_parent () const;
1039 
1040  Elem * interior_parent ();
1041 
1046  void set_interior_parent (Elem * p);
1047 
1053  Real length (const unsigned int n1,
1054  const unsigned int n2) const;
1055 
1066  virtual unsigned int n_second_order_adjacent_vertices (const unsigned int n) const;
1067 
1076  virtual unsigned short int second_order_adjacent_vertex (const unsigned int n,
1077  const unsigned int v) const;
1078 
1094  virtual std::pair<unsigned short int, unsigned short int>
1095  second_order_child_vertex (const unsigned int n) const;
1096 
1110  const bool full_ordered=true);
1111 
1119  static ElemType first_order_equivalent_type (const ElemType et);
1120 
1121 
1129  unsigned int level () const;
1130 
1136  unsigned int p_level () const;
1137 
1141  virtual bool is_child_on_side(const unsigned int c,
1142  const unsigned int s) const = 0;
1143 
1144 #ifdef LIBMESH_ENABLE_AMR
1145 
1157 
1162  const Elem * raw_child_ptr (unsigned int i) const;
1163 
1168  const Elem * child_ptr (unsigned int i) const;
1169 
1174  Elem * child_ptr (unsigned int i);
1175 
1180  class ChildRefIter;
1181  class ConstChildRefIter;
1182 
1191 
1193 
1194 private:
1199  void set_child (unsigned int c, Elem * elem);
1200 
1201 public:
1208  unsigned int which_child_am_i(const Elem * e) const;
1209 
1213  virtual bool is_child_on_edge(const unsigned int c,
1214  const unsigned int e) const;
1215 
1222  void add_child (Elem * elem);
1223 
1230  void add_child (Elem * elem, unsigned int c);
1231 
1235  void replace_child (Elem * elem, unsigned int c);
1236 
1248  void family_tree (std::vector<const Elem *> & family,
1249  bool reset = true) const;
1250 
1254  void family_tree (std::vector<Elem *> & family,
1255  bool reset = true);
1256 
1261  void total_family_tree (std::vector<const Elem *> & family,
1262  bool reset = true) const;
1263 
1267  void total_family_tree (std::vector<Elem *> & family,
1268  bool reset = true);
1269 
1276  void active_family_tree (std::vector<const Elem *> & active_family,
1277  bool reset = true) const;
1278 
1282  void active_family_tree (std::vector<Elem *> & active_family,
1283  bool reset = true);
1284 
1289  void family_tree_by_side (std::vector<const Elem *> & family,
1290  unsigned int side,
1291  bool reset = true) const;
1292 
1296  void family_tree_by_side (std::vector<Elem *> & family,
1297  unsigned int side,
1298  bool reset = true);
1299 
1304  void active_family_tree_by_side (std::vector<const Elem *> & family,
1305  unsigned int side,
1306  bool reset = true) const;
1307 
1311  void active_family_tree_by_side (std::vector<Elem *> & family,
1312  unsigned int side,
1313  bool reset = true);
1314 
1319  void family_tree_by_neighbor (std::vector<const Elem *> & family,
1320  const Elem * neighbor,
1321  bool reset = true) const;
1322 
1326  void family_tree_by_neighbor (std::vector<Elem *> & family,
1327  Elem * neighbor,
1328  bool reset = true);
1329 
1334  void total_family_tree_by_neighbor (std::vector<const Elem *> & family,
1335  const Elem * neighbor,
1336  bool reset = true) const;
1337 
1341  void total_family_tree_by_neighbor (std::vector<Elem *> & family,
1342  Elem * neighbor,
1343  bool reset = true);
1344 
1351  void family_tree_by_subneighbor (std::vector<const Elem *> & family,
1352  const Elem * neighbor,
1353  const Elem * subneighbor,
1354  bool reset = true) const;
1355 
1359  void family_tree_by_subneighbor (std::vector<Elem *> & family,
1360  Elem * neighbor,
1361  Elem * subneighbor,
1362  bool reset = true);
1363 
1368  void total_family_tree_by_subneighbor (std::vector<const Elem *> & family,
1369  const Elem * neighbor,
1370  const Elem * subneighbor,
1371  bool reset = true) const;
1372 
1376  void total_family_tree_by_subneighbor (std::vector<Elem *> & family,
1377  Elem * neighbor,
1378  Elem * subneighbor,
1379  bool reset = true);
1380 
1385  void active_family_tree_by_neighbor (std::vector<const Elem *> & family,
1386  const Elem * neighbor,
1387  bool reset = true) const;
1388 
1392  void active_family_tree_by_neighbor (std::vector<Elem *> & family,
1393  Elem * neighbor,
1394  bool reset = true);
1395 
1401  void active_family_tree_by_topological_neighbor (std::vector<const Elem *> & family,
1402  const Elem * neighbor,
1403  const MeshBase & mesh,
1404  const PointLocatorBase & point_locator,
1405  const PeriodicBoundaries * pb,
1406  bool reset = true) const;
1407 
1411  void active_family_tree_by_topological_neighbor (std::vector<Elem *> & family,
1412  Elem * neighbor,
1413  const MeshBase & mesh,
1414  const PointLocatorBase & point_locator,
1415  const PeriodicBoundaries * pb,
1416  bool reset = true);
1417 
1422 
1426  void set_refinement_flag (const RefinementState rflag);
1427 
1432 
1436  void set_p_refinement_flag (const RefinementState pflag);
1437 
1442  unsigned int max_descendant_p_level () const;
1443 
1449  unsigned int min_p_level_by_neighbor (const Elem * neighbor,
1450  unsigned int current_min) const;
1451 
1457  unsigned int min_new_p_level_by_neighbor (const Elem * neighbor,
1458  unsigned int current_min) const;
1459 
1465  void set_p_level (const unsigned int p);
1466 
1471  void hack_p_level (const unsigned int p);
1472 
1476  virtual void refine (MeshRefinement & mesh_refinement);
1477 
1482  void coarsen ();
1483 
1490  void contract ();
1491 
1492 #endif
1493 
1494 #ifdef DEBUG
1495 
1498  void libmesh_assert_valid_neighbors() const;
1499 
1505 #endif // DEBUG
1506 
1507 protected:
1508 
1519  class SideIter;
1520 
1521 public:
1526 
1531  struct side_iterator;
1532 
1538 
1539 private:
1545  SideIter _last_side();
1546 
1547 public:
1548 
1549 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
1550 
1555  virtual bool infinite () const = 0;
1556 
1564  virtual bool is_mid_infinite_edge_node(const unsigned int /* n */) const
1565  { libmesh_assert (!this->infinite()); return false; }
1566 
1573  virtual Point origin () const { libmesh_not_implemented(); return Point(); }
1574 
1575 #endif
1576 
1577 
1578 
1579 
1583  static std::unique_ptr<Elem> build (const ElemType type,
1584  Elem * p=nullptr);
1585 
1586 #ifdef LIBMESH_ENABLE_AMR
1587 
1593  virtual unsigned int as_parent_node (unsigned int c,
1594  unsigned int n) const;
1595 
1600  virtual
1601  const std::vector<std::pair<unsigned char, unsigned char>> &
1602  parent_bracketing_nodes(unsigned int c,
1603  unsigned int n) const;
1604 
1609  virtual
1610  const std::vector<std::pair<dof_id_type, dof_id_type>>
1611  bracketing_nodes(unsigned int c,
1612  unsigned int n) const;
1613 
1614 
1618  virtual float embedding_matrix (const unsigned int child_num,
1619  const unsigned int child_node_num,
1620  const unsigned int parent_node_num) const = 0;
1621 
1629  virtual unsigned int embedding_matrix_version () const { return 0; }
1630 
1631 #endif // LIBMESH_ENABLE_AMR
1632 
1633 
1634 protected:
1635 
1639  static dof_id_type compute_key (dof_id_type n0);
1640 
1644  static dof_id_type compute_key (dof_id_type n0,
1645  dof_id_type n1);
1646 
1650  static dof_id_type compute_key (dof_id_type n0,
1651  dof_id_type n1,
1652  dof_id_type n2);
1653 
1657  static dof_id_type compute_key (dof_id_type n0,
1658  dof_id_type n1,
1659  dof_id_type n2,
1660  dof_id_type n3);
1661 
1665  template <typename Subclass>
1666  void simple_build_side_ptr(std::unique_ptr<Elem> & side,
1667  const unsigned int i,
1668  ElemType sidetype);
1669 
1673  template <typename Subclass, typename Mapclass>
1674  void simple_side_ptr(std::unique_ptr<Elem> & side,
1675  const unsigned int i,
1676  ElemType sidetype);
1677 
1678 #ifdef LIBMESH_ENABLE_AMR
1679 
1685  virtual
1686  std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> &
1688  {
1689  static std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> c;
1690  libmesh_error();
1691  return c;
1692  }
1693 
1699  virtual
1700  std::vector<std::vector<std::vector<signed char>>> &
1702  {
1703  static std::vector<std::vector<std::vector<signed char>>> c;
1704  libmesh_error();
1705  return c;
1706  }
1707 
1708 #endif // LIBMESH_ENABLE_AMR
1709 
1710 public:
1711 
1716  void nullify_neighbors ();
1717 
1718 protected:
1719 
1724 
1730 
1731 #ifdef LIBMESH_ENABLE_AMR
1732 
1736 #endif
1737 
1742 
1743 #ifdef LIBMESH_ENABLE_AMR
1744 
1748  unsigned char _rflag;
1749 
1754  unsigned char _pflag;
1755 
1764  unsigned char _p_level;
1765 #endif
1766 };
1767 
1768 
1769 
1770 // ------------------------------------------------------------
1771 // Elem helper classes
1772 //
1773 class
1775 {
1776 public:
1777  NodeRefIter (Node * const * nodepp) : PointerToPointerIter<Node>(nodepp) {}
1778 };
1779 
1780 
1781 class
1783 {
1784 public:
1785  ConstNodeRefIter (const Node * const * nodepp) : PointerToPointerIter<const Node>(nodepp) {}
1786 };
1787 
1788 
1789 #ifdef LIBMESH_ENABLE_AMR
1790 class
1792 {
1793 public:
1794  ChildRefIter (Elem * const * childpp) : PointerToPointerIter<Elem>(childpp) {}
1795 };
1796 
1797 
1798 class
1800 {
1801 public:
1802  ConstChildRefIter (const Elem * const * childpp) : PointerToPointerIter<const Elem>(childpp) {}
1803 };
1804 
1805 
1806 inline
1808 {
1809  libmesh_assert(_children);
1810  return {_children, _children + this->n_children()};
1811 }
1812 
1813 
1814 inline
1816 {
1817  libmesh_assert(_children);
1818  return {_children, _children + this->n_children()};
1819 }
1820 #endif // LIBMESH_ENABLE_AMR
1821 
1822 
1823 
1824 
1825 // ------------------------------------------------------------
1826 // global Elem functions
1827 
1828 inline
1829 std::ostream & operator << (std::ostream & os, const Elem & e)
1830 {
1831  e.print_info(os);
1832  return os;
1833 }
1834 
1835 
1836 // ------------------------------------------------------------
1837 // Elem class member functions
1838 inline
1839 Elem::Elem(const unsigned int nn,
1840  const unsigned int ns,
1841  Elem * p,
1842  Elem ** elemlinkdata,
1843  Node ** nodelinkdata) :
1844  _nodes(nodelinkdata),
1845  _elemlinks(elemlinkdata),
1846 #ifdef LIBMESH_ENABLE_AMR
1847  _children(nullptr),
1848 #endif
1849  _sbd_id(0)
1850 #ifdef LIBMESH_ENABLE_AMR
1851  ,
1852  _rflag(Elem::DO_NOTHING),
1853  _pflag(Elem::DO_NOTHING),
1854  _p_level(0)
1855 #endif
1856 {
1858 
1859  // If this ever legitimately fails we need to increase max_n_nodes
1860  libmesh_assert_less_equal(nn, max_n_nodes);
1861 
1862  // Initialize the nodes data structure
1863  if (_nodes)
1864  {
1865  for (unsigned int n=0; n<nn; n++)
1866  _nodes[n] = nullptr;
1867  }
1868 
1869  // Initialize the neighbors/parent data structure
1870  // _elemlinks = new Elem *[ns+1];
1871 
1872  if (_elemlinks)
1873  {
1874  _elemlinks[0] = p;
1875 
1876  for (unsigned int n=1; n<ns+1; n++)
1877  _elemlinks[n] = nullptr;
1878  }
1879 
1880  // Optionally initialize data from the parent
1881  if (this->parent() != nullptr)
1882  {
1883  this->subdomain_id() = this->parent()->subdomain_id();
1884  this->processor_id() = this->parent()->processor_id();
1885  }
1886 
1887 #ifdef LIBMESH_ENABLE_AMR
1888  if (this->parent())
1889  this->set_p_level(this->parent()->p_level());
1890 #endif
1891 }
1892 
1893 
1894 
1895 inline
1896 Elem::~Elem()
1897 {
1898  // Deleting my parent/neighbor/nodes storage isn't necessary since it's
1899  // handled by the subclass
1900 
1901  // if (_nodes != nullptr)
1902  // delete [] _nodes;
1903  // _nodes = nullptr;
1904 
1905  // delete [] _elemlinks;
1906 
1907 #ifdef LIBMESH_ENABLE_AMR
1908 
1909  // Delete my children's storage
1910  if (_children != nullptr)
1911  delete [] _children;
1912  _children = nullptr;
1913 
1914 #endif
1915 }
1916 
1917 
1918 
1919 inline
1920 const Point & Elem::point (const unsigned int i) const
1921 {
1922  libmesh_assert_less (i, this->n_nodes());
1923  libmesh_assert(_nodes[i]);
1924  libmesh_assert_not_equal_to (_nodes[i]->id(), Node::invalid_id);
1925 
1926  return *_nodes[i];
1927 }
1928 
1929 
1930 
1931 inline
1932 Point & Elem::point (const unsigned int i)
1933 {
1934  libmesh_assert_less (i, this->n_nodes());
1935 
1936  return *_nodes[i];
1937 }
1938 
1939 
1940 
1941 inline
1942 dof_id_type Elem::node_id (const unsigned int i) const
1943 {
1944  libmesh_assert_less (i, this->n_nodes());
1945  libmesh_assert(_nodes[i]);
1946  libmesh_assert_not_equal_to (_nodes[i]->id(), Node::invalid_id);
1947 
1948  return _nodes[i]->id();
1949 }
1950 
1951 
1952 
1953 inline
1954 unsigned int Elem::local_node (const dof_id_type i) const
1955 {
1956  for (unsigned int n=0; n != this->n_nodes(); ++n)
1957  if (this->node_id(n) == i)
1958  return n;
1959 
1960  return libMesh::invalid_uint;
1961 }
1962 
1963 
1964 
1965 inline
1966 const Node * const * Elem::get_nodes () const
1967 {
1968  return _nodes;
1969 }
1970 
1971 
1972 
1973 inline
1974 const Node * Elem::node_ptr (const unsigned int i) const
1975 {
1976  libmesh_assert_less (i, this->n_nodes());
1977  libmesh_assert(_nodes[i]);
1978 
1979  return _nodes[i];
1980 }
1981 
1982 
1983 
1984 inline
1985 Node * Elem::node_ptr (const unsigned int i)
1986 {
1987  libmesh_assert_less (i, this->n_nodes());
1988  libmesh_assert(_nodes[i]);
1989 
1990  return _nodes[i];
1991 }
1992 
1993 
1994 
1995 inline
1996 const Node & Elem::node_ref (const unsigned int i) const
1997 {
1998  return *this->node_ptr(i);
1999 }
2000 
2001 
2002 
2003 inline
2004 Node & Elem::node_ref (const unsigned int i)
2005 {
2006  return *this->node_ptr(i);
2007 }
2008 
2009 
2010 
2011 inline
2012 unsigned int Elem::get_node_index (const Node * node_ptr) const
2013 {
2014  for (unsigned int n=0; n != this->n_nodes(); ++n)
2015  if (this->_nodes[n] == node_ptr)
2016  return n;
2017 
2018  return libMesh::invalid_uint;
2019 }
2020 
2021 
2022 
2023 inline
2024 Node * & Elem::set_node (const unsigned int i)
2025 {
2026  libmesh_assert_less (i, this->n_nodes());
2027 
2028  return _nodes[i];
2029 }
2030 
2031 
2032 
2033 inline
2035 {
2036  return _sbd_id;
2037 }
2038 
2039 
2040 
2041 inline
2043 {
2044  return _sbd_id;
2045 }
2046 
2047 
2048 
2049 inline
2050 const Elem * Elem::neighbor_ptr (unsigned int i) const
2051 {
2052  libmesh_assert_less (i, this->n_neighbors());
2053 
2054  return _elemlinks[i+1];
2055 }
2056 
2057 
2058 
2059 inline
2060 Elem * Elem::neighbor_ptr (unsigned int i)
2061 {
2062  libmesh_assert_less (i, this->n_neighbors());
2063 
2064  return _elemlinks[i+1];
2065 }
2066 
2067 
2068 
2069 inline
2070 void Elem::set_neighbor (const unsigned int i, Elem * n)
2071 {
2072  libmesh_assert_less (i, this->n_neighbors());
2073 
2074  _elemlinks[i+1] = n;
2075 }
2076 
2077 
2078 
2079 inline
2080 bool Elem::has_neighbor (const Elem * elem) const
2081 {
2082  for (auto n : this->neighbor_ptr_range())
2083  if (n == elem)
2084  return true;
2085 
2086  return false;
2087 }
2088 
2089 
2090 
2091 inline
2093 {
2094  for (auto n : elem->neighbor_ptr_range())
2095  if (n && n->parent() == this)
2096  return n;
2097 
2098  return nullptr;
2099 }
2100 
2101 
2102 
2103 inline
2104 const Elem * Elem::child_neighbor (const Elem * elem) const
2105 {
2106  for (auto n : elem->neighbor_ptr_range())
2107  if (n && n->parent() == this)
2108  return n;
2109 
2110  return nullptr;
2111 }
2112 
2113 
2114 
2115 inline
2118 {
2119  return {_nodes, _nodes+this->n_nodes()};
2120 }
2121 
2122 
2123 
2124 inline
2127 {
2128  return {_nodes, _nodes+this->n_nodes()};
2129 }
2130 
2131 
2132 
2133 inline
2136 {
2137  return {0, cast_int<unsigned short>(this->n_nodes())};
2138 }
2139 
2140 
2141 
2142 inline
2145 {
2146  return {0, cast_int<unsigned short>(this->n_edges())};
2147 }
2148 
2149 
2150 
2151 inline
2154 {
2155  return {0, cast_int<unsigned short>(this->n_sides())};
2156 }
2157 
2158 
2159 
2160 
2161 inline
2162 std::unique_ptr<const Elem> Elem::side_ptr (unsigned int i) const
2163 {
2164  // Call the non-const version of this function, return the result as
2165  // a std::unique_ptr<const Elem>.
2166  Elem * me = const_cast<Elem *>(this);
2167  const Elem * s = const_cast<const Elem *>(me->side_ptr(i).release());
2168  return std::unique_ptr<const Elem>(s);
2169 }
2170 
2171 
2172 
2173 inline
2174 void
2175 Elem::side_ptr (std::unique_ptr<const Elem> & elem,
2176  const unsigned int i) const
2177 {
2178  // Hand off to the non-const version of this function
2179  Elem * me = const_cast<Elem *>(this);
2180  std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
2181  me->side_ptr(e, i);
2182  elem.reset(e.release());
2183 }
2184 
2185 
2186 
2187 inline
2188 std::unique_ptr<const Elem>
2189 Elem::build_side_ptr (const unsigned int i, bool proxy) const
2190 {
2191  // Call the non-const version of this function, return the result as
2192  // a std::unique_ptr<const Elem>.
2193  Elem * me = const_cast<Elem *>(this);
2194  const Elem * s = const_cast<const Elem *>(me->build_side_ptr(i, proxy).release());
2195  return std::unique_ptr<const Elem>(s);
2196 }
2197 
2198 
2199 
2200 inline
2201 void
2202 Elem::build_side_ptr (std::unique_ptr<const Elem> & elem,
2203  const unsigned int i) const
2204 {
2205  // Hand off to the non-const version of this function
2206  Elem * me = const_cast<Elem *>(this);
2207  std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
2208  me->build_side_ptr(e, i);
2209  elem.reset(e.release());
2210 }
2211 
2212 
2213 
2214 template <typename Subclass>
2215 inline
2216 void
2217 Elem::simple_build_side_ptr (std::unique_ptr<Elem> & side,
2218  const unsigned int i,
2219  ElemType sidetype)
2220 {
2221  libmesh_assert_less (i, this->n_sides());
2222 
2223  if (!side.get() || side->type() != sidetype)
2224  {
2225  Subclass & real_me = cast_ref<Subclass&>(*this);
2226  side = real_me.Subclass::build_side_ptr(i, false);
2227  }
2228  else
2229  {
2230  side->subdomain_id() = this->subdomain_id();
2231 
2232  for (auto n : side->node_index_range())
2233  side->set_node(n) = this->node_ptr(Subclass::side_nodes_map[i][n]);
2234  }
2235 }
2236 
2237 
2238 
2239 template <typename Subclass, typename Mapclass>
2240 inline
2241 void
2242 Elem::simple_side_ptr (std::unique_ptr<Elem> & side,
2243  const unsigned int i,
2244  ElemType sidetype)
2245 {
2246  libmesh_assert_less (i, this->n_sides());
2247 
2248  if (!side.get() || side->type() != sidetype)
2249  {
2250  Subclass & real_me = cast_ref<Subclass&>(*this);
2251  side = real_me.Subclass::side_ptr(i);
2252  }
2253  else
2254  {
2255  side->subdomain_id() = this->subdomain_id();
2256 
2257  for (auto n : side->node_index_range())
2258  side->set_node(n) = this->node_ptr(Mapclass::side_nodes_map[i][n]);
2259  }
2260 }
2261 
2262 
2263 
2264 inline
2265 std::unique_ptr<const Elem>
2266 Elem::build_edge_ptr (const unsigned int i) const
2267 {
2268  // Call the non-const version of this function, return the result as
2269  // a std::unique_ptr<const Elem>.
2270  Elem * me = const_cast<Elem *>(this);
2271  const Elem * e = const_cast<const Elem *>(me->build_edge_ptr(i).release());
2272  return std::unique_ptr<const Elem>(e);
2273 }
2274 
2275 
2276 
2277 inline
2278 bool Elem::on_boundary () const
2279 {
2280  // By convention, the element is on the boundary
2281  // if it has a nullptr neighbor.
2282  return this->has_neighbor(nullptr);
2283 }
2284 
2285 
2286 
2287 inline
2288 unsigned int Elem::which_neighbor_am_i (const Elem * e) const
2289 {
2290  libmesh_assert(e);
2291 
2292  const Elem * eparent = e;
2293 
2294  while (eparent->level() > this->level())
2295  {
2296  eparent = eparent->parent();
2297  libmesh_assert(eparent);
2298  }
2299 
2300  for (unsigned int s=0, n_s = this->n_sides(); s != n_s; ++s)
2301  if (this->neighbor_ptr(s) == eparent)
2302  return s;
2303 
2304  return libMesh::invalid_uint;
2305 }
2306 
2307 
2308 
2309 inline
2310 unsigned int Elem::which_side_am_i (const Elem * e) const
2311 {
2312  libmesh_assert(e);
2313 
2314  const unsigned int ns = this->n_sides();
2315  const unsigned int nn = this->n_nodes();
2316 
2317  const unsigned int en = e->n_nodes();
2318 
2319  // e might be on any side until proven otherwise
2320  std::vector<bool> might_be_side(ns, true);
2321 
2322  for (unsigned int i=0; i != en; ++i)
2323  {
2324  Point side_point = e->point(i);
2325  unsigned int local_node_id = libMesh::invalid_uint;
2326 
2327  // Look for a node of this that's contiguous with node i of
2328  // e. Note that the exact floating point comparison of Point
2329  // positions is intentional, see the class documentation for
2330  // this function.
2331  for (unsigned int j=0; j != nn; ++j)
2332  if (this->point(j) == side_point)
2333  local_node_id = j;
2334 
2335  // If a node of e isn't contiguous with some node of this, then
2336  // e isn't a side of this.
2337  if (local_node_id == libMesh::invalid_uint)
2338  return libMesh::invalid_uint;
2339 
2340  // If a node of e isn't contiguous with some node on side s of
2341  // this, then e isn't on side s.
2342  for (unsigned int s=0; s != ns; ++s)
2343  if (!this->is_node_on_side(local_node_id, s))
2344  might_be_side[s] = false;
2345  }
2346 
2347  for (unsigned int s=0; s != ns; ++s)
2348  if (might_be_side[s])
2349  {
2350 #ifdef DEBUG
2351  for (unsigned int s2=s+1; s2 < ns; ++s2)
2352  libmesh_assert (!might_be_side[s2]);
2353 #endif
2354  return s;
2355  }
2356 
2357  // Didn't find any matching side
2358  return libMesh::invalid_uint;
2359 }
2360 
2361 
2362 
2363 inline
2364 bool Elem::active() const
2365 {
2366 #ifdef LIBMESH_ENABLE_AMR
2367  if ((this->refinement_flag() == INACTIVE) ||
2368  (this->refinement_flag() == COARSEN_INACTIVE))
2369  return false;
2370  else
2371  return true;
2372 #else
2373  return true;
2374 #endif
2375 }
2376 
2377 
2378 
2379 
2380 
2381 inline
2382 bool Elem::subactive() const
2383 {
2384 #ifdef LIBMESH_ENABLE_AMR
2385  if (this->active())
2386  return false;
2387  if (!this->has_children())
2388  return true;
2389  for (const Elem * my_ancestor = this->parent();
2390  my_ancestor != nullptr;
2391  my_ancestor = my_ancestor->parent())
2392  if (my_ancestor->active())
2393  return true;
2394 #endif
2395 
2396  return false;
2397 }
2398 
2399 
2400 
2401 inline
2403 {
2404 #ifdef LIBMESH_ENABLE_AMR
2405  if (_children == nullptr)
2406  return false;
2407  else
2408  return true;
2409 #else
2410  return false;
2411 #endif
2412 }
2413 
2414 
2415 inline
2417 {
2418 #ifdef LIBMESH_ENABLE_AMR
2419  if (_children == nullptr)
2420  return false;
2421  else
2422  for (auto & c : child_ref_range())
2423  if (c.has_children())
2424  return true;
2425 #endif
2426  return false;
2427 }
2428 
2429 
2430 
2431 inline
2433 #ifdef LIBMESH_ENABLE_AMR
2434  descendant
2435 #endif
2436  ) const
2437 {
2438 #ifdef LIBMESH_ENABLE_AMR
2439  const Elem * e = descendant;
2440  while (e)
2441  {
2442  if (this == e)
2443  return true;
2444  e = e->parent();
2445  }
2446 #endif
2447  return false;
2448 }
2449 
2450 
2451 
2452 inline
2453 const Elem * Elem::parent () const
2454 {
2455  return _elemlinks[0];
2456 }
2457 
2458 
2459 
2460 inline
2462 {
2463  return _elemlinks[0];
2464 }
2465 
2466 
2467 
2468 inline
2470 {
2471  _elemlinks[0] = p;
2472 }
2473 
2474 
2475 
2476 inline
2477 const Elem * Elem::top_parent () const
2478 {
2479  const Elem * tp = this;
2480 
2481  // Keep getting the element's parent
2482  // until that parent is at level-0
2483  while (tp->parent() != nullptr)
2484  tp = tp->parent();
2485 
2486  libmesh_assert(tp);
2487  libmesh_assert_equal_to (tp->level(), 0);
2488 
2489  return tp;
2490 }
2491 
2492 
2493 
2494 inline
2495 unsigned int Elem::level() const
2496 {
2497 #ifdef LIBMESH_ENABLE_AMR
2498 
2499  // if I don't have a parent I was
2500  // created directly from file
2501  // or by the user, so I am a
2502  // level-0 element
2503  if (this->parent() == nullptr)
2504  return 0;
2505 
2506  // if the parent and this element are of different
2507  // dimensionality we are at the same level as
2508  // the parent (e.g. we are the 2D side of a
2509  // 3D element)
2510  if (this->dim() != this->parent()->dim())
2511  return this->parent()->level();
2512 
2513  // otherwise we are at a level one
2514  // higher than our parent
2515  return (this->parent()->level() + 1);
2516 
2517 #else
2518 
2519  // Without AMR all elements are
2520  // at level 0.
2521  return 0;
2522 
2523 #endif
2524 }
2525 
2526 
2527 
2528 inline
2529 unsigned int Elem::p_level() const
2530 {
2531 #ifdef LIBMESH_ENABLE_AMR
2532  return _p_level;
2533 #else
2534  return 0;
2535 #endif
2536 }
2537 
2538 
2539 
2540 #ifdef LIBMESH_ENABLE_AMR
2541 
2542 inline
2543 const Elem * Elem::raw_child_ptr (unsigned int i) const
2544 {
2545  if (!_children)
2546  return nullptr;
2547 
2548  return _children[i];
2549 }
2550 
2551 inline
2552 const Elem * Elem::child_ptr (unsigned int i) const
2553 {
2554  libmesh_assert(_children);
2555  libmesh_assert(_children[i]);
2556 
2557  return _children[i];
2558 }
2559 
2560 inline
2561 Elem * Elem::child_ptr (unsigned int i)
2562 {
2563  libmesh_assert(_children);
2564  libmesh_assert(_children[i]);
2565 
2566  return _children[i];
2567 }
2568 
2569 
2570 inline
2571 void Elem::set_child (unsigned int c, Elem * elem)
2572 {
2573  libmesh_assert (this->has_children());
2574 
2575  _children[c] = elem;
2576 }
2577 
2578 
2579 
2580 inline
2581 unsigned int Elem::which_child_am_i (const Elem * e) const
2582 {
2583  libmesh_assert(e);
2584  libmesh_assert (this->has_children());
2585 
2586  unsigned int nc = this->n_children();
2587  for (unsigned int c=0; c != nc; c++)
2588  if (this->child_ptr(c) == e)
2589  return c;
2590 
2591  libmesh_error_msg("ERROR: which_child_am_i() was called with a non-child!");
2592 
2593  return libMesh::invalid_uint;
2594 }
2595 
2596 
2597 
2598 inline
2600 {
2601  return static_cast<RefinementState>(_rflag);
2602 }
2603 
2604 
2605 
2606 inline
2608 {
2609  _rflag = cast_int<RefinementState>(rflag);
2610 }
2611 
2612 
2613 
2614 inline
2616 {
2617  return static_cast<RefinementState>(_pflag);
2618 }
2619 
2620 
2621 
2622 inline
2624 {
2625  if (this->p_level() == 0)
2626  libmesh_assert_not_equal_to
2627  (pflag, Elem::JUST_REFINED);
2628 
2629  _pflag = cast_int<unsigned char>(pflag);
2630 }
2631 
2632 
2633 
2634 inline
2635 unsigned int Elem::max_descendant_p_level () const
2636 {
2637  // This is undefined for subactive elements,
2638  // which have no active descendants
2639  libmesh_assert (!this->subactive());
2640  if (this->active())
2641  return this->p_level();
2642 
2643  unsigned int max_p_level = _p_level;
2644  for (auto & c : child_ref_range())
2645  max_p_level = std::max(max_p_level,
2646  c.max_descendant_p_level());
2647  return max_p_level;
2648 }
2649 
2650 
2651 
2652 inline
2653 void Elem::set_p_level(unsigned int p)
2654 {
2655  // Maintain the parent's p level as the minimum of it's children
2656  if (this->parent() != nullptr)
2657  {
2658  unsigned int parent_p_level = this->parent()->p_level();
2659 
2660  // If our new p level is less than our parents, our parents drops
2661  if (parent_p_level > p)
2662  {
2663  this->parent()->set_p_level(p);
2664 
2665  // And we should keep track of the drop, in case we need to
2666  // do a projection later.
2668  }
2669  // If we are the lowest p level and it increases, so might
2670  // our parent's, but we have to check every other child to see
2671  else if (parent_p_level == _p_level && _p_level < p)
2672  {
2673  _p_level = cast_int<unsigned char>(p);
2674  parent_p_level = cast_int<unsigned char>(p);
2675  for (auto & c : this->parent()->child_ref_range())
2676  parent_p_level = std::min(parent_p_level,
2677  c.p_level());
2678 
2679  // When its children all have a higher p level, the parent's
2680  // should rise
2681  if (parent_p_level > this->parent()->p_level())
2682  {
2683  this->parent()->set_p_level(parent_p_level);
2684 
2685  // And we should keep track of the rise, in case we need to
2686  // do a projection later.
2688  }
2689 
2690  return;
2691  }
2692  }
2693 
2694  _p_level = cast_int<unsigned char>(p);
2695 }
2696 
2697 
2698 
2699 inline
2700 void Elem::hack_p_level(unsigned int p)
2701 {
2702  if (p == 0)
2703  libmesh_assert_not_equal_to
2705 
2706  _p_level = cast_int<unsigned char>(p);
2707 }
2708 
2709 
2710 
2711 #endif // ifdef LIBMESH_ENABLE_AMR
2712 
2713 
2714 inline
2716 {
2717  return n0;
2718 }
2719 
2720 
2721 
2722 inline
2724  dof_id_type n1)
2725 {
2726  // Order the two so that n0 < n1
2727  if (n0 > n1) std::swap (n0, n1);
2728 
2729  return Utility::hashword2(n0, n1);
2730 }
2731 
2732 
2733 
2734 inline
2736  dof_id_type n1,
2737  dof_id_type n2)
2738 {
2739  // Order the numbers such that n0 < n1 < n2.
2740  // We'll do it in 3 steps like this:
2741  //
2742  // n0 n1 n2
2743  // min(n0,n1) max(n0,n1) n2
2744  // min(n0,n1) min(n2,max(n0,n1) max(n2,max(n0,n1)
2745  // |\ /| |
2746  // | \ / | |
2747  // | / | |
2748  // | / \| |
2749  // gb min= min max gb max
2750 
2751  // Step 1
2752  if (n0 > n1) std::swap (n0, n1);
2753 
2754  // Step 2
2755  if (n1 > n2) std::swap (n1, n2);
2756 
2757  // Step 3
2758  if (n0 > n1) std::swap (n0, n1);
2759 
2760  libmesh_assert ((n0 < n1) && (n1 < n2));
2761 
2762  dof_id_type array[3] = {n0, n1, n2};
2763  return Utility::hashword(array, 3);
2764 }
2765 
2766 
2767 
2768 inline
2770  dof_id_type n1,
2771  dof_id_type n2,
2772  dof_id_type n3)
2773 {
2774  // Sort first
2775  // Step 1
2776  if (n0 > n1) std::swap (n0, n1);
2777 
2778  // Step 2
2779  if (n2 > n3) std::swap (n2, n3);
2780 
2781  // Step 3
2782  if (n0 > n2) std::swap (n0, n2);
2783 
2784  // Step 4
2785  if (n1 > n3) std::swap (n1, n3);
2786 
2787  // Finally sort step 5
2788  if (n1 > n2) std::swap (n1, n2);
2789 
2790  libmesh_assert ((n0 < n1) && (n1 < n2) && (n2 < n3));
2791 
2792  dof_id_type array[4] = {n0, n1, n2, n3};
2793  return Utility::hashword(array, 4);
2794 }
2795 
2796 
2797 
2802 {
2803 public:
2804  // Constructor with arguments.
2805  SideIter(const unsigned int side_number,
2806  Elem * parent)
2807  : _side(),
2808  _side_ptr(nullptr),
2809  _parent(parent),
2810  _side_number(side_number)
2811  {}
2812 
2813 
2814  // Empty constructor.
2816  : _side(),
2817  _side_ptr(nullptr),
2818  _parent(nullptr),
2820  {}
2821 
2822 
2823  // Copy constructor
2824  SideIter(const SideIter & other)
2825  : _side(),
2826  _side_ptr(nullptr),
2827  _parent(other._parent),
2828  _side_number(other._side_number)
2829  {}
2830 
2831 
2832  // op=
2833  SideIter & operator=(const SideIter & other)
2834  {
2835  this->_parent = other._parent;
2836  this->_side_number = other._side_number;
2837  return *this;
2838  }
2839 
2840  // unary op*
2841  Elem *& operator*() const
2842  {
2843  // Set the std::unique_ptr
2844  this->_update_side_ptr();
2845 
2846  // Return a reference to _side_ptr
2847  return this->_side_ptr;
2848  }
2849 
2850  // op++
2852  {
2853  ++_side_number;
2854  return *this;
2855  }
2856 
2857  // op== Two side iterators are equal if they have
2858  // the same side number and the same parent element.
2859  bool operator == (const SideIter & other) const
2860  {
2861  return (this->_side_number == other._side_number &&
2862  this->_parent == other._parent);
2863  }
2864 
2865 
2866  // Consults the parent Elem to determine if the side
2867  // is a boundary side. Note: currently side N is a
2868  // boundary side if neighbor N is nullptr. Be careful,
2869  // this could possibly change in the future?
2870  bool side_on_boundary() const
2871  {
2872  return this->_parent->neighbor_ptr(_side_number) == nullptr;
2873  }
2874 
2875 private:
2876  // Update the _side pointer by building the correct side.
2877  // This has to be called before dereferencing.
2878  void _update_side_ptr() const
2879  {
2880  // Construct new side, store in std::unique_ptr
2881  this->_side = this->_parent->build_side_ptr(this->_side_number);
2882 
2883  // Also set our internal naked pointer. Memory is still owned
2884  // by the std::unique_ptr.
2885  this->_side_ptr = _side.get();
2886  }
2887 
2888  // std::unique_ptr to the actual side, handles memory management for
2889  // the sides which are created during the course of iteration.
2890  mutable std::unique_ptr<Elem> _side;
2891 
2892  // Raw pointer needed to facilitate passing back to the user a
2893  // reference to a non-temporary raw pointer in order to conform to
2894  // the variant_filter_iterator interface. It points to the same
2895  // thing the std::unique_ptr "_side" above holds. What happens if the user
2896  // calls delete on the pointer passed back? Well, this is an issue
2897  // which is not addressed by the iterators in libMesh. Basically it
2898  // is a bad idea to ever call delete on an iterator from the library.
2899  mutable Elem * _side_ptr;
2900 
2901  // Pointer to the parent Elem class which generated this iterator
2903 
2904  // A counter variable which keeps track of the side number
2905  unsigned int _side_number;
2906 };
2907 
2908 
2909 
2910 
2911 
2912 
2913 // Private implementation functions in the Elem class for the side iterators.
2914 // They have to come after the definition of the SideIter class.
2915 inline
2917 {
2918  return SideIter(0, this);
2919 }
2920 
2921 
2922 
2923 inline
2925 {
2926  return SideIter(this->n_neighbors(), this);
2927 }
2928 
2929 
2930 
2931 
2935 struct
2936 Elem::side_iterator : variant_filter_iterator<Elem::Predicate, Elem *>
2937 {
2938  // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
2939  template <typename PredType, typename IterType>
2940  side_iterator (const IterType & d,
2941  const IterType & e,
2942  const PredType & p ) :
2944 };
2945 
2946 
2947 
2948 inline
2950 {
2951  return {_elemlinks+1, _elemlinks + 1 + this->n_neighbors()};
2952 }
2953 
2954 
2955 inline
2957 {
2958  return {_elemlinks+1, _elemlinks + 1 + this->n_neighbors()};
2959 }
2960 
2961 } // namespace libMesh
2962 
2963 
2964 // Helper function for default caches in Elem subclasses
2965 
2966 #define LIBMESH_ENABLE_TOPOLOGY_CACHES \
2967  virtual \
2968  std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> & \
2969  _get_bracketing_node_cache() const override \
2970  { \
2971  static std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> c; \
2972  return c; \
2973  } \
2974  \
2975  virtual \
2976  std::vector<std::vector<std::vector<signed char>>> & \
2977  _get_parent_indices_cache() const override \
2978  { \
2979  static std::vector<std::vector<std::vector<signed char>>> c; \
2980  return c; \
2981  }
2982 
2983 
2984 
2985 
2986 
2987 
2988 #endif // LIBMESH_ELEM_H
void active_family_tree_by_topological_neighbor(std::vector< const Elem *> &family, const Elem *neighbor, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb, bool reset=true) const
Same as the active_family_tree_by_neighbor() member, but the neighbor here may be a topological (e...
bool has_neighbor(const Elem *elem) const
Definition: elem.h:2080
void set_p_level(const unsigned int p)
Sets the value of the p-refinement level for the element.
Definition: elem.h:2653
RefinementState refinement_flag() const
Definition: elem.h:2599
ElemType
Defines an enum for geometric element types.
The SimpleRange templated class is intended to make it easy to construct ranges from pairs of iterato...
Definition: simple_range.h:36
virtual BoundingBox loose_bounding_box() const
side_iterator boundary_sides_begin()
Iterator accessor functions.
const Elem * interior_parent() const
void write_connectivity(std::ostream &out, const IOPackage iop) const
Writes the element connectivity for various IO packages to the passed ostream "out".
const Elem * parent() const
Definition: elem.h:2453
virtual void refine(MeshRefinement &mesh_refinement)
Refine the element.
Order
defines an enum for polynomial orders.
Definition: enum_order.h:40
virtual Real quality(const ElemQuality q) const
void print_info(std::ostream &os=libMesh::out) const
Prints relevant information about the element.
void active_family_tree_by_side(std::vector< const Elem *> &family, unsigned int side, bool reset=true) const
Same as the active_family_tree() member, but only adds elements which are next to side...
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:2024
A Node is like a Point, but with more information.
Definition: node.h:52
bool is_ancestor_of(const Elem *descendant) const
Definition: elem.h:2432
Node ** _nodes
Pointers to the nodes we are connected to.
Definition: elem.h:1723
Elem * child_neighbor(Elem *elem)
Definition: elem.h:2092
virtual unsigned int as_parent_node(unsigned int c, unsigned int n) const
variant_filter_iterator(const IterType &d, const IterType &e, const PredType &p)
Templated Constructor.
Predicates::multi_predicate Predicate
Useful iterator typedefs.
Definition: elem.h:1519
const Elem * topological_neighbor(const unsigned int i, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
virtual Point origin() const
Definition: elem.h:1573
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value.
Definition: libmesh.h:245
void set_parent(Elem *p)
Sets the pointer to the element&#39;s parent.
Definition: elem.h:2469
unsigned int get_node_index(const Node *node_ptr) const
Definition: elem.h:2012
std::string get_info() const
Prints relevant information about the element to a string.
virtual bool is_face(const unsigned int i) const =0
bool is_semilocal(const processor_id_type my_pid) const
unsigned char _pflag
p refinement flag.
Definition: elem.h:1754
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
Definition: int_range.h:51
unsigned char _p_level
p refinement level - the difference between the polynomial degree on this element and the minimum pol...
Definition: elem.h:1764
IntRange< unsigned short > side_index_range() const
Definition: elem.h:2153
void contract()
Contract an active element, i.e.
void libmesh_assert_valid_node_pointers() const
Checks for a valid id and pointers to nodes with valid ids on this element.
const Elem * top_parent() const
Definition: elem.h:2477
We&#39;re using a class instead of a typedef to allow forward declarations and future flexibility...
virtual bool is_edge_on_side(const unsigned int e, const unsigned int s) const =0
virtual unsigned int embedding_matrix_version() const
Definition: elem.h:1629
unsigned int which_side_am_i(const Elem *e) const
This function tells you which side the boundary element e is.
Definition: elem.h:2310
virtual bool is_child_on_side(const unsigned int c, const unsigned int s) const =0
SideIter(const unsigned int side_number, Elem *parent)
Definition: elem.h:2805
virtual Real hmax() const
RefinementState p_refinement_flag() const
Definition: elem.h:2615
IOPackage
libMesh interfaces with several different software packages for the purposes of creating, reading, and writing mesh files.
virtual bool has_affine_map() const
Definition: elem.h:939
void find_interior_neighbors(std::set< const Elem *> &neighbor_set) const
This function finds all active elements (not including this one) in the parent manifold of this eleme...
void family_tree_by_subneighbor(std::vector< const Elem *> &family, const Elem *neighbor, const Elem *subneighbor, bool reset=true) const
Same as the family_tree() member, but only adds elements which are next to subneighbor.
virtual dof_id_type key() const
bool operator==(const SideIter &other) const
Definition: elem.h:2859
void family_tree(std::vector< const Elem *> &family, bool reset=true) const
Fills the vector family with the children of this element, recursively.
This is the base class from which all geometric element types are derived.
Definition: elem.h:101
void add_child(Elem *elem)
Adds a child pointer to the array of children of this element.
SideIter & operator=(const SideIter &other)
Definition: elem.h:2833
unsigned int min_new_p_level_by_neighbor(const Elem *neighbor, unsigned int current_min) const
RefinementState
Enumeration of possible element refinement states.
Definition: elem.h:1149
void set_refinement_flag(const RefinementState rflag)
Sets the value of the refinement flag for the element.
Definition: elem.h:2607
std::ostream & operator<<(std::ostream &os, const OrderWrapper &order)
Overload stream operators.
Definition: fe_type.h:165
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
void active_family_tree(std::vector< const Elem *> &active_family, bool reset=true) const
Same as the family_tree() member, but only adds the active children.
virtual float embedding_matrix(const unsigned int child_num, const unsigned int child_node_num, const unsigned int parent_node_num) const =0
virtual ~Elem()
Destructor.
static const unsigned int type_to_n_sides_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the number of sides on the element...
Definition: elem.h:608
static ElemType first_order_equivalent_type(const ElemType et)
virtual unsigned int n_children() const =0
ChildRefIter(Elem *const *childpp)
Definition: elem.h:1794
unsigned int _side_number
Definition: elem.h:2905
unsigned int p_level() const
Definition: elem.h:2529
const Elem * reference_elem() const
void find_edge_neighbors(const Point &p1, const Point &p2, std::set< const Elem *> &neighbor_set) const
This function finds all active elements in the same manifold as this element which touch the current ...
virtual const std::vector< std::pair< unsigned char, unsigned char > > & parent_bracketing_nodes(unsigned int c, unsigned int n) const
static const Real TOLERANCE
void make_links_to_me_remote()
Resets this element&#39;s neighbors&#39; appropriate neighbor pointers and its parent&#39;s and children&#39;s approp...
The libMesh namespace provides an interface to certain functionality in the library.
SideIter & operator++()
Definition: elem.h:2851
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
virtual bool is_linear() const
Definition: elem.h:945
long double max(long double a, double b)
unsigned int min_p_level_by_neighbor(const Elem *neighbor, unsigned int current_min) const
static ElemType second_order_equivalent_type(const ElemType et, const bool full_ordered=true)
void set_interior_parent(Elem *p)
Sets the pointer to the element&#39;s interior_parent.
uint8_t processor_id_type
Definition: id_types.h:104
This is the MeshBase class.
Definition: mesh_base.h:77
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
Definition: elem.h:1807
bool ancestor() const
bool has_topological_neighbor(const Elem *elem, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
IntRange< unsigned short > edge_index_range() const
Definition: elem.h:2144
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i, bool proxy=true)=0
Elem *& operator*() const
Definition: elem.h:2841
const Elem *const * ConstNeighborPtrIter
Definition: elem.h:300
virtual bool is_node_on_edge(const unsigned int n, const unsigned int e) const =0
uint32_t hashword(const uint32_t *k, size_t length, uint32_t initval=0)
The hashword function takes an array of uint32_t&#39;s of length &#39;length&#39; and computes a single key from ...
Definition: hashword.h:153
virtual bool is_vertex_on_parent(unsigned int c, unsigned int n) const
void family_tree_by_side(std::vector< const Elem *> &family, unsigned int side, bool reset=true) const
Same as the family_tree() member, but only adds elements which are next to side.
void replace_child(Elem *elem, unsigned int c)
Replaces the child pointer at the specified index in the child array.
void total_family_tree_by_subneighbor(std::vector< const Elem *> &family, const Elem *neighbor, const Elem *subneighbor, bool reset=true) const
Same as the family_tree_by_subneighbor() member, but also adds any subactive descendants.
static const subdomain_id_type invalid_subdomain_id
A static integral constant representing an invalid subdomain id.
Definition: elem.h:245
virtual Point centroid() const
void remove_links_to_me()
Resets this element&#39;s neighbors&#39; appropriate neighbor pointers and its parent&#39;s and children&#39;s approp...
virtual std::vector< std::vector< std::vector< signed char > > > & _get_parent_indices_cache() const
Elem subclasses which don&#39;t do their own child-to-parent node calculations will need to supply a stat...
Definition: elem.h:1701
Elem *const * NeighborPtrIter
Nested "classes" for use iterating over all neighbors of an element.
Definition: elem.h:299
Implements (adaptive) mesh refinement algorithms for a MeshBase.
Real length(const unsigned int n1, const unsigned int n2) const
Elem & operator=(const Elem &)=delete
const Node & node_ref(const unsigned int i) const
Definition: elem.h:1996
dof_id_type id() const
Definition: dof_object.h:738
virtual unsigned int n_nodes() const =0
static const processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
Definition: dof_object.h:404
bool contains_edge_of(const Elem *e) const
unsigned int which_neighbor_am_i(const Elem *e) const
This function tells you which neighbor e is.
Definition: elem.h:2288
Elem ** _elemlinks
Pointers to this element&#39;s parent and neighbors, and for lower-dimensional elements&#39; interior_parent...
Definition: elem.h:1729
void find_point_neighbors(const Point &p, std::set< const Elem *> &neighbor_set) const
This function finds all active elements (including this one) which are in the same manifold as this e...
Elem ** _children
Pointers to this element&#39;s children.
Definition: elem.h:1735
The definition of the struct used for iterating over sides.
Definition: elem.h:2935
const Node *const * get_nodes() const
Definition: elem.h:1966
bool point_test(const Point &p, Real box_tol, Real map_tol) const
Shared private implementation used by the contains_point() and close_to_point() routines.
void _update_side_ptr() const
Definition: elem.h:2878
bool side_on_boundary() const
Definition: elem.h:2870
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:393
void libmesh_assert_valid_neighbors() const
Checks for consistent neighbor links on this element.
virtual bool is_remote() const
Definition: elem.h:543
OStreamProxy out
This is the base class for point locators.
virtual unsigned int n_edges() const =0
ElemQuality
Defines an enum for element quality metrics.
SideIter _last_side()
Definition: elem.h:2924
static const unsigned int type_to_n_edges_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the number of edges on the element...
Definition: elem.h:657
virtual std::pair< unsigned short int, unsigned short int > second_order_child_vertex(const unsigned int n) const
void set_neighbor(const unsigned int i, Elem *n)
Assigns n as the neighbor.
Definition: elem.h:2070
This class implements reference counting.
subdomain_id_type _sbd_id
The subdomain to which this element belongs.
Definition: elem.h:1741
bool on_boundary() const
Definition: elem.h:2278
virtual unsigned int n_second_order_adjacent_vertices(const unsigned int n) const
Elem(const unsigned int n_nodes, const unsigned int n_sides, Elem *parent, Elem **elemlinkdata, Node **nodelinkdata)
Constructor.
Definition: elem.h:1839
unsigned int which_child_am_i(const Elem *e) const
Definition: elem.h:2581
unsigned int max_descendant_p_level() const
Definition: elem.h:2635
unsigned char _rflag
h refinement flag.
Definition: elem.h:1748
bool contains_vertex_of(const Elem *e) const
virtual unsigned int which_node_am_i(unsigned int side, unsigned int side_node) const =0
void active_family_tree_by_neighbor(std::vector< const Elem *> &family, const Elem *neighbor, bool reset=true) const
Same as the active_family_tree() member, but only adds elements which are next to neighbor...
void total_family_tree_by_neighbor(std::vector< const Elem *> &family, const Elem *neighbor, bool reset=true) const
Same as the family_tree_by_neighbor() member, but also adds any subactive descendants.
SimpleRange< NodeRefIter > node_ref_range()
Returns a range with all nodes of an element, usable in range-based for loops.
Definition: elem.h:2117
virtual unsigned int is_vertex_on_child(unsigned int, unsigned int n) const
Definition: elem.h:682
Defines a Cartesian bounding box by the two corner extremum.
Definition: bounding_box.h:40
std::unique_ptr< Elem > _side
Definition: elem.h:2890
ConstNodeRefIter(const Node *const *nodepp)
Definition: elem.h:1785
virtual unsigned int n_sides() const =0
const Elem * neighbor_ptr(unsigned int i) const
Definition: elem.h:2050
unsigned int level() const
Definition: elem.h:2495
const Elem * raw_child_ptr(unsigned int i) const
Definition: elem.h:2543
static const unsigned int type_to_n_nodes_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the number of nodes in the element...
Definition: elem.h:577
virtual unsigned int n_vertices() const =0
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual std::unique_ptr< Elem > side_ptr(unsigned int i)=0
virtual Real hmin() const
subdomain_id_type subdomain_id() const
Definition: elem.h:2034
virtual unsigned short dim() const =0
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:1974
SideIter(const SideIter &other)
Definition: elem.h:2824
void coarsen()
Coarsen the element.
virtual bool is_vertex(const unsigned int i) const =0
void swap(Iterator &lhs, Iterator &rhs)
swap, used to implement op=
virtual Point master_point(const unsigned int i) const =0
unsigned int n_neighbors() const
Definition: elem.h:632
bool subactive() const
Definition: elem.h:2382
uint32_t hashword2(const uint32_t &first, const uint32_t &second, uint32_t initval=0)
This is a hard-coded version of hashword for hashing exactly 2 numbers.
Definition: hashword.h:210
The DofObject defines an abstract base class for objects that have degrees of freedom associated with...
Definition: dof_object.h:51
void set_child(unsigned int c, Elem *elem)
Sets the pointer to the child for this element.
Definition: elem.h:2571
virtual void connectivity(const unsigned int sc, const IOPackage iop, std::vector< dof_id_type > &conn) const =0
virtual unsigned short int second_order_adjacent_vertex(const unsigned int n, const unsigned int v) const
bool has_ancestor_children() const
Definition: elem.h:2416
virtual unsigned int opposite_side(const unsigned int s) const
IntRange< unsigned short > node_index_range() const
Definition: elem.h:2135
unsigned int local_node(const dof_id_type i) const
Definition: elem.h:1954
virtual bool close_to_point(const Point &p, Real tol) const
void nullify_neighbors()
Replaces this element with nullptr for all of its neighbors.
SimpleRange< NeighborPtrIter > neighbor_ptr_range()
Returns a range with all neighbors of an element, usable in range-based for loops.
Definition: elem.h:2949
void set_p_refinement_flag(const RefinementState pflag)
Sets the value of the p-refinement flag for the element.
Definition: elem.h:2623
virtual unsigned int n_faces() const =0
virtual bool infinite() const =0
virtual std::pair< Real, Real > qual_bounds(const ElemQuality) const
Definition: elem.h:899
void simple_side_ptr(std::unique_ptr< Elem > &side, const unsigned int i, ElemType sidetype)
An implementation for simple (all sides equal) elements.
Definition: elem.h:2242
static dof_id_type compute_key(dof_id_type n0)
Definition: elem.h:2715
virtual unsigned int n_sub_elem() const =0
void total_family_tree(std::vector< const Elem *> &family, bool reset=true) const
Same as the family_tree() member, but also adds any subactive descendants.
void family_tree_by_neighbor(std::vector< const Elem *> &family, const Elem *neighbor, bool reset=true) const
Same as the family_tree() member, but only adds elements which are next to neighbor.
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i)=0
void make_links_to_me_local(unsigned int n)
Resets the appropriate neighbor pointers of our nth neighbor (and its descendants, if appropriate) to point to this Elem instead of to the global remote_elem.
virtual unsigned int opposite_node(const unsigned int n, const unsigned int s) const
ConstChildRefIter(const Elem *const *childpp)
Definition: elem.h:1802
virtual Order default_order() const =0
virtual std::vector< std::vector< std::vector< std::vector< std::pair< unsigned char, unsigned char > > > > > & _get_bracketing_node_cache() const
Elem subclasses which don&#39;t do their own bracketing node calculations will need to supply a static ca...
Definition: elem.h:1687
bool active() const
Definition: elem.h:2364
void hack_p_level(const unsigned int p)
Sets the value of the p-refinement level for the element without altering the p-level of its ancestor...
Definition: elem.h:2700
void simple_build_side_ptr(std::unique_ptr< Elem > &side, const unsigned int i, ElemType sidetype)
An implementation for simple (all sides equal) elements.
Definition: elem.h:2217
processor_id_type processor_id() const
Definition: dof_object.h:800
virtual Real volume() const
virtual ElemType type() const =0
long double min(long double a, double b)
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:1942
const Point & point(const unsigned int i) const
Definition: elem.h:1920
bool operator==(const Elem &rhs) const
virtual bool is_child_on_edge(const unsigned int c, const unsigned int e) const
side_iterator(const IterType &d, const IterType &e, const PredType &p)
Definition: elem.h:2940
bool has_children() const
Definition: elem.h:2402
NodeRefIter(Node *const *nodepp)
Definition: elem.h:1777
virtual bool is_edge(const unsigned int i) const =0
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const
virtual std::vector< unsigned int > nodes_on_side(const unsigned int) const =0
side_iterator boundary_sides_end()
virtual unsigned int n_nodes_in_child(unsigned int) const
Definition: elem.h:601
static const unsigned int max_n_nodes
The maximum number of nodes any element can contain.
Definition: elem.h:588
const Elem * child_ptr(unsigned int i) const
Definition: elem.h:2552
virtual const std::vector< std::pair< dof_id_type, dof_id_type > > bracketing_nodes(unsigned int c, unsigned int n) const
uint8_t dof_id_type
Definition: id_types.h:67
The definition of the protected nested SideIter class.
Definition: elem.h:2801
virtual bool is_mid_infinite_edge_node(const unsigned int) const
Definition: elem.h:1564
SideIter _first_side()
Side iterator helper functions.
Definition: elem.h:2916