elem.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 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"
29 #include "libmesh/node.h"
30 #include "libmesh/enum_elem_type.h" // INVALID_ELEM
31 #include "libmesh/auto_ptr.h" // deprecated
34 #include "libmesh/int_range.h"
35 #include "libmesh/simple_range.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
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 
100 class Elem : public ReferenceCountedObject<Elem>,
101  public DofObject
102 {
103 protected:
104 
111  Elem (const unsigned int n_nodes,
112  const unsigned int n_sides,
113  Elem * parent,
114  Elem ** elemlinkdata,
115  Node ** nodelinkdata);
116 
117 public:
118 
128  Elem (Elem &&) = delete;
129  Elem (const Elem &) = delete;
130  Elem & operator= (const Elem &) = delete;
131  Elem & operator= (Elem &&) = delete;
132 
136  virtual ~Elem();
137 
141  const Point & point (const unsigned int i) const;
142 
147  Point & point (const unsigned int i);
148 
153  virtual Point master_point (const unsigned int i) const = 0;
154 
158  dof_id_type node_id (const unsigned int i) const;
159 
165 #ifdef LIBMESH_ENABLE_DEPRECATED
166  dof_id_type node (const unsigned int i) const;
167 #endif
168 
173  unsigned int local_node (const dof_id_type i) const;
174 
179  unsigned int get_node_index (const Node * node_ptr) const;
180 
184  const Node * const * get_nodes () const;
185 
189  const Node * node_ptr (const unsigned int i) const;
190 
194  Node * node_ptr (const unsigned int i);
195 
199  const Node & node_ref (const unsigned int i) const;
200 
204  Node & node_ref (const unsigned int i);
205 
211 #ifdef LIBMESH_ENABLE_DEPRECATED
212  Node * get_node (const unsigned int i) const;
213 #endif
214 
218  virtual Node * & set_node (const unsigned int i);
219 
223  class NodeRefIter;
224  class ConstNodeRefIter;
225 
234 
236 
241 
247 
263 
272  const Elem * reference_elem () const;
273 
279  virtual dof_id_type key (const unsigned int s) const = 0;
280 
287  virtual dof_id_type key () const;
288 
295  bool operator == (const Elem & rhs) const;
296 
306  const Elem * neighbor_ptr (unsigned int i) const;
307 
311  Elem * neighbor_ptr (unsigned int i);
312 
316 #ifdef LIBMESH_ENABLE_DEPRECATED
317  Elem * neighbor (const unsigned int i) const;
318 #endif
319 
323  typedef Elem * const * NeighborPtrIter;
324  typedef const Elem * const * ConstNeighborPtrIter;
325 
335 
337 
338 #ifdef LIBMESH_ENABLE_PERIODIC
339 
345  const Elem * topological_neighbor (const unsigned int i,
346  const MeshBase & mesh,
347  const PointLocatorBase & point_locator,
348  const PeriodicBoundaries * pb) const;
349 
356  Elem * topological_neighbor (const unsigned int i,
357  MeshBase & mesh,
358  const PointLocatorBase & point_locator,
359  const PeriodicBoundaries * pb);
360 
365  bool has_topological_neighbor (const Elem * elem,
366  const MeshBase & mesh,
367  const PointLocatorBase & point_locator,
368  const PeriodicBoundaries * pb) const;
369 #endif
370 
374  void set_neighbor (const unsigned int i, Elem * n);
375 
380  bool has_neighbor (const Elem * elem) const;
381 
386  Elem * child_neighbor (Elem * elem);
387 
392  const Elem * child_neighbor (const Elem * elem) const;
393 
399  bool on_boundary () const;
400 
405  bool is_semilocal (const processor_id_type my_pid) const;
406 
412  unsigned int which_neighbor_am_i(const Elem * e) const;
413 
430  unsigned int which_side_am_i(const Elem * e) const;
431 
442  virtual unsigned int which_node_am_i(unsigned int side,
443  unsigned int side_node) const = 0;
444 
449  bool contains_vertex_of(const Elem * e) const;
450 
456  bool contains_edge_of(const Elem * e) const;
457 
474  void find_point_neighbors(const Point & p,
475  std::set<const Elem *> & neighbor_set) const;
476 
482  void find_point_neighbors(std::set<const Elem *> & neighbor_set) const;
483 
489  void find_point_neighbors(std::set<const Elem *> & neighbor_set,
490  const Elem * start_elem) const;
491 
497  void find_edge_neighbors(const Point & p1,
498  const Point & p2,
499  std::set<const Elem *> & neighbor_set) const;
500 
509  void find_edge_neighbors(std::set<const Elem *> & neighbor_set) const;
510 
516  void find_interior_neighbors(std::set<const Elem *> & neighbor_set) const;
517 
525  void remove_links_to_me ();
526 
534  void make_links_to_me_remote ();
535 
542  void make_links_to_me_local (unsigned int n);
543 
555  virtual bool is_remote () const
556  { return false; }
557 
562  virtual void connectivity(const unsigned int sc,
563  const IOPackage iop,
564  std::vector<dof_id_type> & conn) const = 0;
565 
571  void write_connectivity (std::ostream & out,
572  const IOPackage iop) const;
573 
578  virtual ElemType type () const = 0;
579 
583  virtual unsigned short dim () const = 0;
584 
589  static const unsigned int type_to_n_nodes_map[INVALID_ELEM];
590 
594  virtual unsigned int n_nodes () const = 0;
595 
600  static const unsigned int max_n_nodes = 27;
601 
607 
613  virtual unsigned int n_nodes_in_child (unsigned int /*c*/) const
614  { return this->n_nodes(); }
615 
620  static const unsigned int type_to_n_sides_map[INVALID_ELEM];
621 
627  virtual unsigned int n_sides () const = 0;
628 
634 
644  unsigned int n_neighbors () const
645  { return this->n_sides(); }
646 
651  virtual unsigned int n_vertices () const = 0;
652 
657  virtual unsigned int n_edges () const = 0;
658 
664 
669  static const unsigned int type_to_n_edges_map[INVALID_ELEM];
670 
675  virtual unsigned int n_faces () const = 0;
676 
681  virtual unsigned int n_children () const = 0;
682 
686  virtual bool is_vertex(const unsigned int i) const = 0;
687 
694  virtual unsigned int is_vertex_on_child (unsigned int /*c*/,
695  unsigned int n) const
696  { return this->is_vertex(n); }
697 
702  virtual bool is_vertex_on_parent(unsigned int c,
703  unsigned int n) const;
704 
708  virtual bool is_edge(const unsigned int i) const = 0;
709 
713  virtual bool is_face(const unsigned int i) const = 0;
714 
719  virtual bool is_node_on_side(const unsigned int n,
720  const unsigned int s) const = 0;
721 
725  virtual std::vector<unsigned int> nodes_on_side(const unsigned int /*s*/) const = 0;
726 
731  virtual bool is_node_on_edge(const unsigned int n,
732  const unsigned int e) const = 0;
733 
737  virtual bool is_edge_on_side(const unsigned int e,
738  const unsigned int s) const = 0;
739 
744  virtual unsigned int opposite_side(const unsigned int s) const;
745 
751  virtual unsigned int opposite_node(const unsigned int n,
752  const unsigned int s) const;
753 
759  virtual unsigned int n_sub_elem () const = 0;
760 
775  virtual std::unique_ptr<Elem> side_ptr (unsigned int i) = 0;
776  std::unique_ptr<const Elem> side_ptr (unsigned int i) const;
777 
793  virtual void side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) = 0;
794  void side_ptr (std::unique_ptr<const Elem> & side, const unsigned int i) const;
795 
796 
805 #ifdef LIBMESH_ENABLE_DEPRECATED
806  std::unique_ptr<Elem> side (const unsigned int i) const;
807 #endif
808 
830  virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i, bool proxy=true) = 0;
831  std::unique_ptr<const Elem> build_side_ptr (const unsigned int i, bool proxy=true) const;
832 
848  virtual void build_side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) = 0;
849  void build_side_ptr (std::unique_ptr<const Elem> & side, const unsigned int i) const;
850 
859 #ifdef LIBMESH_ENABLE_DEPRECATED
860  std::unique_ptr<Elem> build_side (const unsigned int i, bool proxy=true) const;
861 #endif
862 
876  virtual std::unique_ptr<Elem> build_edge_ptr (const unsigned int i) = 0;
877  std::unique_ptr<const Elem> build_edge_ptr (const unsigned int i) const;
878 
887 #ifdef LIBMESH_ENABLE_DEPRECATED
888  std::unique_ptr<Elem> build_edge (const unsigned int i) const;
889 #endif
890 
896  virtual Order default_order () const = 0;
897 
905  virtual Point centroid () const;
906 
910  virtual Real hmin () const;
911 
915  virtual Real hmax () const;
916 
920  virtual Real volume () const;
921 
932  virtual BoundingBox loose_bounding_box () const;
933 
938  virtual Real quality (const ElemQuality q) const;
939 
948  virtual std::pair<Real,Real> qual_bounds (const ElemQuality) const
949  { libmesh_not_implemented(); return std::make_pair(0.,0.); }
950 
966  virtual bool contains_point (const Point & p, Real tol=TOLERANCE) const;
967 
972  virtual bool close_to_point(const Point & p, Real tol) const;
973 
974 private:
981  bool point_test(const Point & p, Real box_tol, Real map_tol) const;
982 
983 public:
988  virtual bool has_affine_map () const { return false; }
989 
994  virtual bool is_linear () const { return false; }
995 
999  void print_info (std::ostream & os=libMesh::out) const;
1000 
1004  std::string get_info () const;
1005 
1012  bool active () const;
1013 
1019  bool ancestor () const;
1020 
1025  bool subactive () const;
1026 
1031  bool has_children () const;
1032 
1037  bool has_ancestor_children () const;
1038 
1044  bool is_ancestor_of(const Elem * descendant) const;
1045 
1050  const Elem * parent () const;
1051 
1056  Elem * parent ();
1057 
1062  void set_parent (Elem * p);
1063 
1071  const Elem * top_parent () const;
1072 
1087  const Elem * interior_parent () const;
1088 
1089  Elem * interior_parent ();
1090 
1095  void set_interior_parent (Elem * p);
1096 
1102  Real length (const unsigned int n1,
1103  const unsigned int n2) const;
1104 
1115  virtual unsigned int n_second_order_adjacent_vertices (const unsigned int n) const;
1116 
1125  virtual unsigned short int second_order_adjacent_vertex (const unsigned int n,
1126  const unsigned int v) const;
1127 
1143  virtual std::pair<unsigned short int, unsigned short int>
1144  second_order_child_vertex (const unsigned int n) const;
1145 
1159  const bool full_ordered=true);
1160 
1168  static ElemType first_order_equivalent_type (const ElemType et);
1169 
1170 
1178  unsigned int level () const;
1179 
1185  unsigned int p_level () const;
1186 
1190  virtual bool is_child_on_side(const unsigned int c,
1191  const unsigned int s) const = 0;
1192 
1193 #ifdef LIBMESH_ENABLE_AMR
1194 
1206 
1211  const Elem * raw_child_ptr (unsigned int i) const;
1212 
1217  const Elem * child_ptr (unsigned int i) const;
1218 
1223  Elem * child_ptr (unsigned int i);
1224 
1231 #ifdef LIBMESH_ENABLE_DEPRECATED
1232  Elem * child (const unsigned int i) const;
1233 #endif
1234 
1239  class ChildRefIter;
1240  class ConstChildRefIter;
1241 
1250 
1252 
1253 private:
1258  void set_child (unsigned int c, Elem * elem);
1259 
1260 public:
1267  unsigned int which_child_am_i(const Elem * e) const;
1268 
1272  virtual bool is_child_on_edge(const unsigned int c,
1273  const unsigned int e) const;
1274 
1281  void add_child (Elem * elem);
1282 
1289  void add_child (Elem * elem, unsigned int c);
1290 
1294  void replace_child (Elem * elem, unsigned int c);
1295 
1307  void family_tree (std::vector<const Elem *> & family,
1308  const bool reset=true) const;
1309 
1314  void total_family_tree (std::vector<const Elem *> & active_family,
1315  const bool reset=true) const;
1316 
1323  void active_family_tree (std::vector<const Elem *> & active_family,
1324  const bool reset=true) const;
1325 
1330  void family_tree_by_side (std::vector<const Elem *> & family,
1331  const unsigned int side,
1332  const bool reset=true) const;
1333 
1338  void active_family_tree_by_side (std::vector<const Elem *> & family,
1339  const unsigned int side,
1340  const bool reset=true) const;
1341 
1346  void family_tree_by_neighbor (std::vector<const Elem *> & family,
1347  const Elem * neighbor,
1348  const bool reset=true) const;
1349 
1354  void total_family_tree_by_neighbor (std::vector<const Elem *> & family,
1355  const Elem * neighbor,
1356  const bool reset=true) const;
1357 
1364  void family_tree_by_subneighbor (std::vector<const Elem *> & family,
1365  const Elem * neighbor,
1366  const Elem * subneighbor,
1367  const bool reset=true) const;
1368 
1373  void total_family_tree_by_subneighbor (std::vector<const Elem *> & family,
1374  const Elem * neighbor,
1375  const Elem * subneighbor,
1376  const bool reset=true) const;
1377 
1382  void active_family_tree_by_neighbor (std::vector<const Elem *> & family,
1383  const Elem * neighbor,
1384  const bool reset=true) const;
1385 
1391  void active_family_tree_by_topological_neighbor (std::vector<const Elem *> & family,
1392  const Elem * neighbor,
1393  const MeshBase & mesh,
1394  const PointLocatorBase & point_locator,
1395  const PeriodicBoundaries * pb,
1396  const bool reset=true) const;
1397 
1402 
1406  void set_refinement_flag (const RefinementState rflag);
1407 
1412 
1416  void set_p_refinement_flag (const RefinementState pflag);
1417 
1422  unsigned int max_descendant_p_level () const;
1423 
1429  unsigned int min_p_level_by_neighbor (const Elem * neighbor,
1430  unsigned int current_min) const;
1431 
1437  unsigned int min_new_p_level_by_neighbor (const Elem * neighbor,
1438  unsigned int current_min) const;
1439 
1445  void set_p_level (const unsigned int p);
1446 
1451  void hack_p_level (const unsigned int p);
1452 
1456  virtual void refine (MeshRefinement & mesh_refinement);
1457 
1462  void coarsen ();
1463 
1470  void contract ();
1471 
1472 #endif
1473 
1474 #ifdef DEBUG
1475 
1478  void libmesh_assert_valid_neighbors() const;
1479 
1485 #endif // DEBUG
1486 
1487 protected:
1488 
1499  class SideIter;
1500 
1501 public:
1506 
1511  struct side_iterator;
1512 
1518 
1519 private:
1525  SideIter _last_side();
1526 
1527 public:
1528 
1529 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
1530 
1535  virtual bool infinite () const = 0;
1536 
1544  virtual bool is_mid_infinite_edge_node(const unsigned int /* n */) const
1545  { libmesh_assert (!this->infinite()); return false; }
1546 
1553  virtual Point origin () const { libmesh_not_implemented(); return Point(); }
1554 
1555 #endif
1556 
1557 
1558 
1559 
1563  static std::unique_ptr<Elem> build (const ElemType type,
1564  Elem * p=nullptr);
1565 
1566 #ifdef LIBMESH_ENABLE_AMR
1567 
1573  virtual unsigned int as_parent_node (unsigned int c,
1574  unsigned int n) const;
1575 
1580  virtual
1581  const std::vector<std::pair<unsigned char, unsigned char>> &
1582  parent_bracketing_nodes(unsigned int c,
1583  unsigned int n) const;
1584 
1589  virtual
1590  const std::vector<std::pair<dof_id_type, dof_id_type>>
1591  bracketing_nodes(unsigned int c,
1592  unsigned int n) const;
1593 
1594 
1598  virtual float embedding_matrix (const unsigned int child_num,
1599  const unsigned int child_node_num,
1600  const unsigned int parent_node_num) const = 0;
1601 
1609  virtual unsigned int embedding_matrix_version () const { return 0; }
1610 
1611 #endif // LIBMESH_ENABLE_AMR
1612 
1613 
1614 protected:
1615 
1619  static dof_id_type compute_key (dof_id_type n0);
1620 
1624  static dof_id_type compute_key (dof_id_type n0,
1625  dof_id_type n1);
1626 
1630  static dof_id_type compute_key (dof_id_type n0,
1631  dof_id_type n1,
1632  dof_id_type n2);
1633 
1637  static dof_id_type compute_key (dof_id_type n0,
1638  dof_id_type n1,
1639  dof_id_type n2,
1640  dof_id_type n3);
1641 
1645  template <typename Subclass>
1646  void simple_build_side_ptr(std::unique_ptr<Elem> & side,
1647  const unsigned int i,
1648  ElemType sidetype);
1649 
1650 #ifdef LIBMESH_ENABLE_AMR
1651 
1657  virtual
1658  std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> &
1660  {
1661  static std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> c;
1662  libmesh_error();
1663  return c;
1664  }
1665 
1671  virtual
1672  std::vector<std::vector<std::vector<signed char>>> &
1674  {
1675  static std::vector<std::vector<std::vector<signed char>>> c;
1676  libmesh_error();
1677  return c;
1678  }
1679 
1680 #endif // LIBMESH_ENABLE_AMR
1681 
1682 public:
1683 
1688  void nullify_neighbors ();
1689 
1690 protected:
1691 
1696 
1702 
1703 #ifdef LIBMESH_ENABLE_AMR
1704 
1708 #endif
1709 
1714 
1715 #ifdef LIBMESH_ENABLE_AMR
1716 
1720  unsigned char _rflag;
1721 
1726  unsigned char _pflag;
1727 
1736  unsigned char _p_level;
1737 #endif
1738 };
1739 
1740 
1741 
1742 // ------------------------------------------------------------
1743 // Elem helper classes
1744 //
1745 class
1747 {
1748 public:
1749  NodeRefIter (Node * const * nodepp) : PointerToPointerIter<Node>(nodepp) {}
1750 };
1751 
1752 
1753 class
1755 {
1756 public:
1757  ConstNodeRefIter (const Node * const * nodepp) : PointerToPointerIter<const Node>(nodepp) {}
1758 };
1759 
1760 
1761 #ifdef LIBMESH_ENABLE_AMR
1762 class
1764 {
1765 public:
1766  ChildRefIter (Elem * const * childpp) : PointerToPointerIter<Elem>(childpp) {}
1767 };
1768 
1769 
1770 class
1772 {
1773 public:
1774  ConstChildRefIter (const Elem * const * childpp) : PointerToPointerIter<const Elem>(childpp) {}
1775 };
1776 
1777 
1778 inline
1780 {
1781  libmesh_assert(_children);
1782  return {_children, _children + this->n_children()};
1783 }
1784 
1785 
1786 inline
1788 {
1789  libmesh_assert(_children);
1790  return {_children, _children + this->n_children()};
1791 }
1792 #endif // LIBMESH_ENABLE_AMR
1793 
1794 
1795 
1796 
1797 // ------------------------------------------------------------
1798 // global Elem functions
1799 
1800 inline
1801 std::ostream & operator << (std::ostream & os, const Elem & e)
1802 {
1803  e.print_info(os);
1804  return os;
1805 }
1806 
1807 
1808 // ------------------------------------------------------------
1809 // Elem class member functions
1810 inline
1811 Elem::Elem(const unsigned int nn,
1812  const unsigned int ns,
1813  Elem * p,
1814  Elem ** elemlinkdata,
1815  Node ** nodelinkdata) :
1816  _nodes(nodelinkdata),
1817  _elemlinks(elemlinkdata),
1818 #ifdef LIBMESH_ENABLE_AMR
1819  _children(nullptr),
1820 #endif
1821  _sbd_id(0)
1822 #ifdef LIBMESH_ENABLE_AMR
1823  ,
1824  _rflag(Elem::DO_NOTHING),
1825  _pflag(Elem::DO_NOTHING),
1826  _p_level(0)
1827 #endif
1828 {
1830 
1831  // If this ever legitimately fails we need to increase max_n_nodes
1832  libmesh_assert_less_equal(nn, max_n_nodes);
1833 
1834  // Initialize the nodes data structure
1835  if (_nodes)
1836  {
1837  for (unsigned int n=0; n<nn; n++)
1838  _nodes[n] = nullptr;
1839  }
1840 
1841  // Initialize the neighbors/parent data structure
1842  // _elemlinks = new Elem *[ns+1];
1843 
1844  if (_elemlinks)
1845  {
1846  _elemlinks[0] = p;
1847 
1848  for (unsigned int n=1; n<ns+1; n++)
1849  _elemlinks[n] = nullptr;
1850  }
1851 
1852  // Optionally initialize data from the parent
1853  if (this->parent() != nullptr)
1854  {
1855  this->subdomain_id() = this->parent()->subdomain_id();
1856  this->processor_id() = this->parent()->processor_id();
1857  }
1858 
1859 #ifdef LIBMESH_ENABLE_AMR
1860  if (this->parent())
1861  this->set_p_level(this->parent()->p_level());
1862 #endif
1863 }
1864 
1865 
1866 
1867 inline
1868 Elem::~Elem()
1869 {
1870  // Deleting my parent/neighbor/nodes storage isn't necessary since it's
1871  // handled by the subclass
1872 
1873  // if (_nodes != nullptr)
1874  // delete [] _nodes;
1875  // _nodes = nullptr;
1876 
1877  // delete [] _elemlinks;
1878 
1879 #ifdef LIBMESH_ENABLE_AMR
1880 
1881  // Delete my children's storage
1882  if (_children != nullptr)
1883  delete [] _children;
1884  _children = nullptr;
1885 
1886 #endif
1887 }
1888 
1889 
1890 
1891 inline
1892 const Point & Elem::point (const unsigned int i) const
1893 {
1894  libmesh_assert_less (i, this->n_nodes());
1895  libmesh_assert(_nodes[i]);
1896  libmesh_assert_not_equal_to (_nodes[i]->id(), Node::invalid_id);
1897 
1898  return *_nodes[i];
1899 }
1900 
1901 
1902 
1903 inline
1904 Point & Elem::point (const unsigned int i)
1905 {
1906  libmesh_assert_less (i, this->n_nodes());
1907 
1908  return *_nodes[i];
1909 }
1910 
1911 
1912 
1913 inline
1914 dof_id_type Elem::node_id (const unsigned int i) const
1915 {
1916  libmesh_assert_less (i, this->n_nodes());
1917  libmesh_assert(_nodes[i]);
1918  libmesh_assert_not_equal_to (_nodes[i]->id(), Node::invalid_id);
1919 
1920  return _nodes[i]->id();
1921 }
1922 
1923 
1924 
1925 #ifdef LIBMESH_ENABLE_DEPRECATED
1926 inline
1927 dof_id_type Elem::node (const unsigned int i) const
1928 {
1929  libmesh_deprecated();
1930  return this->node_id(i);
1931 }
1932 #endif
1933 
1934 
1935 
1936 inline
1937 unsigned int Elem::local_node (const dof_id_type i) const
1938 {
1939  for (unsigned int n=0; n != this->n_nodes(); ++n)
1940  if (this->node_id(n) == i)
1941  return n;
1942 
1943  return libMesh::invalid_uint;
1944 }
1945 
1946 
1947 
1948 inline
1949 const Node * const * Elem::get_nodes () const
1950 {
1951  return _nodes;
1952 }
1953 
1954 
1955 
1956 inline
1957 const Node * Elem::node_ptr (const unsigned int i) const
1958 {
1959  libmesh_assert_less (i, this->n_nodes());
1960  libmesh_assert(_nodes[i]);
1961 
1962  return _nodes[i];
1963 }
1964 
1965 
1966 
1967 inline
1968 Node * Elem::node_ptr (const unsigned int i)
1969 {
1970  libmesh_assert_less (i, this->n_nodes());
1971  libmesh_assert(_nodes[i]);
1972 
1973  return _nodes[i];
1974 }
1975 
1976 
1977 
1978 inline
1979 const Node & Elem::node_ref (const unsigned int i) const
1980 {
1981  return *this->node_ptr(i);
1982 }
1983 
1984 
1985 
1986 inline
1987 Node & Elem::node_ref (const unsigned int i)
1988 {
1989  return *this->node_ptr(i);
1990 }
1991 
1992 
1993 
1994 #ifdef LIBMESH_ENABLE_DEPRECATED
1995 inline
1996 Node * Elem::get_node (const unsigned int i) const
1997 {
1998  // This const function has incorrectly returned a non-const pointer
1999  // for years. Now that it is reimplemented in terms of the new
2000  // interface which does return a const pointer, we need to use a
2001  // const_cast to mimic the old (incorrect) behavior. This function
2002  // is now deprecated and eventually will be removed entirely,
2003  // obviating the need for this ugly cast.
2004  libmesh_deprecated();
2005  return const_cast<Node *>(this->node_ptr(i));
2006 }
2007 #endif
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 #ifdef LIBMESH_ENABLE_DEPRECATED
2070 inline
2071 Elem * Elem::neighbor (const unsigned int i) const
2072 {
2073  // Support the deprecated interface by calling the new,
2074  // const-correct interface and casting the result to an Elem *.
2075  libmesh_deprecated();
2076  return const_cast<Elem *>(this->neighbor_ptr(i));
2077 }
2078 #endif
2079 
2080 
2081 
2082 inline
2083 void Elem::set_neighbor (const unsigned int i, Elem * n)
2084 {
2085  libmesh_assert_less (i, this->n_neighbors());
2086 
2087  _elemlinks[i+1] = n;
2088 }
2089 
2090 
2091 
2092 inline
2093 bool Elem::has_neighbor (const Elem * elem) const
2094 {
2095  for (auto n : this->neighbor_ptr_range())
2096  if (n == elem)
2097  return true;
2098 
2099  return false;
2100 }
2101 
2102 
2103 
2104 inline
2106 {
2107  for (auto n : elem->neighbor_ptr_range())
2108  if (n && n->parent() == this)
2109  return n;
2110 
2111  return nullptr;
2112 }
2113 
2114 
2115 
2116 inline
2117 const Elem * Elem::child_neighbor (const Elem * elem) const
2118 {
2119  for (auto n : elem->neighbor_ptr_range())
2120  if (n && n->parent() == this)
2121  return n;
2122 
2123  return nullptr;
2124 }
2125 
2126 
2127 
2128 inline
2131 {
2132  return {_nodes, _nodes+this->n_nodes()};
2133 }
2134 
2135 
2136 
2137 inline
2140 {
2141  return {_nodes, _nodes+this->n_nodes()};
2142 }
2143 
2144 
2145 
2146 inline
2149 {
2150  return {0, cast_int<unsigned short>(this->n_nodes())};
2151 }
2152 
2153 
2154 
2155 inline
2158 {
2159  return {0, cast_int<unsigned short>(this->n_edges())};
2160 }
2161 
2162 
2163 
2164 inline
2167 {
2168  return {0, cast_int<unsigned short>(this->n_sides())};
2169 }
2170 
2171 
2172 
2173 
2174 inline
2175 std::unique_ptr<const Elem> Elem::side_ptr (unsigned int i) const
2176 {
2177  // Call the non-const version of this function, return the result as
2178  // a std::unique_ptr<const Elem>.
2179  Elem * me = const_cast<Elem *>(this);
2180  const Elem * s = const_cast<const Elem *>(me->side_ptr(i).release());
2181  return std::unique_ptr<const Elem>(s);
2182 }
2183 
2184 
2185 
2186 inline
2187 void
2188 Elem::side_ptr (std::unique_ptr<const Elem> & elem,
2189  const unsigned int i) const
2190 {
2191  // Hand off to the non-const version of this function
2192  Elem * me = const_cast<Elem *>(this);
2193  std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
2194  me->side_ptr(e, i);
2195  elem.reset(e.release());
2196 }
2197 
2198 
2199 
2200 #ifdef LIBMESH_ENABLE_DEPRECATED
2201 inline
2202 std::unique_ptr<Elem> Elem::side (const unsigned int i) const
2203 {
2204  // Call the const version of side_ptr(), and const_cast the result.
2205  libmesh_deprecated();
2206  Elem * s = const_cast<Elem *>(this->side_ptr(i).release());
2207  return std::unique_ptr<Elem>(s);
2208 }
2209 #endif
2210 
2211 
2212 
2213 inline
2214 std::unique_ptr<const Elem>
2215 Elem::build_side_ptr (const unsigned int i, bool proxy) const
2216 {
2217  // Call the non-const version of this function, return the result as
2218  // a std::unique_ptr<const Elem>.
2219  Elem * me = const_cast<Elem *>(this);
2220  const Elem * s = const_cast<const Elem *>(me->build_side_ptr(i, proxy).release());
2221  return std::unique_ptr<const Elem>(s);
2222 }
2223 
2224 
2225 
2226 inline
2227 void
2228 Elem::build_side_ptr (std::unique_ptr<const Elem> & elem,
2229  const unsigned int i) const
2230 {
2231  // Hand off to the non-const version of this function
2232  Elem * me = const_cast<Elem *>(this);
2233  std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
2234  me->build_side_ptr(e, i);
2235  elem.reset(e.release());
2236 }
2237 
2238 
2239 
2240 #ifdef LIBMESH_ENABLE_DEPRECATED
2241 inline
2242 std::unique_ptr<Elem>
2243 Elem::build_side (const unsigned int i, bool proxy) const
2244 {
2245  // Call the const version of build_side_ptr(), and const_cast the result.
2246  libmesh_deprecated();
2247  Elem * s = const_cast<Elem *>(this->build_side_ptr(i, proxy).release());
2248  return std::unique_ptr<Elem>(s);
2249 }
2250 #endif
2251 
2252 
2253 
2254 template <typename Subclass>
2255 inline
2256 void
2257 Elem::simple_build_side_ptr (std::unique_ptr<Elem> & side,
2258  const unsigned int i,
2259  ElemType sidetype)
2260 {
2261  libmesh_assert_less (i, this->n_sides());
2262 
2263  if (!side.get() || side->type() != sidetype)
2264  side = this->build_side_ptr(i, false);
2265  else
2266  {
2267  side->subdomain_id() = this->subdomain_id();
2268 
2269  for (auto n : side->node_index_range())
2270  side->set_node(n) = this->node_ptr(Subclass::side_nodes_map[i][n]);
2271  }
2272 }
2273 
2274 
2275 
2276 inline
2277 std::unique_ptr<const Elem>
2278 Elem::build_edge_ptr (const unsigned int i) const
2279 {
2280  // Call the non-const version of this function, return the result as
2281  // a std::unique_ptr<const Elem>.
2282  Elem * me = const_cast<Elem *>(this);
2283  const Elem * e = const_cast<const Elem *>(me->build_edge_ptr(i).release());
2284  return std::unique_ptr<const Elem>(e);
2285 }
2286 
2287 
2288 
2289 #ifdef LIBMESH_ENABLE_DEPRECATED
2290 inline
2291 std::unique_ptr<Elem>
2292 Elem::build_edge (const unsigned int i) const
2293 {
2294  // Call the const version of build_edge_ptr(), and const_cast the result.
2295  libmesh_deprecated();
2296  Elem * e = const_cast<Elem *>(this->build_edge_ptr(i).release());
2297  return std::unique_ptr<Elem>(e);
2298 }
2299 #endif
2300 
2301 
2302 
2303 inline
2304 bool Elem::on_boundary () const
2305 {
2306  // By convention, the element is on the boundary
2307  // if it has a nullptr neighbor.
2308  return this->has_neighbor(nullptr);
2309 }
2310 
2311 
2312 
2313 inline
2314 unsigned int Elem::which_neighbor_am_i (const Elem * e) const
2315 {
2316  libmesh_assert(e);
2317 
2318  const Elem * eparent = e;
2319 
2320  while (eparent->level() > this->level())
2321  {
2322  eparent = eparent->parent();
2323  libmesh_assert(eparent);
2324  }
2325 
2326  for (unsigned int s=0, n_s = this->n_sides(); s != n_s; ++s)
2327  if (this->neighbor_ptr(s) == eparent)
2328  return s;
2329 
2330  return libMesh::invalid_uint;
2331 }
2332 
2333 
2334 
2335 inline
2336 unsigned int Elem::which_side_am_i (const Elem * e) const
2337 {
2338  libmesh_assert(e);
2339 
2340  const unsigned int ns = this->n_sides();
2341  const unsigned int nn = this->n_nodes();
2342 
2343  const unsigned int en = e->n_nodes();
2344 
2345  // e might be on any side until proven otherwise
2346  std::vector<bool> might_be_side(ns, true);
2347 
2348  for (unsigned int i=0; i != en; ++i)
2349  {
2350  Point side_point = e->point(i);
2351  unsigned int local_node_id = libMesh::invalid_uint;
2352 
2353  // Look for a node of this that's contiguous with node i of
2354  // e. Note that the exact floating point comparison of Point
2355  // positions is intentional, see the class documentation for
2356  // this function.
2357  for (unsigned int j=0; j != nn; ++j)
2358  if (this->point(j) == side_point)
2359  local_node_id = j;
2360 
2361  // If a node of e isn't contiguous with some node of this, then
2362  // e isn't a side of this.
2363  if (local_node_id == libMesh::invalid_uint)
2364  return libMesh::invalid_uint;
2365 
2366  // If a node of e isn't contiguous with some node on side s of
2367  // this, then e isn't on side s.
2368  for (unsigned int s=0; s != ns; ++s)
2369  if (!this->is_node_on_side(local_node_id, s))
2370  might_be_side[s] = false;
2371  }
2372 
2373  for (unsigned int s=0; s != ns; ++s)
2374  if (might_be_side[s])
2375  {
2376 #ifdef DEBUG
2377  for (unsigned int s2=s+1; s2 < ns; ++s2)
2378  libmesh_assert (!might_be_side[s2]);
2379 #endif
2380  return s;
2381  }
2382 
2383  // Didn't find any matching side
2384  return libMesh::invalid_uint;
2385 }
2386 
2387 
2388 
2389 inline
2390 bool Elem::active() const
2391 {
2392 #ifdef LIBMESH_ENABLE_AMR
2393  if ((this->refinement_flag() == INACTIVE) ||
2394  (this->refinement_flag() == COARSEN_INACTIVE))
2395  return false;
2396  else
2397  return true;
2398 #else
2399  return true;
2400 #endif
2401 }
2402 
2403 
2404 
2405 
2406 
2407 inline
2408 bool Elem::subactive() const
2409 {
2410 #ifdef LIBMESH_ENABLE_AMR
2411  if (this->active())
2412  return false;
2413  if (!this->has_children())
2414  return true;
2415  for (const Elem * my_ancestor = this->parent();
2416  my_ancestor != nullptr;
2417  my_ancestor = my_ancestor->parent())
2418  if (my_ancestor->active())
2419  return true;
2420 #endif
2421 
2422  return false;
2423 }
2424 
2425 
2426 
2427 inline
2429 {
2430 #ifdef LIBMESH_ENABLE_AMR
2431  if (_children == nullptr)
2432  return false;
2433  else
2434  return true;
2435 #else
2436  return false;
2437 #endif
2438 }
2439 
2440 
2441 inline
2443 {
2444 #ifdef LIBMESH_ENABLE_AMR
2445  if (_children == nullptr)
2446  return false;
2447  else
2448  for (auto & c : child_ref_range())
2449  if (c.has_children())
2450  return true;
2451 #endif
2452  return false;
2453 }
2454 
2455 
2456 
2457 inline
2459 #ifdef LIBMESH_ENABLE_AMR
2460  descendant
2461 #endif
2462  ) const
2463 {
2464 #ifdef LIBMESH_ENABLE_AMR
2465  const Elem * e = descendant;
2466  while (e)
2467  {
2468  if (this == e)
2469  return true;
2470  e = e->parent();
2471  }
2472 #endif
2473  return false;
2474 }
2475 
2476 
2477 
2478 inline
2479 const Elem * Elem::parent () const
2480 {
2481  return _elemlinks[0];
2482 }
2483 
2484 
2485 
2486 inline
2488 {
2489  return _elemlinks[0];
2490 }
2491 
2492 
2493 
2494 inline
2496 {
2497  _elemlinks[0] = p;
2498 }
2499 
2500 
2501 
2502 inline
2503 const Elem * Elem::top_parent () const
2504 {
2505  const Elem * tp = this;
2506 
2507  // Keep getting the element's parent
2508  // until that parent is at level-0
2509  while (tp->parent() != nullptr)
2510  tp = tp->parent();
2511 
2512  libmesh_assert(tp);
2513  libmesh_assert_equal_to (tp->level(), 0);
2514 
2515  return tp;
2516 }
2517 
2518 
2519 
2520 inline
2521 unsigned int Elem::level() const
2522 {
2523 #ifdef LIBMESH_ENABLE_AMR
2524 
2525  // if I don't have a parent I was
2526  // created directly from file
2527  // or by the user, so I am a
2528  // level-0 element
2529  if (this->parent() == nullptr)
2530  return 0;
2531 
2532  // if the parent and this element are of different
2533  // dimensionality we are at the same level as
2534  // the parent (e.g. we are the 2D side of a
2535  // 3D element)
2536  if (this->dim() != this->parent()->dim())
2537  return this->parent()->level();
2538 
2539  // otherwise we are at a level one
2540  // higher than our parent
2541  return (this->parent()->level() + 1);
2542 
2543 #else
2544 
2545  // Without AMR all elements are
2546  // at level 0.
2547  return 0;
2548 
2549 #endif
2550 }
2551 
2552 
2553 
2554 inline
2555 unsigned int Elem::p_level() const
2556 {
2557 #ifdef LIBMESH_ENABLE_AMR
2558  return _p_level;
2559 #else
2560  return 0;
2561 #endif
2562 }
2563 
2564 
2565 
2566 #ifdef LIBMESH_ENABLE_AMR
2567 
2568 inline
2569 const Elem * Elem::raw_child_ptr (unsigned int i) const
2570 {
2571  if (!_children)
2572  return nullptr;
2573 
2574  return _children[i];
2575 }
2576 
2577 inline
2578 const Elem * Elem::child_ptr (unsigned int i) const
2579 {
2580  libmesh_assert(_children);
2581  libmesh_assert(_children[i]);
2582 
2583  return _children[i];
2584 }
2585 
2586 inline
2587 Elem * Elem::child_ptr (unsigned int i)
2588 {
2589  libmesh_assert(_children);
2590  libmesh_assert(_children[i]);
2591 
2592  return _children[i];
2593 }
2594 
2595 
2596 #ifdef LIBMESH_ENABLE_DEPRECATED
2597 inline
2598 Elem * Elem::child (const unsigned int i) const
2599 {
2600  // Support the deprecated interface by calling the new,
2601  // const-correct interface and casting the result to an Elem *.
2602  libmesh_deprecated();
2603  return const_cast<Elem *>(this->child_ptr(i));
2604 }
2605 #endif
2606 
2607 
2608 
2609 inline
2610 void Elem::set_child (unsigned int c, Elem * elem)
2611 {
2612  libmesh_assert (this->has_children());
2613 
2614  _children[c] = elem;
2615 }
2616 
2617 
2618 
2619 inline
2620 unsigned int Elem::which_child_am_i (const Elem * e) const
2621 {
2622  libmesh_assert(e);
2623  libmesh_assert (this->has_children());
2624 
2625  unsigned int nc = this->n_children();
2626  for (unsigned int c=0; c != nc; c++)
2627  if (this->child_ptr(c) == e)
2628  return c;
2629 
2630  libmesh_error_msg("ERROR: which_child_am_i() was called with a non-child!");
2631 
2632  return libMesh::invalid_uint;
2633 }
2634 
2635 
2636 
2637 inline
2639 {
2640  return static_cast<RefinementState>(_rflag);
2641 }
2642 
2643 
2644 
2645 inline
2647 {
2648  _rflag = cast_int<RefinementState>(rflag);
2649 }
2650 
2651 
2652 
2653 inline
2655 {
2656  return static_cast<RefinementState>(_pflag);
2657 }
2658 
2659 
2660 
2661 inline
2663 {
2664  if (this->p_level() == 0)
2665  libmesh_assert_not_equal_to
2666  (pflag, Elem::JUST_REFINED);
2667 
2668  _pflag = cast_int<unsigned char>(pflag);
2669 }
2670 
2671 
2672 
2673 inline
2674 unsigned int Elem::max_descendant_p_level () const
2675 {
2676  // This is undefined for subactive elements,
2677  // which have no active descendants
2678  libmesh_assert (!this->subactive());
2679  if (this->active())
2680  return this->p_level();
2681 
2682  unsigned int max_p_level = _p_level;
2683  for (auto & c : child_ref_range())
2684  max_p_level = std::max(max_p_level,
2685  c.max_descendant_p_level());
2686  return max_p_level;
2687 }
2688 
2689 
2690 
2691 inline
2692 void Elem::set_p_level(unsigned int p)
2693 {
2694  // Maintain the parent's p level as the minimum of it's children
2695  if (this->parent() != nullptr)
2696  {
2697  unsigned int parent_p_level = this->parent()->p_level();
2698 
2699  // If our new p level is less than our parents, our parents drops
2700  if (parent_p_level > p)
2701  {
2702  this->parent()->set_p_level(p);
2703 
2704  // And we should keep track of the drop, in case we need to
2705  // do a projection later.
2707  }
2708  // If we are the lowest p level and it increases, so might
2709  // our parent's, but we have to check every other child to see
2710  else if (parent_p_level == _p_level && _p_level < p)
2711  {
2712  _p_level = cast_int<unsigned char>(p);
2713  parent_p_level = cast_int<unsigned char>(p);
2714  for (auto & c : this->parent()->child_ref_range())
2715  parent_p_level = std::min(parent_p_level,
2716  c.p_level());
2717 
2718  // When its children all have a higher p level, the parent's
2719  // should rise
2720  if (parent_p_level > this->parent()->p_level())
2721  {
2722  this->parent()->set_p_level(parent_p_level);
2723 
2724  // And we should keep track of the rise, in case we need to
2725  // do a projection later.
2727  }
2728 
2729  return;
2730  }
2731  }
2732 
2733  _p_level = cast_int<unsigned char>(p);
2734 }
2735 
2736 
2737 
2738 inline
2739 void Elem::hack_p_level(unsigned int p)
2740 {
2741  if (p == 0)
2742  libmesh_assert_not_equal_to
2744 
2745  _p_level = cast_int<unsigned char>(p);
2746 }
2747 
2748 
2749 
2750 #endif // ifdef LIBMESH_ENABLE_AMR
2751 
2752 
2753 inline
2755 {
2756  return n0;
2757 }
2758 
2759 
2760 
2761 inline
2763  dof_id_type n1)
2764 {
2765  // Order the two so that n0 < n1
2766  if (n0 > n1) std::swap (n0, n1);
2767 
2768  return Utility::hashword2(n0, n1);
2769 }
2770 
2771 
2772 
2773 inline
2775  dof_id_type n1,
2776  dof_id_type n2)
2777 {
2778  // Order the numbers such that n0 < n1 < n2.
2779  // We'll do it in 3 steps like this:
2780  //
2781  // n0 n1 n2
2782  // min(n0,n1) max(n0,n1) n2
2783  // min(n0,n1) min(n2,max(n0,n1) max(n2,max(n0,n1)
2784  // |\ /| |
2785  // | \ / | |
2786  // | / | |
2787  // | / \| |
2788  // gb min= min max gb max
2789 
2790  // Step 1
2791  if (n0 > n1) std::swap (n0, n1);
2792 
2793  // Step 2
2794  if (n1 > n2) std::swap (n1, n2);
2795 
2796  // Step 3
2797  if (n0 > n1) std::swap (n0, n1);
2798 
2799  libmesh_assert ((n0 < n1) && (n1 < n2));
2800 
2801  dof_id_type array[3] = {n0, n1, n2};
2802  return Utility::hashword(array, 3);
2803 }
2804 
2805 
2806 
2807 inline
2809  dof_id_type n1,
2810  dof_id_type n2,
2811  dof_id_type n3)
2812 {
2813  // Sort first
2814  // Step 1
2815  if (n0 > n1) std::swap (n0, n1);
2816 
2817  // Step 2
2818  if (n2 > n3) std::swap (n2, n3);
2819 
2820  // Step 3
2821  if (n0 > n2) std::swap (n0, n2);
2822 
2823  // Step 4
2824  if (n1 > n3) std::swap (n1, n3);
2825 
2826  // Finally sort step 5
2827  if (n1 > n2) std::swap (n1, n2);
2828 
2829  libmesh_assert ((n0 < n1) && (n1 < n2) && (n2 < n3));
2830 
2831  dof_id_type array[4] = {n0, n1, n2, n3};
2832  return Utility::hashword(array, 4);
2833 }
2834 
2835 
2836 
2841 {
2842 public:
2843  // Constructor with arguments.
2844  SideIter(const unsigned int side_number,
2845  Elem * parent)
2846  : _side(),
2847  _side_ptr(nullptr),
2848  _parent(parent),
2849  _side_number(side_number)
2850  {}
2851 
2852 
2853  // Empty constructor.
2855  : _side(),
2856  _side_ptr(nullptr),
2857  _parent(nullptr),
2859  {}
2860 
2861 
2862  // Copy constructor
2863  SideIter(const SideIter & other)
2864  : _side(),
2865  _side_ptr(nullptr),
2866  _parent(other._parent),
2867  _side_number(other._side_number)
2868  {}
2869 
2870 
2871  // op=
2872  SideIter & operator=(const SideIter & other)
2873  {
2874  this->_parent = other._parent;
2875  this->_side_number = other._side_number;
2876  return *this;
2877  }
2878 
2879  // unary op*
2880  Elem *& operator*() const
2881  {
2882  // Set the std::unique_ptr
2883  this->_update_side_ptr();
2884 
2885  // Return a reference to _side_ptr
2886  return this->_side_ptr;
2887  }
2888 
2889  // op++
2891  {
2892  ++_side_number;
2893  return *this;
2894  }
2895 
2896  // op== Two side iterators are equal if they have
2897  // the same side number and the same parent element.
2898  bool operator == (const SideIter & other) const
2899  {
2900  return (this->_side_number == other._side_number &&
2901  this->_parent == other._parent);
2902  }
2903 
2904 
2905  // Consults the parent Elem to determine if the side
2906  // is a boundary side. Note: currently side N is a
2907  // boundary side if neighbor N is nullptr. Be careful,
2908  // this could possibly change in the future?
2909  bool side_on_boundary() const
2910  {
2911  return this->_parent->neighbor_ptr(_side_number) == nullptr;
2912  }
2913 
2914 private:
2915  // Update the _side pointer by building the correct side.
2916  // This has to be called before dereferencing.
2917  void _update_side_ptr() const
2918  {
2919  // Construct new side, store in std::unique_ptr
2920  this->_side = this->_parent->build_side_ptr(this->_side_number);
2921 
2922  // Also set our internal naked pointer. Memory is still owned
2923  // by the std::unique_ptr.
2924  this->_side_ptr = _side.get();
2925  }
2926 
2927  // std::unique_ptr to the actual side, handles memory management for
2928  // the sides which are created during the course of iteration.
2929  mutable std::unique_ptr<Elem> _side;
2930 
2931  // Raw pointer needed to facilitate passing back to the user a
2932  // reference to a non-temporary raw pointer in order to conform to
2933  // the variant_filter_iterator interface. It points to the same
2934  // thing the std::unique_ptr "_side" above holds. What happens if the user
2935  // calls delete on the pointer passed back? Well, this is an issue
2936  // which is not addressed by the iterators in libMesh. Basically it
2937  // is a bad idea to ever call delete on an iterator from the library.
2938  mutable Elem * _side_ptr;
2939 
2940  // Pointer to the parent Elem class which generated this iterator
2942 
2943  // A counter variable which keeps track of the side number
2944  unsigned int _side_number;
2945 };
2946 
2947 
2948 
2949 
2950 
2951 
2952 // Private implementation functions in the Elem class for the side iterators.
2953 // They have to come after the definition of the SideIter class.
2954 inline
2956 {
2957  return SideIter(0, this);
2958 }
2959 
2960 
2961 
2962 inline
2964 {
2965  return SideIter(this->n_neighbors(), this);
2966 }
2967 
2968 
2969 
2970 
2974 struct
2975 Elem::side_iterator : variant_filter_iterator<Elem::Predicate, Elem *>
2976 {
2977  // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
2978  template <typename PredType, typename IterType>
2979  side_iterator (const IterType & d,
2980  const IterType & e,
2981  const PredType & p ) :
2983 };
2984 
2985 
2986 
2987 inline
2989 {
2990  return {_elemlinks+1, _elemlinks + 1 + this->n_neighbors()};
2991 }
2992 
2993 
2994 inline
2996 {
2997  return {_elemlinks+1, _elemlinks + 1 + this->n_neighbors()};
2998 }
2999 
3000 
3001 } // namespace libMesh
3002 
3003 
3004 // Helper function for default caches in Elem subclasses
3005 
3006 #define LIBMESH_ENABLE_TOPOLOGY_CACHES \
3007  virtual \
3008  std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> & \
3009  _get_bracketing_node_cache() const override \
3010  { \
3011  static std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> c; \
3012  return c; \
3013  } \
3014  \
3015  virtual \
3016  std::vector<std::vector<std::vector<signed char>>> & \
3017  _get_parent_indices_cache() const override \
3018  { \
3019  static std::vector<std::vector<std::vector<signed char>>> c; \
3020  return c; \
3021  }
3022 
3023 
3024 #endif // LIBMESH_ELEM_H
void total_family_tree_by_subneighbor(std::vector< const Elem *> &family, const Elem *neighbor, const Elem *subneighbor, const bool reset=true) const
Definition: elem.C:1754
bool has_neighbor(const Elem *elem) const
Definition: elem.h:2093
void set_p_level(const unsigned int p)
Definition: elem.h:2692
virtual bool is_vertex_on_parent(unsigned int c, unsigned int n) const
Definition: elem.C:2879
RefinementState refinement_flag() const
Definition: elem.h:2638
void write_connectivity(std::ostream &out, const IOPackage iop) const
Definition: elem.C:1360
const Elem * parent() const
Definition: elem.h:2479
virtual const std::vector< std::pair< dof_id_type, dof_id_type > > bracketing_nodes(unsigned int c, unsigned int n) const
Definition: elem.C:2206
void print_info(std::ostream &os=libMesh::out) const
Definition: elem.C:2440
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:2024
A geometric point in (x,y,z) space associated with a DOF.
Definition: node.h:52
bool is_ancestor_of(const Elem *descendant) const
Definition: elem.h:2458
Node ** _nodes
Definition: elem.h:1695
void family_tree_by_neighbor(std::vector< const Elem *> &family, const Elem *neighbor, const bool reset=true) const
Definition: elem.C:1661
Elem * child_neighbor(Elem *elem)
Definition: elem.h:2105
variant_filter_iterator(const IterType &d, const IterType &e, const PredType &p)
Predicates::multi_predicate Predicate
Definition: elem.h:1499
virtual Point origin() const
Definition: elem.h:1553
const unsigned int invalid_uint
Definition: libmesh.h:245
void set_parent(Elem *p)
Definition: elem.h:2495
unsigned int get_node_index(const Node *node_ptr) const
Definition: elem.h:2012
std::string get_info() const
Definition: elem.C:2448
static const unsigned int type_to_n_sides_map[INVALID_ELEM]
Definition: elem.h:620
const Elem * interior_parent() const
Definition: elem.C:804
const Elem * topological_neighbor(const unsigned int i, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
Definition: elem.C:920
virtual bool is_face(const unsigned int i) const =0
bool is_semilocal(const processor_id_type my_pid) const
Definition: elem.C:451
unsigned char _pflag
Definition: elem.h:1726
unsigned char _p_level
Definition: elem.h:1736
IntRange< unsigned short > side_index_range() const
Definition: elem.h:2166
void libmesh_assert_valid_node_pointers() const
Definition: elem.C:978
virtual dof_id_type key() const
Definition: elem.C:401
const Elem * top_parent() const
Definition: elem.h:2503
Maps between boundary ids and PeriodicBoundaryBase objects.
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:1609
unsigned int which_side_am_i(const Elem *e) const
Definition: elem.h:2336
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:2844
RefinementState p_refinement_flag() const
Definition: elem.h:2654
virtual bool has_affine_map() const
Definition: elem.h:988
void find_interior_neighbors(std::set< const Elem *> &neighbor_set) const
Definition: elem.C:725
unsigned short int side
Definition: xdr_io.C:50
bool operator==(const SideIter &other) const
Definition: elem.h:2898
The base class for all geometric element types.
Definition: elem.h:100
MeshBase & mesh
uint8_t processor_id_type
Definition: id_types.h:99
void add_child(Elem *elem)
Definition: elem.C:1461
virtual BoundingBox loose_bounding_box() const
Definition: elem.C:2857
SideIter & operator=(const SideIter &other)
Definition: elem.h:2872
unsigned int min_new_p_level_by_neighbor(const Elem *neighbor, unsigned int current_min) const
Definition: elem.C:1899
void set_refinement_flag(const RefinementState rflag)
Definition: elem.h:2646
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
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()
virtual unsigned int n_children() const =0
ChildRefIter(Elem *const *childpp)
Definition: elem.h:1766
unsigned int _side_number
Definition: elem.h:2944
unsigned int p_level() const
Definition: elem.h:2555
void find_edge_neighbors(const Point &p1, const Point &p2, std::set< const Elem *> &neighbor_set) const
Definition: elem.C:637
side_iterator boundary_sides_end()
Definition: elem.C:2817
static const Real TOLERANCE
void active_family_tree(std::vector< const Elem *> &active_family, const bool reset=true) const
Definition: elem.C:1577
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, const bool reset=true) const
Definition: elem.C:1795
void make_links_to_me_remote()
Definition: elem.C:1149
SideIter & operator++()
Definition: elem.h:2890
std::unique_ptr< Elem > build_side(const unsigned int i, bool proxy=true) const
Definition: elem.h:2243
virtual Real hmax() const
Definition: elem.C:373
virtual bool is_linear() const
Definition: elem.h:994
long double max(long double a, double b)
dof_id_type node(const unsigned int i) const
Definition: elem.h:1927
unsigned int min_p_level_by_neighbor(const Elem *neighbor, unsigned int current_min) const
Definition: elem.C:1870
void set_interior_parent(Elem *p)
Definition: elem.C:856
static const unsigned int type_to_n_nodes_map[INVALID_ELEM]
Definition: elem.h:589
void total_family_tree(std::vector< const Elem *> &active_family, const bool reset=true) const
Definition: elem.C:1557
Base class for Mesh.
Definition: mesh_base.h:77
SimpleRange< ChildRefIter > child_ref_range()
Definition: elem.h:1779
void family_tree_by_side(std::vector< const Elem *> &family, const unsigned int side, const bool reset=true) const
Definition: elem.C:1601
bool ancestor() const
Definition: elem.C:1427
bool has_topological_neighbor(const Elem *elem, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
Definition: elem.C:957
IntRange< unsigned short > edge_index_range() const
Definition: elem.h:2157
side_iterator boundary_sides_begin()
Definition: elem.C:2808
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i, bool proxy=true)=0
Elem *& operator*() const
Definition: elem.h:2880
virtual void refine(MeshRefinement &mesh_refinement)
const Elem *const * ConstNeighborPtrIter
Definition: elem.h:324
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)
Definition: hashword.h:153
void total_family_tree_by_neighbor(std::vector< const Elem *> &family, const Elem *neighbor, const bool reset=true) const
Definition: elem.C:1688
void replace_child(Elem *elem, unsigned int c)
Definition: elem.C:1507
std::unique_ptr< Elem > build_edge(const unsigned int i) const
Definition: elem.h:2292
static const subdomain_id_type invalid_subdomain_id
Definition: elem.h:262
void remove_links_to_me()
Definition: elem.C:1260
virtual std::vector< std::vector< std::vector< signed char > > > & _get_parent_indices_cache() const
Definition: elem.h:1673
Elem *const * NeighborPtrIter
Definition: elem.h:323
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const
Definition: elem.C:2301
Responsible for mesh refinement algorithms and data.
Real length(const unsigned int n1, const unsigned int n2) const
Definition: elem.C:390
void active_family_tree_by_side(std::vector< const Elem *> &family, const unsigned int side, const bool reset=true) const
Definition: elem.C:1630
Elem & operator=(const Elem &)=delete
const Node & node_ref(const unsigned int i) const
Definition: elem.h:1979
dof_id_type id() const
Definition: dof_object.h:655
virtual Real hmin() const
Definition: elem.C:356
virtual unsigned int n_nodes() const =0
static const processor_id_type invalid_processor_id
Definition: dof_object.h:358
static const unsigned int type_to_n_edges_map[INVALID_ELEM]
Definition: elem.h:669
bool contains_edge_of(const Elem *e) const
Definition: elem.C:477
unsigned int which_neighbor_am_i(const Elem *e) const
Definition: elem.h:2314
virtual unsigned int as_parent_node(unsigned int c, unsigned int n) const
Definition: elem.C:1933
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition: elem.C:245
virtual unsigned int opposite_node(const unsigned int n, const unsigned int s) const
Definition: elem.C:2911
virtual std::pair< unsigned short int, unsigned short int > second_order_child_vertex(const unsigned int n) const
Definition: elem.C:2576
Elem ** _elemlinks
Definition: elem.h:1701
void find_point_neighbors(const Point &p, std::set< const Elem *> &neighbor_set) const
Definition: elem.C:498
Elem ** _children
Definition: elem.h:1707
const Node *const * get_nodes() const
Definition: elem.h:1949
bool point_test(const Point &p, Real box_tol, Real map_tol) const
Definition: elem.C:2338
void _update_side_ptr() const
Definition: elem.h:2917
bool side_on_boundary() const
Definition: elem.h:2909
void family_tree(std::vector< const Elem *> &family, const bool reset=true) const
Definition: elem.C:1534
static const dof_id_type invalid_id
Definition: dof_object.h:347
const Elem * reference_elem() const
Definition: elem.C:337
void libmesh_assert_valid_neighbors() const
Definition: elem.C:990
virtual bool is_remote() const
Definition: elem.h:555
virtual unsigned int n_edges() const =0
virtual unsigned int n_second_order_adjacent_vertices(const unsigned int n) const
Definition: elem.C:2558
SideIter _last_side()
Definition: elem.h:2963
void set_neighbor(const unsigned int i, Elem *n)
Definition: elem.h:2083
subdomain_id_type _sbd_id
Definition: elem.h:1713
static ElemType second_order_equivalent_type(const ElemType et, const bool full_ordered=true)
Definition: elem.C:2643
Elem * neighbor(const unsigned int i) const
Definition: elem.h:2071
bool on_boundary() const
Definition: elem.h:2304
Elem(const unsigned int n_nodes, const unsigned int n_sides, Elem *parent, Elem **elemlinkdata, Node **nodelinkdata)
Definition: elem.h:1811
unsigned int which_child_am_i(const Elem *e) const
Definition: elem.h:2620
unsigned int max_descendant_p_level() const
Definition: elem.h:2674
unsigned char _rflag
Definition: elem.h:1720
bool contains_vertex_of(const Elem *e) const
Definition: elem.C:466
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, const bool reset=true) const
Definition: elem.C:1837
Elem * child(const unsigned int i) const
Definition: elem.h:2598
SimpleRange< NodeRefIter > node_ref_range()
Definition: elem.h:2130
virtual unsigned int is_vertex_on_child(unsigned int, unsigned int n) const
Definition: elem.h:694
std::unique_ptr< Elem > _side
Definition: elem.h:2929
ConstNodeRefIter(const Node *const *nodepp)
Definition: elem.h:1757
virtual unsigned int n_sides() const =0
const Elem * neighbor_ptr(unsigned int i) const
Definition: elem.h:2050
virtual bool close_to_point(const Point &p, Real tol) const
Definition: elem.C:2326
unsigned int level() const
Definition: elem.h:2521
const Elem * raw_child_ptr(unsigned int i) const
Definition: elem.h:2569
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
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:1957
SideIter(const SideIter &other)
Definition: elem.h:2863
virtual bool is_vertex(const unsigned int i) const =0
void swap(Iterator &lhs, Iterator &rhs)
virtual Point master_point(const unsigned int i) const =0
unsigned int n_neighbors() const
Definition: elem.h:644
virtual Real quality(const ElemQuality q) const
Definition: elem.C:1403
virtual unsigned short int second_order_adjacent_vertex(const unsigned int n, const unsigned int v) const
Definition: elem.C:2566
bool subactive() const
Definition: elem.h:2408
virtual Real volume() const
Definition: elem.C:2826
uint32_t hashword2(const uint32_t &first, const uint32_t &second, uint32_t initval=0)
Definition: hashword.h:210
void set_child(unsigned int c, Elem *elem)
Definition: elem.h:2610
virtual void connectivity(const unsigned int sc, const IOPackage iop, std::vector< dof_id_type > &conn) const =0
bool has_ancestor_children() const
Definition: elem.h:2442
IntRange< unsigned short > node_index_range() const
Definition: elem.h:2148
unsigned int local_node(const dof_id_type i) const
Definition: elem.h:1937
void nullify_neighbors()
Definition: elem.C:2532
SimpleRange< NeighborPtrIter > neighbor_ptr_range()
Definition: elem.h:2988
void set_p_refinement_flag(const RefinementState pflag)
Definition: elem.h:2662
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:948
static dof_id_type compute_key(dof_id_type n0)
Definition: elem.h:2754
virtual unsigned int n_sub_elem() const =0
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i)=0
void make_links_to_me_local(unsigned int n)
Definition: elem.C:1062
ConstChildRefIter(const Elem *const *childpp)
Definition: elem.h:1774
virtual Order default_order() const =0
virtual const std::vector< std::pair< unsigned char, unsigned char > > & parent_bracketing_nodes(unsigned int c, unsigned int n) const
Definition: elem.C:2001
virtual std::vector< std::vector< std::vector< std::vector< std::pair< unsigned char, unsigned char > > > > > & _get_bracketing_node_cache() const
Definition: elem.h:1659
virtual unsigned int opposite_side(const unsigned int s) const
Definition: elem.C:2903
OStreamProxy out(std::cout)
bool active() const
Definition: elem.h:2390
void hack_p_level(const unsigned int p)
Definition: elem.h:2739
void simple_build_side_ptr(std::unique_ptr< Elem > &side, const unsigned int i, ElemType sidetype)
Definition: elem.h:2257
static ElemType first_order_equivalent_type(const ElemType et)
Definition: elem.C:2584
processor_id_type processor_id() const
Definition: dof_object.h:717
virtual ElemType type() const =0
std::ostream & operator<<(std::ostream &os, const FEAbstract &fe)
Definition: fe_abstract.C:809
long double min(long double a, double b)
A geometric point in (x,y,z) space.
Definition: point.h:38
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:1914
const Point & point(const unsigned int i) const
Definition: elem.h:1892
virtual Point centroid() const
Definition: elem.C:344
bool operator==(const Elem &rhs) const
Definition: elem.C:419
side_iterator(const IterType &d, const IterType &e, const PredType &p)
Definition: elem.h:2979
bool has_children() const
Definition: elem.h:2428
NodeRefIter(Node *const *nodepp)
Definition: elem.h:1749
virtual bool is_child_on_edge(const unsigned int c, const unsigned int e) const
Definition: elem.C:1518
virtual bool is_edge(const unsigned int i) const =0
virtual std::vector< unsigned int > nodes_on_side(const unsigned int) const =0
std::unique_ptr< Elem > side(const unsigned int i) const
Definition: elem.h:2202
virtual unsigned int n_nodes_in_child(unsigned int) const
Definition: elem.h:613
Node * get_node(const unsigned int i) const
Definition: elem.h:1996
static const unsigned int max_n_nodes
Definition: elem.h:600
const Elem * child_ptr(unsigned int i) const
Definition: elem.h:2578
uint8_t dof_id_type
Definition: id_types.h:64
void family_tree_by_subneighbor(std::vector< const Elem *> &family, const Elem *neighbor, const Elem *subneighbor, const bool reset=true) const
Definition: elem.C:1712
virtual bool is_mid_infinite_edge_node(const unsigned int) const
Definition: elem.h:1544
SideIter _first_side()
Definition: elem.h:2955