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 
245  static constexpr subdomain_id_type invalid_subdomain_id
246  = std::numeric_limits<subdomain_id_type>::max();
247 
254  virtual bool runtime_topology() const { return false; }
255 
268  const Elem * reference_elem () const;
269 
274  virtual dof_id_type key (const unsigned int s) const = 0;
275 
282  virtual dof_id_type low_order_key (const unsigned int s) const = 0;
283 
290  virtual dof_id_type key () const;
291 
298  bool operator == (const Elem & rhs) const;
299 
307  bool topologically_equal (const Elem & rhs) const;
308 
318  const Elem * neighbor_ptr (unsigned int i) const;
319 
323  Elem * neighbor_ptr (unsigned int i);
324 
328  typedef Elem * const * NeighborPtrIter;
329  typedef const Elem * const * ConstNeighborPtrIter;
330 
340 
342 
343 #ifdef LIBMESH_ENABLE_PERIODIC
344 
350  const Elem * topological_neighbor (const unsigned int i,
351  const MeshBase & mesh,
352  const PointLocatorBase & point_locator,
353  const PeriodicBoundaries * pb) const;
354 
361  Elem * topological_neighbor (const unsigned int i,
362  MeshBase & mesh,
363  const PointLocatorBase & point_locator,
364  const PeriodicBoundaries * pb);
365 
370  bool has_topological_neighbor (const Elem * elem,
371  const MeshBase & mesh,
372  const PointLocatorBase & point_locator,
373  const PeriodicBoundaries * pb) const;
374 #endif
375 
379  void set_neighbor (const unsigned int i, Elem * n);
380 
385  bool has_neighbor (const Elem * elem) const;
386 
391  Elem * child_neighbor (Elem * elem);
392 
397  const Elem * child_neighbor (const Elem * elem) const;
398 
404  bool on_boundary () const;
405 
415  bool is_semilocal (const processor_id_type my_pid) const;
416 
422  unsigned int which_neighbor_am_i(const Elem * e) const;
423 
440  unsigned int which_side_am_i(const Elem * e) const;
441 
452  virtual unsigned int local_side_node(unsigned int side,
453  unsigned int side_node) const = 0;
454 
462  virtual unsigned int local_edge_node(unsigned int edge,
463  unsigned int edge_node) const = 0;
464 
465 #ifdef LIBMESH_ENABLE_DEPRECATED
466 
469  unsigned int which_node_am_i(unsigned int side,
470  unsigned int side_node) const;
471 #endif // LIBMESH_ENABLE_DEPRECATED
472 
480  bool contains_vertex_of(const Elem * e, bool mesh_connection=false) const;
481 
487  bool contains_edge_of(const Elem * e) const;
488 
505  void find_point_neighbors(const Point & p,
506  std::set<const Elem *> & neighbor_set) const;
507 
513  void find_point_neighbors(std::set<const Elem *> & neighbor_set) const;
514 
520  void find_point_neighbors(std::set<const Elem *> & neighbor_set,
521  const Elem * start_elem) const;
522 
526  void find_point_neighbors(std::set<Elem *> & neighbor_set,
527  Elem * start_elem);
528 
534  void find_edge_neighbors(const Point & p1,
535  const Point & p2,
536  std::set<const Elem *> & neighbor_set) const;
537 
546  void find_edge_neighbors(std::set<const Elem *> & neighbor_set) const;
547 
553  void find_interior_neighbors(std::set<const Elem *> & neighbor_set) const;
554 
559  void find_interior_neighbors(std::set<Elem *> & neighbor_set);
560 
568  void remove_links_to_me ();
569 
577  void make_links_to_me_remote ();
578 
585  void make_links_to_me_local (unsigned int n, unsigned int neighbor_side);
586 
598  virtual bool is_remote () const
599  { return false; }
600 
605  virtual void connectivity(const unsigned int sc,
606  const IOPackage iop,
607  std::vector<dof_id_type> & conn) const = 0;
608 
614  void write_connectivity (std::ostream & out,
615  const IOPackage iop) const;
616 
621  virtual ElemType type () const = 0;
622 
630  static const unsigned int type_to_dim_map[INVALID_ELEM];
631 
635  virtual unsigned short dim () const = 0;
636 
645  static const unsigned int type_to_n_nodes_map[INVALID_ELEM];
646 
650  virtual unsigned int n_nodes () const = 0;
651 
656  static const unsigned int max_n_nodes = 27;
657 
663 
669  virtual unsigned int n_nodes_in_child (unsigned int /*c*/) const
670  { return this->n_nodes(); }
671 
680  static const unsigned int type_to_n_sides_map[INVALID_ELEM];
681 
687  virtual unsigned int n_sides () const = 0;
688 
692  virtual ElemType side_type (const unsigned int s) const = 0;
693 
698  virtual Point side_vertex_average_normal(const unsigned int s) const;
699 
705 
715  unsigned int n_neighbors () const
716  { return this->n_sides(); }
717 
722  virtual unsigned int n_vertices () const = 0;
723 
728  virtual unsigned int n_edges () const = 0;
729 
735 
744  static const unsigned int type_to_n_edges_map[INVALID_ELEM];
745 
750  virtual unsigned int n_faces () const = 0;
751 
757 
762  virtual unsigned int n_children () const = 0;
763 
767  virtual bool is_vertex(const unsigned int i) const = 0;
768 
775  virtual bool is_vertex_on_child (unsigned int /*c*/,
776  unsigned int n) const
777  { return this->is_vertex(n); }
778 
783  virtual bool is_vertex_on_parent(unsigned int c,
784  unsigned int n) const;
785 
790  virtual bool is_edge(const unsigned int i) const = 0;
791 
797  virtual bool is_face(const unsigned int i) const = 0;
798 
802  bool is_internal(const unsigned int i) const;
803 
808  virtual bool is_node_on_side(const unsigned int n,
809  const unsigned int s) const = 0;
810 
814  virtual std::vector<unsigned int> nodes_on_side(const unsigned int /*s*/) const = 0;
815 
819  virtual std::vector<unsigned int> nodes_on_edge(const unsigned int /*e*/) const = 0;
820 
824  virtual std::vector<unsigned int> sides_on_edge(const unsigned int /*e*/) const = 0;
825 
829  virtual std::vector<unsigned int> edges_adjacent_to_node(const unsigned int /*n*/) const = 0;
830 
835  virtual bool is_node_on_edge(const unsigned int n,
836  const unsigned int e) const = 0;
837 
841  virtual bool is_edge_on_side(const unsigned int e,
842  const unsigned int s) const = 0;
843 
848  virtual unsigned int opposite_side(const unsigned int s) const;
849 
855  virtual unsigned int opposite_node(const unsigned int n,
856  const unsigned int s) const;
857 
863  virtual unsigned int n_sub_elem () const = 0;
864 
881  virtual std::unique_ptr<Elem> side_ptr (unsigned int i) = 0;
882  std::unique_ptr<const Elem> side_ptr (unsigned int i) const;
883 
898  virtual void side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) = 0;
899  void side_ptr (std::unique_ptr<const Elem> & side, const unsigned int i) const;
900 
921  virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i) = 0;
922  std::unique_ptr<const Elem> build_side_ptr (const unsigned int i) const;
923 
924 #ifdef LIBMESH_ENABLE_DEPRECATED
925  /*
926  * Older versions of libMesh supported a "proxy" option here.
927  */
928  virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i, bool proxy)
929  { if (proxy) libmesh_error(); libmesh_deprecated(); return this->build_side_ptr(i); }
930 
931  std::unique_ptr<const Elem> build_side_ptr (const unsigned int i, bool proxy) const
932  { if (proxy) libmesh_error(); libmesh_deprecated(); return this->build_side_ptr(i); }
933 #endif
934 
949  virtual void build_side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) = 0;
950  void build_side_ptr (std::unique_ptr<const Elem> & side, const unsigned int i) const;
951 
965  virtual std::unique_ptr<Elem> build_edge_ptr (const unsigned int i) = 0;
966  std::unique_ptr<const Elem> build_edge_ptr (const unsigned int i) const;
967 
982  virtual void build_edge_ptr (std::unique_ptr<Elem> & edge, const unsigned int i) = 0;
983  void build_edge_ptr (std::unique_ptr<const Elem> & edge, const unsigned int i) const;
984 
993 
999  virtual Order default_order () const = 0;
1000 
1006  virtual Order supported_nodal_order() const { return default_order(); }
1007 
1013  virtual Order default_side_order () const { return default_order(); }
1014 
1015 #ifdef LIBMESH_ENABLE_DEPRECATED
1016 
1025  virtual Point centroid () const;
1026 #endif // LIBMESH_ENABLE_DEPRECATED
1027 
1042  virtual Point true_centroid () const;
1043 
1052  Point vertex_average () const;
1053 
1061  virtual Point quasicircumcenter () const
1062  { libmesh_not_implemented(); }
1063 
1067  virtual Real hmin () const;
1068 
1072  virtual Real hmax () const;
1073 
1081  virtual Real volume () const;
1082 
1093  virtual BoundingBox loose_bounding_box () const;
1094 
1111  virtual Real quality (const ElemQuality q) const;
1112 
1121  virtual std::pair<Real,Real> qual_bounds (const ElemQuality) const
1122  { libmesh_not_implemented(); return std::make_pair(0.,0.); }
1123 
1139  virtual bool contains_point (const Point & p, Real tol=TOLERANCE) const;
1140 
1149  virtual bool on_reference_element(const Point & p,
1150  const Real eps = TOLERANCE) const = 0;
1151 
1156  virtual bool close_to_point(const Point & p, Real tol) const;
1157 
1163  bool positive_edge_orientation(const unsigned int i) const;
1164 
1172  bool positive_face_orientation(const unsigned int i) const;
1173 
1174 
1181  void inherit_data_from(const Elem & src);
1182 
1183 
1184 private:
1191  bool point_test(const Point & p, Real box_tol, Real map_tol) const;
1192 
1193 public:
1198  virtual bool has_affine_map () const { return false; }
1199 
1208  virtual bool has_invertible_map(Real tol = TOLERANCE*TOLERANCE) const;
1209 
1214  virtual bool is_linear () const { return false; }
1215 
1219  void print_info (std::ostream & os=libMesh::out) const;
1220 
1224  std::string get_info () const;
1225 
1232  bool active () const;
1233 
1239  bool ancestor () const;
1240 
1245  bool subactive () const;
1246 
1251  bool has_children () const;
1252 
1257  bool has_ancestor_children () const;
1258 
1264  bool is_ancestor_of(const Elem * descendant) const;
1265 
1270  const Elem * parent () const;
1271 
1276  Elem * parent ();
1277 
1282  void set_parent (Elem * p);
1283 
1291  const Elem * top_parent () const;
1292 
1307  const Elem * interior_parent () const;
1308 
1309  Elem * interior_parent ();
1310 
1315  void set_interior_parent (Elem * p);
1316 
1322  Real length (const unsigned int n1,
1323  const unsigned int n2) const;
1324 
1335  virtual unsigned int n_second_order_adjacent_vertices (const unsigned int n) const;
1336 
1345  virtual unsigned short int second_order_adjacent_vertex (const unsigned int n,
1346  const unsigned int v) const;
1347 
1363  virtual std::pair<unsigned short int, unsigned short int>
1364  second_order_child_vertex (const unsigned int n) const;
1365 
1380  const bool full_ordered=true);
1381 
1389  static ElemType first_order_equivalent_type (const ElemType et);
1390 
1404 
1412  unsigned int level () const;
1413 
1419  unsigned int p_level () const;
1420 
1424  virtual bool is_child_on_side(const unsigned int c,
1425  const unsigned int s) const = 0;
1426 
1430  ElemMappingType mapping_type () const;
1431 
1435  void set_mapping_type (const ElemMappingType type);
1436 
1440  unsigned char mapping_data () const;
1441 
1445  void set_mapping_data (const unsigned char data);
1446 
1447 
1448 #ifdef LIBMESH_ENABLE_AMR
1449 
1461 
1466  const Elem * raw_child_ptr (unsigned int i) const;
1467 
1472  const Elem * child_ptr (unsigned int i) const;
1473 
1478  Elem * child_ptr (unsigned int i);
1479 
1484  class ChildRefIter;
1485  class ConstChildRefIter;
1486 
1495 
1497 
1498 private:
1503  void set_child (unsigned int c, Elem * elem);
1504 
1505 public:
1512  unsigned int which_child_am_i(const Elem * e) const;
1513 
1517  virtual bool is_child_on_edge(const unsigned int c,
1518  const unsigned int e) const;
1519 
1526  void add_child (Elem * elem);
1527 
1534  void add_child (Elem * elem, unsigned int c);
1535 
1539  void replace_child (Elem * elem, unsigned int c);
1540 
1552  void family_tree (std::vector<const Elem *> & family,
1553  bool reset = true) const;
1554 
1558  void family_tree (std::vector<Elem *> & family,
1559  bool reset = true);
1560 
1565  void total_family_tree (std::vector<const Elem *> & family,
1566  bool reset = true) const;
1567 
1571  void total_family_tree (std::vector<Elem *> & family,
1572  bool reset = true);
1573 
1580  void active_family_tree (std::vector<const Elem *> & active_family,
1581  bool reset = true) const;
1582 
1586  void active_family_tree (std::vector<Elem *> & active_family,
1587  bool reset = true);
1588 
1593  void family_tree_by_side (std::vector<const Elem *> & family,
1594  unsigned int side,
1595  bool reset = true) const;
1596 
1600  void family_tree_by_side (std::vector<Elem *> & family,
1601  unsigned int side,
1602  bool reset = true);
1603 
1608  void active_family_tree_by_side (std::vector<const Elem *> & family,
1609  unsigned int side,
1610  bool reset = true) const;
1611 
1615  void active_family_tree_by_side (std::vector<Elem *> & family,
1616  unsigned int side,
1617  bool reset = true);
1618 
1623  void family_tree_by_neighbor (std::vector<const Elem *> & family,
1624  const Elem * neighbor,
1625  bool reset = true) const;
1626 
1630  void family_tree_by_neighbor (std::vector<Elem *> & family,
1631  Elem * neighbor,
1632  bool reset = true);
1633 
1638  void total_family_tree_by_neighbor (std::vector<const Elem *> & family,
1639  const Elem * neighbor,
1640  bool reset = true) const;
1641 
1645  void total_family_tree_by_neighbor (std::vector<Elem *> & family,
1646  Elem * neighbor,
1647  bool reset = true);
1648 
1655  void family_tree_by_subneighbor (std::vector<const Elem *> & family,
1656  const Elem * neighbor,
1657  const Elem * subneighbor,
1658  bool reset = true) const;
1659 
1663  void family_tree_by_subneighbor (std::vector<Elem *> & family,
1664  Elem * neighbor,
1665  Elem * subneighbor,
1666  bool reset = true);
1667 
1672  void total_family_tree_by_subneighbor (std::vector<const Elem *> & family,
1673  const Elem * neighbor,
1674  const Elem * subneighbor,
1675  bool reset = true) const;
1676 
1680  void total_family_tree_by_subneighbor (std::vector<Elem *> & family,
1681  Elem * neighbor,
1682  Elem * subneighbor,
1683  bool reset = true);
1684 
1689  void active_family_tree_by_neighbor (std::vector<const Elem *> & family,
1690  const Elem * neighbor,
1691  bool reset = true) const;
1692 
1696  void active_family_tree_by_neighbor (std::vector<Elem *> & family,
1697  Elem * neighbor,
1698  bool reset = true);
1699 
1705  void active_family_tree_by_topological_neighbor (std::vector<const Elem *> & family,
1706  const Elem * neighbor,
1707  const MeshBase & mesh,
1708  const PointLocatorBase & point_locator,
1709  const PeriodicBoundaries * pb,
1710  bool reset = true) const;
1711 
1715  void active_family_tree_by_topological_neighbor (std::vector<Elem *> & family,
1716  Elem * neighbor,
1717  const MeshBase & mesh,
1718  const PointLocatorBase & point_locator,
1719  const PeriodicBoundaries * pb,
1720  bool reset = true);
1721 
1726 
1730  void set_refinement_flag (const RefinementState rflag);
1731 
1736 
1740  void set_p_refinement_flag (const RefinementState pflag);
1741 
1746  unsigned int max_descendant_p_level () const;
1747 
1753  unsigned int min_p_level_by_neighbor (const Elem * neighbor,
1754  unsigned int current_min) const;
1755 
1761  unsigned int min_new_p_level_by_neighbor (const Elem * neighbor,
1762  unsigned int current_min) const;
1763 
1769  void set_p_level (const unsigned int p);
1770 
1775  void hack_p_level (const unsigned int p);
1776 
1783  void hack_p_level_and_refinement_flag (const unsigned int p,
1784  RefinementState pflag);
1785 
1789  virtual void refine (MeshRefinement & mesh_refinement);
1790 
1795  void coarsen ();
1796 
1803  void contract ();
1804 
1805 #endif
1806 
1807 #ifndef NDEBUG
1808 
1811  void libmesh_assert_valid_neighbors() const;
1812 
1818 #endif // !NDEBUG
1819 
1832  virtual unsigned int local_singular_node(const Point & /* p */, const Real /* tol */ = TOLERANCE*TOLERANCE) const
1833  { return invalid_uint; }
1834 
1839  virtual bool is_singular_node(unsigned int /* node_i */) const { return false; }
1840 
1847  virtual unsigned int center_node_on_side(const unsigned short side) const;
1848 
1849 protected:
1850 
1861  class SideIter;
1862 
1863 public:
1868 
1873  struct side_iterator;
1874 
1880 
1881 private:
1887  SideIter _last_side();
1888 
1889 public:
1890 
1891 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
1892 
1897  virtual bool infinite () const = 0;
1898 
1906  virtual bool is_mid_infinite_edge_node(const unsigned int /* n */) const
1907  { libmesh_assert (!this->infinite()); return false; }
1908 
1915  virtual Point origin () const { libmesh_not_implemented(); return Point(); }
1916 
1917 #else
1918 
1919  static constexpr bool infinite () { return false; }
1920 
1921 #endif
1922 
1926  static std::unique_ptr<Elem> build (const ElemType type,
1927  Elem * p=nullptr);
1928 
1934  static std::unique_ptr<Elem> build_with_id (const ElemType type,
1935  dof_id_type id);
1936 
1949  virtual std::unique_ptr<Elem> disconnected_clone () const;
1950 
1960  virtual unsigned int n_permutations() const = 0;
1961 
1974  virtual void permute(unsigned int perm_num) = 0;
1975 
1987  virtual void flip(BoundaryInfo * boundary_info) = 0;
1988 
1999  virtual bool is_flipped() const = 0;
2000 
2007  void orient(BoundaryInfo * boundary_info);
2008 
2009 #ifdef LIBMESH_ENABLE_AMR
2010 
2016  virtual unsigned int as_parent_node (unsigned int c,
2017  unsigned int n) const;
2018 
2023  virtual
2024  const std::vector<std::pair<unsigned char, unsigned char>> &
2025  parent_bracketing_nodes(unsigned int c,
2026  unsigned int n) const;
2027 
2032  virtual
2033  const std::vector<std::pair<dof_id_type, dof_id_type>>
2034  bracketing_nodes(unsigned int c,
2035  unsigned int n) const;
2036 
2037 
2041  virtual Real embedding_matrix (const unsigned int child_num,
2042  const unsigned int child_node_num,
2043  const unsigned int parent_node_num) const = 0;
2044 
2052  virtual unsigned int embedding_matrix_version () const { return 0; }
2053 
2054 #endif // LIBMESH_ENABLE_AMR
2055 
2056 
2057 protected:
2058 
2062  static constexpr Real affine_tol = TOLERANCE*TOLERANCE;
2063 
2067  static dof_id_type compute_key (dof_id_type n0);
2068 
2072  static dof_id_type compute_key (dof_id_type n0,
2073  dof_id_type n1);
2074 
2078  static dof_id_type compute_key (dof_id_type n0,
2079  dof_id_type n1,
2080  dof_id_type n2);
2081 
2085  static dof_id_type compute_key (dof_id_type n0,
2086  dof_id_type n1,
2087  dof_id_type n2,
2088  dof_id_type n3);
2089 
2093  void swap2nodes(unsigned int n1, unsigned int n2)
2094  {
2095  Node * temp = this->node_ptr(n1);
2096  this->set_node(n1, this->node_ptr(n2));
2097  this->set_node(n2, temp);
2098  }
2099 
2103  void swap2neighbors(unsigned int n1, unsigned int n2)
2104  {
2105  Elem * temp = this->neighbor_ptr(n1);
2106  this->set_neighbor(n1, this->neighbor_ptr(n2));
2107  this->set_neighbor(n2, temp);
2108  }
2109 
2113  void swap2boundarysides(unsigned short s1, unsigned short s2,
2114  BoundaryInfo * boundary_info) const;
2115 
2119  void swap2boundaryedges(unsigned short e1, unsigned short e2,
2120  BoundaryInfo * boundary_info) const;
2121 
2125  void swap3nodes(unsigned int n1, unsigned int n2, unsigned int n3)
2126  {
2127  swap2nodes(n1, n2);
2128  swap2nodes(n2, n3);
2129  }
2130 
2134  void swap3neighbors(unsigned int n1, unsigned int n2,
2135  unsigned int n3)
2136  {
2137  swap2neighbors(n1, n2);
2138  swap2neighbors(n2, n3);
2139  }
2140 
2144  void swap4nodes(unsigned int n1, unsigned int n2, unsigned int n3,
2145  unsigned int n4)
2146  {
2147  swap3nodes(n1, n2, n3);
2148  swap2nodes(n3, n4);
2149  }
2150 
2154  void swap4neighbors(unsigned int n1, unsigned int n2,
2155  unsigned int n3, unsigned int n4)
2156  {
2157  swap3neighbors(n1, n2, n3);
2158  swap2neighbors(n3, n4);
2159  }
2160 
2161 
2165  template <typename Sideclass, typename Subclass>
2166  std::unique_ptr<Elem>
2167  simple_build_side_ptr(const unsigned int i);
2168 
2172  template <typename Subclass>
2173  void simple_build_side_ptr(std::unique_ptr<Elem> & side,
2174  const unsigned int i,
2175  ElemType sidetype);
2176 
2180  template <typename Subclass, typename Mapclass>
2181  void simple_side_ptr(std::unique_ptr<Elem> & side,
2182  const unsigned int i,
2183  ElemType sidetype);
2184 
2188  template <typename Edgeclass, typename Subclass>
2189  std::unique_ptr<Elem>
2190  simple_build_edge_ptr(const unsigned int i);
2191 
2195  template <typename Subclass>
2196  void simple_build_edge_ptr(std::unique_ptr<Elem> & edge,
2197  const unsigned int i,
2198  ElemType edgetype);
2199 
2200 
2201 #ifdef LIBMESH_ENABLE_AMR
2202 
2208  virtual
2209  std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> &
2211  {
2212  static std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> c;
2213  libmesh_error();
2214  return c;
2215  }
2216 
2222  virtual
2223  std::vector<std::vector<std::vector<signed char>>> &
2225  {
2226  static std::vector<std::vector<std::vector<signed char>>> c;
2227  libmesh_error();
2228  return c;
2229  }
2230 
2231 #endif // LIBMESH_ENABLE_AMR
2232 
2233 public:
2234 
2239  void nullify_neighbors ();
2240 
2241 protected:
2242 
2247 
2253 
2254 #ifdef LIBMESH_ENABLE_AMR
2255 
2262  std::unique_ptr<Elem *[]> _children;
2263 #endif
2264 
2269 
2270 #ifdef LIBMESH_ENABLE_AMR
2271 
2275  unsigned char _rflag;
2276 
2281  unsigned char _pflag;
2282 
2291  unsigned char _p_level;
2292 #endif
2293 
2298  unsigned char _map_type;
2299 
2304  unsigned char _map_data;
2305 };
2306 
2307 
2308 
2309 // ------------------------------------------------------------
2310 // Elem helper classes
2311 //
2312 class
2314 {
2315 public:
2316  NodeRefIter (Node * const * nodepp) : PointerToPointerIter<Node>(nodepp) {}
2317 };
2318 
2319 
2320 class
2322 {
2323 public:
2324  ConstNodeRefIter (const Node * const * nodepp) : PointerToPointerIter<const Node>(nodepp) {}
2325 };
2326 
2327 
2328 #ifdef LIBMESH_ENABLE_AMR
2329 class
2331 {
2332 public:
2333  ChildRefIter (Elem * const * childpp) : PointerToPointerIter<Elem>(childpp) {}
2334 };
2335 
2336 
2337 class
2339 {
2340 public:
2341  ConstChildRefIter (const Elem * const * childpp) : PointerToPointerIter<const Elem>(childpp) {}
2342 };
2343 
2344 
2345 
2346 inline
2348 {
2350  return {_children.get(), _children.get() + this->n_children()};
2351 }
2352 
2353 
2354 inline
2356 {
2358  return {_children.get(), _children.get() + this->n_children()};
2359 }
2360 #endif // LIBMESH_ENABLE_AMR
2361 
2362 
2363 
2364 
2365 // ------------------------------------------------------------
2366 // global Elem functions
2367 
2368 inline
2369 std::ostream & operator << (std::ostream & os, const Elem & e)
2370 {
2371  e.print_info(os);
2372  return os;
2373 }
2374 
2375 
2376 // ------------------------------------------------------------
2377 // Elem class member functions
2378 inline
2379 Elem::Elem(const unsigned int nn,
2380  const unsigned int ns,
2381  Elem * p,
2382  Elem ** elemlinkdata,
2383  Node ** nodelinkdata) :
2384  _nodes(nodelinkdata),
2385  _elemlinks(elemlinkdata),
2386  _sbd_id(0),
2387 #ifdef LIBMESH_ENABLE_AMR
2388  _rflag(Elem::DO_NOTHING),
2389  _pflag(Elem::DO_NOTHING),
2390  _p_level(0),
2391 #endif
2392  _map_type(p ? p->mapping_type() : 0),
2393  _map_data(p ? p->mapping_data() : 0)
2394 {
2396 
2397  // If this ever legitimately fails we need to increase max_n_nodes
2398  libmesh_assert_less_equal(nn, max_n_nodes);
2399 
2400  // We currently only support refinement of elements into child
2401  // elements of the same type. We can't test elem->type() here,
2402  // because that's virtual and we're still in the base class
2403  // constructor, but we can at least usually verify constency with
2404  // the arguments we were handed.
2405 #ifndef NDEBUG
2406  if (p && !p->runtime_topology())
2407  {
2408  libmesh_assert_equal_to(nn, p->n_nodes());
2409  libmesh_assert_equal_to(ns, p->n_sides());
2410  }
2411 #endif
2412 
2413  // Initialize the nodes data structure if we're given a pointer to
2414  // memory for it.
2415  if (_nodes)
2416  {
2417  for (unsigned int n=0; n<nn; n++)
2418  _nodes[n] = nullptr;
2419  }
2420 
2421  // Initialize the neighbors/parent data structure
2422  // _elemlinks = new Elem *[ns+1];
2423 
2424  // Initialize the elements data structure if we're given a pointer
2425  // to memory for it. If we *weren't* given memory for it, e.g.
2426  // because a subclass like an arbitrary Polygon needs to
2427  // heap-allocate this memory, then that subclass will have to handle
2428  // this initialization too.
2429  if (_elemlinks)
2430  {
2431  _elemlinks[0] = p;
2432 
2433  for (unsigned int n=1; n<ns+1; n++)
2434  _elemlinks[n] = nullptr;
2435 
2436  // Optionally initialize data from the parent
2437  if (this->parent())
2438  {
2439  this->subdomain_id() = this->parent()->subdomain_id();
2440  this->processor_id() = this->parent()->processor_id();
2441  _map_type = this->parent()->_map_type;
2442  _map_data = this->parent()->_map_data;
2443 
2444 #ifdef LIBMESH_ENABLE_AMR
2445  this->set_p_level(this->parent()->p_level());
2446 #endif
2447  }
2448  }
2449 }
2450 
2451 
2452 
2453 inline
2454 const Point & Elem::point (const unsigned int i) const
2455 {
2456  libmesh_assert_less (i, this->n_nodes());
2457  libmesh_assert(_nodes[i]);
2458  libmesh_assert_not_equal_to (_nodes[i]->id(), Node::invalid_id);
2459 
2460  return *_nodes[i];
2461 }
2462 
2463 
2464 
2465 inline
2466 Point & Elem::point (const unsigned int i)
2467 {
2468  libmesh_assert_less (i, this->n_nodes());
2469 
2470  return *_nodes[i];
2471 }
2472 
2473 
2474 
2475 inline
2476 dof_id_type Elem::node_id (const unsigned int i) const
2477 {
2478  libmesh_assert_less (i, this->n_nodes());
2479  libmesh_assert(_nodes[i]);
2480  libmesh_assert_not_equal_to (_nodes[i]->id(), Node::invalid_id);
2481 
2482  return _nodes[i]->id();
2483 }
2484 
2485 
2486 
2487 inline
2488 unsigned int Elem::local_node (const dof_id_type i) const
2489 {
2490  for (auto n : make_range(this->n_nodes()))
2491  if (this->node_id(n) == i)
2492  return n;
2493 
2494  return libMesh::invalid_uint;
2495 }
2496 
2497 
2498 
2499 inline
2500 const Node * const * Elem::get_nodes () const
2501 {
2502  return _nodes;
2503 }
2504 
2505 
2506 
2507 inline
2508 const Node * Elem::node_ptr (const unsigned int i) const
2509 {
2510  libmesh_assert_less (i, this->n_nodes());
2511  libmesh_assert(_nodes[i]);
2512 
2513  return _nodes[i];
2514 }
2515 
2516 
2517 
2518 inline
2519 Node * Elem::node_ptr (const unsigned int i)
2520 {
2521  libmesh_assert_less (i, this->n_nodes());
2522  libmesh_assert(_nodes[i]);
2523 
2524  return _nodes[i];
2525 }
2526 
2527 
2528 
2529 inline
2530 const Node & Elem::node_ref (const unsigned int i) const
2531 {
2532  return *this->node_ptr(i);
2533 }
2534 
2535 
2536 
2537 inline
2538 Node & Elem::node_ref (const unsigned int i)
2539 {
2540  return *this->node_ptr(i);
2541 }
2542 
2543 
2544 
2545 inline
2546 unsigned int Elem::get_node_index (const Node * node_ptr) const
2547 {
2548  for (auto n : make_range(this->n_nodes()))
2549  if (this->_nodes[n] == node_ptr)
2550  return n;
2551 
2552  return libMesh::invalid_uint;
2553 }
2554 
2555 
2556 
2557 #ifdef LIBMESH_ENABLE_DEPRECATED
2558 inline
2559 Node * & Elem::set_node (const unsigned int i)
2560 {
2561  libmesh_assert_less (i, this->n_nodes());
2562 
2563  libmesh_deprecated();
2564 
2565  return _nodes[i];
2566 }
2567 #endif // LIBMESH_ENABLE_DEPRECATED
2568 
2569 
2570 
2571 inline
2572 void Elem::set_node (const unsigned int i,
2573  Node * node)
2574 {
2575  libmesh_assert_less (i, this->n_nodes());
2576 
2577  _nodes[i] = node;
2578 }
2579 
2580 
2581 
2582 inline
2584 {
2585  return _sbd_id;
2586 }
2587 
2588 
2589 
2590 inline
2592 {
2593  return _sbd_id;
2594 }
2595 
2596 
2597 
2598 inline
2599 const Elem * Elem::neighbor_ptr (unsigned int i) const
2600 {
2601  libmesh_assert_less (i, this->n_neighbors());
2602 
2603  return _elemlinks[i+1];
2604 }
2605 
2606 
2607 
2608 inline
2609 Elem * Elem::neighbor_ptr (unsigned int i)
2610 {
2611  libmesh_assert_less (i, this->n_neighbors());
2612 
2613  return _elemlinks[i+1];
2614 }
2615 
2616 
2617 
2618 inline
2619 void Elem::set_neighbor (const unsigned int i, Elem * n)
2620 {
2621  libmesh_assert_less (i, this->n_neighbors());
2622 
2623  _elemlinks[i+1] = n;
2624 }
2625 
2626 
2627 
2628 inline
2629 bool Elem::has_neighbor (const Elem * elem) const
2630 {
2631  for (auto n : this->neighbor_ptr_range())
2632  if (n == elem)
2633  return true;
2634 
2635  return false;
2636 }
2637 
2638 
2639 
2640 inline
2642 {
2643  for (auto n : elem->neighbor_ptr_range())
2644  if (n && n->parent() == this)
2645  return n;
2646 
2647  return nullptr;
2648 }
2649 
2650 
2651 
2652 inline
2653 const Elem * Elem::child_neighbor (const Elem * elem) const
2654 {
2655  for (auto n : elem->neighbor_ptr_range())
2656  if (n && n->parent() == this)
2657  return n;
2658 
2659  return nullptr;
2660 }
2661 
2662 
2663 
2664 inline
2667 {
2668  return {_nodes, _nodes+this->n_nodes()};
2669 }
2670 
2671 
2672 
2673 inline
2676 {
2677  return {_nodes, _nodes+this->n_nodes()};
2678 }
2679 
2680 
2681 
2682 inline
2685 {
2686  return {0, cast_int<unsigned short>(this->n_nodes())};
2687 }
2688 
2689 
2690 
2691 inline
2694 {
2695  return {0, cast_int<unsigned short>(this->n_edges())};
2696 }
2697 
2698 
2699 
2700 inline
2703 {
2704  return {0, cast_int<unsigned short>(this->n_faces())};
2705 }
2706 
2707 
2708 
2709 inline
2712 {
2713  return {0, cast_int<unsigned short>(this->n_sides())};
2714 }
2715 
2716 
2717 
2718 
2719 inline
2720 std::unique_ptr<const Elem> Elem::side_ptr (unsigned int i) const
2721 {
2722  // Call the non-const version of this function, return the result as
2723  // a std::unique_ptr<const Elem>.
2724  Elem * me = const_cast<Elem *>(this);
2725  return me->side_ptr(i);
2726 }
2727 
2728 
2729 
2730 inline
2731 void
2732 Elem::side_ptr (std::unique_ptr<const Elem> & elem,
2733  const unsigned int i) const
2734 {
2735  // Hand off to the non-const version of this function
2736  Elem * me = const_cast<Elem *>(this);
2737  std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
2738  me->side_ptr(e, i);
2739  elem = std::move(e);
2740 }
2741 
2742 
2743 
2744 inline
2745 std::unique_ptr<const Elem>
2746 Elem::build_side_ptr (const unsigned int i) const
2747 {
2748  // Call the non-const version of this function, return the result as
2749  // a std::unique_ptr<const Elem>.
2750  Elem * me = const_cast<Elem *>(this);
2751  return me->build_side_ptr(i);
2752 }
2753 
2754 
2755 
2756 inline
2757 void
2758 Elem::build_side_ptr (std::unique_ptr<const Elem> & elem,
2759  const unsigned int i) const
2760 {
2761  // Hand off to the non-const version of this function
2762  Elem * me = const_cast<Elem *>(this);
2763  std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
2764  me->build_side_ptr(e, i);
2765  elem = std::move(e);
2766 }
2767 
2768 
2769 
2770 template <typename Sideclass, typename Subclass>
2771 inline
2772 std::unique_ptr<Elem>
2773 Elem::simple_build_side_ptr (const unsigned int i)
2774 {
2775  libmesh_assert_less (i, this->n_sides());
2776 
2777  std::unique_ptr<Elem> face = std::make_unique<Sideclass>();
2778  for (auto n : face->node_index_range())
2779  face->set_node(n, this->node_ptr(Subclass::side_nodes_map[i][n]));
2780 
2781  face->set_interior_parent(this);
2782  face->inherit_data_from(*this);
2783 
2784  return face;
2785 }
2786 
2787 
2788 
2789 template <typename Subclass>
2790 inline
2791 void
2792 Elem::simple_build_side_ptr (std::unique_ptr<Elem> & side,
2793  const unsigned int i,
2794  ElemType sidetype)
2795 {
2796  libmesh_assert_less (i, this->n_sides());
2797 
2798  if (!side.get() || side->type() != sidetype)
2799  {
2800  Subclass & real_me = cast_ref<Subclass&>(*this);
2801  side = real_me.Subclass::build_side_ptr(i);
2802  }
2803  else
2804  {
2805  side->set_interior_parent(this);
2806  side->inherit_data_from(*this);
2807  for (auto n : side->node_index_range())
2808  side->set_node(n, this->node_ptr(Subclass::side_nodes_map[i][n]));
2809  }
2810 }
2811 
2812 
2813 
2814 template <typename Subclass, typename Mapclass>
2815 inline
2816 void
2817 Elem::simple_side_ptr (std::unique_ptr<Elem> & side,
2818  const unsigned int i,
2819  ElemType sidetype)
2820 {
2821  libmesh_assert_less (i, this->n_sides());
2822 
2823  if (!side.get() || side->type() != sidetype)
2824  {
2825  Subclass & real_me = cast_ref<Subclass&>(*this);
2826  side = real_me.Subclass::side_ptr(i);
2827  }
2828  else
2829  {
2830  side->subdomain_id() = this->subdomain_id();
2831 
2832  for (auto n : side->node_index_range())
2833  side->set_node(n, this->node_ptr(Mapclass::side_nodes_map[i][n]));
2834  }
2835 }
2836 
2837 
2838 
2839 inline
2840 std::unique_ptr<const Elem>
2841 Elem::build_edge_ptr (const unsigned int i) const
2842 {
2843  // Call the non-const version of this function, return the result as
2844  // a std::unique_ptr<const Elem>.
2845  Elem * me = const_cast<Elem *>(this);
2846  return me->build_edge_ptr(i);
2847 }
2848 
2849 
2850 
2851 inline
2852 void
2853 Elem::build_edge_ptr (std::unique_ptr<const Elem> & elem,
2854  const unsigned int i) const
2855 {
2856  // Hand off to the non-const version of this function
2857  Elem * me = const_cast<Elem *>(this);
2858  std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
2859  me->build_edge_ptr(e, i);
2860  elem = std::move(e);
2861 }
2862 
2863 
2864 template <typename Edgeclass, typename Subclass>
2865 inline
2866 std::unique_ptr<Elem>
2867 Elem::simple_build_edge_ptr (const unsigned int i)
2868 {
2869  libmesh_assert_less (i, this->n_edges());
2870 
2871  std::unique_ptr<Elem> edge = std::make_unique<Edgeclass>();
2872 
2873  for (auto n : edge->node_index_range())
2874  edge->set_node(n, this->node_ptr(Subclass::edge_nodes_map[i][n]));
2875 
2876  edge->set_interior_parent(this);
2877  edge->inherit_data_from(*this);
2878 
2879  return edge;
2880 }
2881 
2882 
2883 
2884 
2885 template <typename Subclass>
2886 inline
2887 void
2888 Elem::simple_build_edge_ptr (std::unique_ptr<Elem> & edge,
2889  const unsigned int i,
2890  ElemType edgetype)
2891 {
2892  libmesh_assert_less (i, this->n_edges());
2893 
2894  if (!edge.get() || edge->type() != edgetype)
2895  {
2896  Subclass & real_me = cast_ref<Subclass&>(*this);
2897  edge = real_me.Subclass::build_edge_ptr(i);
2898  }
2899  else
2900  {
2901  edge->inherit_data_from(*this);
2902  for (auto n : edge->node_index_range())
2903  edge->set_node(n, this->node_ptr(Subclass::edge_nodes_map[i][n]));
2904  }
2905 }
2906 
2907 
2908 
2909 inline
2910 bool Elem::on_boundary () const
2911 {
2912  // By convention, the element is on the boundary
2913  // if it has a nullptr neighbor.
2914  return this->has_neighbor(nullptr);
2915 }
2916 
2917 
2918 
2919 inline
2920 unsigned int Elem::which_neighbor_am_i (const Elem * e) const
2921 {
2922  libmesh_assert(e);
2923 
2924  const Elem * eparent = e;
2925 
2926  while (eparent->level() > this->level())
2927  {
2928  eparent = eparent->parent();
2929  libmesh_assert(eparent);
2930  }
2931 
2932  for (auto s : make_range(this->n_sides()))
2933  if (this->neighbor_ptr(s) == eparent)
2934  return s;
2935 
2936  return libMesh::invalid_uint;
2937 }
2938 
2939 
2940 
2941 inline
2942 bool Elem::active() const
2943 {
2944 #ifdef LIBMESH_ENABLE_AMR
2945  if ((this->refinement_flag() == INACTIVE) ||
2946  (this->refinement_flag() == COARSEN_INACTIVE))
2947  return false;
2948  else
2949  return true;
2950 #else
2951  return true;
2952 #endif
2953 }
2954 
2955 
2956 
2957 
2958 
2959 inline
2960 bool Elem::subactive() const
2961 {
2962 #ifdef LIBMESH_ENABLE_AMR
2963  if (this->active())
2964  return false;
2965  if (!this->has_children())
2966  return true;
2967  for (const Elem * my_ancestor = this->parent();
2968  my_ancestor != nullptr;
2969  my_ancestor = my_ancestor->parent())
2970  if (my_ancestor->active())
2971  return true;
2972 #endif
2973 
2974  return false;
2975 }
2976 
2977 
2978 
2979 inline
2981 {
2982 #ifdef LIBMESH_ENABLE_AMR
2983  if (!_children)
2984  return false;
2985  else
2986  return true;
2987 #else
2988  return false;
2989 #endif
2990 }
2991 
2992 
2993 inline
2995 {
2996 #ifdef LIBMESH_ENABLE_AMR
2997  if (!_children)
2998  return false;
2999  else
3000  for (auto & c : child_ref_range())
3001  if (c.has_children())
3002  return true;
3003 #endif
3004  return false;
3005 }
3006 
3007 
3008 
3009 inline
3011 #ifdef LIBMESH_ENABLE_AMR
3012  descendant
3013 #endif
3014  ) const
3015 {
3016 #ifdef LIBMESH_ENABLE_AMR
3017  const Elem * e = descendant;
3018  while (e)
3019  {
3020  if (this == e)
3021  return true;
3022  e = e->parent();
3023  }
3024 #endif
3025  return false;
3026 }
3027 
3028 
3029 
3030 inline
3031 const Elem * Elem::parent () const
3032 {
3033  return _elemlinks[0];
3034 }
3035 
3036 
3037 
3038 inline
3040 {
3041  return _elemlinks[0];
3042 }
3043 
3044 
3045 
3046 inline
3048 {
3049  // We no longer support using parent() as interior_parent()
3050  libmesh_assert_equal_to(this->dim(), p ? p->dim() : this->dim());
3051  _elemlinks[0] = p;
3052 }
3053 
3054 
3055 
3056 inline
3057 const Elem * Elem::top_parent () const
3058 {
3059  const Elem * tp = this;
3060 
3061  // Keep getting the element's parent
3062  // until that parent is at level-0
3063  while (tp->parent() != nullptr)
3064  tp = tp->parent();
3065 
3066  libmesh_assert(tp);
3067  libmesh_assert_equal_to (tp->level(), 0);
3068 
3069  return tp;
3070 }
3071 
3072 
3073 
3074 inline
3075 unsigned int Elem::level() const
3076 {
3077 #ifdef LIBMESH_ENABLE_AMR
3078 
3079  // if I don't have a parent I was
3080  // created directly from file
3081  // or by the user, so I am a
3082  // level-0 element
3083  if (this->parent() == nullptr)
3084  return 0;
3085 
3086  // if the parent and this element are of different
3087  // dimensionality we are at the same level as
3088  // the parent (e.g. we are the 2D side of a
3089  // 3D element)
3090  if (this->dim() != this->parent()->dim())
3091  return this->parent()->level();
3092 
3093  // otherwise we are at a level one
3094  // higher than our parent
3095  return (this->parent()->level() + 1);
3096 
3097 #else
3098 
3099  // Without AMR all elements are
3100  // at level 0.
3101  return 0;
3102 
3103 #endif
3104 }
3105 
3106 
3107 
3108 inline
3109 unsigned int Elem::p_level() const
3110 {
3111 #ifdef LIBMESH_ENABLE_AMR
3112  return _p_level;
3113 #else
3114  return 0;
3115 #endif
3116 }
3117 
3118 
3119 
3120 inline
3122 {
3123  return static_cast<ElemMappingType>(_map_type);
3124 }
3125 
3126 
3127 
3128 inline
3130 {
3131  _map_type = cast_int<unsigned char>(type);
3132 }
3133 
3134 
3135 
3136 inline
3137 unsigned char Elem::mapping_data () const
3138 {
3139  return _map_data;
3140 }
3141 
3142 
3143 
3144 inline
3145 void Elem::set_mapping_data(const unsigned char data)
3146 {
3147  _map_data = data;
3148 }
3149 
3150 
3151 
3152 #ifdef LIBMESH_ENABLE_AMR
3153 
3154 inline
3155 const Elem * Elem::raw_child_ptr (unsigned int i) const
3156 {
3157  if (!_children)
3158  return nullptr;
3159 
3160  return _children[i];
3161 }
3162 
3163 inline
3164 const Elem * Elem::child_ptr (unsigned int i) const
3165 {
3168 
3169  return _children[i];
3170 }
3171 
3172 inline
3173 Elem * Elem::child_ptr (unsigned int i)
3174 {
3177 
3178  return _children[i];
3179 }
3180 
3181 
3182 inline
3183 void Elem::set_child (unsigned int c, Elem * elem)
3184 {
3185  libmesh_assert (this->has_children());
3186 
3187  _children[c] = elem;
3188 }
3189 
3190 
3191 
3192 inline
3193 unsigned int Elem::which_child_am_i (const Elem * e) const
3194 {
3195  libmesh_assert(e);
3196  libmesh_assert (this->has_children());
3197 
3198  unsigned int nc = this->n_children();
3199  for (unsigned int c=0; c != nc; c++)
3200  if (this->child_ptr(c) == e)
3201  return c;
3202 
3203  libmesh_error_msg("ERROR: which_child_am_i() was called with a non-child!");
3204 
3205  return libMesh::invalid_uint;
3206 }
3207 
3208 
3209 
3210 inline
3212 {
3213  return static_cast<RefinementState>(_rflag);
3214 }
3215 
3216 
3217 
3218 inline
3220 {
3221  _rflag = cast_int<unsigned char>(rflag);
3222 }
3223 
3224 
3225 
3226 inline
3228 {
3229  return static_cast<RefinementState>(_pflag);
3230 }
3231 
3232 
3233 
3234 inline
3236 {
3237  if (this->p_level() == 0)
3238  libmesh_assert_not_equal_to
3239  (pflag, Elem::JUST_REFINED);
3240 
3241  _pflag = cast_int<unsigned char>(pflag);
3242 }
3243 
3244 
3245 
3246 inline
3247 unsigned int Elem::max_descendant_p_level () const
3248 {
3249  // This is undefined for subactive elements,
3250  // which have no active descendants
3251  libmesh_assert (!this->subactive());
3252  if (this->active())
3253  return this->p_level();
3254 
3255  unsigned int max_p_level = _p_level;
3256  for (auto & c : child_ref_range())
3257  max_p_level = std::max(max_p_level,
3258  c.max_descendant_p_level());
3259  return max_p_level;
3260 }
3261 
3262 
3263 
3264 inline
3265 void Elem::hack_p_level(unsigned int p)
3266 {
3267  if (p == 0)
3268  libmesh_assert_not_equal_to
3270 
3271  _p_level = cast_int<unsigned char>(p);
3272 }
3273 
3274 
3275 inline
3277  RefinementState pflag)
3278 {
3279  _pflag = cast_int<unsigned char>(pflag);
3280  this->hack_p_level(p);
3281 }
3282 
3283 #endif // ifdef LIBMESH_ENABLE_AMR
3284 
3285 
3286 inline
3287 void Elem::orient(BoundaryInfo * boundary_info)
3288 {
3289  if (this->is_flipped())
3290  this->flip(boundary_info);
3291 }
3292 
3293 
3294 inline
3296 {
3297  return n0;
3298 }
3299 
3300 
3301 
3302 inline
3304  dof_id_type n1)
3305 {
3306  // Order the two so that n0 < n1
3307  if (n0 > n1) std::swap (n0, n1);
3308 
3309  return Utility::hashword2(n0, n1);
3310 }
3311 
3312 
3313 
3314 inline
3316  dof_id_type n1,
3317  dof_id_type n2)
3318 {
3319  std::array<dof_id_type, 3> array = {{n0, n1, n2}};
3320  std::sort(array.begin(), array.end());
3321  return Utility::hashword(array);
3322 }
3323 
3324 
3325 
3326 inline
3328  dof_id_type n1,
3329  dof_id_type n2,
3330  dof_id_type n3)
3331 {
3332  std::array<dof_id_type, 4> array = {{n0, n1, n2, n3}};
3333  std::sort(array.begin(), array.end());
3334  return Utility::hashword(array);
3335 }
3336 
3337 
3338 
3339 inline
3340 void Elem::inherit_data_from (const Elem & src)
3341 {
3342  this->set_mapping_type(src.mapping_type());
3343  this->set_mapping_data(src.mapping_data());
3344  this->subdomain_id() = src.subdomain_id();
3345  this->processor_id(src.processor_id());
3346 #ifdef LIBMESH_ENABLE_AMR
3347  this->set_p_level(src.p_level());
3348 #endif
3349 }
3350 
3351 
3352 
3357 {
3358 public:
3359  // Constructor with arguments.
3360  SideIter(const unsigned int side_number,
3361  Elem * parent)
3362  : _side(),
3363  _side_ptr(nullptr),
3364  _parent(parent),
3365  _side_number(side_number)
3366  {}
3367 
3368 
3369  // Empty constructor.
3371  : _side(),
3372  _side_ptr(nullptr),
3373  _parent(nullptr),
3375  {}
3376 
3377 
3378  // Copy constructor
3379  SideIter(const SideIter & other)
3380  : _side(),
3381  _side_ptr(nullptr),
3382  _parent(other._parent),
3383  _side_number(other._side_number)
3384  {}
3385 
3386 
3387  // op=
3388  SideIter & operator=(const SideIter & other)
3389  {
3390  this->_parent = other._parent;
3391  this->_side_number = other._side_number;
3392  return *this;
3393  }
3394 
3395  // unary op*
3396  Elem *& operator*() const
3397  {
3398  // Set the std::unique_ptr
3399  this->_update_side_ptr();
3400 
3401  // Return a reference to _side_ptr
3402  return this->_side_ptr;
3403  }
3404 
3405  // op++
3407  {
3408  ++_side_number;
3409  return *this;
3410  }
3411 
3412  // op== Two side iterators are equal if they have
3413  // the same side number and the same parent element.
3414  bool operator == (const SideIter & other) const
3415  {
3416  return (this->_side_number == other._side_number &&
3417  this->_parent == other._parent);
3418  }
3419 
3420 
3421  // Consults the parent Elem to determine if the side
3422  // is a boundary side. Note: currently side N is a
3423  // boundary side if neighbor N is nullptr. Be careful,
3424  // this could possibly change in the future?
3425  bool side_on_boundary() const
3426  {
3427  return this->_parent->neighbor_ptr(_side_number) == nullptr;
3428  }
3429 
3430 private:
3431  // Update the _side pointer by building the correct side.
3432  // This has to be called before dereferencing.
3433  void _update_side_ptr() const
3434  {
3435  // Construct new side, store in std::unique_ptr
3436  this->_side = this->_parent->build_side_ptr(this->_side_number);
3437 
3438  // Also set our internal naked pointer. Memory is still owned
3439  // by the std::unique_ptr.
3440  this->_side_ptr = _side.get();
3441  }
3442 
3443  // std::unique_ptr to the actual side, handles memory management for
3444  // the sides which are created during the course of iteration.
3445  mutable std::unique_ptr<Elem> _side;
3446 
3447  // Raw pointer needed to facilitate passing back to the user a
3448  // reference to a non-temporary raw pointer in order to conform to
3449  // the variant_filter_iterator interface. It points to the same
3450  // thing the std::unique_ptr "_side" above holds. What happens if the user
3451  // calls delete on the pointer passed back? Well, this is an issue
3452  // which is not addressed by the iterators in libMesh. Basically it
3453  // is a bad idea to ever call delete on an iterator from the library.
3454  mutable Elem * _side_ptr;
3455 
3456  // Pointer to the parent Elem class which generated this iterator
3458 
3459  // A counter variable which keeps track of the side number
3460  unsigned int _side_number;
3461 };
3462 
3463 
3464 
3465 
3466 
3467 
3468 // Private implementation functions in the Elem class for the side iterators.
3469 // They have to come after the definition of the SideIter class.
3470 inline
3472 {
3473  return SideIter(0, this);
3474 }
3475 
3476 
3477 
3478 inline
3480 {
3481  return SideIter(this->n_neighbors(), this);
3482 }
3483 
3484 
3485 
3486 
3490 struct
3492 {
3493  // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
3494  template <typename PredType, typename IterType>
3495  side_iterator (const IterType & d,
3496  const IterType & e,
3497  const PredType & p ) :
3499 };
3500 
3501 
3502 
3503 inline
3505 {
3506  return {_elemlinks+1, _elemlinks + 1 + this->n_neighbors()};
3507 }
3508 
3509 
3510 inline
3512 {
3513  return {_elemlinks+1, _elemlinks + 1 + this->n_neighbors()};
3514 }
3515 
3516 } // namespace libMesh
3517 
3518 
3519 // Helper function for default caches in Elem subclasses
3520 
3521 #define LIBMESH_ENABLE_TOPOLOGY_CACHES \
3522  virtual \
3523  std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> & \
3524  _get_bracketing_node_cache() const override \
3525  { \
3526  static std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> c; \
3527  return c; \
3528  } \
3529  \
3530  virtual \
3531  std::vector<std::vector<std::vector<signed char>>> & \
3532  _get_parent_indices_cache() const override \
3533  { \
3534  static std::vector<std::vector<std::vector<signed char>>> c; \
3535  return c; \
3536  }
3537 
3538 
3539 
3540 
3541 
3542 
3543 #endif // LIBMESH_ELEM_H
virtual Point true_centroid() const
Definition: elem.C:592
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:2277
bool has_neighbor(const Elem *elem) const
Definition: elem.h:2629
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:3137
virtual bool is_vertex_on_parent(unsigned int c, unsigned int n) const
Definition: elem.C:3502
std::unique_ptr< Elem > simple_build_side_ptr(const unsigned int i)
An implementation for simple (all sides equal) elements.
Definition: elem.h:2773
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:992
RefinementState refinement_flag() const
Definition: elem.h:3211
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:3565
virtual Point quasicircumcenter() const
Definition: elem.h:1061
unsigned char _map_type
Mapping function type; currently either 0 (LAGRANGE) or 1 (RATIONAL_BERNSTEIN).
Definition: elem.h:2298
unsigned char _map_data
Mapping function data; currently used when needed to store the RATIONAL_BERNSTEIN nodal weight data i...
Definition: elem.h:2304
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:1729
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i, bool proxy)
Definition: elem.h:928
const Elem * parent() const
Definition: elem.h:3031
virtual const std::vector< std::pair< dof_id_type, dof_id_type > > bracketing_nodes(unsigned int c, unsigned int n) const
Definition: elem.C:2655
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:2919
static constexpr 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
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:2165
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:2559
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:3010
Node ** _nodes
Pointers to the nodes we are connected to.
Definition: elem.h:2246
Elem * child_neighbor(Elem *elem)
Definition: elem.h:2641
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:3323
Predicates::multi_predicate Predicate
Useful iterator typedefs.
Definition: elem.h:1861
virtual Order default_side_order() const
Definition: elem.h:1013
virtual Point origin() const
Definition: elem.h:1915
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:3047
unsigned int get_node_index(const Node *node_ptr) const
Definition: elem.h:2546
std::string get_info() const
Prints relevant information about the element to a string.
Definition: elem.C:2927
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:680
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:1184
const Elem * topological_neighbor(const unsigned int i, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
Definition: elem.C:1311
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:3287
void set_mapping_type(const ElemMappingType type)
Sets the value of the mapping type for the element.
Definition: elem.h:3129
virtual bool is_face(const unsigned int i) const =0
bool is_semilocal(const processor_id_type my_pid) const
Definition: elem.C:853
unsigned char _pflag
p refinement flag.
Definition: elem.h:2281
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:2291
IntRange< unsigned short > side_index_range() const
Definition: elem.h:2711
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:1369
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i)=0
virtual dof_id_type key() const
Definition: elem.C:751
static constexpr Real TOLERANCE
const Elem * top_parent() const
Definition: elem.h:3057
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:254
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:2052
unsigned int which_side_am_i(const Elem *e) const
This function tells you which side the boundary element e is.
Definition: elem.C:868
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:3360
virtual ~Elem()=default
Destructor.
RefinementState p_refinement_flag() const
Definition: elem.h:3227
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:1198
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:1170
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:630
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:2219
bool operator==(const SideIter &other) const
Definition: elem.h:3414
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:2099
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:2042
virtual BoundingBox loose_bounding_box() const
Definition: elem.C:3469
SideIter & operator=(const SideIter &other)
Definition: elem.h:3388
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:2350
RefinementState
Enumeration of possible element refinement states.
Definition: elem.h:1453
void set_refinement_flag(const RefinementState rflag)
Sets the value of the refinement flag for the element.
Definition: elem.h:3219
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:2131
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:3549
virtual unsigned int n_children() const =0
ChildRefIter(Elem *const *childpp)
Definition: elem.h:2333
unsigned int _side_number
Definition: elem.h:3460
unsigned int p_level() const
Definition: elem.h:3109
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:1081
side_iterator boundary_sides_end()
Definition: elem.C:3424
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:1531
The libMesh namespace provides an interface to certain functionality in the library.
SideIter & operator++()
Definition: elem.h:3406
virtual Real hmax() const
Definition: elem.C:720
virtual bool is_linear() const
Definition: elem.h:1214
unsigned int min_p_level_by_neighbor(const Elem *neighbor, unsigned int current_min) const
Definition: elem.C:2321
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:1246
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:645
bool contains_vertex_of(const Elem *e, bool mesh_connection=false) const
Definition: elem.C:932
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:2347
bool ancestor() const
Definition: elem.C:2008
bool has_topological_neighbor(const Elem *elem, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
Definition: elem.C:1348
IntRange< unsigned short > edge_index_range() const
Definition: elem.h:2693
void swap3neighbors(unsigned int n1, unsigned int n2, unsigned int n3)
Swaps three neighbor_ptrs, "rotating" them.
Definition: elem.h:2134
side_iterator boundary_sides_begin()
Iterator accessor functions.
Definition: elem.C:3415
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:3396
virtual void refine(MeshRefinement &mesh_refinement)
Refine the element.
const Elem *const * ConstNeighborPtrIter
Definition: elem.h:329
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:2125
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:2147
void replace_child(Elem *elem, unsigned int c)
Replaces the child pointer at the specified index in the child array.
Definition: elem.C:2088
void swap4nodes(unsigned int n1, unsigned int n2, unsigned int n3, unsigned int n4)
Swaps four node_ptrs, "rotating" them.
Definition: elem.h:2144
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:2239
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:1637
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:2224
Elem *const * NeighborPtrIter
Nested "classes" for use iterating over all neighbors of an element.
Definition: elem.h:328
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const
Definition: elem.C:2755
Implements (adaptive) mesh refinement algorithms for a MeshBase.
virtual Order supported_nodal_order() const
Definition: elem.h:1006
Real length(const unsigned int n1, const unsigned int n2) const
Definition: elem.C:740
IntRange< unsigned short > face_index_range() const
Definition: elem.h:2702
ElemMappingType mapping_type() const
Definition: elem.h:3121
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:1453
void swap2nodes(unsigned int n1, unsigned int n2)
Swaps two node_ptrs.
Definition: elem.h:2093
const Node & node_ref(const unsigned int i) const
Definition: elem.h:2530
dof_id_type id() const
Definition: dof_object.h:828
virtual Real hmin() const
Definition: elem.C:700
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
virtual unsigned int n_nodes() const =0
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:922
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:744
bool contains_edge_of(const Elem *e) const
Definition: elem.C:970
unsigned int which_neighbor_am_i(const Elem *e) const
This function tells you which neighbor e is.
Definition: elem.h:2920
virtual unsigned int as_parent_node(unsigned int c, unsigned int n) const
Definition: elem.C:2384
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:442
virtual unsigned int opposite_node(const unsigned int n, const unsigned int s) const
Definition: elem.C:3534
virtual std::pair< unsigned short int, unsigned short int > second_order_child_vertex(const unsigned int n) const
Definition: elem.C:3062
static constexpr bool infinite()
Definition: elem.h:1919
Elem ** _elemlinks
Pointers to this element&#39;s parent and neighbors, and for lower-dimensional elements&#39; interior_parent...
Definition: elem.h:2252
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:991
void set_mapping_data(const unsigned char data)
Sets the value of the mapping data for the element.
Definition: elem.h:3145
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:3490
const Node *const * get_nodes() const
Definition: elem.h:2500
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:2792
void _update_side_ptr() const
Definition: elem.h:3433
bool side_on_boundary() const
Definition: elem.h:3425
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
Definition: boundary_info.h:57
libmesh_assert(ctx)
virtual Point side_vertex_average_normal(const unsigned int s) const
Definition: elem.C:3490
const Elem * reference_elem() const
Definition: elem.C:568
void libmesh_assert_valid_neighbors() const
Checks for consistent neighbor links on this element.
Definition: elem.C:1381
virtual bool is_remote() const
Definition: elem.h:598
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:410
virtual unsigned int n_second_order_adjacent_vertices(const unsigned int n) const
Definition: elem.C:3044
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:3276
SideIter _last_side()
Definition: elem.h:3479
static constexpr Real affine_tol
Default tolerance to use in has_affine_map().
Definition: elem.h:2062
bool positive_edge_orientation(const unsigned int i) const
Definition: elem.C:3604
void set_neighbor(const unsigned int i, Elem *n)
Assigns n as the neighbor.
Definition: elem.h:2619
This class implements reference counting.
subdomain_id_type _sbd_id
The subdomain to which this element belongs.
Definition: elem.h:2268
static ElemType second_order_equivalent_type(const ElemType et, const bool full_ordered=true)
Definition: elem.C:3139
bool on_boundary() const
Definition: elem.h:2910
Elem(const unsigned int n_nodes, const unsigned int n_sides, Elem *parent, Elem **elemlinkdata, Node **nodelinkdata)
Constructor.
Definition: elem.h:2379
unsigned int which_child_am_i(const Elem *e) const
Definition: elem.h:3193
unsigned int max_descendant_p_level() const
Definition: elem.h:3247
unsigned char _rflag
h refinement flag.
Definition: elem.h:2275
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:2103
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:2259
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:2201
SimpleRange< NodeRefIter > node_ref_range()
Returns a range with all nodes of an element, usable in range-based for loops.
Definition: elem.h:2666
Defines a Cartesian bounding box by the two corner extremum.
Definition: bounding_box.h:40
std::unique_ptr< Elem > _side
Definition: elem.h:3445
ElemMappingType
Enumeration of possible element master->physical mapping types.
ConstNodeRefIter(const Node *const *nodepp)
Definition: elem.h:2324
virtual unsigned int n_sides() const =0
bool topologically_equal(const Elem &rhs) const
Definition: elem.C:801
const Elem * neighbor_ptr(unsigned int i) const
Definition: elem.h:2599
virtual bool close_to_point(const Point &p, Real tol) const
Definition: elem.C:2780
unsigned int level() const
Definition: elem.h:3075
const Elem * raw_child_ptr(unsigned int i) const
Definition: elem.h:3155
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:1832
subdomain_id_type subdomain_id() const
Definition: elem.h:2583
virtual bool is_singular_node(unsigned int) const
Definition: elem.h:1839
virtual unsigned short dim() const =0
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:2508
SideIter(const SideIter &other)
Definition: elem.h:3379
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:556
unsigned int n_neighbors() const
Definition: elem.h:715
virtual Real quality(const ElemQuality q) const
Definition: elem.C:1772
virtual unsigned short int second_order_adjacent_vertex(const unsigned int n, const unsigned int v) const
Definition: elem.C:3052
bool subactive() const
Definition: elem.h:2960
virtual Real volume() const
Definition: elem.C:3433
void swap4neighbors(unsigned int n1, unsigned int n2, unsigned int n3, unsigned int n4)
Swaps four neighbor_ptrs, "rotating" them.
Definition: elem.h:2154
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:3183
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:2994
virtual bool has_invertible_map(Real tol=TOLERANCE *TOLERANCE) const
Definition: elem.C:2885
IntRange< unsigned short > node_index_range() const
Definition: elem.h:2684
bool positive_face_orientation(const unsigned int i) const
Definition: elem.C:3613
unsigned int local_node(const dof_id_type i) const
Definition: elem.h:2488
virtual bool is_vertex_on_child(unsigned int, unsigned int n) const
Definition: elem.h:775
void nullify_neighbors()
Replaces this element with nullptr for all of its neighbors.
Definition: elem.C:3018
SimpleRange< NeighborPtrIter > neighbor_ptr_range()
Returns a range with all neighbors of an element, usable in range-based for loops.
Definition: elem.h:3504
void set_p_refinement_flag(const RefinementState pflag)
Sets the value of the p-refinement flag for the element.
Definition: elem.h:3235
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:3340
virtual bool infinite() const =0
virtual std::pair< Real, Real > qual_bounds(const ElemQuality) const
Definition: elem.h:1121
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:2817
static dof_id_type compute_key(dof_id_type n0)
Definition: elem.h:3295
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:2115
std::unique_ptr< const Elem > build_side_ptr(const unsigned int i, bool proxy) const
Definition: elem.h:931
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:2183
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i)=0
static constexpr subdomain_id_type invalid_subdomain_id
A static integral constant representing an invalid subdomain id.
Definition: elem.h:246
ConstChildRefIter(const Elem *const *childpp)
Definition: elem.h:2341
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:2867
virtual const std::vector< std::pair< unsigned char, unsigned char > > & parent_bracketing_nodes(unsigned int c, unsigned int n) const
Definition: elem.C:2452
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:2210
virtual unsigned int opposite_side(const unsigned int s) const
Definition: elem.C:3526
bool active() const
Definition: elem.h:2942
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:3265
static ElemType first_order_equivalent_type(const ElemType et)
Definition: elem.C:3070
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:2476
const Point & point(const unsigned int i) const
Definition: elem.h:2454
virtual Point centroid() const
Calls Elem::vertex_average() for backwards compatibility.
Definition: elem.C:576
bool operator==(const Elem &rhs) const
Definition: elem.C:769
side_iterator(const IterType &d, const IterType &e, const PredType &p)
Definition: elem.h:3495
bool has_children() const
Definition: elem.h:2980
virtual unsigned int center_node_on_side(const unsigned short side) const
Definition: elem.C:3542
void ErrorVector unsigned int
Definition: adjoints_ex3.C:360
NodeRefIter(Node *const *nodepp)
Definition: elem.h:2316
std::unique_ptr< Elem *[]> _children
unique_ptr to array of this element&#39;s children.
Definition: elem.h:2262
virtual bool is_child_on_edge(const unsigned int c, const unsigned int e) const
Definition: elem.C:2304
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:669
Point vertex_average() const
Definition: elem.C:686
static const unsigned int max_n_nodes
The maximum number of nodes any element can contain.
Definition: elem.h:656
const Elem * child_ptr(unsigned int i) const
Definition: elem.h:3164
uint8_t dof_id_type
Definition: id_types.h:67
The definition of the protected nested SideIter class.
Definition: elem.h:3356
virtual bool is_mid_infinite_edge_node(const unsigned int) const
Definition: elem.h:1906
bool is_internal(const unsigned int i) const
Definition: elem.C:3581
SideIter _first_side()
Side iterator helper functions.
Definition: elem.h:3471