libMesh
elem.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 #ifndef LIBMESH_ELEM_H
21 #define LIBMESH_ELEM_H
22 
23 // Local includes
24 #include "libmesh/libmesh_common.h"
25 #include "libmesh/bounding_box.h"
26 #include "libmesh/dof_object.h"
27 #include "libmesh/id_types.h"
28 #include "libmesh/reference_counted_object.h"
29 #include "libmesh/node.h"
30 #include "libmesh/enum_elem_type.h" // INVALID_ELEM
31 #include "libmesh/multi_predicates.h"
32 #include "libmesh/pointer_to_pointer_iter.h"
33 #include "libmesh/int_range.h"
34 #include "libmesh/simple_range.h"
35 #include "libmesh/variant_filter_iterator.h"
36 #include "libmesh/hashword.h" // Used in compute_key() functions
37 
38 // C++ includes
39 #include <algorithm>
40 #include <cstddef>
41 #include <iostream>
42 #include <limits.h> // CHAR_BIT
43 #include <set>
44 #include <vector>
45 #include <memory>
46 #include <array>
47 
48 namespace libMesh
49 {
50 
51 // Forward declarations
52 class BoundaryInfo;
53 class Elem;
54 class MeshBase;
55 class MeshRefinement;
56 #ifdef LIBMESH_ENABLE_PERIODIC
57 class PeriodicBoundaries;
58 class PointLocatorBase;
59 #endif
60 template <class SideType, class ParentType>
61 class Side;
62 enum ElemQuality : int;
63 enum IOPackage : int;
64 enum Order : int;
65 
66 
94 class Elem : public ReferenceCountedObject<Elem>,
95  public DofObject
96 {
97 protected:
98 
105  Elem (const unsigned int n_nodes,
106  const unsigned int n_sides,
107  Elem * parent,
108  Elem ** elemlinkdata,
109  Node ** nodelinkdata);
110 
111 public:
112 
122  Elem (Elem &&) = delete;
123  Elem (const Elem &) = delete;
124  Elem & operator= (const Elem &) = delete;
125  Elem & operator= (Elem &&) = delete;
126 
130  virtual ~Elem() = default;
131 
135  const Point & point (const unsigned int i) const;
136 
141  Point & point (const unsigned int i);
142 
147  virtual Point master_point (const unsigned int i) const = 0;
148 
152  dof_id_type node_id (const unsigned int i) const;
153 
158  unsigned int local_node (const dof_id_type i) const;
159 
164  unsigned int get_node_index (const Node * node_ptr) const;
165 
169  const Node * const * get_nodes () const;
170 
174  const Node * node_ptr (const unsigned int i) const;
175 
179  Node * node_ptr (const unsigned int i);
180 
184  const Node & node_ref (const unsigned int i) const;
185 
189  Node & node_ref (const unsigned int i);
190 
191 #ifdef LIBMESH_ENABLE_DEPRECATED
192 
200  virtual Node * & set_node (const unsigned int i);
201 #endif // LIBMESH_ENABLE_DEPRECATED
202 
206  virtual void set_node (const unsigned int i,
207  Node * node);
208 
212  class NodeRefIter;
213  class ConstNodeRefIter;
214 
223 
225 
230 
236 
252 
259  virtual bool runtime_topology() const { return false; }
260 
273  const Elem * reference_elem () const;
274 
279  virtual dof_id_type key (const unsigned int s) const = 0;
280 
287  virtual dof_id_type low_order_key (const unsigned int s) const = 0;
288 
295  virtual dof_id_type key () const;
296 
303  bool operator == (const Elem & rhs) const;
304 
312  bool topologically_equal (const Elem & rhs) const;
313 
323  const Elem * neighbor_ptr (unsigned int i) const;
324 
328  Elem * neighbor_ptr (unsigned int i);
329 
333  typedef Elem * const * NeighborPtrIter;
334  typedef const Elem * const * ConstNeighborPtrIter;
335 
345 
347 
348 #ifdef LIBMESH_ENABLE_PERIODIC
349 
355  const Elem * topological_neighbor (const unsigned int i,
356  const MeshBase & mesh,
357  const PointLocatorBase & point_locator,
358  const PeriodicBoundaries * pb) const;
359 
366  Elem * topological_neighbor (const unsigned int i,
367  MeshBase & mesh,
368  const PointLocatorBase & point_locator,
369  const PeriodicBoundaries * pb);
370 
375  bool has_topological_neighbor (const Elem * elem,
376  const MeshBase & mesh,
377  const PointLocatorBase & point_locator,
378  const PeriodicBoundaries * pb) const;
379 #endif
380 
384  void set_neighbor (const unsigned int i, Elem * n);
385 
390  bool has_neighbor (const Elem * elem) const;
391 
396  Elem * child_neighbor (Elem * elem);
397 
402  const Elem * child_neighbor (const Elem * elem) const;
403 
409  bool on_boundary () const;
410 
420  bool is_semilocal (const processor_id_type my_pid) const;
421 
427  unsigned int which_neighbor_am_i(const Elem * e) const;
428 
445  unsigned int which_side_am_i(const Elem * e) const;
446 
457  virtual unsigned int local_side_node(unsigned int side,
458  unsigned int side_node) const = 0;
459 
467  virtual unsigned int local_edge_node(unsigned int edge,
468  unsigned int edge_node) const = 0;
469 
470 #ifdef LIBMESH_ENABLE_DEPRECATED
471 
474  unsigned int which_node_am_i(unsigned int side,
475  unsigned int side_node) const;
476 #endif // LIBMESH_ENABLE_DEPRECATED
477 
485  bool contains_vertex_of(const Elem * e, bool mesh_connection=false) const;
486 
492  bool contains_edge_of(const Elem * e) const;
493 
510  void find_point_neighbors(const Point & p,
511  std::set<const Elem *> & neighbor_set) const;
512 
518  void find_point_neighbors(std::set<const Elem *> & neighbor_set) const;
519 
525  void find_point_neighbors(std::set<const Elem *> & neighbor_set,
526  const Elem * start_elem) const;
527 
531  void find_point_neighbors(std::set<Elem *> & neighbor_set,
532  Elem * start_elem);
533 
539  void find_edge_neighbors(const Point & p1,
540  const Point & p2,
541  std::set<const Elem *> & neighbor_set) const;
542 
551  void find_edge_neighbors(std::set<const Elem *> & neighbor_set) const;
552 
558  void find_interior_neighbors(std::set<const Elem *> & neighbor_set) const;
559 
564  void find_interior_neighbors(std::set<Elem *> & neighbor_set);
565 
573  void remove_links_to_me ();
574 
582  void make_links_to_me_remote ();
583 
590  void make_links_to_me_local (unsigned int n, unsigned int neighbor_side);
591 
603  virtual bool is_remote () const
604  { return false; }
605 
610  virtual void connectivity(const unsigned int sc,
611  const IOPackage iop,
612  std::vector<dof_id_type> & conn) const = 0;
613 
619  void write_connectivity (std::ostream & out,
620  const IOPackage iop) const;
621 
626  virtual ElemType type () const = 0;
627 
635  static const unsigned int type_to_dim_map[INVALID_ELEM];
636 
640  virtual unsigned short dim () const = 0;
641 
650  static const unsigned int type_to_n_nodes_map[INVALID_ELEM];
651 
655  virtual unsigned int n_nodes () const = 0;
656 
661  static const unsigned int max_n_nodes = 27;
662 
668 
674  virtual unsigned int n_nodes_in_child (unsigned int /*c*/) const
675  { return this->n_nodes(); }
676 
685  static const unsigned int type_to_n_sides_map[INVALID_ELEM];
686 
692  virtual unsigned int n_sides () const = 0;
693 
697  virtual ElemType side_type (const unsigned int s) const = 0;
698 
704 
714  unsigned int n_neighbors () const
715  { return this->n_sides(); }
716 
721  virtual unsigned int n_vertices () const = 0;
722 
727  virtual unsigned int n_edges () const = 0;
728 
734 
743  static const unsigned int type_to_n_edges_map[INVALID_ELEM];
744 
749  virtual unsigned int n_faces () const = 0;
750 
756 
761  virtual unsigned int n_children () const = 0;
762 
766  virtual bool is_vertex(const unsigned int i) const = 0;
767 
774  virtual bool is_vertex_on_child (unsigned int /*c*/,
775  unsigned int n) const
776  { return this->is_vertex(n); }
777 
782  virtual bool is_vertex_on_parent(unsigned int c,
783  unsigned int n) const;
784 
789  virtual bool is_edge(const unsigned int i) const = 0;
790 
796  virtual bool is_face(const unsigned int i) const = 0;
797 
801  bool is_internal(const unsigned int i) const;
802 
807  virtual bool is_node_on_side(const unsigned int n,
808  const unsigned int s) const = 0;
809 
813  virtual std::vector<unsigned int> nodes_on_side(const unsigned int /*s*/) const = 0;
814 
818  virtual std::vector<unsigned int> nodes_on_edge(const unsigned int /*e*/) const = 0;
819 
823  virtual std::vector<unsigned int> sides_on_edge(const unsigned int /*e*/) const = 0;
824 
828  virtual std::vector<unsigned int> edges_adjacent_to_node(const unsigned int /*n*/) const = 0;
829 
834  virtual bool is_node_on_edge(const unsigned int n,
835  const unsigned int e) const = 0;
836 
840  virtual bool is_edge_on_side(const unsigned int e,
841  const unsigned int s) const = 0;
842 
847  virtual unsigned int opposite_side(const unsigned int s) const;
848 
854  virtual unsigned int opposite_node(const unsigned int n,
855  const unsigned int s) const;
856 
862  virtual unsigned int n_sub_elem () const = 0;
863 
880  virtual std::unique_ptr<Elem> side_ptr (unsigned int i) = 0;
881  std::unique_ptr<const Elem> side_ptr (unsigned int i) const;
882 
897  virtual void side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) = 0;
898  void side_ptr (std::unique_ptr<const Elem> & side, const unsigned int i) const;
899 
920  virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i) = 0;
921  std::unique_ptr<const Elem> build_side_ptr (const unsigned int i) const;
922 
923 #ifdef LIBMESH_ENABLE_DEPRECATED
924  /*
925  * Older versions of libMesh supported a "proxy" option here.
926  */
927  virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i, bool proxy)
928  { if (proxy) libmesh_error(); libmesh_deprecated(); return this->build_side_ptr(i); }
929 
930  std::unique_ptr<const Elem> build_side_ptr (const unsigned int i, bool proxy) const
931  { if (proxy) libmesh_error(); libmesh_deprecated(); return this->build_side_ptr(i); }
932 #endif
933 
948  virtual void build_side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) = 0;
949  void build_side_ptr (std::unique_ptr<const Elem> & side, const unsigned int i) const;
950 
964  virtual std::unique_ptr<Elem> build_edge_ptr (const unsigned int i) = 0;
965  std::unique_ptr<const Elem> build_edge_ptr (const unsigned int i) const;
966 
981  virtual void build_edge_ptr (std::unique_ptr<Elem> & edge, const unsigned int i) = 0;
982  void build_edge_ptr (std::unique_ptr<const Elem> & edge, const unsigned int i) const;
983 
992 
998  virtual Order default_order () const = 0;
999 
1005  virtual Order supported_nodal_order() const { return default_order(); }
1006 
1012  virtual Order default_side_order () const { return default_order(); }
1013 
1014 #ifdef LIBMESH_ENABLE_DEPRECATED
1015 
1024  virtual Point centroid () const;
1025 #endif // LIBMESH_ENABLE_DEPRECATED
1026 
1041  virtual Point true_centroid () const;
1042 
1051  Point vertex_average () const;
1052 
1060  virtual Point quasicircumcenter () const
1061  { libmesh_not_implemented(); }
1062 
1066  virtual Real hmin () const;
1067 
1071  virtual Real hmax () const;
1072 
1080  virtual Real volume () const;
1081 
1092  virtual BoundingBox loose_bounding_box () const;
1093 
1110  virtual Real quality (const ElemQuality q) const;
1111 
1120  virtual std::pair<Real,Real> qual_bounds (const ElemQuality) const
1121  { libmesh_not_implemented(); return std::make_pair(0.,0.); }
1122 
1138  virtual bool contains_point (const Point & p, Real tol=TOLERANCE) const;
1139 
1148  virtual bool on_reference_element(const Point & p,
1149  const Real eps = TOLERANCE) const = 0;
1150 
1155  virtual bool close_to_point(const Point & p, Real tol) const;
1156 
1162  bool positive_edge_orientation(const unsigned int i) const;
1163 
1171  bool positive_face_orientation(const unsigned int i) const;
1172 
1173 
1180  void inherit_data_from(const Elem & src);
1181 
1182 
1183 private:
1190  bool point_test(const Point & p, Real box_tol, Real map_tol) const;
1191 
1192 public:
1197  virtual bool has_affine_map () const { return false; }
1198 
1207  virtual bool has_invertible_map(Real tol = TOLERANCE*TOLERANCE) const;
1208 
1213  virtual bool is_linear () const { return false; }
1214 
1218  void print_info (std::ostream & os=libMesh::out) const;
1219 
1223  std::string get_info () const;
1224 
1231  bool active () const;
1232 
1238  bool ancestor () const;
1239 
1244  bool subactive () const;
1245 
1250  bool has_children () const;
1251 
1256  bool has_ancestor_children () const;
1257 
1263  bool is_ancestor_of(const Elem * descendant) const;
1264 
1269  const Elem * parent () const;
1270 
1275  Elem * parent ();
1276 
1281  void set_parent (Elem * p);
1282 
1290  const Elem * top_parent () const;
1291 
1306  const Elem * interior_parent () const;
1307 
1308  Elem * interior_parent ();
1309 
1314  void set_interior_parent (Elem * p);
1315 
1321  Real length (const unsigned int n1,
1322  const unsigned int n2) const;
1323 
1334  virtual unsigned int n_second_order_adjacent_vertices (const unsigned int n) const;
1335 
1344  virtual unsigned short int second_order_adjacent_vertex (const unsigned int n,
1345  const unsigned int v) const;
1346 
1362  virtual std::pair<unsigned short int, unsigned short int>
1363  second_order_child_vertex (const unsigned int n) const;
1364 
1379  const bool full_ordered=true);
1380 
1388  static ElemType first_order_equivalent_type (const ElemType et);
1389 
1403 
1411  unsigned int level () const;
1412 
1418  unsigned int p_level () const;
1419 
1423  virtual bool is_child_on_side(const unsigned int c,
1424  const unsigned int s) const = 0;
1425 
1429  ElemMappingType mapping_type () const;
1430 
1434  void set_mapping_type (const ElemMappingType type);
1435 
1439  unsigned char mapping_data () const;
1440 
1444  void set_mapping_data (const unsigned char data);
1445 
1446 
1447 #ifdef LIBMESH_ENABLE_AMR
1448 
1460 
1465  const Elem * raw_child_ptr (unsigned int i) const;
1466 
1471  const Elem * child_ptr (unsigned int i) const;
1472 
1477  Elem * child_ptr (unsigned int i);
1478 
1483  class ChildRefIter;
1484  class ConstChildRefIter;
1485 
1494 
1496 
1497 private:
1502  void set_child (unsigned int c, Elem * elem);
1503 
1504 public:
1511  unsigned int which_child_am_i(const Elem * e) const;
1512 
1516  virtual bool is_child_on_edge(const unsigned int c,
1517  const unsigned int e) const;
1518 
1525  void add_child (Elem * elem);
1526 
1533  void add_child (Elem * elem, unsigned int c);
1534 
1538  void replace_child (Elem * elem, unsigned int c);
1539 
1551  void family_tree (std::vector<const Elem *> & family,
1552  bool reset = true) const;
1553 
1557  void family_tree (std::vector<Elem *> & family,
1558  bool reset = true);
1559 
1564  void total_family_tree (std::vector<const Elem *> & family,
1565  bool reset = true) const;
1566 
1570  void total_family_tree (std::vector<Elem *> & family,
1571  bool reset = true);
1572 
1579  void active_family_tree (std::vector<const Elem *> & active_family,
1580  bool reset = true) const;
1581 
1585  void active_family_tree (std::vector<Elem *> & active_family,
1586  bool reset = true);
1587 
1592  void family_tree_by_side (std::vector<const Elem *> & family,
1593  unsigned int side,
1594  bool reset = true) const;
1595 
1599  void family_tree_by_side (std::vector<Elem *> & family,
1600  unsigned int side,
1601  bool reset = true);
1602 
1607  void active_family_tree_by_side (std::vector<const Elem *> & family,
1608  unsigned int side,
1609  bool reset = true) const;
1610 
1614  void active_family_tree_by_side (std::vector<Elem *> & family,
1615  unsigned int side,
1616  bool reset = true);
1617 
1622  void family_tree_by_neighbor (std::vector<const Elem *> & family,
1623  const Elem * neighbor,
1624  bool reset = true) const;
1625 
1629  void family_tree_by_neighbor (std::vector<Elem *> & family,
1630  Elem * neighbor,
1631  bool reset = true);
1632 
1637  void total_family_tree_by_neighbor (std::vector<const Elem *> & family,
1638  const Elem * neighbor,
1639  bool reset = true) const;
1640 
1644  void total_family_tree_by_neighbor (std::vector<Elem *> & family,
1645  Elem * neighbor,
1646  bool reset = true);
1647 
1654  void family_tree_by_subneighbor (std::vector<const Elem *> & family,
1655  const Elem * neighbor,
1656  const Elem * subneighbor,
1657  bool reset = true) const;
1658 
1662  void family_tree_by_subneighbor (std::vector<Elem *> & family,
1663  Elem * neighbor,
1664  Elem * subneighbor,
1665  bool reset = true);
1666 
1671  void total_family_tree_by_subneighbor (std::vector<const Elem *> & family,
1672  const Elem * neighbor,
1673  const Elem * subneighbor,
1674  bool reset = true) const;
1675 
1679  void total_family_tree_by_subneighbor (std::vector<Elem *> & family,
1680  Elem * neighbor,
1681  Elem * subneighbor,
1682  bool reset = true);
1683 
1688  void active_family_tree_by_neighbor (std::vector<const Elem *> & family,
1689  const Elem * neighbor,
1690  bool reset = true) const;
1691 
1695  void active_family_tree_by_neighbor (std::vector<Elem *> & family,
1696  Elem * neighbor,
1697  bool reset = true);
1698 
1704  void active_family_tree_by_topological_neighbor (std::vector<const Elem *> & family,
1705  const Elem * neighbor,
1706  const MeshBase & mesh,
1707  const PointLocatorBase & point_locator,
1708  const PeriodicBoundaries * pb,
1709  bool reset = true) const;
1710 
1714  void active_family_tree_by_topological_neighbor (std::vector<Elem *> & family,
1715  Elem * neighbor,
1716  const MeshBase & mesh,
1717  const PointLocatorBase & point_locator,
1718  const PeriodicBoundaries * pb,
1719  bool reset = true);
1720 
1725 
1729  void set_refinement_flag (const RefinementState rflag);
1730 
1735 
1739  void set_p_refinement_flag (const RefinementState pflag);
1740 
1745  unsigned int max_descendant_p_level () const;
1746 
1752  unsigned int min_p_level_by_neighbor (const Elem * neighbor,
1753  unsigned int current_min) const;
1754 
1760  unsigned int min_new_p_level_by_neighbor (const Elem * neighbor,
1761  unsigned int current_min) const;
1762 
1768  void set_p_level (const unsigned int p);
1769 
1774  void hack_p_level (const unsigned int p);
1775 
1782  void hack_p_level_and_refinement_flag (const unsigned int p,
1783  RefinementState pflag);
1784 
1788  virtual void refine (MeshRefinement & mesh_refinement);
1789 
1794  void coarsen ();
1795 
1802  void contract ();
1803 
1804 #endif
1805 
1806 #ifndef NDEBUG
1807 
1810  void libmesh_assert_valid_neighbors() const;
1811 
1817 #endif // !NDEBUG
1818 
1831  virtual unsigned int local_singular_node(const Point & /* p */, const Real /* tol */ = TOLERANCE*TOLERANCE) const
1832  { return invalid_uint; }
1833 
1838  virtual bool is_singular_node(unsigned int /* node_i */) const { return false; }
1839 
1846  virtual unsigned int center_node_on_side(const unsigned short side) const;
1847 
1848 protected:
1849 
1860  class SideIter;
1861 
1862 public:
1867 
1872  struct side_iterator;
1873 
1879 
1880 private:
1886  SideIter _last_side();
1887 
1888 public:
1889 
1890 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
1891 
1896  virtual bool infinite () const = 0;
1897 
1905  virtual bool is_mid_infinite_edge_node(const unsigned int /* n */) const
1906  { libmesh_assert (!this->infinite()); return false; }
1907 
1914  virtual Point origin () const { libmesh_not_implemented(); return Point(); }
1915 
1916 #else
1917 
1918  static constexpr bool infinite () { return false; }
1919 
1920 #endif
1921 
1925  static std::unique_ptr<Elem> build (const ElemType type,
1926  Elem * p=nullptr);
1927 
1933  static std::unique_ptr<Elem> build_with_id (const ElemType type,
1934  dof_id_type id);
1935 
1948  virtual std::unique_ptr<Elem> disconnected_clone () const;
1949 
1959  virtual unsigned int n_permutations() const = 0;
1960 
1973  virtual void permute(unsigned int perm_num) = 0;
1974 
1986  virtual void flip(BoundaryInfo * boundary_info) = 0;
1987 
1998  virtual bool is_flipped() const = 0;
1999 
2006  void orient(BoundaryInfo * boundary_info);
2007 
2008 #ifdef LIBMESH_ENABLE_AMR
2009 
2015  virtual unsigned int as_parent_node (unsigned int c,
2016  unsigned int n) const;
2017 
2022  virtual
2023  const std::vector<std::pair<unsigned char, unsigned char>> &
2024  parent_bracketing_nodes(unsigned int c,
2025  unsigned int n) const;
2026 
2031  virtual
2032  const std::vector<std::pair<dof_id_type, dof_id_type>>
2033  bracketing_nodes(unsigned int c,
2034  unsigned int n) const;
2035 
2036 
2040  virtual Real embedding_matrix (const unsigned int child_num,
2041  const unsigned int child_node_num,
2042  const unsigned int parent_node_num) const = 0;
2043 
2051  virtual unsigned int embedding_matrix_version () const { return 0; }
2052 
2053 #endif // LIBMESH_ENABLE_AMR
2054 
2055 
2056 protected:
2057 
2061  static constexpr Real affine_tol = TOLERANCE*TOLERANCE;
2062 
2066  static dof_id_type compute_key (dof_id_type n0);
2067 
2071  static dof_id_type compute_key (dof_id_type n0,
2072  dof_id_type n1);
2073 
2077  static dof_id_type compute_key (dof_id_type n0,
2078  dof_id_type n1,
2079  dof_id_type n2);
2080 
2084  static dof_id_type compute_key (dof_id_type n0,
2085  dof_id_type n1,
2086  dof_id_type n2,
2087  dof_id_type n3);
2088 
2092  void swap2nodes(unsigned int n1, unsigned int n2)
2093  {
2094  Node * temp = this->node_ptr(n1);
2095  this->set_node(n1, this->node_ptr(n2));
2096  this->set_node(n2, temp);
2097  }
2098 
2102  void swap2neighbors(unsigned int n1, unsigned int n2)
2103  {
2104  Elem * temp = this->neighbor_ptr(n1);
2105  this->set_neighbor(n1, this->neighbor_ptr(n2));
2106  this->set_neighbor(n2, temp);
2107  }
2108 
2112  void swap2boundarysides(unsigned short s1, unsigned short s2,
2113  BoundaryInfo * boundary_info) const;
2114 
2118  void swap2boundaryedges(unsigned short e1, unsigned short e2,
2119  BoundaryInfo * boundary_info) const;
2120 
2124  void swap3nodes(unsigned int n1, unsigned int n2, unsigned int n3)
2125  {
2126  swap2nodes(n1, n2);
2127  swap2nodes(n2, n3);
2128  }
2129 
2133  void swap3neighbors(unsigned int n1, unsigned int n2,
2134  unsigned int n3)
2135  {
2136  swap2neighbors(n1, n2);
2137  swap2neighbors(n2, n3);
2138  }
2139 
2143  void swap4nodes(unsigned int n1, unsigned int n2, unsigned int n3,
2144  unsigned int n4)
2145  {
2146  swap3nodes(n1, n2, n3);
2147  swap2nodes(n3, n4);
2148  }
2149 
2153  void swap4neighbors(unsigned int n1, unsigned int n2,
2154  unsigned int n3, unsigned int n4)
2155  {
2156  swap3neighbors(n1, n2, n3);
2157  swap2neighbors(n3, n4);
2158  }
2159 
2160 
2164  template <typename Sideclass, typename Subclass>
2165  std::unique_ptr<Elem>
2166  simple_build_side_ptr(const unsigned int i);
2167 
2171  template <typename Subclass>
2172  void simple_build_side_ptr(std::unique_ptr<Elem> & side,
2173  const unsigned int i,
2174  ElemType sidetype);
2175 
2179  template <typename Subclass, typename Mapclass>
2180  void simple_side_ptr(std::unique_ptr<Elem> & side,
2181  const unsigned int i,
2182  ElemType sidetype);
2183 
2187  template <typename Edgeclass, typename Subclass>
2188  std::unique_ptr<Elem>
2189  simple_build_edge_ptr(const unsigned int i);
2190 
2194  template <typename Subclass>
2195  void simple_build_edge_ptr(std::unique_ptr<Elem> & edge,
2196  const unsigned int i,
2197  ElemType edgetype);
2198 
2199 
2200 #ifdef LIBMESH_ENABLE_AMR
2201 
2207  virtual
2208  std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> &
2210  {
2211  static std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> c;
2212  libmesh_error();
2213  return c;
2214  }
2215 
2221  virtual
2222  std::vector<std::vector<std::vector<signed char>>> &
2224  {
2225  static std::vector<std::vector<std::vector<signed char>>> c;
2226  libmesh_error();
2227  return c;
2228  }
2229 
2230 #endif // LIBMESH_ENABLE_AMR
2231 
2232 public:
2233 
2238  void nullify_neighbors ();
2239 
2240 protected:
2241 
2246 
2252 
2253 #ifdef LIBMESH_ENABLE_AMR
2254 
2261  std::unique_ptr<Elem *[]> _children;
2262 #endif
2263 
2268 
2269 #ifdef LIBMESH_ENABLE_AMR
2270 
2274  unsigned char _rflag;
2275 
2280  unsigned char _pflag;
2281 
2290  unsigned char _p_level;
2291 #endif
2292 
2297  unsigned char _map_type;
2298 
2303  unsigned char _map_data;
2304 };
2305 
2306 
2307 
2308 // ------------------------------------------------------------
2309 // Elem helper classes
2310 //
2311 class
2313 {
2314 public:
2315  NodeRefIter (Node * const * nodepp) : PointerToPointerIter<Node>(nodepp) {}
2316 };
2317 
2318 
2319 class
2321 {
2322 public:
2323  ConstNodeRefIter (const Node * const * nodepp) : PointerToPointerIter<const Node>(nodepp) {}
2324 };
2325 
2326 
2327 #ifdef LIBMESH_ENABLE_AMR
2328 class
2330 {
2331 public:
2332  ChildRefIter (Elem * const * childpp) : PointerToPointerIter<Elem>(childpp) {}
2333 };
2334 
2335 
2336 class
2338 {
2339 public:
2340  ConstChildRefIter (const Elem * const * childpp) : PointerToPointerIter<const Elem>(childpp) {}
2341 };
2342 
2343 
2344 
2345 inline
2347 {
2349  return {_children.get(), _children.get() + this->n_children()};
2350 }
2351 
2352 
2353 inline
2355 {
2357  return {_children.get(), _children.get() + this->n_children()};
2358 }
2359 #endif // LIBMESH_ENABLE_AMR
2360 
2361 
2362 
2363 
2364 // ------------------------------------------------------------
2365 // global Elem functions
2366 
2367 inline
2368 std::ostream & operator << (std::ostream & os, const Elem & e)
2369 {
2370  e.print_info(os);
2371  return os;
2372 }
2373 
2374 
2375 // ------------------------------------------------------------
2376 // Elem class member functions
2377 inline
2378 Elem::Elem(const unsigned int nn,
2379  const unsigned int ns,
2380  Elem * p,
2381  Elem ** elemlinkdata,
2382  Node ** nodelinkdata) :
2383  _nodes(nodelinkdata),
2384  _elemlinks(elemlinkdata),
2385  _sbd_id(0),
2386 #ifdef LIBMESH_ENABLE_AMR
2387  _rflag(Elem::DO_NOTHING),
2388  _pflag(Elem::DO_NOTHING),
2389  _p_level(0),
2390 #endif
2391  _map_type(p ? p->mapping_type() : 0),
2392  _map_data(p ? p->mapping_data() : 0)
2393 {
2395 
2396  // If this ever legitimately fails we need to increase max_n_nodes
2397  libmesh_assert_less_equal(nn, max_n_nodes);
2398 
2399  // We currently only support refinement of elements into child
2400  // elements of the same type. We can't test elem->type() here,
2401  // because that's virtual and we're still in the base class
2402  // constructor, but we can at least usually verify constency with
2403  // the arguments we were handed.
2404 #ifndef NDEBUG
2405  if (p && !p->runtime_topology())
2406  {
2407  libmesh_assert_equal_to(nn, p->n_nodes());
2408  libmesh_assert_equal_to(ns, p->n_sides());
2409  }
2410 #endif
2411 
2412  // Initialize the nodes data structure if we're given a pointer to
2413  // memory for it.
2414  if (_nodes)
2415  {
2416  for (unsigned int n=0; n<nn; n++)
2417  _nodes[n] = nullptr;
2418  }
2419 
2420  // Initialize the neighbors/parent data structure
2421  // _elemlinks = new Elem *[ns+1];
2422 
2423  // Initialize the elements data structure if we're given a pointer
2424  // to memory for it. If we *weren't* given memory for it, e.g.
2425  // because a subclass like an arbitrary Polygon needs to
2426  // heap-allocate this memory, then that subclass will have to handle
2427  // this initialization too.
2428  if (_elemlinks)
2429  {
2430  _elemlinks[0] = p;
2431 
2432  for (unsigned int n=1; n<ns+1; n++)
2433  _elemlinks[n] = nullptr;
2434 
2435  // Optionally initialize data from the parent
2436  if (this->parent())
2437  {
2438  this->subdomain_id() = this->parent()->subdomain_id();
2439  this->processor_id() = this->parent()->processor_id();
2440  _map_type = this->parent()->_map_type;
2441  _map_data = this->parent()->_map_data;
2442 
2443 #ifdef LIBMESH_ENABLE_AMR
2444  this->set_p_level(this->parent()->p_level());
2445 #endif
2446  }
2447  }
2448 }
2449 
2450 
2451 
2452 inline
2453 const Point & Elem::point (const unsigned int i) const
2454 {
2455  libmesh_assert_less (i, this->n_nodes());
2456  libmesh_assert(_nodes[i]);
2457  libmesh_assert_not_equal_to (_nodes[i]->id(), Node::invalid_id);
2458 
2459  return *_nodes[i];
2460 }
2461 
2462 
2463 
2464 inline
2465 Point & Elem::point (const unsigned int i)
2466 {
2467  libmesh_assert_less (i, this->n_nodes());
2468 
2469  return *_nodes[i];
2470 }
2471 
2472 
2473 
2474 inline
2475 dof_id_type Elem::node_id (const unsigned int i) const
2476 {
2477  libmesh_assert_less (i, this->n_nodes());
2478  libmesh_assert(_nodes[i]);
2479  libmesh_assert_not_equal_to (_nodes[i]->id(), Node::invalid_id);
2480 
2481  return _nodes[i]->id();
2482 }
2483 
2484 
2485 
2486 inline
2487 unsigned int Elem::local_node (const dof_id_type i) const
2488 {
2489  for (auto n : make_range(this->n_nodes()))
2490  if (this->node_id(n) == i)
2491  return n;
2492 
2493  return libMesh::invalid_uint;
2494 }
2495 
2496 
2497 
2498 inline
2499 const Node * const * Elem::get_nodes () const
2500 {
2501  return _nodes;
2502 }
2503 
2504 
2505 
2506 inline
2507 const Node * Elem::node_ptr (const unsigned int i) const
2508 {
2509  libmesh_assert_less (i, this->n_nodes());
2510  libmesh_assert(_nodes[i]);
2511 
2512  return _nodes[i];
2513 }
2514 
2515 
2516 
2517 inline
2518 Node * Elem::node_ptr (const unsigned int i)
2519 {
2520  libmesh_assert_less (i, this->n_nodes());
2521  libmesh_assert(_nodes[i]);
2522 
2523  return _nodes[i];
2524 }
2525 
2526 
2527 
2528 inline
2529 const Node & Elem::node_ref (const unsigned int i) const
2530 {
2531  return *this->node_ptr(i);
2532 }
2533 
2534 
2535 
2536 inline
2537 Node & Elem::node_ref (const unsigned int i)
2538 {
2539  return *this->node_ptr(i);
2540 }
2541 
2542 
2543 
2544 inline
2545 unsigned int Elem::get_node_index (const Node * node_ptr) const
2546 {
2547  for (auto n : make_range(this->n_nodes()))
2548  if (this->_nodes[n] == node_ptr)
2549  return n;
2550 
2551  return libMesh::invalid_uint;
2552 }
2553 
2554 
2555 
2556 #ifdef LIBMESH_ENABLE_DEPRECATED
2557 inline
2558 Node * & Elem::set_node (const unsigned int i)
2559 {
2560  libmesh_assert_less (i, this->n_nodes());
2561 
2562  libmesh_deprecated();
2563 
2564  return _nodes[i];
2565 }
2566 #endif // LIBMESH_ENABLE_DEPRECATED
2567 
2568 
2569 
2570 inline
2571 void Elem::set_node (const unsigned int i,
2572  Node * node)
2573 {
2574  libmesh_assert_less (i, this->n_nodes());
2575 
2576  _nodes[i] = node;
2577 }
2578 
2579 
2580 
2581 inline
2583 {
2584  return _sbd_id;
2585 }
2586 
2587 
2588 
2589 inline
2591 {
2592  return _sbd_id;
2593 }
2594 
2595 
2596 
2597 inline
2598 const Elem * Elem::neighbor_ptr (unsigned int i) const
2599 {
2600  libmesh_assert_less (i, this->n_neighbors());
2601 
2602  return _elemlinks[i+1];
2603 }
2604 
2605 
2606 
2607 inline
2608 Elem * Elem::neighbor_ptr (unsigned int i)
2609 {
2610  libmesh_assert_less (i, this->n_neighbors());
2611 
2612  return _elemlinks[i+1];
2613 }
2614 
2615 
2616 
2617 inline
2618 void Elem::set_neighbor (const unsigned int i, Elem * n)
2619 {
2620  libmesh_assert_less (i, this->n_neighbors());
2621 
2622  _elemlinks[i+1] = n;
2623 }
2624 
2625 
2626 
2627 inline
2628 bool Elem::has_neighbor (const Elem * elem) const
2629 {
2630  for (auto n : this->neighbor_ptr_range())
2631  if (n == elem)
2632  return true;
2633 
2634  return false;
2635 }
2636 
2637 
2638 
2639 inline
2641 {
2642  for (auto n : elem->neighbor_ptr_range())
2643  if (n && n->parent() == this)
2644  return n;
2645 
2646  return nullptr;
2647 }
2648 
2649 
2650 
2651 inline
2652 const Elem * Elem::child_neighbor (const Elem * elem) const
2653 {
2654  for (auto n : elem->neighbor_ptr_range())
2655  if (n && n->parent() == this)
2656  return n;
2657 
2658  return nullptr;
2659 }
2660 
2661 
2662 
2663 inline
2666 {
2667  return {_nodes, _nodes+this->n_nodes()};
2668 }
2669 
2670 
2671 
2672 inline
2675 {
2676  return {_nodes, _nodes+this->n_nodes()};
2677 }
2678 
2679 
2680 
2681 inline
2684 {
2685  return {0, cast_int<unsigned short>(this->n_nodes())};
2686 }
2687 
2688 
2689 
2690 inline
2693 {
2694  return {0, cast_int<unsigned short>(this->n_edges())};
2695 }
2696 
2697 
2698 
2699 inline
2702 {
2703  return {0, cast_int<unsigned short>(this->n_faces())};
2704 }
2705 
2706 
2707 
2708 inline
2711 {
2712  return {0, cast_int<unsigned short>(this->n_sides())};
2713 }
2714 
2715 
2716 
2717 
2718 inline
2719 std::unique_ptr<const Elem> Elem::side_ptr (unsigned int i) const
2720 {
2721  // Call the non-const version of this function, return the result as
2722  // a std::unique_ptr<const Elem>.
2723  Elem * me = const_cast<Elem *>(this);
2724  return me->side_ptr(i);
2725 }
2726 
2727 
2728 
2729 inline
2730 void
2731 Elem::side_ptr (std::unique_ptr<const Elem> & elem,
2732  const unsigned int i) const
2733 {
2734  // Hand off to the non-const version of this function
2735  Elem * me = const_cast<Elem *>(this);
2736  std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
2737  me->side_ptr(e, i);
2738  elem = std::move(e);
2739 }
2740 
2741 
2742 
2743 inline
2744 std::unique_ptr<const Elem>
2745 Elem::build_side_ptr (const unsigned int i) const
2746 {
2747  // Call the non-const version of this function, return the result as
2748  // a std::unique_ptr<const Elem>.
2749  Elem * me = const_cast<Elem *>(this);
2750  return me->build_side_ptr(i);
2751 }
2752 
2753 
2754 
2755 inline
2756 void
2757 Elem::build_side_ptr (std::unique_ptr<const Elem> & elem,
2758  const unsigned int i) const
2759 {
2760  // Hand off to the non-const version of this function
2761  Elem * me = const_cast<Elem *>(this);
2762  std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
2763  me->build_side_ptr(e, i);
2764  elem = std::move(e);
2765 }
2766 
2767 
2768 
2769 template <typename Sideclass, typename Subclass>
2770 inline
2771 std::unique_ptr<Elem>
2772 Elem::simple_build_side_ptr (const unsigned int i)
2773 {
2774  libmesh_assert_less (i, this->n_sides());
2775 
2776  std::unique_ptr<Elem> face = std::make_unique<Sideclass>();
2777  for (auto n : face->node_index_range())
2778  face->set_node(n, this->node_ptr(Subclass::side_nodes_map[i][n]));
2779 
2780  face->set_interior_parent(this);
2781  face->inherit_data_from(*this);
2782 
2783  return face;
2784 }
2785 
2786 
2787 
2788 template <typename Subclass>
2789 inline
2790 void
2791 Elem::simple_build_side_ptr (std::unique_ptr<Elem> & side,
2792  const unsigned int i,
2793  ElemType sidetype)
2794 {
2795  libmesh_assert_less (i, this->n_sides());
2796 
2797  if (!side.get() || side->type() != sidetype)
2798  {
2799  Subclass & real_me = cast_ref<Subclass&>(*this);
2800  side = real_me.Subclass::build_side_ptr(i);
2801  }
2802  else
2803  {
2804  side->set_interior_parent(this);
2805  side->inherit_data_from(*this);
2806  for (auto n : side->node_index_range())
2807  side->set_node(n, this->node_ptr(Subclass::side_nodes_map[i][n]));
2808  }
2809 }
2810 
2811 
2812 
2813 template <typename Subclass, typename Mapclass>
2814 inline
2815 void
2816 Elem::simple_side_ptr (std::unique_ptr<Elem> & side,
2817  const unsigned int i,
2818  ElemType sidetype)
2819 {
2820  libmesh_assert_less (i, this->n_sides());
2821 
2822  if (!side.get() || side->type() != sidetype)
2823  {
2824  Subclass & real_me = cast_ref<Subclass&>(*this);
2825  side = real_me.Subclass::side_ptr(i);
2826  }
2827  else
2828  {
2829  side->subdomain_id() = this->subdomain_id();
2830 
2831  for (auto n : side->node_index_range())
2832  side->set_node(n, this->node_ptr(Mapclass::side_nodes_map[i][n]));
2833  }
2834 }
2835 
2836 
2837 
2838 inline
2839 std::unique_ptr<const Elem>
2840 Elem::build_edge_ptr (const unsigned int i) const
2841 {
2842  // Call the non-const version of this function, return the result as
2843  // a std::unique_ptr<const Elem>.
2844  Elem * me = const_cast<Elem *>(this);
2845  return me->build_edge_ptr(i);
2846 }
2847 
2848 
2849 
2850 inline
2851 void
2852 Elem::build_edge_ptr (std::unique_ptr<const Elem> & elem,
2853  const unsigned int i) const
2854 {
2855  // Hand off to the non-const version of this function
2856  Elem * me = const_cast<Elem *>(this);
2857  std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
2858  me->build_edge_ptr(e, i);
2859  elem = std::move(e);
2860 }
2861 
2862 
2863 template <typename Edgeclass, typename Subclass>
2864 inline
2865 std::unique_ptr<Elem>
2866 Elem::simple_build_edge_ptr (const unsigned int i)
2867 {
2868  libmesh_assert_less (i, this->n_edges());
2869 
2870  std::unique_ptr<Elem> edge = std::make_unique<Edgeclass>();
2871 
2872  for (auto n : edge->node_index_range())
2873  edge->set_node(n, this->node_ptr(Subclass::edge_nodes_map[i][n]));
2874 
2875  edge->set_interior_parent(this);
2876  edge->inherit_data_from(*this);
2877 
2878  return edge;
2879 }
2880 
2881 
2882 
2883 
2884 template <typename Subclass>
2885 inline
2886 void
2887 Elem::simple_build_edge_ptr (std::unique_ptr<Elem> & edge,
2888  const unsigned int i,
2889  ElemType edgetype)
2890 {
2891  libmesh_assert_less (i, this->n_edges());
2892 
2893  if (!edge.get() || edge->type() != edgetype)
2894  {
2895  Subclass & real_me = cast_ref<Subclass&>(*this);
2896  edge = real_me.Subclass::build_edge_ptr(i);
2897  }
2898  else
2899  {
2900  edge->inherit_data_from(*this);
2901  for (auto n : edge->node_index_range())
2902  edge->set_node(n, this->node_ptr(Subclass::edge_nodes_map[i][n]));
2903  }
2904 }
2905 
2906 
2907 
2908 inline
2909 bool Elem::on_boundary () const
2910 {
2911  // By convention, the element is on the boundary
2912  // if it has a nullptr neighbor.
2913  return this->has_neighbor(nullptr);
2914 }
2915 
2916 
2917 
2918 inline
2919 unsigned int Elem::which_neighbor_am_i (const Elem * e) const
2920 {
2921  libmesh_assert(e);
2922 
2923  const Elem * eparent = e;
2924 
2925  while (eparent->level() > this->level())
2926  {
2927  eparent = eparent->parent();
2928  libmesh_assert(eparent);
2929  }
2930 
2931  for (auto s : make_range(this->n_sides()))
2932  if (this->neighbor_ptr(s) == eparent)
2933  return s;
2934 
2935  return libMesh::invalid_uint;
2936 }
2937 
2938 
2939 
2940 inline
2941 bool Elem::active() const
2942 {
2943 #ifdef LIBMESH_ENABLE_AMR
2944  if ((this->refinement_flag() == INACTIVE) ||
2945  (this->refinement_flag() == COARSEN_INACTIVE))
2946  return false;
2947  else
2948  return true;
2949 #else
2950  return true;
2951 #endif
2952 }
2953 
2954 
2955 
2956 
2957 
2958 inline
2959 bool Elem::subactive() const
2960 {
2961 #ifdef LIBMESH_ENABLE_AMR
2962  if (this->active())
2963  return false;
2964  if (!this->has_children())
2965  return true;
2966  for (const Elem * my_ancestor = this->parent();
2967  my_ancestor != nullptr;
2968  my_ancestor = my_ancestor->parent())
2969  if (my_ancestor->active())
2970  return true;
2971 #endif
2972 
2973  return false;
2974 }
2975 
2976 
2977 
2978 inline
2980 {
2981 #ifdef LIBMESH_ENABLE_AMR
2982  if (!_children)
2983  return false;
2984  else
2985  return true;
2986 #else
2987  return false;
2988 #endif
2989 }
2990 
2991 
2992 inline
2994 {
2995 #ifdef LIBMESH_ENABLE_AMR
2996  if (!_children)
2997  return false;
2998  else
2999  for (auto & c : child_ref_range())
3000  if (c.has_children())
3001  return true;
3002 #endif
3003  return false;
3004 }
3005 
3006 
3007 
3008 inline
3010 #ifdef LIBMESH_ENABLE_AMR
3011  descendant
3012 #endif
3013  ) const
3014 {
3015 #ifdef LIBMESH_ENABLE_AMR
3016  const Elem * e = descendant;
3017  while (e)
3018  {
3019  if (this == e)
3020  return true;
3021  e = e->parent();
3022  }
3023 #endif
3024  return false;
3025 }
3026 
3027 
3028 
3029 inline
3030 const Elem * Elem::parent () const
3031 {
3032  return _elemlinks[0];
3033 }
3034 
3035 
3036 
3037 inline
3039 {
3040  return _elemlinks[0];
3041 }
3042 
3043 
3044 
3045 inline
3047 {
3048  // We no longer support using parent() as interior_parent()
3049  libmesh_assert_equal_to(this->dim(), p ? p->dim() : this->dim());
3050  _elemlinks[0] = p;
3051 }
3052 
3053 
3054 
3055 inline
3056 const Elem * Elem::top_parent () const
3057 {
3058  const Elem * tp = this;
3059 
3060  // Keep getting the element's parent
3061  // until that parent is at level-0
3062  while (tp->parent() != nullptr)
3063  tp = tp->parent();
3064 
3065  libmesh_assert(tp);
3066  libmesh_assert_equal_to (tp->level(), 0);
3067 
3068  return tp;
3069 }
3070 
3071 
3072 
3073 inline
3074 unsigned int Elem::level() const
3075 {
3076 #ifdef LIBMESH_ENABLE_AMR
3077 
3078  // if I don't have a parent I was
3079  // created directly from file
3080  // or by the user, so I am a
3081  // level-0 element
3082  if (this->parent() == nullptr)
3083  return 0;
3084 
3085  // if the parent and this element are of different
3086  // dimensionality we are at the same level as
3087  // the parent (e.g. we are the 2D side of a
3088  // 3D element)
3089  if (this->dim() != this->parent()->dim())
3090  return this->parent()->level();
3091 
3092  // otherwise we are at a level one
3093  // higher than our parent
3094  return (this->parent()->level() + 1);
3095 
3096 #else
3097 
3098  // Without AMR all elements are
3099  // at level 0.
3100  return 0;
3101 
3102 #endif
3103 }
3104 
3105 
3106 
3107 inline
3108 unsigned int Elem::p_level() const
3109 {
3110 #ifdef LIBMESH_ENABLE_AMR
3111  return _p_level;
3112 #else
3113  return 0;
3114 #endif
3115 }
3116 
3117 
3118 
3119 inline
3121 {
3122  return static_cast<ElemMappingType>(_map_type);
3123 }
3124 
3125 
3126 
3127 inline
3129 {
3130  _map_type = cast_int<unsigned char>(type);
3131 }
3132 
3133 
3134 
3135 inline
3136 unsigned char Elem::mapping_data () const
3137 {
3138  return _map_data;
3139 }
3140 
3141 
3142 
3143 inline
3144 void Elem::set_mapping_data(const unsigned char data)
3145 {
3146  _map_data = data;
3147 }
3148 
3149 
3150 
3151 #ifdef LIBMESH_ENABLE_AMR
3152 
3153 inline
3154 const Elem * Elem::raw_child_ptr (unsigned int i) const
3155 {
3156  if (!_children)
3157  return nullptr;
3158 
3159  return _children[i];
3160 }
3161 
3162 inline
3163 const Elem * Elem::child_ptr (unsigned int i) const
3164 {
3167 
3168  return _children[i];
3169 }
3170 
3171 inline
3172 Elem * Elem::child_ptr (unsigned int i)
3173 {
3176 
3177  return _children[i];
3178 }
3179 
3180 
3181 inline
3182 void Elem::set_child (unsigned int c, Elem * elem)
3183 {
3184  libmesh_assert (this->has_children());
3185 
3186  _children[c] = elem;
3187 }
3188 
3189 
3190 
3191 inline
3192 unsigned int Elem::which_child_am_i (const Elem * e) const
3193 {
3194  libmesh_assert(e);
3195  libmesh_assert (this->has_children());
3196 
3197  unsigned int nc = this->n_children();
3198  for (unsigned int c=0; c != nc; c++)
3199  if (this->child_ptr(c) == e)
3200  return c;
3201 
3202  libmesh_error_msg("ERROR: which_child_am_i() was called with a non-child!");
3203 
3204  return libMesh::invalid_uint;
3205 }
3206 
3207 
3208 
3209 inline
3211 {
3212  return static_cast<RefinementState>(_rflag);
3213 }
3214 
3215 
3216 
3217 inline
3219 {
3220  _rflag = cast_int<unsigned char>(rflag);
3221 }
3222 
3223 
3224 
3225 inline
3227 {
3228  return static_cast<RefinementState>(_pflag);
3229 }
3230 
3231 
3232 
3233 inline
3235 {
3236  if (this->p_level() == 0)
3237  libmesh_assert_not_equal_to
3238  (pflag, Elem::JUST_REFINED);
3239 
3240  _pflag = cast_int<unsigned char>(pflag);
3241 }
3242 
3243 
3244 
3245 inline
3246 unsigned int Elem::max_descendant_p_level () const
3247 {
3248  // This is undefined for subactive elements,
3249  // which have no active descendants
3250  libmesh_assert (!this->subactive());
3251  if (this->active())
3252  return this->p_level();
3253 
3254  unsigned int max_p_level = _p_level;
3255  for (auto & c : child_ref_range())
3256  max_p_level = std::max(max_p_level,
3257  c.max_descendant_p_level());
3258  return max_p_level;
3259 }
3260 
3261 
3262 
3263 inline
3264 void Elem::hack_p_level(unsigned int p)
3265 {
3266  if (p == 0)
3267  libmesh_assert_not_equal_to
3269 
3270  _p_level = cast_int<unsigned char>(p);
3271 }
3272 
3273 
3274 inline
3276  RefinementState pflag)
3277 {
3278  _pflag = cast_int<unsigned char>(pflag);
3279  this->hack_p_level(p);
3280 }
3281 
3282 #endif // ifdef LIBMESH_ENABLE_AMR
3283 
3284 
3285 inline
3286 void Elem::orient(BoundaryInfo * boundary_info)
3287 {
3288  if (this->is_flipped())
3289  this->flip(boundary_info);
3290 }
3291 
3292 
3293 inline
3295 {
3296  return n0;
3297 }
3298 
3299 
3300 
3301 inline
3303  dof_id_type n1)
3304 {
3305  // Order the two so that n0 < n1
3306  if (n0 > n1) std::swap (n0, n1);
3307 
3308  return Utility::hashword2(n0, n1);
3309 }
3310 
3311 
3312 
3313 inline
3315  dof_id_type n1,
3316  dof_id_type n2)
3317 {
3318  std::array<dof_id_type, 3> array = {{n0, n1, n2}};
3319  std::sort(array.begin(), array.end());
3320  return Utility::hashword(array);
3321 }
3322 
3323 
3324 
3325 inline
3327  dof_id_type n1,
3328  dof_id_type n2,
3329  dof_id_type n3)
3330 {
3331  std::array<dof_id_type, 4> array = {{n0, n1, n2, n3}};
3332  std::sort(array.begin(), array.end());
3333  return Utility::hashword(array);
3334 }
3335 
3336 
3337 
3338 inline
3339 void Elem::inherit_data_from (const Elem & src)
3340 {
3341  this->set_mapping_type(src.mapping_type());
3342  this->set_mapping_data(src.mapping_data());
3343  this->subdomain_id() = src.subdomain_id();
3344  this->processor_id(src.processor_id());
3345 #ifdef LIBMESH_ENABLE_AMR
3346  this->set_p_level(src.p_level());
3347 #endif
3348 }
3349 
3350 
3351 
3356 {
3357 public:
3358  // Constructor with arguments.
3359  SideIter(const unsigned int side_number,
3360  Elem * parent)
3361  : _side(),
3362  _side_ptr(nullptr),
3363  _parent(parent),
3364  _side_number(side_number)
3365  {}
3366 
3367 
3368  // Empty constructor.
3370  : _side(),
3371  _side_ptr(nullptr),
3372  _parent(nullptr),
3374  {}
3375 
3376 
3377  // Copy constructor
3378  SideIter(const SideIter & other)
3379  : _side(),
3380  _side_ptr(nullptr),
3381  _parent(other._parent),
3382  _side_number(other._side_number)
3383  {}
3384 
3385 
3386  // op=
3387  SideIter & operator=(const SideIter & other)
3388  {
3389  this->_parent = other._parent;
3390  this->_side_number = other._side_number;
3391  return *this;
3392  }
3393 
3394  // unary op*
3395  Elem *& operator*() const
3396  {
3397  // Set the std::unique_ptr
3398  this->_update_side_ptr();
3399 
3400  // Return a reference to _side_ptr
3401  return this->_side_ptr;
3402  }
3403 
3404  // op++
3406  {
3407  ++_side_number;
3408  return *this;
3409  }
3410 
3411  // op== Two side iterators are equal if they have
3412  // the same side number and the same parent element.
3413  bool operator == (const SideIter & other) const
3414  {
3415  return (this->_side_number == other._side_number &&
3416  this->_parent == other._parent);
3417  }
3418 
3419 
3420  // Consults the parent Elem to determine if the side
3421  // is a boundary side. Note: currently side N is a
3422  // boundary side if neighbor N is nullptr. Be careful,
3423  // this could possibly change in the future?
3424  bool side_on_boundary() const
3425  {
3426  return this->_parent->neighbor_ptr(_side_number) == nullptr;
3427  }
3428 
3429 private:
3430  // Update the _side pointer by building the correct side.
3431  // This has to be called before dereferencing.
3432  void _update_side_ptr() const
3433  {
3434  // Construct new side, store in std::unique_ptr
3435  this->_side = this->_parent->build_side_ptr(this->_side_number);
3436 
3437  // Also set our internal naked pointer. Memory is still owned
3438  // by the std::unique_ptr.
3439  this->_side_ptr = _side.get();
3440  }
3441 
3442  // std::unique_ptr to the actual side, handles memory management for
3443  // the sides which are created during the course of iteration.
3444  mutable std::unique_ptr<Elem> _side;
3445 
3446  // Raw pointer needed to facilitate passing back to the user a
3447  // reference to a non-temporary raw pointer in order to conform to
3448  // the variant_filter_iterator interface. It points to the same
3449  // thing the std::unique_ptr "_side" above holds. What happens if the user
3450  // calls delete on the pointer passed back? Well, this is an issue
3451  // which is not addressed by the iterators in libMesh. Basically it
3452  // is a bad idea to ever call delete on an iterator from the library.
3453  mutable Elem * _side_ptr;
3454 
3455  // Pointer to the parent Elem class which generated this iterator
3457 
3458  // A counter variable which keeps track of the side number
3459  unsigned int _side_number;
3460 };
3461 
3462 
3463 
3464 
3465 
3466 
3467 // Private implementation functions in the Elem class for the side iterators.
3468 // They have to come after the definition of the SideIter class.
3469 inline
3471 {
3472  return SideIter(0, this);
3473 }
3474 
3475 
3476 
3477 inline
3479 {
3480  return SideIter(this->n_neighbors(), this);
3481 }
3482 
3483 
3484 
3485 
3489 struct
3491 {
3492  // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
3493  template <typename PredType, typename IterType>
3494  side_iterator (const IterType & d,
3495  const IterType & e,
3496  const PredType & p ) :
3498 };
3499 
3500 
3501 
3502 inline
3504 {
3505  return {_elemlinks+1, _elemlinks + 1 + this->n_neighbors()};
3506 }
3507 
3508 
3509 inline
3511 {
3512  return {_elemlinks+1, _elemlinks + 1 + this->n_neighbors()};
3513 }
3514 
3515 } // namespace libMesh
3516 
3517 
3518 // Helper function for default caches in Elem subclasses
3519 
3520 #define LIBMESH_ENABLE_TOPOLOGY_CACHES \
3521  virtual \
3522  std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> & \
3523  _get_bracketing_node_cache() const override \
3524  { \
3525  static std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> c; \
3526  return c; \
3527  } \
3528  \
3529  virtual \
3530  std::vector<std::vector<std::vector<signed char>>> & \
3531  _get_parent_indices_cache() const override \
3532  { \
3533  static std::vector<std::vector<std::vector<signed char>>> c; \
3534  return c; \
3535  }
3536 
3537 
3538 
3539 
3540 
3541 
3542 #endif // LIBMESH_ELEM_H
virtual Point true_centroid() const
Definition: elem.C:594
void active_family_tree_by_topological_neighbor(std::vector< const Elem *> &family, const Elem *neighbor, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb, bool reset=true) const
Same as the active_family_tree_by_neighbor() member, but the neighbor here may be a topological (e...
Definition: elem.C:2279
bool has_neighbor(const Elem *elem) const
Definition: elem.h:2628
void set_p_level(const unsigned int p)
Sets the value of the p-refinement level for the element.
unsigned char mapping_data() const
Definition: elem.h:3136
virtual bool is_vertex_on_parent(unsigned int c, unsigned int n) const
Definition: elem.C:3487
std::unique_ptr< Elem > simple_build_side_ptr(const unsigned int i)
An implementation for simple (all sides equal) elements.
Definition: elem.h:2772
static const Order type_to_default_order_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the default approximation order of...
Definition: elem.h:991
RefinementState refinement_flag() const
Definition: elem.h:3210
ElemType
Defines an enum for geometric element types.
The SimpleRange templated class is intended to make it easy to construct ranges from pairs of iterato...
Definition: simple_range.h:36
void swap2boundaryedges(unsigned short e1, unsigned short e2, BoundaryInfo *boundary_info) const
Swaps two edges in boundary_info, if it is non-null.
Definition: elem.C:3550
virtual Point quasicircumcenter() const
Definition: elem.h:1060
unsigned char _map_type
Mapping function type; currently either 0 (LAGRANGE) or 1 (RATIONAL_BERNSTEIN).
Definition: elem.h:2297
unsigned char _map_data
Mapping function data; currently used when needed to store the RATIONAL_BERNSTEIN nodal weight data i...
Definition: elem.h:2303
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:1731
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i, bool proxy)
Definition: elem.h:927
const Elem * parent() const
Definition: elem.h:3030
virtual const std::vector< std::pair< dof_id_type, dof_id_type > > bracketing_nodes(unsigned int c, unsigned int n) const
Definition: elem.C:2657
Order
defines an enum for polynomial orders.
Definition: enum_order.h:40
void print_info(std::ostream &os=libMesh::out) const
Prints relevant information about the element.
Definition: elem.C:2915
void active_family_tree_by_side(std::vector< const Elem *> &family, unsigned int side, bool reset=true) const
Same as the active_family_tree() member, but only adds elements which are next to side...
Definition: elem.C:2167
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:2558
A Node is like a Point, but with more information.
Definition: node.h:52
bool is_ancestor_of(const Elem *descendant) const
Definition: elem.h:3009
Node ** _nodes
Pointers to the nodes we are connected to.
Definition: elem.h:2245
Elem * child_neighbor(Elem *elem)
Definition: elem.h:2640
virtual std::vector< unsigned int > sides_on_edge(const unsigned int) const =0
static ElemType complete_order_equivalent_type(const ElemType et)
Definition: elem.C:3319
Predicates::multi_predicate Predicate
Useful iterator typedefs.
Definition: elem.h:1860
virtual Order default_side_order() const
Definition: elem.h:1012
virtual Point origin() const
Definition: elem.h:1914
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:310
void set_parent(Elem *p)
Sets the pointer to the element&#39;s parent.
Definition: elem.h:3046
unsigned int get_node_index(const Node *node_ptr) const
Definition: elem.h:2545
std::string get_info() const
Prints relevant information about the element to a string.
Definition: elem.C:2923
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:685
Original Authors: Corwin Joy * Michael Gradman [email protected] * [email protected] Caminus, Suite 1150, Two Allen Center, 1200 Smith Street, Houston, TX 77002 This class is an extension of variant_bidirectional_iterator to a filter_iterator similar to boost&#39;s.
const Elem * interior_parent() const
Definition: elem.C:1186
const Elem * topological_neighbor(const unsigned int i, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
Definition: elem.C:1313
void orient(BoundaryInfo *boundary_info)
Flips the element (by swapping node and neighbor pointers) to have a mapping Jacobian of opposite sig...
Definition: elem.h:3286
void set_mapping_type(const ElemMappingType type)
Sets the value of the mapping type for the element.
Definition: elem.h:3128
virtual bool is_face(const unsigned int i) const =0
bool is_semilocal(const processor_id_type my_pid) const
Definition: elem.C:855
unsigned char _pflag
p refinement flag.
Definition: elem.h:2280
virtual ElemType side_type(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:53
unsigned char _p_level
p refinement level - the difference between the polynomial degree on this element and the minimum pol...
Definition: elem.h:2290
IntRange< unsigned short > side_index_range() const
Definition: elem.h:2710
void contract()
Contract an active element, i.e.
void libmesh_assert_valid_node_pointers() const
Checks for a valid id and pointers to nodes with valid ids on this element.
Definition: elem.C:1371
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i)=0
virtual dof_id_type key() const
Definition: elem.C:753
static constexpr Real TOLERANCE
const Elem * top_parent() const
Definition: elem.h:3056
We&#39;re using a class instead of a typedef to allow forward declarations and future flexibility...
virtual bool runtime_topology() const
Definition: elem.h:259
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:2051
unsigned int which_side_am_i(const Elem *e) const
This function tells you which side the boundary element e is.
Definition: elem.C:870
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:3359
virtual ~Elem()=default
Destructor.
RefinementState p_refinement_flag() const
Definition: elem.h:3226
IOPackage
libMesh interfaces with several different software packages for the purposes of creating, reading, and writing mesh files.
virtual dof_id_type low_order_key(const unsigned int s) const =0
virtual bool has_affine_map() const
Definition: elem.h:1197
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:1172
static const unsigned int type_to_dim_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the geometric dimension of the ele...
Definition: elem.h:635
void family_tree_by_subneighbor(std::vector< const Elem *> &family, const Elem *neighbor, const Elem *subneighbor, bool reset=true) const
Same as the family_tree() member, but only adds elements which are next to subneighbor.
Definition: elem.C:2221
bool operator==(const SideIter &other) const
Definition: elem.h:3413
void family_tree(std::vector< const Elem *> &family, bool reset=true) const
Fills the vector family with the children of this element, recursively.
Definition: elem.C:2101
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
void add_child(Elem *elem)
Adds a child pointer to the array of children of this element.
Definition: elem.C:2044
virtual BoundingBox loose_bounding_box() const
Definition: elem.C:3465
SideIter & operator=(const SideIter &other)
Definition: elem.h:3387
virtual bool on_reference_element(const Point &p, const Real eps=TOLERANCE) const =0
unsigned int min_new_p_level_by_neighbor(const Elem *neighbor, unsigned int current_min) const
Definition: elem.C:2352
RefinementState
Enumeration of possible element refinement states.
Definition: elem.h:1452
void set_refinement_flag(const RefinementState rflag)
Sets the value of the refinement flag for the element.
Definition: elem.h:3218
std::ostream & operator<<(std::ostream &os, const OrderWrapper &order)
Overload stream operators.
Definition: fe_type.h:182
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
void active_family_tree(std::vector< const Elem *> &active_family, bool reset=true) const
Same as the family_tree() member, but only adds the active children.
Definition: elem.C:2133
void swap2boundarysides(unsigned short s1, unsigned short s2, BoundaryInfo *boundary_info) const
Swaps two sides in boundary_info, if it is non-null.
Definition: elem.C:3534
virtual unsigned int n_children() const =0
ChildRefIter(Elem *const *childpp)
Definition: elem.h:2332
unsigned int _side_number
Definition: elem.h:3459
unsigned int p_level() const
Definition: elem.h:3108
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:1083
side_iterator boundary_sides_end()
Definition: elem.C:3420
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:1533
The libMesh namespace provides an interface to certain functionality in the library.
SideIter & operator++()
Definition: elem.h:3405
virtual Real hmax() const
Definition: elem.C:722
virtual bool is_linear() const
Definition: elem.h:1213
unsigned int min_p_level_by_neighbor(const Elem *neighbor, unsigned int current_min) const
Definition: elem.C:2323
virtual bool is_flipped() const =0
void set_interior_parent(Elem *p)
Sets the pointer to the element&#39;s interior_parent.
Definition: elem.C:1248
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:650
bool contains_vertex_of(const Elem *e, bool mesh_connection=false) const
Definition: elem.C:934
uint8_t processor_id_type
Definition: id_types.h:104
This is the MeshBase class.
Definition: mesh_base.h:75
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
Definition: elem.h:2346
bool ancestor() const
Definition: elem.C:2010
bool has_topological_neighbor(const Elem *elem, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
Definition: elem.C:1350
IntRange< unsigned short > edge_index_range() const
Definition: elem.h:2692
void swap3neighbors(unsigned int n1, unsigned int n2, unsigned int n3)
Swaps three neighbor_ptrs, "rotating" them.
Definition: elem.h:2133
side_iterator boundary_sides_begin()
Iterator accessor functions.
Definition: elem.C:3411
virtual Real embedding_matrix(const unsigned int child_num, const unsigned int child_node_num, const unsigned int parent_node_num) const =0
Elem *& operator*() const
Definition: elem.h:3395
virtual void refine(MeshRefinement &mesh_refinement)
Refine the element.
const Elem *const * ConstNeighborPtrIter
Definition: elem.h:334
virtual bool is_node_on_edge(const unsigned int n, const unsigned int e) const =0
uint32_t hashword(const uint32_t *k, size_t length, uint32_t initval=0)
The hashword function takes an array of uint32_t&#39;s of length &#39;length&#39; and computes a single key from ...
Definition: hashword.h:158
void swap3nodes(unsigned int n1, unsigned int n2, unsigned int n3)
Swaps three node_ptrs, "rotating" them.
Definition: elem.h:2124
void family_tree_by_side(std::vector< const Elem *> &family, unsigned int side, bool reset=true) const
Same as the family_tree() member, but only adds elements which are next to side.
Definition: elem.C:2149
void replace_child(Elem *elem, unsigned int c)
Replaces the child pointer at the specified index in the child array.
Definition: elem.C:2090
void swap4nodes(unsigned int n1, unsigned int n2, unsigned int n3, unsigned int n4)
Swaps four node_ptrs, "rotating" them.
Definition: elem.h:2143
void total_family_tree_by_subneighbor(std::vector< const Elem *> &family, const Elem *neighbor, const Elem *subneighbor, bool reset=true) const
Same as the family_tree_by_subneighbor() member, but also adds any subactive descendants.
Definition: elem.C:2241
static const subdomain_id_type invalid_subdomain_id
A static integral constant representing an invalid subdomain id.
Definition: elem.h:251
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:1639
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:2223
Elem *const * NeighborPtrIter
Nested "classes" for use iterating over all neighbors of an element.
Definition: elem.h:333
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const
Definition: elem.C:2751
Implements (adaptive) mesh refinement algorithms for a MeshBase.
virtual Order supported_nodal_order() const
Definition: elem.h:1005
Real length(const unsigned int n1, const unsigned int n2) const
Definition: elem.C:742
IntRange< unsigned short > face_index_range() const
Definition: elem.h:2701
ElemMappingType mapping_type() const
Definition: elem.h:3120
Elem & operator=(const Elem &)=delete
void make_links_to_me_local(unsigned int n, unsigned int neighbor_side)
Resets the neighbor_side pointers of our nth neighbor (and its descendants, if appropriate) to point ...
Definition: elem.C:1455
void swap2nodes(unsigned int n1, unsigned int n2)
Swaps two node_ptrs.
Definition: elem.h:2092
const Node & node_ref(const unsigned int i) const
Definition: elem.h:2529
dof_id_type id() const
Definition: dof_object.h:828
virtual Real hmin() const
Definition: elem.C:702
virtual unsigned int n_nodes() const =0
static const processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
Definition: dof_object.h:493
virtual unsigned int local_side_node(unsigned int side, unsigned int side_node) const =0
unsigned int which_node_am_i(unsigned int side, unsigned int side_node) const
This function is deprecated, call local_side_node(side, side_node) instead.
Definition: elem.C:924
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:743
bool contains_edge_of(const Elem *e) const
Definition: elem.C:972
unsigned int which_neighbor_am_i(const Elem *e) const
This function tells you which neighbor e is.
Definition: elem.h:2919
virtual unsigned int as_parent_node(unsigned int c, unsigned int n) const
Definition: elem.C:2386
virtual std::vector< unsigned int > edges_adjacent_to_node(const unsigned int) const =0
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition: elem.C:444
virtual unsigned int opposite_node(const unsigned int n, const unsigned int s) const
Definition: elem.C:3519
virtual std::pair< unsigned short int, unsigned short int > second_order_child_vertex(const unsigned int n) const
Definition: elem.C:3058
static constexpr bool infinite()
Definition: elem.h:1918
Elem ** _elemlinks
Pointers to this element&#39;s parent and neighbors, and for lower-dimensional elements&#39; interior_parent...
Definition: elem.h:2251
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:993
void set_mapping_data(const unsigned char data)
Sets the value of the mapping data for the element.
Definition: elem.h:3144
virtual unsigned int local_edge_node(unsigned int edge, unsigned int edge_node) const =0
Similar to Elem::local_side_node(), but instead of a side id, takes an edge id and a node id on that ...
The definition of the struct used for iterating over sides.
Definition: elem.h:3489
const Node *const * get_nodes() const
Definition: elem.h:2499
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:2788
void _update_side_ptr() const
Definition: elem.h:3432
bool side_on_boundary() const
Definition: elem.h:3424
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
Definition: boundary_info.h:57
libmesh_assert(ctx)
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
const Elem * reference_elem() const
Definition: elem.C:570
void libmesh_assert_valid_neighbors() const
Checks for consistent neighbor links on this element.
Definition: elem.C:1383
virtual bool is_remote() const
Definition: elem.h:603
This is the base class for point locators.
virtual unsigned int n_edges() const =0
ElemQuality
Defines an enum for element quality metrics.
virtual std::unique_ptr< Elem > disconnected_clone() const
Definition: elem.C:412
virtual unsigned int n_second_order_adjacent_vertices(const unsigned int n) const
Definition: elem.C:3040
void hack_p_level_and_refinement_flag(const unsigned int p, RefinementState pflag)
Sets the value of the p-refinement level for the element without altering the p-level of its ancestor...
Definition: elem.h:3275
SideIter _last_side()
Definition: elem.h:3478
static constexpr Real affine_tol
Default tolerance to use in has_affine_map().
Definition: elem.h:2061
bool positive_edge_orientation(const unsigned int i) const
Definition: elem.C:3589
void set_neighbor(const unsigned int i, Elem *n)
Assigns n as the neighbor.
Definition: elem.h:2618
This class implements reference counting.
subdomain_id_type _sbd_id
The subdomain to which this element belongs.
Definition: elem.h:2267
static ElemType second_order_equivalent_type(const ElemType et, const bool full_ordered=true)
Definition: elem.C:3135
bool on_boundary() const
Definition: elem.h:2909
Elem(const unsigned int n_nodes, const unsigned int n_sides, Elem *parent, Elem **elemlinkdata, Node **nodelinkdata)
Constructor.
Definition: elem.h:2378
unsigned int which_child_am_i(const Elem *e) const
Definition: elem.h:3192
unsigned int max_descendant_p_level() const
Definition: elem.h:3246
unsigned char _rflag
h refinement flag.
Definition: elem.h:2274
virtual void flip(BoundaryInfo *boundary_info)=0
Flips the element (by swapping node and neighbor pointers) to have a mapping Jacobian of opposite sig...
void swap2neighbors(unsigned int n1, unsigned int n2)
Swaps two neighbor_ptrs.
Definition: elem.h:2102
void active_family_tree_by_neighbor(std::vector< const Elem *> &family, const Elem *neighbor, bool reset=true) const
Same as the active_family_tree() member, but only adds elements which are next to neighbor...
Definition: elem.C:2261
virtual std::vector< unsigned int > nodes_on_edge(const unsigned int) const =0
void total_family_tree_by_neighbor(std::vector< const Elem *> &family, const Elem *neighbor, bool reset=true) const
Same as the family_tree_by_neighbor() member, but also adds any subactive descendants.
Definition: elem.C:2203
SimpleRange< NodeRefIter > node_ref_range()
Returns a range with all nodes of an element, usable in range-based for loops.
Definition: elem.h:2665
Defines a Cartesian bounding box by the two corner extremum.
Definition: bounding_box.h:40
std::unique_ptr< Elem > _side
Definition: elem.h:3444
ElemMappingType
Enumeration of possible element master->physical mapping types.
ConstNodeRefIter(const Node *const *nodepp)
Definition: elem.h:2323
virtual unsigned int n_sides() const =0
bool topologically_equal(const Elem &rhs) const
Definition: elem.C:803
const Elem * neighbor_ptr(unsigned int i) const
Definition: elem.h:2598
virtual bool close_to_point(const Point &p, Real tol) const
Definition: elem.C:2776
unsigned int level() const
Definition: elem.h:3074
const Elem * raw_child_ptr(unsigned int i) const
Definition: elem.h:3154
virtual unsigned int n_vertices() const =0
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual std::unique_ptr< Elem > side_ptr(unsigned int i)=0
virtual unsigned int local_singular_node(const Point &, const Real=TOLERANCE *TOLERANCE) const
Definition: elem.h:1831
subdomain_id_type subdomain_id() const
Definition: elem.h:2582
virtual bool is_singular_node(unsigned int) const
Definition: elem.h:1838
virtual unsigned short dim() const =0
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:2507
SideIter(const SideIter &other)
Definition: elem.h:3378
void coarsen()
Coarsen the element.
virtual bool is_vertex(const unsigned int i) const =0
OStreamProxy out
virtual Point master_point(const unsigned int i) const =0
static std::unique_ptr< Elem > build_with_id(const ElemType type, dof_id_type id)
Calls the build() method above with a nullptr parent, and additionally sets the newly-created Elem&#39;s ...
Definition: elem.C:558
unsigned int n_neighbors() const
Definition: elem.h:714
virtual Real quality(const ElemQuality q) const
Definition: elem.C:1774
virtual unsigned short int second_order_adjacent_vertex(const unsigned int n, const unsigned int v) const
Definition: elem.C:3048
bool subactive() const
Definition: elem.h:2959
virtual Real volume() const
Definition: elem.C:3429
void swap4neighbors(unsigned int n1, unsigned int n2, unsigned int n3, unsigned int n4)
Swaps four neighbor_ptrs, "rotating" them.
Definition: elem.h:2153
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:140
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:215
virtual void permute(unsigned int perm_num)=0
Permutes the element (by swapping node and neighbor pointers) according to the specified index...
The DofObject defines an abstract base class for objects that have degrees of freedom associated with...
Definition: dof_object.h:54
void set_child(unsigned int c, Elem *elem)
Sets the pointer to the child for this element.
Definition: elem.h:3182
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:2993
virtual bool has_invertible_map(Real tol=TOLERANCE *TOLERANCE) const
Definition: elem.C:2881
IntRange< unsigned short > node_index_range() const
Definition: elem.h:2683
bool positive_face_orientation(const unsigned int i) const
Definition: elem.C:3598
unsigned int local_node(const dof_id_type i) const
Definition: elem.h:2487
virtual bool is_vertex_on_child(unsigned int, unsigned int n) const
Definition: elem.h:774
void nullify_neighbors()
Replaces this element with nullptr for all of its neighbors.
Definition: elem.C:3014
SimpleRange< NeighborPtrIter > neighbor_ptr_range()
Returns a range with all neighbors of an element, usable in range-based for loops.
Definition: elem.h:3503
void set_p_refinement_flag(const RefinementState pflag)
Sets the value of the p-refinement flag for the element.
Definition: elem.h:3234
virtual unsigned int n_faces() const =0
void inherit_data_from(const Elem &src)
A helper function for copying generic element data (mapping, subdomain, processor) from an element to...
Definition: elem.h:3339
virtual bool infinite() const =0
virtual std::pair< Real, Real > qual_bounds(const ElemQuality) const
Definition: elem.h:1120
void simple_side_ptr(std::unique_ptr< Elem > &side, const unsigned int i, ElemType sidetype)
An implementation for simple (all sides equal) elements.
Definition: elem.h:2816
static dof_id_type compute_key(dof_id_type n0)
Definition: elem.h:3294
virtual unsigned int n_sub_elem() const =0
void total_family_tree(std::vector< const Elem *> &family, bool reset=true) const
Same as the family_tree() member, but also adds any subactive descendants.
Definition: elem.C:2117
std::unique_ptr< const Elem > build_side_ptr(const unsigned int i, bool proxy) const
Definition: elem.h:930
void family_tree_by_neighbor(std::vector< const Elem *> &family, const Elem *neighbor, bool reset=true) const
Same as the family_tree() member, but only adds elements which are next to neighbor.
Definition: elem.C:2185
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i)=0
ConstChildRefIter(const Elem *const *childpp)
Definition: elem.h:2340
virtual Order default_order() const =0
std::unique_ptr< Elem > simple_build_edge_ptr(const unsigned int i)
An implementation for simple (all edges equal) elements.
Definition: elem.h:2866
virtual const std::vector< std::pair< unsigned char, unsigned char > > & parent_bracketing_nodes(unsigned int c, unsigned int n) const
Definition: elem.C:2454
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:2209
virtual unsigned int opposite_side(const unsigned int s) const
Definition: elem.C:3511
bool active() const
Definition: elem.h:2941
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:3264
static ElemType first_order_equivalent_type(const ElemType et)
Definition: elem.C:3066
processor_id_type processor_id() const
Definition: dof_object.h:905
virtual ElemType type() const =0
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:2475
const Point & point(const unsigned int i) const
Definition: elem.h:2453
virtual Point centroid() const
Calls Elem::vertex_average() for backwards compatibility.
Definition: elem.C:578
bool operator==(const Elem &rhs) const
Definition: elem.C:771
side_iterator(const IterType &d, const IterType &e, const PredType &p)
Definition: elem.h:3494
bool has_children() const
Definition: elem.h:2979
virtual unsigned int center_node_on_side(const unsigned short side) const
Definition: elem.C:3527
void ErrorVector unsigned int
Definition: adjoints_ex3.C:360
NodeRefIter(Node *const *nodepp)
Definition: elem.h:2315
std::unique_ptr< Elem *[]> _children
unique_ptr to array of this element&#39;s children.
Definition: elem.h:2261
virtual bool is_child_on_edge(const unsigned int c, const unsigned int e) const
Definition: elem.C:2306
virtual bool is_edge(const unsigned int i) const =0
virtual unsigned int n_permutations() const =0
Returns the number of independent permutations of element nodes - e.g.
virtual std::vector< unsigned int > nodes_on_side(const unsigned int) const =0
virtual unsigned int n_nodes_in_child(unsigned int) const
Definition: elem.h:674
Point vertex_average() const
Definition: elem.C:688
static const unsigned int max_n_nodes
The maximum number of nodes any element can contain.
Definition: elem.h:661
const Elem * child_ptr(unsigned int i) const
Definition: elem.h:3163
uint8_t dof_id_type
Definition: id_types.h:67
The definition of the protected nested SideIter class.
Definition: elem.h:3355
virtual bool is_mid_infinite_edge_node(const unsigned int) const
Definition: elem.h:1905
bool is_internal(const unsigned int i) const
Definition: elem.C:3566
SideIter _first_side()
Side iterator helper functions.
Definition: elem.h:3470