libMesh
elem.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2017 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"
31 #include "libmesh/enum_elem_quality.h"
32 #include "libmesh/enum_order.h"
33 #include "libmesh/enum_io_package.h"
34 #include "libmesh/auto_ptr.h"
35 #include "libmesh/multi_predicates.h"
36 #include "libmesh/pointer_to_pointer_iter.h"
37 #include "libmesh/int_range.h"
38 #include "libmesh/simple_range.h"
39 #include "libmesh/variant_filter_iterator.h"
40 #include "libmesh/hashword.h" // Used in compute_key() functions
41 
42 // C++ includes
43 #include <algorithm>
44 #include <cstddef>
45 #include <iostream>
46 #include <limits.h> // CHAR_BIT
47 #include <set>
48 #include <vector>
49 
50 namespace libMesh
51 {
52 
53 // Forward declarations
54 class MeshBase;
55 class MeshRefinement;
56 class Elem;
57 #ifdef LIBMESH_ENABLE_PERIODIC
58 class PeriodicBoundaries;
59 class PointLocatorBase;
60 #endif
61 
89 class Elem : public ReferenceCountedObject<Elem>,
90  public DofObject
91 {
92 protected:
93 
100  Elem (const unsigned int n_nodes,
101  const unsigned int n_sides,
102  Elem * parent,
103  Elem ** elemlinkdata,
104  Node ** nodelinkdata);
105 
106 public:
107 
111  virtual ~Elem();
112 
116  const Point & point (const unsigned int i) const;
117 
122  Point & point (const unsigned int i);
123 
128  virtual Point master_point (const unsigned int i) const = 0;
129 
133  dof_id_type node_id (const unsigned int i) const;
134 
140 #ifdef LIBMESH_ENABLE_DEPRECATED
141  dof_id_type node (const unsigned int i) const;
142 #endif
143 
148  unsigned int local_node (const dof_id_type i) const;
149 
154  unsigned int get_node_index (const Node * node_ptr) const;
155 
159  const Node * const * get_nodes () const;
160 
164  const Node * node_ptr (const unsigned int i) const;
165 
169  Node * node_ptr (const unsigned int i);
170 
174  const Node & node_ref (const unsigned int i) const;
175 
179  Node & node_ref (const unsigned int i);
180 
186 #ifdef LIBMESH_ENABLE_DEPRECATED
187  Node * get_node (const unsigned int i) const;
188 #endif
189 
193  virtual Node * & set_node (const unsigned int i);
194 
198  class NodeRefIter;
199  class ConstNodeRefIter;
200 
209 
211 
216 
222 
238 
247  const Elem * reference_elem () const;
248 
254  virtual dof_id_type key (const unsigned int s) const = 0;
255 
262  virtual dof_id_type key () const;
263 
270  bool operator == (const Elem & rhs) const;
271 
281  const Elem * neighbor_ptr (unsigned int i) const;
282 
286  Elem * neighbor_ptr (unsigned int i);
287 
291 #ifdef LIBMESH_ENABLE_DEPRECATED
292  Elem * neighbor (const unsigned int i) const;
293 #endif
294 
298  typedef Elem * const * NeighborPtrIter;
299  typedef const Elem * const * ConstNeighborPtrIter;
300 
310 
312 
313 #ifdef LIBMESH_ENABLE_PERIODIC
314 
320  const Elem * topological_neighbor (const unsigned int i,
321  const MeshBase & mesh,
322  const PointLocatorBase & point_locator,
323  const PeriodicBoundaries * pb) const;
324 
331  Elem * topological_neighbor (const unsigned int i,
332  MeshBase & mesh,
333  const PointLocatorBase & point_locator,
334  const PeriodicBoundaries * pb);
335 
340  bool has_topological_neighbor (const Elem * elem,
341  const MeshBase & mesh,
342  const PointLocatorBase & point_locator,
343  const PeriodicBoundaries * pb) const;
344 #endif
345 
349  void set_neighbor (const unsigned int i, Elem * n);
350 
355  bool has_neighbor (const Elem * elem) const;
356 
361  Elem * child_neighbor (Elem * elem);
362 
367  const Elem * child_neighbor (const Elem * elem) const;
368 
374  bool on_boundary () const;
375 
380  bool is_semilocal (const processor_id_type my_pid) const;
381 
387  unsigned int which_neighbor_am_i(const Elem * e) const;
388 
405  unsigned int which_side_am_i(const Elem * e) const;
406 
417  virtual unsigned int which_node_am_i(unsigned int side,
418  unsigned int side_node) const = 0;
419 
424  bool contains_vertex_of(const Elem * e) const;
425 
431  bool contains_edge_of(const Elem * e) const;
432 
449  void find_point_neighbors(const Point & p,
450  std::set<const Elem *> & neighbor_set) const;
451 
457  void find_point_neighbors(std::set<const Elem *> & neighbor_set) const;
458 
464  void find_point_neighbors(std::set<const Elem *> & neighbor_set,
465  const Elem * start_elem) const;
466 
472  void find_edge_neighbors(const Point & p1,
473  const Point & p2,
474  std::set<const Elem *> & neighbor_set) const;
475 
484  void find_edge_neighbors(std::set<const Elem *> & neighbor_set) const;
485 
491  void find_interior_neighbors(std::set<const Elem *> & neighbor_set) const;
492 
500  void remove_links_to_me ();
501 
509  void make_links_to_me_remote ();
510 
517  void make_links_to_me_local (unsigned int n);
518 
530  virtual bool is_remote () const
531  { return false; }
532 
537  virtual void connectivity(const unsigned int sc,
538  const IOPackage iop,
539  std::vector<dof_id_type> & conn) const = 0;
540 
546  void write_connectivity (std::ostream & out,
547  const IOPackage iop) const;
548 
553  virtual ElemType type () const = 0;
554 
558  virtual unsigned int dim () const = 0;
559 
564  static const unsigned int type_to_n_nodes_map[INVALID_ELEM];
565 
569  virtual unsigned int n_nodes () const = 0;
570 
576 
582  virtual unsigned int n_nodes_in_child (unsigned int /*c*/) const
583  { return this->n_nodes(); }
584 
589  static const unsigned int type_to_n_sides_map[INVALID_ELEM];
590 
596  virtual unsigned int n_sides () const = 0;
597 
603 
613  unsigned int n_neighbors () const
614  { return this->n_sides(); }
615 
620  virtual unsigned int n_vertices () const = 0;
621 
626  virtual unsigned int n_edges () const = 0;
627 
633 
638  static const unsigned int type_to_n_edges_map[INVALID_ELEM];
639 
644  virtual unsigned int n_faces () const = 0;
645 
650  virtual unsigned int n_children () const = 0;
651 
655  virtual bool is_vertex(const unsigned int i) const = 0;
656 
663  virtual unsigned int is_vertex_on_child (unsigned int /*c*/,
664  unsigned int n) const
665  { return this->is_vertex(n); }
666 
671  virtual bool is_vertex_on_parent(unsigned int c,
672  unsigned int n) const;
673 
677  virtual bool is_edge(const unsigned int i) const = 0;
678 
682  virtual bool is_face(const unsigned int i) const = 0;
683 
688  virtual bool is_node_on_side(const unsigned int n,
689  const unsigned int s) const = 0;
690 
695  virtual bool is_node_on_edge(const unsigned int n,
696  const unsigned int e) const = 0;
697 
701  virtual bool is_edge_on_side(const unsigned int e,
702  const unsigned int s) const = 0;
703 
708  virtual unsigned int opposite_side(const unsigned int s) const;
709 
715  virtual unsigned int opposite_node(const unsigned int n,
716  const unsigned int s) const;
717 
723  virtual unsigned int n_sub_elem () const = 0;
724 
739  virtual UniquePtr<Elem> side_ptr (unsigned int i) = 0;
740  UniquePtr<const Elem> side_ptr (unsigned int i) const;
741 
750 #ifdef LIBMESH_ENABLE_DEPRECATED
751  UniquePtr<Elem> side (const unsigned int i) const;
752 #endif
753 
775  virtual UniquePtr<Elem> build_side_ptr (const unsigned int i, bool proxy=true) = 0;
776  UniquePtr<const Elem> build_side_ptr (const unsigned int i, bool proxy=true) const;
777 
786 #ifdef LIBMESH_ENABLE_DEPRECATED
787  UniquePtr<Elem> build_side (const unsigned int i, bool proxy=true) const;
788 #endif
789 
803  virtual UniquePtr<Elem> build_edge_ptr (const unsigned int i) = 0;
804  UniquePtr<const Elem> build_edge_ptr (const unsigned int i) const;
805 
814 #ifdef LIBMESH_ENABLE_DEPRECATED
815  UniquePtr<Elem> build_edge (const unsigned int i) const;
816 #endif
817 
823  virtual Order default_order () const = 0;
824 
832  virtual Point centroid () const;
833 
837  virtual Real hmin () const;
838 
842  virtual Real hmax () const;
843 
847  virtual Real volume () const;
848 
859  virtual BoundingBox loose_bounding_box () const;
860 
865  virtual Real quality (const ElemQuality q) const;
866 
875  virtual std::pair<Real,Real> qual_bounds (const ElemQuality) const
876  { libmesh_not_implemented(); return std::make_pair(0.,0.); }
877 
893  virtual bool contains_point (const Point & p, Real tol=TOLERANCE) const;
894 
899  virtual bool close_to_point(const Point & p, Real tol) const;
900 
901 private:
908  bool point_test(const Point & p, Real box_tol, Real map_tol) const;
909 
910 public:
915  virtual bool has_affine_map () const { return false; }
916 
921  virtual bool is_linear () const { return false; }
922 
926  void print_info (std::ostream & os=libMesh::out) const;
927 
931  std::string get_info () const;
932 
939  bool active () const;
940 
946  bool ancestor () const;
947 
952  bool subactive () const;
953 
958  bool has_children () const;
959 
964  bool has_ancestor_children () const;
965 
971  bool is_ancestor_of(const Elem * descendant) const;
972 
977  const Elem * parent () const;
978 
983  Elem * parent ();
984 
989  void set_parent (Elem * p);
990 
998  const Elem * top_parent () const;
999 
1014  const Elem * interior_parent () const;
1015 
1016  Elem * interior_parent ();
1017 
1022  void set_interior_parent (Elem * p);
1023 
1029  Real length (const unsigned int n1,
1030  const unsigned int n2) const;
1031 
1042  virtual unsigned int n_second_order_adjacent_vertices (const unsigned int n) const;
1043 
1052  virtual unsigned short int second_order_adjacent_vertex (const unsigned int n,
1053  const unsigned int v) const;
1054 
1070  virtual std::pair<unsigned short int, unsigned short int>
1071  second_order_child_vertex (const unsigned int n) const;
1072 
1086  const bool full_ordered=true);
1087 
1095  static ElemType first_order_equivalent_type (const ElemType et);
1096 
1097 
1105  unsigned int level () const;
1106 
1112  unsigned int p_level () const;
1113 
1117  virtual bool is_child_on_side(const unsigned int c,
1118  const unsigned int s) const = 0;
1119 
1120 #ifdef LIBMESH_ENABLE_AMR
1121 
1133 
1138  const Elem * raw_child_ptr (unsigned int i) const;
1139 
1144  const Elem * child_ptr (unsigned int i) const;
1145 
1150  Elem * child_ptr (unsigned int i);
1151 
1158 #ifdef LIBMESH_ENABLE_DEPRECATED
1159  Elem * child (const unsigned int i) const;
1160 #endif
1161 
1166  class ChildRefIter;
1167  class ConstChildRefIter;
1168 
1177 
1179 
1180 private:
1185  void set_child (unsigned int c, Elem * elem);
1186 
1187 public:
1194  unsigned int which_child_am_i(const Elem * e) const;
1195 
1199  virtual bool is_child_on_edge(const unsigned int c,
1200  const unsigned int e) const;
1201 
1208  void add_child (Elem * elem);
1209 
1216  void add_child (Elem * elem, unsigned int c);
1217 
1221  void replace_child (Elem * elem, unsigned int c);
1222 
1234  void family_tree (std::vector<const Elem *> & family,
1235  const bool reset=true) const;
1236 
1241  void total_family_tree (std::vector<const Elem *> & active_family,
1242  const bool reset=true) const;
1243 
1250  void active_family_tree (std::vector<const Elem *> & active_family,
1251  const bool reset=true) const;
1252 
1257  void family_tree_by_side (std::vector<const Elem *> & family,
1258  const unsigned int side,
1259  const bool reset=true) const;
1260 
1265  void active_family_tree_by_side (std::vector<const Elem *> & family,
1266  const unsigned int side,
1267  const bool reset=true) const;
1268 
1273  void family_tree_by_neighbor (std::vector<const Elem *> & family,
1274  const Elem * neighbor,
1275  const bool reset=true) const;
1276 
1281  void total_family_tree_by_neighbor (std::vector<const Elem *> & family,
1282  const Elem * neighbor,
1283  const bool reset=true) const;
1284 
1291  void family_tree_by_subneighbor (std::vector<const Elem *> & family,
1292  const Elem * neighbor,
1293  const Elem * subneighbor,
1294  const bool reset=true) const;
1295 
1300  void total_family_tree_by_subneighbor (std::vector<const Elem *> & family,
1301  const Elem * neighbor,
1302  const Elem * subneighbor,
1303  const bool reset=true) const;
1304 
1309  void active_family_tree_by_neighbor (std::vector<const Elem *> & family,
1310  const Elem * neighbor,
1311  const bool reset=true) const;
1312 
1318  void active_family_tree_by_topological_neighbor (std::vector<const Elem *> & family,
1319  const Elem * neighbor,
1320  const MeshBase & mesh,
1321  const PointLocatorBase & point_locator,
1322  const PeriodicBoundaries * pb,
1323  const bool reset=true) const;
1324 
1329 
1333  void set_refinement_flag (const RefinementState rflag);
1334 
1339 
1343  void set_p_refinement_flag (const RefinementState pflag);
1344 
1349  unsigned int max_descendant_p_level () const;
1350 
1356  unsigned int min_p_level_by_neighbor (const Elem * neighbor,
1357  unsigned int current_min) const;
1358 
1364  unsigned int min_new_p_level_by_neighbor (const Elem * neighbor,
1365  unsigned int current_min) const;
1366 
1372  void set_p_level (const unsigned int p);
1373 
1378  void hack_p_level (const unsigned int p);
1379 
1383  virtual void refine (MeshRefinement & mesh_refinement);
1384 
1389  void coarsen ();
1390 
1397  void contract ();
1398 
1399 #endif
1400 
1401 #ifdef DEBUG
1402 
1405  void libmesh_assert_valid_neighbors() const;
1406 
1412 #endif // DEBUG
1413 
1414 protected:
1415 
1426  class SideIter;
1427 
1428 public:
1433 
1438  struct side_iterator;
1439 
1445 
1446 private:
1452  SideIter _last_side();
1453 
1454 public:
1455 
1456 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
1457 
1462  virtual bool infinite () const = 0;
1463 
1471  virtual bool is_mid_infinite_edge_node(const unsigned int /* n */) const
1472  { libmesh_assert (!this->infinite()); return false; }
1473 
1480  virtual Point origin () const { libmesh_not_implemented(); return Point(); }
1481 
1482 #endif
1483 
1484 
1485 
1486 
1490  static UniquePtr<Elem> build (const ElemType type,
1491  Elem * p=libmesh_nullptr);
1492 
1493 #ifdef LIBMESH_ENABLE_AMR
1494 
1500  virtual unsigned int as_parent_node (unsigned int c,
1501  unsigned int n) const;
1502 
1507  virtual
1508  const std::vector<std::pair<unsigned char, unsigned char>> &
1509  parent_bracketing_nodes(unsigned int c,
1510  unsigned int n) const;
1511 
1516  virtual
1517  const std::vector<std::pair<dof_id_type, dof_id_type>>
1518  bracketing_nodes(unsigned int c,
1519  unsigned int n) const;
1520 
1521 
1525  virtual float embedding_matrix (const unsigned int child_num,
1526  const unsigned int child_node_num,
1527  const unsigned int parent_node_num) const = 0;
1528 
1536  virtual unsigned int embedding_matrix_version () const { return 0; }
1537 
1538 #endif // LIBMESH_ENABLE_AMR
1539 
1540 
1541 protected:
1542 
1546  static dof_id_type compute_key (dof_id_type n0);
1547 
1551  static dof_id_type compute_key (dof_id_type n0,
1552  dof_id_type n1);
1553 
1557  static dof_id_type compute_key (dof_id_type n0,
1558  dof_id_type n1,
1559  dof_id_type n2);
1560 
1564  static dof_id_type compute_key (dof_id_type n0,
1565  dof_id_type n1,
1566  dof_id_type n2,
1567  dof_id_type n3);
1568 
1569 
1570 #ifdef LIBMESH_ENABLE_AMR
1571 
1577  virtual
1578  std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> &
1580  {
1581  static std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> c;
1582  libmesh_error();
1583  return c;
1584  }
1585 
1591  virtual
1592  std::vector<std::vector<std::vector<signed char>>> &
1594  {
1595  static std::vector<std::vector<std::vector<signed char>>> c;
1596  libmesh_error();
1597  return c;
1598  }
1599 
1600 #endif // LIBMESH_ENABLE_AMR
1601 
1602 public:
1603 
1608  void nullify_neighbors ();
1609 
1610 protected:
1611 
1616 
1622 
1623 #ifdef LIBMESH_ENABLE_AMR
1624 
1628 #endif
1629 
1634 
1635 #ifdef LIBMESH_ENABLE_AMR
1636 
1640  unsigned char _rflag;
1641 
1646  unsigned char _pflag;
1647 
1656  unsigned char _p_level;
1657 #endif
1658 };
1659 
1660 
1661 
1662 // ------------------------------------------------------------
1663 // Elem helper classes
1664 //
1665 class
1667 {
1668 public:
1669  NodeRefIter (Node * const * nodepp) : PointerToPointerIter<Node>(nodepp) {}
1670 };
1671 
1672 
1673 class
1675 {
1676 public:
1677  ConstNodeRefIter (const Node * const * nodepp) : PointerToPointerIter<const Node>(nodepp) {}
1678 };
1679 
1680 
1681 #ifdef LIBMESH_ENABLE_AMR
1682 class
1684 {
1685 public:
1686  ChildRefIter (Elem * const * childpp) : PointerToPointerIter<Elem>(childpp) {}
1687 };
1688 
1689 
1690 class
1692 {
1693 public:
1694  ConstChildRefIter (const Elem * const * childpp) : PointerToPointerIter<const Elem>(childpp) {}
1695 };
1696 
1697 
1698 inline
1700 {
1702  return {_children, _children + this->n_children()};
1703 }
1704 
1705 
1706 inline
1708 {
1710  return {_children, _children + this->n_children()};
1711 }
1712 #endif // LIBMESH_ENABLE_AMR
1713 
1714 
1715 
1716 
1717 // ------------------------------------------------------------
1718 // global Elem functions
1719 
1720 inline
1721 std::ostream & operator << (std::ostream & os, const Elem & e)
1722 {
1723  e.print_info(os);
1724  return os;
1725 }
1726 
1727 
1728 // ------------------------------------------------------------
1729 // Elem class member functions
1730 inline
1731 Elem::Elem(const unsigned int nn,
1732  const unsigned int ns,
1733  Elem * p,
1734  Elem ** elemlinkdata,
1735  Node ** nodelinkdata) :
1736  _nodes(nodelinkdata),
1737  _elemlinks(elemlinkdata),
1738 #ifdef LIBMESH_ENABLE_AMR
1740 #endif
1741  _sbd_id(0)
1742 #ifdef LIBMESH_ENABLE_AMR
1743  ,
1746  _p_level(0)
1747 #endif
1748 {
1750 
1751  // Initialize the nodes data structure
1752  if (_nodes)
1753  {
1754  for (unsigned int n=0; n<nn; n++)
1755  _nodes[n] = libmesh_nullptr;
1756  }
1757 
1758  // Initialize the neighbors/parent data structure
1759  // _elemlinks = new Elem *[ns+1];
1760 
1761  if (_elemlinks)
1762  {
1763  _elemlinks[0] = p;
1764 
1765  for (unsigned int n=1; n<ns+1; n++)
1767  }
1768 
1769  // Optionally initialize data from the parent
1770  if (this->parent() != libmesh_nullptr)
1771  {
1772  this->subdomain_id() = this->parent()->subdomain_id();
1773  this->processor_id() = this->parent()->processor_id();
1774  }
1775 
1776 #ifdef LIBMESH_ENABLE_AMR
1777  if (this->parent())
1778  this->set_p_level(this->parent()->p_level());
1779 #endif
1780 }
1781 
1782 
1783 
1784 inline
1785 Elem::~Elem()
1786 {
1787  // Deleting my parent/neighbor/nodes storage isn't necessary since it's
1788  // handled by the subclass
1789 
1790  // if (_nodes != libmesh_nullptr)
1791  // delete [] _nodes;
1792  // _nodes = libmesh_nullptr;
1793 
1794  // delete [] _elemlinks;
1795 
1796 #ifdef LIBMESH_ENABLE_AMR
1797 
1798  // Delete my children's storage
1799  if (_children != libmesh_nullptr)
1800  delete [] _children;
1802 
1803 #endif
1804 }
1805 
1806 
1807 
1808 inline
1809 const Point & Elem::point (const unsigned int i) const
1810 {
1811  libmesh_assert_less (i, this->n_nodes());
1812  libmesh_assert(_nodes[i]);
1813  libmesh_assert_not_equal_to (_nodes[i]->id(), Node::invalid_id);
1814 
1815  return *_nodes[i];
1816 }
1817 
1818 
1819 
1820 inline
1821 Point & Elem::point (const unsigned int i)
1822 {
1823  libmesh_assert_less (i, this->n_nodes());
1824 
1825  return *_nodes[i];
1826 }
1827 
1828 
1829 
1830 inline
1831 dof_id_type Elem::node_id (const unsigned int i) const
1832 {
1833  libmesh_assert_less (i, this->n_nodes());
1834  libmesh_assert(_nodes[i]);
1835  libmesh_assert_not_equal_to (_nodes[i]->id(), Node::invalid_id);
1836 
1837  return _nodes[i]->id();
1838 }
1839 
1840 
1841 
1842 #ifdef LIBMESH_ENABLE_DEPRECATED
1843 inline
1844 dof_id_type Elem::node (const unsigned int i) const
1845 {
1846  libmesh_deprecated();
1847  return this->node_id(i);
1848 }
1849 #endif
1850 
1851 
1852 
1853 inline
1854 unsigned int Elem::local_node (const dof_id_type i) const
1855 {
1856  for (unsigned int n=0; n != this->n_nodes(); ++n)
1857  if (this->node_id(n) == i)
1858  return n;
1859 
1860  return libMesh::invalid_uint;
1861 }
1862 
1863 
1864 
1865 inline
1866 const Node * const * Elem::get_nodes () const
1867 {
1868  return _nodes;
1869 }
1870 
1871 
1872 
1873 inline
1874 const Node * Elem::node_ptr (const unsigned int i) const
1875 {
1876  libmesh_assert_less (i, this->n_nodes());
1877  libmesh_assert(_nodes[i]);
1878 
1879  return _nodes[i];
1880 }
1881 
1882 
1883 
1884 inline
1885 Node * Elem::node_ptr (const unsigned int i)
1886 {
1887  libmesh_assert_less (i, this->n_nodes());
1888  libmesh_assert(_nodes[i]);
1889 
1890  return _nodes[i];
1891 }
1892 
1893 
1894 
1895 inline
1896 const Node & Elem::node_ref (const unsigned int i) const
1897 {
1898  return *this->node_ptr(i);
1899 }
1900 
1901 
1902 
1903 inline
1904 Node & Elem::node_ref (const unsigned int i)
1905 {
1906  return *this->node_ptr(i);
1907 }
1908 
1909 
1910 
1911 #ifdef LIBMESH_ENABLE_DEPRECATED
1912 inline
1913 Node * Elem::get_node (const unsigned int i) const
1914 {
1915  // This const function has incorrectly returned a non-const pointer
1916  // for years. Now that it is reimplemented in terms of the new
1917  // interface which does return a const pointer, we need to use a
1918  // const_cast to mimic the old (incorrect) behavior. This function
1919  // is now deprecated and eventually will be removed entirely,
1920  // obviating the need for this ugly cast.
1921  libmesh_deprecated();
1922  return const_cast<Node *>(this->node_ptr(i));
1923 }
1924 #endif
1925 
1926 
1927 
1928 inline
1929 unsigned int Elem::get_node_index (const Node * node_ptr) const
1930 {
1931  for (unsigned int n=0; n != this->n_nodes(); ++n)
1932  if (this->_nodes[n] == node_ptr)
1933  return n;
1934 
1935  return libMesh::invalid_uint;
1936 }
1937 
1938 
1939 
1940 inline
1941 Node * & Elem::set_node (const unsigned int i)
1942 {
1943  libmesh_assert_less (i, this->n_nodes());
1944 
1945  return _nodes[i];
1946 }
1947 
1948 
1949 
1950 inline
1952 {
1953  return _sbd_id;
1954 }
1955 
1956 
1957 
1958 inline
1960 {
1961  return _sbd_id;
1962 }
1963 
1964 
1965 
1966 inline
1967 const Elem * Elem::neighbor_ptr (unsigned int i) const
1968 {
1969  libmesh_assert_less (i, this->n_neighbors());
1970 
1971  return _elemlinks[i+1];
1972 }
1973 
1974 
1975 
1976 inline
1977 Elem * Elem::neighbor_ptr (unsigned int i)
1978 {
1979  libmesh_assert_less (i, this->n_neighbors());
1980 
1981  return _elemlinks[i+1];
1982 }
1983 
1984 
1985 
1986 #ifdef LIBMESH_ENABLE_DEPRECATED
1987 inline
1988 Elem * Elem::neighbor (const unsigned int i) const
1989 {
1990  // Support the deprecated interface by calling the new,
1991  // const-correct interface and casting the result to an Elem *.
1992  libmesh_deprecated();
1993  return const_cast<Elem *>(this->neighbor_ptr(i));
1994 }
1995 #endif
1996 
1997 
1998 
1999 inline
2000 void Elem::set_neighbor (const unsigned int i, Elem * n)
2001 {
2002  libmesh_assert_less (i, this->n_neighbors());
2003 
2004  _elemlinks[i+1] = n;
2005 }
2006 
2007 
2008 
2009 inline
2010 bool Elem::has_neighbor (const Elem * elem) const
2011 {
2012  for (auto n : this->neighbor_ptr_range())
2013  if (n == elem)
2014  return true;
2015 
2016  return false;
2017 }
2018 
2019 
2020 
2021 inline
2023 {
2024  for (auto n : elem->neighbor_ptr_range())
2025  if (n && n->parent() == this)
2026  return n;
2027 
2028  return libmesh_nullptr;
2029 }
2030 
2031 
2032 
2033 inline
2034 const Elem * Elem::child_neighbor (const Elem * elem) const
2035 {
2036  for (auto n : elem->neighbor_ptr_range())
2037  if (n && n->parent() == this)
2038  return n;
2039 
2040  return libmesh_nullptr;
2041 }
2042 
2043 
2044 
2045 inline
2048 {
2049  return {_nodes, _nodes+this->n_nodes()};
2050 }
2051 
2052 
2053 
2054 inline
2057 {
2058  return {_nodes, _nodes+this->n_nodes()};
2059 }
2060 
2061 
2062 
2063 inline
2066 {
2067  return {0, cast_int<unsigned short>(this->n_nodes())};
2068 }
2069 
2070 
2071 
2072 inline
2075 {
2076  return {0, cast_int<unsigned short>(this->n_edges())};
2077 }
2078 
2079 
2080 
2081 inline
2084 {
2085  return {0, cast_int<unsigned short>(this->n_sides())};
2086 }
2087 
2088 
2089 
2090 
2091 inline
2093 {
2094  // Call the non-const version of this function, return the result as
2095  // a UniquePtr<const Elem>.
2096  Elem * me = const_cast<Elem *>(this);
2097  const Elem * s = const_cast<const Elem *>(me->side_ptr(i).release());
2098  return UniquePtr<const Elem>(s);
2099 }
2100 
2101 
2102 
2103 #ifdef LIBMESH_ENABLE_DEPRECATED
2104 inline
2105 UniquePtr<Elem> Elem::side (const unsigned int i) const
2106 {
2107  // Call the const version of side_ptr(), and const_cast the result.
2108  libmesh_deprecated();
2109  Elem * s = const_cast<Elem *>(this->side_ptr(i).release());
2110  return UniquePtr<Elem>(s);
2111 }
2112 #endif
2113 
2114 
2115 
2116 inline
2118 Elem::build_side_ptr (const unsigned int i, bool proxy) const
2119 {
2120  // Call the non-const version of this function, return the result as
2121  // a UniquePtr<const Elem>.
2122  Elem * me = const_cast<Elem *>(this);
2123  const Elem * s = const_cast<const Elem *>(me->build_side_ptr(i, proxy).release());
2124  return UniquePtr<const Elem>(s);
2125 }
2126 
2127 
2128 
2129 #ifdef LIBMESH_ENABLE_DEPRECATED
2130 inline
2132 Elem::build_side (const unsigned int i, bool proxy) const
2133 {
2134  // Call the const version of build_side_ptr(), and const_cast the result.
2135  libmesh_deprecated();
2136  Elem * s = const_cast<Elem *>(this->build_side_ptr(i, proxy).release());
2137  return UniquePtr<Elem>(s);
2138 }
2139 #endif
2140 
2141 
2142 
2143 inline
2145 Elem::build_edge_ptr (const unsigned int i) const
2146 {
2147  // Call the non-const version of this function, return the result as
2148  // a UniquePtr<const Elem>.
2149  Elem * me = const_cast<Elem *>(this);
2150  const Elem * e = const_cast<const Elem *>(me->build_edge_ptr(i).release());
2151  return UniquePtr<const Elem>(e);
2152 }
2153 
2154 
2155 
2156 #ifdef LIBMESH_ENABLE_DEPRECATED
2157 inline
2159 Elem::build_edge (const unsigned int i) const
2160 {
2161  // Call the const version of build_edge_ptr(), and const_cast the result.
2162  libmesh_deprecated();
2163  Elem * e = const_cast<Elem *>(this->build_edge_ptr(i).release());
2164  return UniquePtr<Elem>(e);
2165 }
2166 #endif
2167 
2168 
2169 
2170 inline
2171 bool Elem::on_boundary () const
2172 {
2173  // By convention, the element is on the boundary
2174  // if it has a NULL neighbor.
2175  return this->has_neighbor(libmesh_nullptr);
2176 }
2177 
2178 
2179 
2180 inline
2181 unsigned int Elem::which_neighbor_am_i (const Elem * e) const
2182 {
2183  libmesh_assert(e);
2184 
2185  const Elem * eparent = e;
2186 
2187  while (eparent->level() > this->level())
2188  {
2189  eparent = eparent->parent();
2190  libmesh_assert(eparent);
2191  }
2192 
2193  for (unsigned int s=0, n_s = this->n_sides(); s != n_s; ++s)
2194  if (this->neighbor_ptr(s) == eparent)
2195  return s;
2196 
2197  return libMesh::invalid_uint;
2198 }
2199 
2200 
2201 
2202 inline
2203 unsigned int Elem::which_side_am_i (const Elem * e) const
2204 {
2205  libmesh_assert(e);
2206 
2207  const unsigned int ns = this->n_sides();
2208  const unsigned int nn = this->n_nodes();
2209 
2210  const unsigned int en = e->n_nodes();
2211 
2212  // e might be on any side until proven otherwise
2213  std::vector<bool> might_be_side(ns, true);
2214 
2215  for (unsigned int i=0; i != en; ++i)
2216  {
2217  Point side_point = e->point(i);
2218  unsigned int local_node_id = libMesh::invalid_uint;
2219 
2220  // Look for a node of this that's contiguous with node i of
2221  // e. Note that the exact floating point comparison of Point
2222  // positions is intentional, see the class documentation for
2223  // this function.
2224  for (unsigned int j=0; j != nn; ++j)
2225  if (this->point(j) == side_point)
2226  local_node_id = j;
2227 
2228  // If a node of e isn't contiguous with some node of this, then
2229  // e isn't a side of this.
2230  if (local_node_id == libMesh::invalid_uint)
2231  return libMesh::invalid_uint;
2232 
2233  // If a node of e isn't contiguous with some node on side s of
2234  // this, then e isn't on side s.
2235  for (unsigned int s=0; s != ns; ++s)
2236  if (!this->is_node_on_side(local_node_id, s))
2237  might_be_side[s] = false;
2238  }
2239 
2240  for (unsigned int s=0; s != ns; ++s)
2241  if (might_be_side[s])
2242  {
2243 #ifdef DEBUG
2244  for (unsigned int s2=s+1; s2 < ns; ++s2)
2245  libmesh_assert (!might_be_side[s2]);
2246 #endif
2247  return s;
2248  }
2249 
2250  // Didn't find any matching side
2251  return libMesh::invalid_uint;
2252 }
2253 
2254 
2255 
2256 inline
2257 bool Elem::active() const
2258 {
2259 #ifdef LIBMESH_ENABLE_AMR
2260  if ((this->refinement_flag() == INACTIVE) ||
2261  (this->refinement_flag() == COARSEN_INACTIVE))
2262  return false;
2263  else
2264  return true;
2265 #else
2266  return true;
2267 #endif
2268 }
2269 
2270 
2271 
2272 
2273 
2274 inline
2275 bool Elem::subactive() const
2276 {
2277 #ifdef LIBMESH_ENABLE_AMR
2278  if (this->active())
2279  return false;
2280  if (!this->has_children())
2281  return true;
2282  for (const Elem * my_ancestor = this->parent();
2283  my_ancestor != libmesh_nullptr;
2284  my_ancestor = my_ancestor->parent())
2285  if (my_ancestor->active())
2286  return true;
2287 #endif
2288 
2289  return false;
2290 }
2291 
2292 
2293 
2294 inline
2296 {
2297 #ifdef LIBMESH_ENABLE_AMR
2298  if (_children == libmesh_nullptr)
2299  return false;
2300  else
2301  return true;
2302 #else
2303  return false;
2304 #endif
2305 }
2306 
2307 
2308 inline
2310 {
2311 #ifdef LIBMESH_ENABLE_AMR
2312  if (_children == libmesh_nullptr)
2313  return false;
2314  else
2315  for (auto & c : child_ref_range())
2316  if (c.has_children())
2317  return true;
2318 #endif
2319  return false;
2320 }
2321 
2322 
2323 
2324 inline
2326 #ifdef LIBMESH_ENABLE_AMR
2327  descendant
2328 #endif
2329  ) const
2330 {
2331 #ifdef LIBMESH_ENABLE_AMR
2332  const Elem * e = descendant;
2333  while (e)
2334  {
2335  if (this == e)
2336  return true;
2337  e = e->parent();
2338  }
2339 #endif
2340  return false;
2341 }
2342 
2343 
2344 
2345 inline
2346 const Elem * Elem::parent () const
2347 {
2348  return _elemlinks[0];
2349 }
2350 
2351 
2352 
2353 inline
2355 {
2356  return _elemlinks[0];
2357 }
2358 
2359 
2360 
2361 inline
2363 {
2364  _elemlinks[0] = p;
2365 }
2366 
2367 
2368 
2369 inline
2370 const Elem * Elem::top_parent () const
2371 {
2372  const Elem * tp = this;
2373 
2374  // Keep getting the element's parent
2375  // until that parent is at level-0
2376  while (tp->parent() != libmesh_nullptr)
2377  tp = tp->parent();
2378 
2379  libmesh_assert(tp);
2380  libmesh_assert_equal_to (tp->level(), 0);
2381 
2382  return tp;
2383 }
2384 
2385 
2386 
2387 inline
2388 unsigned int Elem::level() const
2389 {
2390 #ifdef LIBMESH_ENABLE_AMR
2391 
2392  // if I don't have a parent I was
2393  // created directly from file
2394  // or by the user, so I am a
2395  // level-0 element
2396  if (this->parent() == libmesh_nullptr)
2397  return 0;
2398 
2399  // if the parent and this element are of different
2400  // dimensionality we are at the same level as
2401  // the parent (e.g. we are the 2D side of a
2402  // 3D element)
2403  if (this->dim() != this->parent()->dim())
2404  return this->parent()->level();
2405 
2406  // otherwise we are at a level one
2407  // higher than our parent
2408  return (this->parent()->level() + 1);
2409 
2410 #else
2411 
2412  // Without AMR all elements are
2413  // at level 0.
2414  return 0;
2415 
2416 #endif
2417 }
2418 
2419 
2420 
2421 inline
2422 unsigned int Elem::p_level() const
2423 {
2424 #ifdef LIBMESH_ENABLE_AMR
2425  return _p_level;
2426 #else
2427  return 0;
2428 #endif
2429 }
2430 
2431 
2432 
2433 #ifdef LIBMESH_ENABLE_AMR
2434 
2435 inline
2436 const Elem * Elem::raw_child_ptr (unsigned int i) const
2437 {
2438  if (!_children)
2439  return libmesh_nullptr;
2440 
2441  return _children[i];
2442 }
2443 
2444 inline
2445 const Elem * Elem::child_ptr (unsigned int i) const
2446 {
2449 
2450  return _children[i];
2451 }
2452 
2453 inline
2454 Elem * Elem::child_ptr (unsigned int i)
2455 {
2458 
2459  return _children[i];
2460 }
2461 
2462 
2463 #ifdef LIBMESH_ENABLE_DEPRECATED
2464 inline
2465 Elem * Elem::child (const unsigned int i) const
2466 {
2467  // Support the deprecated interface by calling the new,
2468  // const-correct interface and casting the result to an Elem *.
2469  libmesh_deprecated();
2470  return const_cast<Elem *>(this->child_ptr(i));
2471 }
2472 #endif
2473 
2474 
2475 
2476 inline
2477 void Elem::set_child (unsigned int c, Elem * elem)
2478 {
2479  libmesh_assert (this->has_children());
2480 
2481  _children[c] = elem;
2482 }
2483 
2484 
2485 
2486 inline
2487 unsigned int Elem::which_child_am_i (const Elem * e) const
2488 {
2489  libmesh_assert(e);
2490  libmesh_assert (this->has_children());
2491 
2492  unsigned int nc = this->n_children();
2493  for (unsigned int c=0; c != nc; c++)
2494  if (this->child_ptr(c) == e)
2495  return c;
2496 
2497  libmesh_error_msg("ERROR: which_child_am_i() was called with a non-child!");
2498 
2499  return libMesh::invalid_uint;
2500 }
2501 
2502 
2503 
2504 inline
2506 {
2507  return static_cast<RefinementState>(_rflag);
2508 }
2509 
2510 
2511 
2512 inline
2514 {
2515  _rflag = cast_int<RefinementState>(rflag);
2516 }
2517 
2518 
2519 
2520 inline
2522 {
2523  return static_cast<RefinementState>(_pflag);
2524 }
2525 
2526 
2527 
2528 inline
2530 {
2531  if (this->p_level() == 0)
2532  libmesh_assert_not_equal_to
2533  (pflag, Elem::JUST_REFINED);
2534 
2535  _pflag = cast_int<unsigned char>(pflag);
2536 }
2537 
2538 
2539 
2540 inline
2541 unsigned int Elem::max_descendant_p_level () const
2542 {
2543  // This is undefined for subactive elements,
2544  // which have no active descendants
2545  libmesh_assert (!this->subactive());
2546  if (this->active())
2547  return this->p_level();
2548 
2549  unsigned int max_p_level = _p_level;
2550  for (auto & c : child_ref_range())
2551  max_p_level = std::max(max_p_level,
2552  c.max_descendant_p_level());
2553  return max_p_level;
2554 }
2555 
2556 
2557 
2558 inline
2559 void Elem::set_p_level(unsigned int p)
2560 {
2561  // Maintain the parent's p level as the minimum of it's children
2562  if (this->parent() != libmesh_nullptr)
2563  {
2564  unsigned int parent_p_level = this->parent()->p_level();
2565 
2566  // If our new p level is less than our parents, our parents drops
2567  if (parent_p_level > p)
2568  {
2569  this->parent()->set_p_level(p);
2570 
2571  // And we should keep track of the drop, in case we need to
2572  // do a projection later.
2574  }
2575  // If we are the lowest p level and it increases, so might
2576  // our parent's, but we have to check every other child to see
2577  else if (parent_p_level == _p_level && _p_level < p)
2578  {
2579  _p_level = cast_int<unsigned char>(p);
2580  parent_p_level = cast_int<unsigned char>(p);
2581  for (auto & c : this->parent()->child_ref_range())
2582  parent_p_level = std::min(parent_p_level,
2583  c.p_level());
2584 
2585  // When its children all have a higher p level, the parent's
2586  // should rise
2587  if (parent_p_level > this->parent()->p_level())
2588  {
2589  this->parent()->set_p_level(parent_p_level);
2590 
2591  // And we should keep track of the rise, in case we need to
2592  // do a projection later.
2594  }
2595 
2596  return;
2597  }
2598  }
2599 
2600  _p_level = cast_int<unsigned char>(p);
2601 }
2602 
2603 
2604 
2605 inline
2606 void Elem::hack_p_level(unsigned int p)
2607 {
2608  if (p == 0)
2609  libmesh_assert_not_equal_to
2611 
2612  _p_level = cast_int<unsigned char>(p);
2613 }
2614 
2615 
2616 
2617 #endif // ifdef LIBMESH_ENABLE_AMR
2618 
2619 
2620 inline
2622 {
2623  return n0;
2624 }
2625 
2626 
2627 
2628 inline
2630  dof_id_type n1)
2631 {
2632  // Order the two so that n0 < n1
2633  if (n0 > n1) std::swap (n0, n1);
2634 
2635  return Utility::hashword2(n0, n1);
2636 }
2637 
2638 
2639 
2640 inline
2642  dof_id_type n1,
2643  dof_id_type n2)
2644 {
2645  // Order the numbers such that n0 < n1 < n2.
2646  // We'll do it in 3 steps like this:
2647  //
2648  // n0 n1 n2
2649  // min(n0,n1) max(n0,n1) n2
2650  // min(n0,n1) min(n2,max(n0,n1) max(n2,max(n0,n1)
2651  // |\ /| |
2652  // | \ / | |
2653  // | / | |
2654  // | / \| |
2655  // gb min= min max gb max
2656 
2657  // Step 1
2658  if (n0 > n1) std::swap (n0, n1);
2659 
2660  // Step 2
2661  if (n1 > n2) std::swap (n1, n2);
2662 
2663  // Step 3
2664  if (n0 > n1) std::swap (n0, n1);
2665 
2666  libmesh_assert ((n0 < n1) && (n1 < n2));
2667 
2668  dof_id_type array[3] = {n0, n1, n2};
2669  return Utility::hashword(array, 3);
2670 }
2671 
2672 
2673 
2674 inline
2676  dof_id_type n1,
2677  dof_id_type n2,
2678  dof_id_type n3)
2679 {
2680  // Sort first
2681  // Step 1
2682  if (n0 > n1) std::swap (n0, n1);
2683 
2684  // Step 2
2685  if (n2 > n3) std::swap (n2, n3);
2686 
2687  // Step 3
2688  if (n0 > n2) std::swap (n0, n2);
2689 
2690  // Step 4
2691  if (n1 > n3) std::swap (n1, n3);
2692 
2693  // Finally sort step 5
2694  if (n1 > n2) std::swap (n1, n2);
2695 
2696  libmesh_assert ((n0 < n1) && (n1 < n2) && (n2 < n3));
2697 
2698  dof_id_type array[4] = {n0, n1, n2, n3};
2699  return Utility::hashword(array, 4);
2700 }
2701 
2702 
2703 
2708 {
2709 public:
2710  // Constructor with arguments.
2711  SideIter(const unsigned int side_number,
2712  Elem * parent)
2713  : _side(),
2714  _side_ptr(libmesh_nullptr),
2715  _parent(parent),
2716  _side_number(side_number)
2717  {}
2718 
2719 
2720  // Empty constructor.
2722  : _side(),
2723  _side_ptr(libmesh_nullptr),
2724  _parent(libmesh_nullptr),
2725  _side_number(libMesh::invalid_uint)
2726  {}
2727 
2728 
2729  // Copy constructor
2730  SideIter(const SideIter & other)
2731  : _side(),
2732  _side_ptr(libmesh_nullptr),
2733  _parent(other._parent),
2734  _side_number(other._side_number)
2735  {}
2736 
2737 
2738  // op=
2739  SideIter & operator=(const SideIter & other)
2740  {
2741  this->_parent = other._parent;
2742  this->_side_number = other._side_number;
2743  return *this;
2744  }
2745 
2746  // unary op*
2747  Elem *& operator*() const
2748  {
2749  // Set the UniquePtr
2750  this->_update_side_ptr();
2751 
2752  // Return a reference to _side_ptr
2753  return this->_side_ptr;
2754  }
2755 
2756  // op++
2758  {
2759  ++_side_number;
2760  return *this;
2761  }
2762 
2763  // op== Two side iterators are equal if they have
2764  // the same side number and the same parent element.
2765  bool operator == (const SideIter & other) const
2766  {
2767  return (this->_side_number == other._side_number &&
2768  this->_parent == other._parent);
2769  }
2770 
2771 
2772  // Consults the parent Elem to determine if the side
2773  // is a boundary side. Note: currently side N is a
2774  // boundary side if neighbor N is NULL. Be careful,
2775  // this could possibly change in the future?
2776  bool side_on_boundary() const
2777  {
2778  return this->_parent->neighbor_ptr(_side_number) == libmesh_nullptr;
2779  }
2780 
2781 private:
2782  // Update the _side pointer by building the correct side.
2783  // This has to be called before dereferencing.
2784  void _update_side_ptr() const
2785  {
2786  // Construct new side, store in UniquePtr
2787  this->_side = this->_parent->build_side_ptr(this->_side_number);
2788 
2789  // Also set our internal naked pointer. Memory is still owned
2790  // by the UniquePtr.
2791  this->_side_ptr = _side.get();
2792  }
2793 
2794  // UniquePtr to the actual side, handles memory management for
2795  // the sides which are created during the course of iteration.
2797 
2798  // Raw pointer needed to facilitate passing back to the user a
2799  // reference to a non-temporary raw pointer in order to conform to
2800  // the variant_filter_iterator interface. It points to the same
2801  // thing the UniquePtr "_side" above holds. What happens if the user
2802  // calls delete on the pointer passed back? Well, this is an issue
2803  // which is not addressed by the iterators in libMesh. Basically it
2804  // is a bad idea to ever call delete on an iterator from the library.
2805  mutable Elem * _side_ptr;
2806 
2807  // Pointer to the parent Elem class which generated this iterator
2809 
2810  // A counter variable which keeps track of the side number
2811  unsigned int _side_number;
2812 };
2813 
2814 
2815 
2816 
2817 
2818 
2819 // Private implementation functions in the Elem class for the side iterators.
2820 // They have to come after the definition of the SideIter class.
2821 inline
2823 {
2824  return SideIter(0, this);
2825 }
2826 
2827 
2828 
2829 inline
2831 {
2832  return SideIter(this->n_neighbors(), this);
2833 }
2834 
2835 
2836 
2837 
2841 struct
2842 Elem::side_iterator : variant_filter_iterator<Elem::Predicate, Elem *>
2843 {
2844  // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
2845  template <typename PredType, typename IterType>
2846  side_iterator (const IterType & d,
2847  const IterType & e,
2848  const PredType & p ) :
2850 };
2851 
2852 
2853 
2854 inline
2856 {
2857  return {_elemlinks+1, _elemlinks + 1 + this->n_neighbors()};
2858 }
2859 
2860 
2861 inline
2863 {
2864  return {_elemlinks+1, _elemlinks + 1 + this->n_neighbors()};
2865 }
2866 
2867 
2868 } // namespace libMesh
2869 
2870 
2871 // Helper function for default caches in Elem subclasses
2872 
2873 #define LIBMESH_ENABLE_TOPOLOGY_CACHES \
2874  virtual \
2875  std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> & \
2876  _get_bracketing_node_cache() const libmesh_override \
2877  { \
2878  static std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> c; \
2879  return c; \
2880  } \
2881  \
2882  virtual \
2883  std::vector<std::vector<std::vector<signed char>>> & \
2884  _get_parent_indices_cache() const libmesh_override \
2885  { \
2886  static std::vector<std::vector<std::vector<signed char>>> c; \
2887  return c; \
2888  }
2889 
2890 
2891 #endif // LIBMESH_ELEM_H
virtual bool is_node_on_edge(const unsigned int n, const unsigned int e) const =0
bool ancestor() const
Definition: elem.C:1574
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
void set_p_level(const unsigned int p)
Sets the value of the p-refinement level for the element.
Definition: elem.h:2559
std::string get_info() const
Prints relevant information about the element to a string.
Definition: elem.C:2595
bool has_children() const
Definition: elem.h:2295
The SimpleRange templated class is intended to make it easy to construct ranges from pairs of iterato...
Definition: simple_range.h:36
virtual bool is_edge(const unsigned int i) const =0
void family_tree_by_side(std::vector< const Elem * > &family, const unsigned int side, const bool reset=true) const
Same as the family_tree() member, but only adds elements which are next to side.
Definition: elem.C:1748
void total_family_tree_by_neighbor(std::vector< const Elem * > &family, const Elem *neighbor, const bool reset=true) const
Same as the family_tree_by_neighbor() member, but also adds any subactive descendants.
Definition: elem.C:1835
virtual UniquePtr< Elem > build_side_ptr(const unsigned int i, bool proxy=true)=0
virtual void connectivity(const unsigned int sc, const IOPackage iop, std::vector< dof_id_type > &conn) const =0
virtual unsigned int n_second_order_adjacent_vertices(const unsigned int n) const
Definition: elem.C:2698
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:1941
A Node is like a Point, but with more information.
Definition: node.h:52
Node ** _nodes
Pointers to the nodes we are connected to.
Definition: elem.h:1615
Elem * child_neighbor(Elem *elem)
Definition: elem.h:2022
virtual unsigned int opposite_node(const unsigned int n, const unsigned int s) const
Definition: elem.C:3052
variant_filter_iterator(const IterType &d, const IterType &e, const PredType &p)
Templated Constructor.
Predicates::multi_predicate Predicate
Useful iterator typedefs.
Definition: elem.h:1426
bool subactive() const
Definition: elem.h:2275
bool active() const
Definition: elem.h:2257
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value.
Definition: libmesh.h:184
static UniquePtr< Elem > build(const ElemType type, Elem *p=libmesh_nullptr)
Definition: elem.C:238
void set_parent(Elem *p)
Sets the pointer to the element&#39;s parent.
Definition: elem.h:2362
virtual bool is_vertex_on_parent(unsigned int c, unsigned int n) const
Definition: elem.C:3019
virtual ElemType type() const =0
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:589
virtual bool close_to_point(const Point &p, Real tol) const
Definition: elem.C:2473
unsigned char _pflag
p refinement flag.
Definition: elem.h:1646
bool has_topological_neighbor(const Elem *elem, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
Definition: elem.C:1104
virtual std::pair< unsigned short int, unsigned short int > second_order_child_vertex(const unsigned int n) const
Definition: elem.C:2716
virtual bool is_edge_on_side(const unsigned int e, const unsigned int s) const =0
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
Definition: int_range.h:42
unsigned char _p_level
p refinement level - the difference between the polynomial degree on this element and the minimum pol...
Definition: elem.h:1656
unsigned int p_level() const
Definition: elem.h:2422
virtual bool is_child_on_edge(const unsigned int c, const unsigned int e) const
Definition: elem.C:1665
void contract()
Contract an active element, i.e.
bool operator==(const Elem &rhs) const
Definition: elem.C:521
void family_tree_by_subneighbor(std::vector< const Elem * > &family, const Elem *neighbor, const Elem *subneighbor, const bool reset=true) const
Same as the family_tree() member, but only adds elements which are next to subneighbor.
Definition: elem.C:1859
We&#39;re using a class instead of a typedef to allow forward declarations and future flexibility...
IntRange< unsigned short > side_index_range() const
Definition: elem.h:2083
UniquePtr< Elem > side(const unsigned int i) const
Definition: elem.h:2105
virtual unsigned int n_edges() const =0
SideIter(const unsigned int side_number, Elem *parent)
Definition: elem.h:2711
ElemType
Defines an enum for geometric element types.
IntRange< unsigned short > node_index_range() const
Definition: elem.h:2065
const Elem * parent() const
Definition: elem.h:2346
unsigned int which_neighbor_am_i(const Elem *e) const
This function tells you which neighbor e is.
Definition: elem.h:2181
UniquePtr< Elem > build_side(const unsigned int i, bool proxy=true) const
Definition: elem.h:2132
unsigned int max_descendant_p_level() const
Definition: elem.h:2541
const Elem * interior_parent() const
Definition: elem.C:951
unsigned int min_p_level_by_neighbor(const Elem *neighbor, unsigned int current_min) const
Definition: elem.C:2017
This is the base class from which all geometric element types are derived.
Definition: elem.h:89
unsigned int n_neighbors() const
Definition: elem.h:613
virtual Real hmin() const
Definition: elem.C:458
MeshBase & mesh
uint8_t processor_id_type
Definition: id_types.h:99
void add_child(Elem *elem)
Adds a child pointer to the array of children of this element.
Definition: elem.C:1608
virtual bool is_linear() const
Definition: elem.h:921
SideIter & operator=(const SideIter &other)
Definition: elem.h:2739
Node * get_node(const unsigned int i) const
Definition: elem.h:1913
RefinementState
Enumeration of possible element refinement states.
Definition: elem.h:1125
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
Same as the active_family_tree_by_neighbor() member, but the neighbor here may be a topological (e...
Definition: elem.C:1942
const class libmesh_nullptr_t libmesh_nullptr
void set_refinement_flag(const RefinementState rflag)
Sets the value of the refinement flag for the element.
Definition: elem.h:2513
std::ostream & operator<<(std::ostream &os, const OrderWrapper &order)
Overload stream operators.
Definition: fe_type.h:164
virtual ~Elem()
Destructor.
ChildRefIter(Elem *const *childpp)
Definition: elem.h:1686
unsigned int _side_number
Definition: elem.h:2811
side_iterator boundary_sides_end()
Definition: elem.C:2957
bool is_semilocal(const processor_id_type my_pid) const
Definition: elem.C:552
static const Real TOLERANCE
virtual Real volume() const
Definition: elem.C:2966
bool contains_edge_of(const Elem *e) const
Definition: elem.C:584
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...
Definition: elem.C:1293
Elem * child(const unsigned int i) const
Definition: elem.h:2465
The libMesh namespace provides an interface to certain functionality in the library.
SideIter & operator++()
Definition: elem.h:2757
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...
Definition: elem.C:605
void active_family_tree(std::vector< const Elem * > &active_family, const bool reset=true) const
Same as the family_tree() member, but only adds the active children.
Definition: elem.C:1724
long double max(long double a, double b)
const Elem * reference_elem() const
Definition: elem.C:439
bool contains_vertex_of(const Elem *e) const
Definition: elem.C:573
virtual bool is_child_on_side(const unsigned int c, const unsigned int s) const =0
void set_interior_parent(Elem *p)
Sets the pointer to the element&#39;s interior_parent.
Definition: elem.C:1003
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:564
void total_family_tree_by_subneighbor(std::vector< const Elem * > &family, const Elem *neighbor, const Elem *subneighbor, const bool reset=true) const
Same as the family_tree_by_subneighbor() member, but also adds any subactive descendants.
Definition: elem.C:1901
IntRange< unsigned short > edge_index_range() const
Definition: elem.h:2074
This is the MeshBase class.
Definition: mesh_base.h:68
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
Definition: elem.h:1699
bool has_ancestor_children() const
Definition: elem.h:2309
virtual bool has_affine_map() const
Definition: elem.h:915
libmesh_assert(j)
std::unique_ptr< T > UniquePtr
Definition: auto_ptr.h:46
virtual bool infinite() const =0
void total_family_tree(std::vector< const Elem * > &active_family, const bool reset=true) const
Same as the family_tree() member, but also adds any subactive descendants.
Definition: elem.C:1704
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.
Definition: elem.C:2485
virtual unsigned int n_nodes() const =0
const Elem * neighbor_ptr(unsigned int i) const
Definition: elem.h:1967
side_iterator boundary_sides_begin()
Iterator accessor functions.
Definition: elem.C:2948
virtual void refine(MeshRefinement &mesh_refinement)
Refine the element.
const Elem *const * ConstNeighborPtrIter
Definition: elem.h:299
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 unsigned int n_nodes_in_child(unsigned int) const
Definition: elem.h:582
void replace_child(Elem *elem, unsigned int c)
Replaces the child pointer at the specified index in the child array.
Definition: elem.C:1654
static const subdomain_id_type invalid_subdomain_id
A static integral constant representing an invalid subdomain id.
Definition: elem.h:237
virtual dof_id_type key() const
Definition: elem.C:503
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...
Definition: elem.C:1404
const Elem * topological_neighbor(const unsigned int i, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
Definition: elem.C:1067
Elem *const * NeighborPtrIter
Nested "classes" for use iterating over all neighbors of an element.
Definition: elem.h:298
This is the MeshRefinement class.
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:1874
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 ...
Definition: elem.C:770
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:335
bool is_ancestor_of(const Elem *descendant) const
Definition: elem.h:2325
virtual Real quality(const ElemQuality q) const
Definition: elem.C:1547
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:638
UniquePtr< Elem > build_edge(const unsigned int i) const
Creates an element coincident with edge i.
Definition: elem.h:2159
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...
Definition: elem.C:872
Elem ** _elemlinks
Pointers to this element&#39;s parent and neighbors, and for lower-dimensional elements&#39; interior_parent...
Definition: elem.h:1621
void write_connectivity(std::ostream &out, const IOPackage iop) const
Writes the element connectivity for various IO packages to the passed ostream "out".
Definition: elem.C:1504
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:1593
Elem ** _children
Pointers to this element&#39;s children.
Definition: elem.h:1627
The definition of the struct used for iterating over sides.
Definition: elem.h:2841
void libmesh_assert_valid_node_pointers() const
Checks for a valid id and pointers to nodes with valid ids on this element.
Definition: elem.C:1125
const Elem * child_ptr(unsigned int i) const
Definition: elem.h:2445
virtual unsigned int n_faces() const =0
const Node & node_ref(const unsigned int i) const
Definition: elem.h:1896
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:324
RefinementState p_refinement_flag() const
Definition: elem.h:2521
virtual Order default_order() const =0
virtual const std::vector< std::pair< dof_id_type, dof_id_type > > bracketing_nodes(unsigned int c, unsigned int n) const
Definition: elem.C:2353
subdomain_id_type subdomain_id() const
Definition: elem.h:1951
This is the base class for point locators.
virtual unsigned int n_sides() const =0
virtual unsigned int which_node_am_i(unsigned int side, unsigned int side_node) const =0
SideIter _last_side()
Definition: elem.h:2830
virtual bool is_remote() const
Definition: elem.h:530
void family_tree_by_neighbor(std::vector< const Elem * > &family, const Elem *neighbor, const bool reset=true) const
Same as the family_tree() member, but only adds elements which are next to neighbor.
Definition: elem.C:1808
unsigned int which_side_am_i(const Elem *e) const
This function tells you which side the boundary element e is.
Definition: elem.h:2203
void set_neighbor(const unsigned int i, Elem *n)
Assigns n as the neighbor.
Definition: elem.h:2000
This class implements reference counting.
dof_id_type node(const unsigned int i) const
Definition: elem.h:1844
virtual unsigned int n_children() const =0
bool side_on_boundary() const
Definition: elem.h:2776
subdomain_id_type _sbd_id
The subdomain to which this element belongs.
Definition: elem.h:1633
static ElemType second_order_equivalent_type(const ElemType et, const bool full_ordered=true)
Definition: elem.C:2783
Elem(const unsigned int n_nodes, const unsigned int n_sides, Elem *parent, Elem **elemlinkdata, Node **nodelinkdata)
Constructor.
Definition: elem.h:1731
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:1579
unsigned char _rflag
h refinement flag.
Definition: elem.h:1640
virtual Point origin() const
Definition: elem.h:1480
unsigned int min_new_p_level_by_neighbor(const Elem *neighbor, unsigned int current_min) const
Definition: elem.C:2046
virtual unsigned int embedding_matrix_version() const
Definition: elem.h:1536
SimpleRange< NodeRefIter > node_ref_range()
Returns a range with all nodes of an element, usable in range-based for loops.
Definition: elem.h:2047
bool on_boundary() const
Definition: elem.h:2171
Defines a Cartesian bounding box by the two corner extremum.
Definition: bounding_box.h:40
ConstNodeRefIter(const Node *const *nodepp)
Definition: elem.h:1677
unsigned int which_child_am_i(const Elem *e) const
Definition: elem.h:2487
UniquePtr< Elem > _side
Definition: elem.h:2796
virtual Real hmax() const
Definition: elem.C:475
const Elem * raw_child_ptr(unsigned int i) const
Definition: elem.h:2436
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const Point & point(const unsigned int i) const
Definition: elem.h:1809
virtual bool is_vertex(const unsigned int i) const =0
SideIter(const SideIter &other)
Definition: elem.h:2730
void coarsen()
Coarsen the element.
OStreamProxy out
void swap(Iterator &lhs, Iterator &rhs)
swap, used to implement op=
bool has_neighbor(const Elem *elem) const
Definition: elem.h:2010
virtual bool is_face(const unsigned int i) const =0
virtual unsigned int is_vertex_on_child(unsigned int, unsigned int n) const
Definition: elem.h:663
void _update_side_ptr() const
Definition: elem.h:2784
virtual unsigned int n_vertices() const =0
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
virtual unsigned int dim() const =0
The DofObject defines an abstract base class for objects that have degrees of freedom associated with...
Definition: dof_object.h:51
Order
defines an enum for polynomial orders.
Definition: enum_order.h:32
unsigned int level() const
Definition: elem.h:2388
virtual const std::vector< std::pair< unsigned char, unsigned char > > & parent_bracketing_nodes(unsigned int c, unsigned int n) const
Definition: elem.C:2148
void set_child(unsigned int c, Elem *elem)
Sets the pointer to the child for this element.
Definition: elem.h:2477
RefinementState refinement_flag() const
Definition: elem.h:2505
virtual UniquePtr< Elem > build_edge_ptr(const unsigned int i)=0
virtual Point centroid() const
Definition: elem.C:446
Real length(const unsigned int n1, const unsigned int n2) const
Definition: elem.C:492
void active_family_tree_by_side(std::vector< const Elem * > &family, const unsigned int side, const bool reset=true) const
Same as the active_family_tree() member, but only adds elements which are next to side...
Definition: elem.C:1777
const Elem * top_parent() const
Definition: elem.h:2370
void nullify_neighbors()
Replaces this element with NULL for all of its neighbors.
Definition: elem.C:2672
SimpleRange< NeighborPtrIter > neighbor_ptr_range()
Returns a range with all neighbors of an element, usable in range-based for loops.
Definition: elem.h:2855
void set_p_refinement_flag(const RefinementState pflag)
Sets the value of the p-refinement flag for the element.
Definition: elem.h:2529
virtual unsigned int as_parent_node(unsigned int c, unsigned int n) const
Definition: elem.C:2080
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:1831
ElemQuality
Defines an enum for element quality metrics.
unsigned int local_node(const dof_id_type i) const
Definition: elem.h:1854
void print_info(std::ostream &os=libMesh::out) const
Prints relevant information about the element.
Definition: elem.C:2587
static dof_id_type compute_key(dof_id_type n0)
Definition: elem.h:2621
IOPackage
libMesh interfaces with several different software packages for the purposes of creating, reading, and writing mesh files.
virtual unsigned int n_sub_elem() const =0
void active_family_tree_by_neighbor(std::vector< const Elem * > &family, const Elem *neighbor, const bool reset=true) const
Same as the active_family_tree() member, but only adds elements which are next to neighbor...
Definition: elem.C:1984
dof_id_type id() const
Definition: dof_object.h:632
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.
Definition: elem.C:1209
ConstChildRefIter(const Elem *const *childpp)
Definition: elem.h:1694
virtual bool is_mid_infinite_edge_node(const unsigned int) const
Definition: elem.h:1471
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:2606
Elem * neighbor(const unsigned int i) const
Definition: elem.h:1988
static ElemType first_order_equivalent_type(const ElemType et)
Definition: elem.C:2724
virtual unsigned short int second_order_adjacent_vertex(const unsigned int n, const unsigned int v) const
Definition: elem.C:2706
void libmesh_assert_valid_neighbors() const
Checks for consistent neighbor links on this element.
Definition: elem.C:1137
long double min(long double a, double b)
virtual unsigned int opposite_side(const unsigned int s) const
Definition: elem.C:3044
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
side_iterator(const IterType &d, const IterType &e, const PredType &p)
Definition: elem.h:2846
Elem *& operator*() const
Definition: elem.h:2747
virtual std::pair< Real, Real > qual_bounds(const ElemQuality) const
Definition: elem.h:875
NodeRefIter(Node *const *nodepp)
Definition: elem.h:1669
const Node *const * get_nodes() const
Definition: elem.h:1866
virtual UniquePtr< Elem > side_ptr(unsigned int i)=0
unsigned int get_node_index(const Node *node_ptr) const
Definition: elem.h:1929
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const
Definition: elem.C:2448
virtual BoundingBox loose_bounding_box() const
Definition: elem.C:2997
uint8_t dof_id_type
Definition: id_types.h:64
The definition of the protected nested SideIter class.
Definition: elem.h:2707
processor_id_type processor_id() const
Definition: dof_object.h:694
virtual float embedding_matrix(const unsigned int child_num, const unsigned int child_node_num, const unsigned int parent_node_num) const =0
void family_tree(std::vector< const Elem * > &family, const bool reset=true) const
Fills the vector family with the children of this element, recursively.
Definition: elem.C:1681
virtual Point master_point(const unsigned int i) const =0
SideIter _first_side()
Side iterator helper functions.
Definition: elem.h:2822