libMesh
elem.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2026 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 
304  bool operator != (const Elem & rhs) const;
305 
313  bool topologically_equal (const Elem & rhs) const;
314 
324  const Elem * neighbor_ptr (unsigned int i) const;
325 
329  Elem * neighbor_ptr (unsigned int i);
330 
334  typedef Elem * const * NeighborPtrIter;
335  typedef const Elem * const * ConstNeighborPtrIter;
336 
346 
348 
349 #ifdef LIBMESH_ENABLE_PERIODIC
350 
356  const Elem * topological_neighbor (const unsigned int i,
357  const MeshBase & mesh,
358  const PointLocatorBase & point_locator,
359  const PeriodicBoundaries * pb) const;
360 
367  Elem * topological_neighbor (const unsigned int i,
368  MeshBase & mesh,
369  const PointLocatorBase & point_locator,
370  const PeriodicBoundaries * pb);
371 
376  bool has_topological_neighbor (const Elem * elem,
377  const MeshBase & mesh,
378  const PointLocatorBase & point_locator,
379  const PeriodicBoundaries * pb) const;
380 #endif
381 
385  void set_neighbor (const unsigned int i, Elem * n);
386 
391  bool has_neighbor (const Elem * elem) const;
392 
397  Elem * child_neighbor (Elem * elem);
398 
403  const Elem * child_neighbor (const Elem * elem) const;
404 
410  bool on_boundary () const;
411 
421  bool is_semilocal (const processor_id_type my_pid) const;
422 
428  unsigned int which_neighbor_am_i(const Elem * e) const;
429 
446  unsigned int which_side_am_i(const Elem * e) const;
447 
458  virtual unsigned int local_side_node(unsigned int side,
459  unsigned int side_node) const = 0;
460 
468  virtual unsigned int local_edge_node(unsigned int edge,
469  unsigned int edge_node) const = 0;
470 
478  bool contains_vertex_of(const Elem * e, bool mesh_connection=false) const;
479 
485  bool contains_edge_of(const Elem * e) const;
486 
503  void find_point_neighbors(const Point & p,
504  std::set<const Elem *> & neighbor_set) const;
505 
511  void find_point_neighbors(std::set<const Elem *> & neighbor_set) const;
512 
518  void find_point_neighbors(std::set<const Elem *> & neighbor_set,
519  const Elem * start_elem) const;
520 
524  void find_point_neighbors(std::set<Elem *> & neighbor_set,
525  Elem * start_elem);
526 
532  void find_edge_neighbors(const Point & p1,
533  const Point & p2,
534  std::set<const Elem *> & neighbor_set) const;
535 
544  void find_edge_neighbors(std::set<const Elem *> & neighbor_set) const;
545 
551  void find_interior_neighbors(std::set<const Elem *> & neighbor_set) const;
552 
557  void find_interior_neighbors(std::set<Elem *> & neighbor_set);
558 
566  void remove_links_to_me ();
567 
575  void make_links_to_me_remote ();
576 
583  void make_links_to_me_local (unsigned int n, unsigned int neighbor_side);
584 
596  virtual bool is_remote () const
597  { return false; }
598 
603  virtual void connectivity(const unsigned int sc,
604  const IOPackage iop,
605  std::vector<dof_id_type> & conn) const = 0;
606 
612  void write_connectivity (std::ostream & out,
613  const IOPackage iop) const;
614 
619  virtual ElemType type () const = 0;
620 
628  static const unsigned int type_to_dim_map[INVALID_ELEM];
629 
633  virtual unsigned short dim () const = 0;
634 
643  static const unsigned int type_to_n_nodes_map[INVALID_ELEM];
644 
648  virtual unsigned int n_nodes () const = 0;
649 
654  static const unsigned int max_n_nodes = 27;
655 
661 
667  virtual unsigned int n_nodes_in_child (unsigned int /*c*/) const
668  { return this->n_nodes(); }
669 
678  static const unsigned int type_to_n_sides_map[INVALID_ELEM];
679 
685  virtual unsigned int n_sides () const = 0;
686 
690  virtual ElemType side_type (const unsigned int s) const = 0;
691 
696  virtual Point side_vertex_average_normal(const unsigned int s) const;
697 
703 
713  unsigned int n_neighbors () const
714  { return this->n_sides(); }
715 
720  virtual unsigned int n_vertices () const = 0;
721 
726  virtual unsigned int n_edges () const = 0;
727 
733 
742  static const unsigned int type_to_n_edges_map[INVALID_ELEM];
743 
748  virtual unsigned int n_faces () const = 0;
749 
755 
760  virtual unsigned int n_children () const = 0;
761 
765  virtual bool is_vertex(const unsigned int i) const = 0;
766 
773  virtual bool is_vertex_on_child (unsigned int /*c*/,
774  unsigned int n) const
775  { return this->is_vertex(n); }
776 
781  virtual bool is_vertex_on_parent(unsigned int c,
782  unsigned int n) const;
783 
788  virtual bool is_edge(const unsigned int i) const = 0;
789 
795  virtual bool is_face(const unsigned int i) const = 0;
796 
800  bool is_internal(const unsigned int i) const;
801 
806  virtual bool is_node_on_side(const unsigned int n,
807  const unsigned int s) const = 0;
808 
812  virtual std::vector<unsigned int> nodes_on_side(const unsigned int /*s*/) const = 0;
813 
817  virtual std::vector<unsigned int> nodes_on_edge(const unsigned int /*e*/) const = 0;
818 
822  virtual std::vector<unsigned int> sides_on_edge(const unsigned int /*e*/) const = 0;
823 
827  virtual std::vector<unsigned int> edges_adjacent_to_node(const unsigned int /*n*/) const = 0;
828 
833  virtual bool is_node_on_edge(const unsigned int n,
834  const unsigned int e) const = 0;
835 
839  virtual bool is_edge_on_side(const unsigned int e,
840  const unsigned int s) const = 0;
841 
846  virtual unsigned int opposite_side(const unsigned int s) const;
847 
853  virtual unsigned int opposite_node(const unsigned int n,
854  const unsigned int s) const;
855 
861  virtual unsigned int n_sub_elem () const = 0;
862 
879  virtual std::unique_ptr<Elem> side_ptr (unsigned int i) = 0;
880  std::unique_ptr<const Elem> side_ptr (unsigned int i) const;
881 
896  virtual void side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) = 0;
897  void side_ptr (std::unique_ptr<const Elem> & side, const unsigned int i) const;
898 
919  virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i) = 0;
920  std::unique_ptr<const Elem> build_side_ptr (const unsigned int i) const;
921 
922 #ifdef LIBMESH_ENABLE_DEPRECATED
923  /*
924  * Older versions of libMesh supported a "proxy" option here.
925  */
926  virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i, bool proxy)
927  { if (proxy) libmesh_error(); libmesh_deprecated(); return this->build_side_ptr(i); }
928 
929  std::unique_ptr<const Elem> build_side_ptr (const unsigned int i, bool proxy) const
930  { if (proxy) libmesh_error(); libmesh_deprecated(); return this->build_side_ptr(i); }
931 #endif
932 
947  virtual void build_side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) = 0;
948  void build_side_ptr (std::unique_ptr<const Elem> & side, const unsigned int i) const;
949 
963  virtual std::unique_ptr<Elem> build_edge_ptr (const unsigned int i) = 0;
964  std::unique_ptr<const Elem> build_edge_ptr (const unsigned int i) const;
965 
980  virtual void build_edge_ptr (std::unique_ptr<Elem> & edge, const unsigned int i) = 0;
981  void build_edge_ptr (std::unique_ptr<const Elem> & edge, const unsigned int i) const;
982 
991 
997  virtual Order default_order () const = 0;
998 
1004  virtual Order supported_nodal_order() const { return default_order(); }
1005 
1011  virtual Order default_side_order () const { return default_order(); }
1012 
1027  virtual Point true_centroid () const;
1028 
1037  Point vertex_average () const;
1038 
1046  virtual Point quasicircumcenter () const
1047  { libmesh_not_implemented(); }
1048 
1052  virtual Real hmin () const;
1053 
1057  virtual Real hmax () const;
1058 
1066  virtual Real volume () const;
1067 
1078  virtual BoundingBox loose_bounding_box () const;
1079 
1096  virtual Real quality (const ElemQuality q) const;
1097 
1106  virtual std::pair<Real,Real> qual_bounds (const ElemQuality) const
1107  { libmesh_not_implemented(); return std::make_pair(0.,0.); }
1108 
1124  virtual bool contains_point (const Point & p, Real tol=TOLERANCE) const;
1125 
1134  virtual bool on_reference_element(const Point & p,
1135  const Real eps = TOLERANCE) const = 0;
1136 
1141  virtual bool close_to_point(const Point & p, Real tol) const;
1142 
1148  bool positive_edge_orientation(const unsigned int i) const;
1149 
1157  bool positive_face_orientation(const unsigned int i) const;
1158 
1164  bool relative_edge_face_order(const unsigned int e, const unsigned int s) const;
1165 
1172  void inherit_data_from(const Elem & src);
1173 
1174 private:
1181  bool point_test(const Point & p, Real box_tol, Real map_tol) const;
1182 
1183 public:
1188  virtual bool has_affine_map () const { return false; }
1189 
1198  virtual bool has_invertible_map(Real tol = TOLERANCE*TOLERANCE) const;
1199 
1204  virtual bool is_linear () const { return false; }
1205 
1209  void print_info (std::ostream & os=libMesh::out) const;
1210 
1214  std::string get_info () const;
1215 
1222  bool active () const;
1223 
1229  bool ancestor () const;
1230 
1235  bool subactive () const;
1236 
1241  bool has_children () const;
1242 
1247  bool has_ancestor_children () const;
1248 
1254  bool is_ancestor_of(const Elem * descendant) const;
1255 
1260  const Elem * parent () const;
1261 
1266  Elem * parent ();
1267 
1272  void set_parent (Elem * p);
1273 
1281  const Elem * top_parent () const;
1282 
1297  const Elem * interior_parent () const;
1298 
1299  Elem * interior_parent ();
1300 
1305  void set_interior_parent (Elem * p);
1306 
1312  Real length (const unsigned int n1,
1313  const unsigned int n2) const;
1314 
1325  virtual unsigned int n_second_order_adjacent_vertices (const unsigned int n) const;
1326 
1335  virtual unsigned short int second_order_adjacent_vertex (const unsigned int n,
1336  const unsigned int v) const;
1337 
1353  virtual std::pair<unsigned short int, unsigned short int>
1354  second_order_child_vertex (const unsigned int n) const;
1355 
1370  const bool full_ordered=true);
1371 
1379  static ElemType first_order_equivalent_type (const ElemType et);
1380 
1394 
1402  unsigned int level () const;
1403 
1409  unsigned int p_level () const;
1410 
1414  virtual bool is_child_on_side(const unsigned int c,
1415  const unsigned int s) const = 0;
1416 
1420  ElemMappingType mapping_type () const;
1421 
1425  void set_mapping_type (const ElemMappingType type);
1426 
1430  unsigned char mapping_data () const;
1431 
1435  void set_mapping_data (const unsigned char data);
1436 
1437 
1438 #ifdef LIBMESH_ENABLE_AMR
1439 
1451 
1456  const Elem * raw_child_ptr (unsigned int i) const;
1457 
1462  const Elem * child_ptr (unsigned int i) const;
1463 
1468  Elem * child_ptr (unsigned int i);
1469 
1474  class ChildRefIter;
1475  class ConstChildRefIter;
1476 
1485 
1487 
1488 private:
1493  void set_child (unsigned int c, Elem * elem);
1494 
1495 public:
1502  unsigned int which_child_am_i(const Elem * e) const;
1503 
1507  virtual bool is_child_on_edge(const unsigned int c,
1508  const unsigned int e) const;
1509 
1516  void add_child (Elem * elem);
1517 
1524  void add_child (Elem * elem, unsigned int c);
1525 
1529  void replace_child (Elem * elem, unsigned int c);
1530 
1542  void family_tree (std::vector<const Elem *> & family,
1543  bool reset = true) const;
1544 
1548  void family_tree (std::vector<Elem *> & family,
1549  bool reset = true);
1550 
1555  void total_family_tree (std::vector<const Elem *> & family,
1556  bool reset = true) const;
1557 
1561  void total_family_tree (std::vector<Elem *> & family,
1562  bool reset = true);
1563 
1570  void active_family_tree (std::vector<const Elem *> & active_family,
1571  bool reset = true) const;
1572 
1576  void active_family_tree (std::vector<Elem *> & active_family,
1577  bool reset = true);
1578 
1583  void family_tree_by_side (std::vector<const Elem *> & family,
1584  unsigned int side,
1585  bool reset = true) const;
1586 
1590  void family_tree_by_side (std::vector<Elem *> & family,
1591  unsigned int side,
1592  bool reset = true);
1593 
1598  void total_family_tree_by_side (std::vector<const Elem *> & family,
1599  unsigned int side,
1600  bool reset = true) const;
1601 
1605  void total_family_tree_by_side (std::vector<Elem *> & family,
1606  unsigned int side,
1607  bool reset = true);
1608 
1613  void active_family_tree_by_side (std::vector<const Elem *> & family,
1614  unsigned int side,
1615  bool reset = true) const;
1616 
1620  void active_family_tree_by_side (std::vector<Elem *> & family,
1621  unsigned int side,
1622  bool reset = true);
1623 
1628  void family_tree_by_neighbor (std::vector<const Elem *> & family,
1629  const Elem * neighbor,
1630  bool reset = true) const;
1631 
1635  void family_tree_by_neighbor (std::vector<Elem *> & family,
1636  Elem * neighbor,
1637  bool reset = true);
1638 
1643  void total_family_tree_by_neighbor (std::vector<const Elem *> & family,
1644  const Elem * neighbor,
1645  bool reset = true) const;
1646 
1650  void total_family_tree_by_neighbor (std::vector<Elem *> & family,
1651  Elem * neighbor,
1652  bool reset = true);
1653 
1660  void family_tree_by_subneighbor (std::vector<const Elem *> & family,
1661  const Elem * neighbor,
1662  const Elem * subneighbor,
1663  bool reset = true) const;
1664 
1668  void family_tree_by_subneighbor (std::vector<Elem *> & family,
1669  Elem * neighbor,
1670  Elem * subneighbor,
1671  bool reset = true);
1672 
1677  void total_family_tree_by_subneighbor (std::vector<const Elem *> & family,
1678  const Elem * neighbor,
1679  const Elem * subneighbor,
1680  bool reset = true) const;
1681 
1685  void total_family_tree_by_subneighbor (std::vector<Elem *> & family,
1686  Elem * neighbor,
1687  Elem * subneighbor,
1688  bool reset = true);
1689 
1694  void active_family_tree_by_neighbor (std::vector<const Elem *> & family,
1695  const Elem * neighbor,
1696  bool reset = true) const;
1697 
1701  void active_family_tree_by_neighbor (std::vector<Elem *> & family,
1702  Elem * neighbor,
1703  bool reset = true);
1704 
1710  void active_family_tree_by_topological_neighbor (std::vector<const Elem *> & family,
1711  const Elem * neighbor,
1712  const MeshBase & mesh,
1713  const PointLocatorBase & point_locator,
1714  const PeriodicBoundaries * pb,
1715  bool reset = true) const;
1716 
1720  void active_family_tree_by_topological_neighbor (std::vector<Elem *> & family,
1721  Elem * neighbor,
1722  const MeshBase & mesh,
1723  const PointLocatorBase & point_locator,
1724  const PeriodicBoundaries * pb,
1725  bool reset = true);
1726 
1731 
1735  void set_refinement_flag (const RefinementState rflag);
1736 
1741 
1745  void set_p_refinement_flag (const RefinementState pflag);
1746 
1751  unsigned int max_descendant_p_level () const;
1752 
1758  unsigned int min_p_level_by_neighbor (const Elem * neighbor,
1759  unsigned int current_min) const;
1760 
1766  unsigned int min_new_p_level_by_neighbor (const Elem * neighbor,
1767  unsigned int current_min) const;
1768 
1774  void set_p_level (const unsigned int p);
1775 
1780  void hack_p_level (const unsigned int p);
1781 
1788  void hack_p_level_and_refinement_flag (const unsigned int p,
1789  RefinementState pflag);
1790 
1794  virtual void refine (MeshRefinement & mesh_refinement);
1795 
1800  void coarsen ();
1801 
1808  void contract ();
1809 
1810 #endif
1811 
1812 #ifndef NDEBUG
1813 
1816  void libmesh_assert_valid_neighbors() const;
1817 
1823 #endif // !NDEBUG
1824 
1837  virtual unsigned int local_singular_node(const Point & /* p */, const Real /* tol */ = TOLERANCE*TOLERANCE) const
1838  { return invalid_uint; }
1839 
1844  virtual bool is_singular_node(unsigned int /* node_i */) const { return false; }
1845 
1852  virtual unsigned int center_node_on_side(const unsigned short side) const;
1853 
1854 protected:
1855 
1866  class SideIter;
1867 
1868 public:
1873 
1878  struct side_iterator;
1879 
1885 
1886 private:
1892  SideIter _last_side();
1893 
1894 public:
1895 
1896 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
1897 
1902  virtual bool infinite () const = 0;
1903 
1911  virtual bool is_mid_infinite_edge_node(const unsigned int /* n */) const
1912  { libmesh_assert (!this->infinite()); return false; }
1913 
1920  virtual Point origin () const { libmesh_not_implemented(); return Point(); }
1921 
1922 #else
1923 
1924  static constexpr bool infinite () { return false; }
1925 
1926 #endif
1927 
1931  static std::unique_ptr<Elem> build (const ElemType type,
1932  Elem * p=nullptr);
1933 
1939  static std::unique_ptr<Elem> build_with_id (const ElemType type,
1940  dof_id_type id);
1941 
1954  virtual std::unique_ptr<Elem> disconnected_clone () const;
1955 
1965  virtual unsigned int n_permutations() const = 0;
1966 
1979  virtual void permute(unsigned int perm_num) = 0;
1980 
1992  virtual void flip(BoundaryInfo * boundary_info) = 0;
1993 
2004  virtual bool is_flipped() const = 0;
2005 
2012  void orient(BoundaryInfo * boundary_info);
2013 
2014 #ifdef LIBMESH_ENABLE_AMR
2015 
2021  virtual unsigned int as_parent_node (unsigned int c,
2022  unsigned int n) const;
2023 
2028  virtual
2029  const std::vector<std::pair<unsigned char, unsigned char>> &
2030  parent_bracketing_nodes(unsigned int c,
2031  unsigned int n) const;
2032 
2037  virtual
2038  const std::vector<std::pair<dof_id_type, dof_id_type>>
2039  bracketing_nodes(unsigned int c,
2040  unsigned int n) const;
2041 
2042 
2046  virtual Real embedding_matrix (const unsigned int child_num,
2047  const unsigned int child_node_num,
2048  const unsigned int parent_node_num) const = 0;
2049 
2057  virtual unsigned int embedding_matrix_version () const { return 0; }
2058 
2059 #endif // LIBMESH_ENABLE_AMR
2060 
2061 
2062 protected:
2063 
2067  static constexpr Real affine_tol = TOLERANCE*TOLERANCE;
2068 
2072  static dof_id_type compute_key (dof_id_type n0);
2073 
2077  static dof_id_type compute_key (dof_id_type n0,
2078  dof_id_type n1);
2079 
2083  static dof_id_type compute_key (dof_id_type n0,
2084  dof_id_type n1,
2085  dof_id_type n2);
2086 
2090  static dof_id_type compute_key (dof_id_type n0,
2091  dof_id_type n1,
2092  dof_id_type n2,
2093  dof_id_type n3);
2094 
2098  void swap2nodes(unsigned int n1, unsigned int n2)
2099  {
2100  Node * temp = this->node_ptr(n1);
2101  this->set_node(n1, this->node_ptr(n2));
2102  this->set_node(n2, temp);
2103  }
2104 
2108  void swap2neighbors(unsigned int n1, unsigned int n2)
2109  {
2110  Elem * temp = this->neighbor_ptr(n1);
2111  this->set_neighbor(n1, this->neighbor_ptr(n2));
2112  this->set_neighbor(n2, temp);
2113  }
2114 
2118  void swap2boundarysides(unsigned short s1, unsigned short s2,
2119  BoundaryInfo * boundary_info) const;
2120 
2124  void swap2boundaryedges(unsigned short e1, unsigned short e2,
2125  BoundaryInfo * boundary_info) const;
2126 
2130  void swap3nodes(unsigned int n1, unsigned int n2, unsigned int n3)
2131  {
2132  swap2nodes(n1, n2);
2133  swap2nodes(n2, n3);
2134  }
2135 
2139  void swap3neighbors(unsigned int n1, unsigned int n2,
2140  unsigned int n3)
2141  {
2142  swap2neighbors(n1, n2);
2143  swap2neighbors(n2, n3);
2144  }
2145 
2149  void swap4nodes(unsigned int n1, unsigned int n2, unsigned int n3,
2150  unsigned int n4)
2151  {
2152  swap3nodes(n1, n2, n3);
2153  swap2nodes(n3, n4);
2154  }
2155 
2159  void swap4neighbors(unsigned int n1, unsigned int n2,
2160  unsigned int n3, unsigned int n4)
2161  {
2162  swap3neighbors(n1, n2, n3);
2163  swap2neighbors(n3, n4);
2164  }
2165 
2166 
2170  template <typename Sideclass, typename Subclass>
2171  std::unique_ptr<Elem>
2172  simple_build_side_ptr(const unsigned int i);
2173 
2177  template <typename Subclass>
2178  void simple_build_side_ptr(std::unique_ptr<Elem> & side,
2179  const unsigned int i,
2180  ElemType sidetype);
2181 
2185  template <typename Subclass, typename Mapclass>
2186  void simple_side_ptr(std::unique_ptr<Elem> & side,
2187  const unsigned int i,
2188  ElemType sidetype);
2189 
2193  template <typename Edgeclass, typename Subclass>
2194  std::unique_ptr<Elem>
2195  simple_build_edge_ptr(const unsigned int i);
2196 
2200  template <typename Subclass>
2201  void simple_build_edge_ptr(std::unique_ptr<Elem> & edge,
2202  const unsigned int i,
2203  ElemType edgetype);
2204 
2205 
2206 #ifdef LIBMESH_ENABLE_AMR
2207 
2213  virtual
2214  std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> &
2216  {
2217  static std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> c;
2218  libmesh_error();
2219  return c;
2220  }
2221 
2227  virtual
2228  std::vector<std::vector<std::vector<signed char>>> &
2230  {
2231  static std::vector<std::vector<std::vector<signed char>>> c;
2232  libmesh_error();
2233  return c;
2234  }
2235 
2236 #endif // LIBMESH_ENABLE_AMR
2237 
2238 public:
2239 
2244  void nullify_neighbors ();
2245 
2246 protected:
2247 
2252 
2258 
2259 #ifdef LIBMESH_ENABLE_AMR
2260 
2267  std::unique_ptr<Elem *[]> _children;
2268 #endif
2269 
2274 
2275 #ifdef LIBMESH_ENABLE_AMR
2276 
2280  unsigned char _rflag;
2281 
2286  unsigned char _pflag;
2287 
2296  unsigned char _p_level;
2297 #endif
2298 
2303  unsigned char _map_type;
2304 
2309  unsigned char _map_data;
2310 };
2311 
2312 
2313 
2314 // ------------------------------------------------------------
2315 // Elem helper classes
2316 //
2317 class
2319 {
2320 public:
2321  NodeRefIter (Node * const * nodepp) : PointerToPointerIter<Node>(nodepp) {}
2322 };
2323 
2324 
2325 class
2327 {
2328 public:
2329  ConstNodeRefIter (const Node * const * nodepp) : PointerToPointerIter<const Node>(nodepp) {}
2330 };
2331 
2332 
2333 #ifdef LIBMESH_ENABLE_AMR
2334 class
2336 {
2337 public:
2338  ChildRefIter (Elem * const * childpp) : PointerToPointerIter<Elem>(childpp) {}
2339 };
2340 
2341 
2342 class
2344 {
2345 public:
2346  ConstChildRefIter (const Elem * const * childpp) : PointerToPointerIter<const Elem>(childpp) {}
2347 };
2348 
2349 
2350 
2351 inline
2353 {
2355  return {_children.get(), _children.get() + this->n_children()};
2356 }
2357 
2358 
2359 inline
2361 {
2363  return {_children.get(), _children.get() + this->n_children()};
2364 }
2365 #endif // LIBMESH_ENABLE_AMR
2366 
2367 
2368 
2369 
2370 // ------------------------------------------------------------
2371 // global Elem functions
2372 
2373 inline
2374 std::ostream & operator << (std::ostream & os, const Elem & e)
2375 {
2376  e.print_info(os);
2377  return os;
2378 }
2379 
2380 
2381 // ------------------------------------------------------------
2382 // Elem class member functions
2383 inline
2384 Elem::Elem(const unsigned int nn,
2385  const unsigned int ns,
2386  Elem * p,
2387  Elem ** elemlinkdata,
2388  Node ** nodelinkdata) :
2389  _nodes(nodelinkdata),
2390  _elemlinks(elemlinkdata),
2391  _sbd_id(0),
2392 #ifdef LIBMESH_ENABLE_AMR
2393  _rflag(Elem::DO_NOTHING),
2394  _pflag(Elem::DO_NOTHING),
2395  _p_level(0),
2396 #endif
2397  _map_type(p ? p->mapping_type() : 0),
2398  _map_data(p ? p->mapping_data() : 0)
2399 {
2401 
2402  // If this ever legitimately fails we need to increase max_n_nodes
2403  libmesh_assert_less_equal(nn, max_n_nodes);
2404 
2405  // We currently only support refinement of elements into child
2406  // elements of the same type. We can't test elem->type() here,
2407  // because that's virtual and we're still in the base class
2408  // constructor, but we can at least usually verify constency with
2409  // the arguments we were handed.
2410 #ifndef NDEBUG
2411  if (p && !p->runtime_topology())
2412  {
2413  libmesh_assert_equal_to(nn, p->n_nodes());
2414  libmesh_assert_equal_to(ns, p->n_sides());
2415  }
2416 #endif
2417 
2418  // Initialize the nodes data structure if we're given a pointer to
2419  // memory for it.
2420  if (_nodes)
2421  {
2422  for (unsigned int n=0; n<nn; n++)
2423  _nodes[n] = nullptr;
2424  }
2425 
2426  // Initialize the neighbors/parent data structure
2427  // _elemlinks = new Elem *[ns+1];
2428 
2429  // Initialize the elements data structure if we're given a pointer
2430  // to memory for it. If we *weren't* given memory for it, e.g.
2431  // because a subclass like an arbitrary Polygon needs to
2432  // heap-allocate this memory, then that subclass will have to handle
2433  // this initialization too.
2434  if (_elemlinks)
2435  {
2436  _elemlinks[0] = p;
2437 
2438  for (unsigned int n=1; n<ns+1; n++)
2439  _elemlinks[n] = nullptr;
2440 
2441  // Optionally initialize data from the parent
2442  if (this->parent())
2443  {
2444  this->subdomain_id() = this->parent()->subdomain_id();
2445  this->processor_id() = this->parent()->processor_id();
2446  _map_type = this->parent()->_map_type;
2447  _map_data = this->parent()->_map_data;
2448 
2449 #ifdef LIBMESH_ENABLE_AMR
2450  this->set_p_level(this->parent()->p_level());
2451 #endif
2452  }
2453  }
2454 }
2455 
2456 
2457 
2458 inline
2459 const Point & Elem::point (const unsigned int i) const
2460 {
2461  libmesh_assert_less (i, this->n_nodes());
2462  libmesh_assert(_nodes[i]);
2463  libmesh_assert_not_equal_to (_nodes[i]->id(), Node::invalid_id);
2464 
2465  return *_nodes[i];
2466 }
2467 
2468 
2469 
2470 inline
2471 Point & Elem::point (const unsigned int i)
2472 {
2473  libmesh_assert_less (i, this->n_nodes());
2474 
2475  return *_nodes[i];
2476 }
2477 
2478 
2479 
2480 inline
2481 dof_id_type Elem::node_id (const unsigned int i) const
2482 {
2483  libmesh_assert_less (i, this->n_nodes());
2484  libmesh_assert(_nodes[i]);
2485  libmesh_assert_not_equal_to (_nodes[i]->id(), Node::invalid_id);
2486 
2487  return _nodes[i]->id();
2488 }
2489 
2490 
2491 
2492 inline
2493 unsigned int Elem::local_node (const dof_id_type i) const
2494 {
2495  for (auto n : make_range(this->n_nodes()))
2496  if (this->node_id(n) == i)
2497  return n;
2498 
2499  return libMesh::invalid_uint;
2500 }
2501 
2502 
2503 
2504 inline
2505 const Node * const * Elem::get_nodes () const
2506 {
2507  return _nodes;
2508 }
2509 
2510 
2511 
2512 inline
2513 const Node * Elem::node_ptr (const unsigned int i) const
2514 {
2515  libmesh_assert_less (i, this->n_nodes());
2516  libmesh_assert(_nodes[i]);
2517 
2518  return _nodes[i];
2519 }
2520 
2521 
2522 
2523 inline
2524 Node * Elem::node_ptr (const unsigned int i)
2525 {
2526  libmesh_assert_less (i, this->n_nodes());
2527  libmesh_assert(_nodes[i]);
2528 
2529  return _nodes[i];
2530 }
2531 
2532 
2533 
2534 inline
2535 const Node & Elem::node_ref (const unsigned int i) const
2536 {
2537  return *this->node_ptr(i);
2538 }
2539 
2540 
2541 
2542 inline
2543 Node & Elem::node_ref (const unsigned int i)
2544 {
2545  return *this->node_ptr(i);
2546 }
2547 
2548 
2549 
2550 inline
2551 unsigned int Elem::get_node_index (const Node * node_ptr) const
2552 {
2553  for (auto n : make_range(this->n_nodes()))
2554  if (this->_nodes[n] == node_ptr)
2555  return n;
2556 
2557  return libMesh::invalid_uint;
2558 }
2559 
2560 
2561 
2562 #ifdef LIBMESH_ENABLE_DEPRECATED
2563 inline
2564 Node * & Elem::set_node (const unsigned int i)
2565 {
2566  libmesh_assert_less (i, this->n_nodes());
2567 
2568  libmesh_deprecated();
2569 
2570  return _nodes[i];
2571 }
2572 #endif // LIBMESH_ENABLE_DEPRECATED
2573 
2574 
2575 
2576 inline
2577 void Elem::set_node (const unsigned int i,
2578  Node * node)
2579 {
2580  libmesh_assert_less (i, this->n_nodes());
2581 
2582  _nodes[i] = node;
2583 }
2584 
2585 
2586 
2587 inline
2589 {
2590  return _sbd_id;
2591 }
2592 
2593 
2594 
2595 inline
2597 {
2598  return _sbd_id;
2599 }
2600 
2601 
2602 
2603 inline
2604 bool Elem::operator != (const Elem & rhs) const
2605 {
2606  return !(*this == rhs);
2607 }
2608 
2609 
2610 
2611 inline
2612 const Elem * Elem::neighbor_ptr (unsigned int i) const
2613 {
2614  libmesh_assert_less (i, this->n_neighbors());
2615 
2616  return _elemlinks[i+1];
2617 }
2618 
2619 
2620 
2621 inline
2622 Elem * Elem::neighbor_ptr (unsigned int i)
2623 {
2624  libmesh_assert_less (i, this->n_neighbors());
2625 
2626  return _elemlinks[i+1];
2627 }
2628 
2629 
2630 
2631 inline
2632 void Elem::set_neighbor (const unsigned int i, Elem * n)
2633 {
2634  libmesh_assert_less (i, this->n_neighbors());
2635 
2636  _elemlinks[i+1] = n;
2637 }
2638 
2639 
2640 
2641 inline
2642 bool Elem::has_neighbor (const Elem * elem) const
2643 {
2644  for (auto n : this->neighbor_ptr_range())
2645  if (n == elem)
2646  return true;
2647 
2648  return false;
2649 }
2650 
2651 
2652 
2653 inline
2655 {
2656  for (auto n : elem->neighbor_ptr_range())
2657  if (n && n->parent() == this)
2658  return n;
2659 
2660  return nullptr;
2661 }
2662 
2663 
2664 
2665 inline
2666 const Elem * Elem::child_neighbor (const Elem * elem) const
2667 {
2668  for (auto n : elem->neighbor_ptr_range())
2669  if (n && n->parent() == this)
2670  return n;
2671 
2672  return nullptr;
2673 }
2674 
2675 
2676 
2677 inline
2680 {
2681  return {_nodes, _nodes+this->n_nodes()};
2682 }
2683 
2684 
2685 
2686 inline
2689 {
2690  return {_nodes, _nodes+this->n_nodes()};
2691 }
2692 
2693 
2694 
2695 inline
2698 {
2699  return {0, cast_int<unsigned short>(this->n_nodes())};
2700 }
2701 
2702 
2703 
2704 inline
2707 {
2708  return {0, cast_int<unsigned short>(this->n_edges())};
2709 }
2710 
2711 
2712 
2713 inline
2716 {
2717  return {0, cast_int<unsigned short>(this->n_faces())};
2718 }
2719 
2720 
2721 
2722 inline
2725 {
2726  return {0, cast_int<unsigned short>(this->n_sides())};
2727 }
2728 
2729 
2730 
2731 
2732 inline
2733 std::unique_ptr<const Elem> Elem::side_ptr (unsigned int i) const
2734 {
2735  // Call the non-const version of this function, return the result as
2736  // a std::unique_ptr<const Elem>.
2737  Elem * me = const_cast<Elem *>(this);
2738  return me->side_ptr(i);
2739 }
2740 
2741 
2742 
2743 inline
2744 void
2745 Elem::side_ptr (std::unique_ptr<const Elem> & elem,
2746  const unsigned int i) const
2747 {
2748  // Hand off to the non-const version of this function
2749  Elem * me = const_cast<Elem *>(this);
2750  std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
2751  me->side_ptr(e, i);
2752  elem = std::move(e);
2753 }
2754 
2755 
2756 
2757 inline
2758 std::unique_ptr<const Elem>
2759 Elem::build_side_ptr (const unsigned int i) const
2760 {
2761  // Call the non-const version of this function, return the result as
2762  // a std::unique_ptr<const Elem>.
2763  Elem * me = const_cast<Elem *>(this);
2764  return me->build_side_ptr(i);
2765 }
2766 
2767 
2768 
2769 inline
2770 void
2771 Elem::build_side_ptr (std::unique_ptr<const Elem> & elem,
2772  const unsigned int i) const
2773 {
2774  // Hand off to the non-const version of this function
2775  Elem * me = const_cast<Elem *>(this);
2776  std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
2777  me->build_side_ptr(e, i);
2778  elem = std::move(e);
2779 }
2780 
2781 
2782 
2783 template <typename Sideclass, typename Subclass>
2784 inline
2785 std::unique_ptr<Elem>
2786 Elem::simple_build_side_ptr (const unsigned int i)
2787 {
2788  libmesh_assert_less (i, this->n_sides());
2789 
2790  std::unique_ptr<Elem> face = std::make_unique<Sideclass>();
2791  for (auto n : face->node_index_range())
2792  face->set_node(n, this->node_ptr(Subclass::side_nodes_map[i][n]));
2793 
2794  face->set_interior_parent(this);
2795  face->inherit_data_from(*this);
2796 
2797  return face;
2798 }
2799 
2800 
2801 
2802 template <typename Subclass>
2803 inline
2804 void
2805 Elem::simple_build_side_ptr (std::unique_ptr<Elem> & side,
2806  const unsigned int i,
2807  ElemType sidetype)
2808 {
2809  libmesh_assert_less (i, this->n_sides());
2810 
2811  if (!side.get() || side->type() != sidetype)
2812  {
2813  Subclass & real_me = cast_ref<Subclass&>(*this);
2814  side = real_me.Subclass::build_side_ptr(i);
2815  }
2816  else
2817  {
2818  side->set_interior_parent(this);
2819  side->inherit_data_from(*this);
2820  for (auto n : side->node_index_range())
2821  side->set_node(n, this->node_ptr(Subclass::side_nodes_map[i][n]));
2822  }
2823 }
2824 
2825 
2826 
2827 template <typename Subclass, typename Mapclass>
2828 inline
2829 void
2830 Elem::simple_side_ptr (std::unique_ptr<Elem> & side,
2831  const unsigned int i,
2832  ElemType sidetype)
2833 {
2834  libmesh_assert_less (i, this->n_sides());
2835 
2836  if (!side.get() || side->type() != sidetype)
2837  {
2838  Subclass & real_me = cast_ref<Subclass&>(*this);
2839  side = real_me.Subclass::side_ptr(i);
2840  }
2841  else
2842  {
2843  side->subdomain_id() = this->subdomain_id();
2844 
2845  for (auto n : side->node_index_range())
2846  side->set_node(n, this->node_ptr(Mapclass::side_nodes_map[i][n]));
2847  }
2848 }
2849 
2850 
2851 
2852 inline
2853 std::unique_ptr<const Elem>
2854 Elem::build_edge_ptr (const unsigned int i) const
2855 {
2856  // Call the non-const version of this function, return the result as
2857  // a std::unique_ptr<const Elem>.
2858  Elem * me = const_cast<Elem *>(this);
2859  return me->build_edge_ptr(i);
2860 }
2861 
2862 
2863 
2864 inline
2865 void
2866 Elem::build_edge_ptr (std::unique_ptr<const Elem> & elem,
2867  const unsigned int i) const
2868 {
2869  // Hand off to the non-const version of this function
2870  Elem * me = const_cast<Elem *>(this);
2871  std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
2872  me->build_edge_ptr(e, i);
2873  elem = std::move(e);
2874 }
2875 
2876 
2877 template <typename Edgeclass, typename Subclass>
2878 inline
2879 std::unique_ptr<Elem>
2880 Elem::simple_build_edge_ptr (const unsigned int i)
2881 {
2882  libmesh_assert_less (i, this->n_edges());
2883 
2884  std::unique_ptr<Elem> edge = std::make_unique<Edgeclass>();
2885 
2886  for (auto n : edge->node_index_range())
2887  edge->set_node(n, this->node_ptr(Subclass::edge_nodes_map[i][n]));
2888 
2889  edge->set_interior_parent(this);
2890  edge->inherit_data_from(*this);
2891 
2892  return edge;
2893 }
2894 
2895 
2896 
2897 
2898 template <typename Subclass>
2899 inline
2900 void
2901 Elem::simple_build_edge_ptr (std::unique_ptr<Elem> & edge,
2902  const unsigned int i,
2903  ElemType edgetype)
2904 {
2905  libmesh_assert_less (i, this->n_edges());
2906 
2907  if (!edge.get() || edge->type() != edgetype)
2908  {
2909  Subclass & real_me = cast_ref<Subclass&>(*this);
2910  edge = real_me.Subclass::build_edge_ptr(i);
2911  }
2912  else
2913  {
2914  edge->inherit_data_from(*this);
2915  for (auto n : edge->node_index_range())
2916  edge->set_node(n, this->node_ptr(Subclass::edge_nodes_map[i][n]));
2917  }
2918 }
2919 
2920 
2921 
2922 inline
2923 bool Elem::on_boundary () const
2924 {
2925  // By convention, the element is on the boundary
2926  // if it has a nullptr neighbor.
2927  return this->has_neighbor(nullptr);
2928 }
2929 
2930 
2931 
2932 inline
2933 unsigned int Elem::which_neighbor_am_i (const Elem * e) const
2934 {
2935  libmesh_assert(e);
2936 
2937  const Elem * eparent = e;
2938 
2939  while (eparent->level() > this->level())
2940  {
2941  eparent = eparent->parent();
2942  libmesh_assert(eparent);
2943  }
2944 
2945  for (auto s : make_range(this->n_sides()))
2946  if (this->neighbor_ptr(s) == eparent)
2947  return s;
2948 
2949  return libMesh::invalid_uint;
2950 }
2951 
2952 
2953 
2954 inline
2955 bool Elem::active() const
2956 {
2957 #ifdef LIBMESH_ENABLE_AMR
2958  if ((this->refinement_flag() == INACTIVE) ||
2959  (this->refinement_flag() == COARSEN_INACTIVE))
2960  return false;
2961  else
2962  return true;
2963 #else
2964  return true;
2965 #endif
2966 }
2967 
2968 
2969 
2970 
2971 
2972 inline
2973 bool Elem::subactive() const
2974 {
2975 #ifdef LIBMESH_ENABLE_AMR
2976  if (this->active())
2977  return false;
2978  if (!this->has_children())
2979  return true;
2980  for (const Elem * my_ancestor = this->parent();
2981  my_ancestor != nullptr;
2982  my_ancestor = my_ancestor->parent())
2983  if (my_ancestor->active())
2984  return true;
2985 #endif
2986 
2987  return false;
2988 }
2989 
2990 
2991 
2992 inline
2994 {
2995 #ifdef LIBMESH_ENABLE_AMR
2996  if (!_children)
2997  return false;
2998  else
2999  return true;
3000 #else
3001  return false;
3002 #endif
3003 }
3004 
3005 
3006 inline
3008 {
3009 #ifdef LIBMESH_ENABLE_AMR
3010  if (!_children)
3011  return false;
3012  else
3013  for (auto & c : child_ref_range())
3014  if (c.has_children())
3015  return true;
3016 #endif
3017  return false;
3018 }
3019 
3020 
3021 
3022 inline
3024 #ifdef LIBMESH_ENABLE_AMR
3025  descendant
3026 #endif
3027  ) const
3028 {
3029 #ifdef LIBMESH_ENABLE_AMR
3030  const Elem * e = descendant;
3031  while (e)
3032  {
3033  if (this == e)
3034  return true;
3035  e = e->parent();
3036  }
3037 #endif
3038  return false;
3039 }
3040 
3041 
3042 
3043 inline
3044 const Elem * Elem::parent () const
3045 {
3046  return _elemlinks[0];
3047 }
3048 
3049 
3050 
3051 inline
3053 {
3054  return _elemlinks[0];
3055 }
3056 
3057 
3058 
3059 inline
3061 {
3062  // We no longer support using parent() as interior_parent()
3063  libmesh_assert_equal_to(this->dim(), p ? p->dim() : this->dim());
3064  _elemlinks[0] = p;
3065 }
3066 
3067 
3068 
3069 inline
3070 const Elem * Elem::top_parent () const
3071 {
3072  const Elem * tp = this;
3073 
3074  // Keep getting the element's parent
3075  // until that parent is at level-0
3076  while (tp->parent() != nullptr)
3077  tp = tp->parent();
3078 
3079  libmesh_assert(tp);
3080  libmesh_assert_equal_to (tp->level(), 0);
3081 
3082  return tp;
3083 }
3084 
3085 
3086 
3087 inline
3088 unsigned int Elem::level() const
3089 {
3090 #ifdef LIBMESH_ENABLE_AMR
3091 
3092  // if I don't have a parent I was
3093  // created directly from file
3094  // or by the user, so I am a
3095  // level-0 element
3096  if (this->parent() == nullptr)
3097  return 0;
3098 
3099  // if the parent and this element are of different
3100  // dimensionality we are at the same level as
3101  // the parent (e.g. we are the 2D side of a
3102  // 3D element)
3103  if (this->dim() != this->parent()->dim())
3104  return this->parent()->level();
3105 
3106  // otherwise we are at a level one
3107  // higher than our parent
3108  return (this->parent()->level() + 1);
3109 
3110 #else
3111 
3112  // Without AMR all elements are
3113  // at level 0.
3114  return 0;
3115 
3116 #endif
3117 }
3118 
3119 
3120 
3121 inline
3122 unsigned int Elem::p_level() const
3123 {
3124 #ifdef LIBMESH_ENABLE_AMR
3125  return _p_level;
3126 #else
3127  return 0;
3128 #endif
3129 }
3130 
3131 
3132 
3133 inline
3135 {
3136  return static_cast<ElemMappingType>(_map_type);
3137 }
3138 
3139 
3140 
3141 inline
3143 {
3144  _map_type = cast_int<unsigned char>(type);
3145 }
3146 
3147 
3148 
3149 inline
3150 unsigned char Elem::mapping_data () const
3151 {
3152  return _map_data;
3153 }
3154 
3155 
3156 
3157 inline
3158 void Elem::set_mapping_data(const unsigned char data)
3159 {
3160  _map_data = data;
3161 }
3162 
3163 
3164 
3165 #ifdef LIBMESH_ENABLE_AMR
3166 
3167 inline
3168 const Elem * Elem::raw_child_ptr (unsigned int i) const
3169 {
3170  if (!_children)
3171  return nullptr;
3172 
3173  return _children[i];
3174 }
3175 
3176 inline
3177 const Elem * Elem::child_ptr (unsigned int i) const
3178 {
3181 
3182  return _children[i];
3183 }
3184 
3185 inline
3186 Elem * Elem::child_ptr (unsigned int i)
3187 {
3190 
3191  return _children[i];
3192 }
3193 
3194 
3195 inline
3196 void Elem::set_child (unsigned int c, Elem * elem)
3197 {
3198  libmesh_assert (this->has_children());
3199 
3200  _children[c] = elem;
3201 }
3202 
3203 
3204 
3205 inline
3206 unsigned int Elem::which_child_am_i (const Elem * e) const
3207 {
3208  libmesh_assert(e);
3209  libmesh_assert (this->has_children());
3210 
3211  unsigned int nc = this->n_children();
3212  for (unsigned int c=0; c != nc; c++)
3213  if (this->child_ptr(c) == e)
3214  return c;
3215 
3216  libmesh_error_msg("ERROR: which_child_am_i() was called with a non-child!");
3217 
3218  return libMesh::invalid_uint;
3219 }
3220 
3221 
3222 
3223 inline
3225 {
3226  return static_cast<RefinementState>(_rflag);
3227 }
3228 
3229 
3230 
3231 inline
3233 {
3234  _rflag = cast_int<unsigned char>(rflag);
3235 }
3236 
3237 
3238 
3239 inline
3241 {
3242  return static_cast<RefinementState>(_pflag);
3243 }
3244 
3245 
3246 
3247 inline
3249 {
3250  if (this->p_level() == 0)
3251  libmesh_assert_not_equal_to
3252  (pflag, Elem::JUST_REFINED);
3253 
3254  _pflag = cast_int<unsigned char>(pflag);
3255 }
3256 
3257 
3258 
3259 inline
3260 unsigned int Elem::max_descendant_p_level () const
3261 {
3262  // This is undefined for subactive elements,
3263  // which have no active descendants
3264  libmesh_assert (!this->subactive());
3265  if (this->active())
3266  return this->p_level();
3267 
3268  unsigned int max_p_level = _p_level;
3269  for (auto & c : child_ref_range())
3270  max_p_level = std::max(max_p_level,
3271  c.max_descendant_p_level());
3272  return max_p_level;
3273 }
3274 
3275 
3276 
3277 inline
3278 void Elem::hack_p_level(unsigned int p)
3279 {
3280  if (p == 0)
3281  libmesh_assert_not_equal_to
3283 
3284  _p_level = cast_int<unsigned char>(p);
3285 }
3286 
3287 
3288 inline
3290  RefinementState pflag)
3291 {
3292  _pflag = cast_int<unsigned char>(pflag);
3293  this->hack_p_level(p);
3294 }
3295 
3296 #endif // ifdef LIBMESH_ENABLE_AMR
3297 
3298 
3299 inline
3300 void Elem::orient(BoundaryInfo * boundary_info)
3301 {
3302  if (this->is_flipped())
3303  this->flip(boundary_info);
3304 }
3305 
3306 
3307 inline
3309 {
3310  return n0;
3311 }
3312 
3313 
3314 
3315 inline
3317  dof_id_type n1)
3318 {
3319  // Order the two so that n0 < n1
3320  if (n0 > n1) std::swap (n0, n1);
3321 
3322  return Utility::hashword2(n0, n1);
3323 }
3324 
3325 
3326 
3327 inline
3329  dof_id_type n1,
3330  dof_id_type n2)
3331 {
3332  std::array<dof_id_type, 3> array = {{n0, n1, n2}};
3333  std::sort(array.begin(), array.end());
3334  return Utility::hashword(array);
3335 }
3336 
3337 
3338 
3339 inline
3341  dof_id_type n1,
3342  dof_id_type n2,
3343  dof_id_type n3)
3344 {
3345  std::array<dof_id_type, 4> array = {{n0, n1, n2, n3}};
3346  std::sort(array.begin(), array.end());
3347  return Utility::hashword(array);
3348 }
3349 
3350 
3351 
3352 inline
3353 void Elem::inherit_data_from (const Elem & src)
3354 {
3355  this->set_mapping_type(src.mapping_type());
3356  this->set_mapping_data(src.mapping_data());
3357  this->subdomain_id() = src.subdomain_id();
3358  this->processor_id(src.processor_id());
3359 #ifdef LIBMESH_ENABLE_AMR
3360  this->set_p_level(src.p_level());
3361 #endif
3362 }
3363 
3364 
3365 
3370 {
3371 public:
3372  // Constructor with arguments.
3373  SideIter(const unsigned int side_number,
3374  Elem * parent)
3375  : _side(),
3376  _side_ptr(nullptr),
3377  _parent(parent),
3378  _side_number(side_number)
3379  {}
3380 
3381 
3382  // Empty constructor.
3384  : _side(),
3385  _side_ptr(nullptr),
3386  _parent(nullptr),
3388  {}
3389 
3390 
3391  // Copy constructor
3392  SideIter(const SideIter & other)
3393  : _side(),
3394  _side_ptr(nullptr),
3395  _parent(other._parent),
3396  _side_number(other._side_number)
3397  {}
3398 
3399 
3400  // op=
3401  SideIter & operator=(const SideIter & other)
3402  {
3403  this->_parent = other._parent;
3404  this->_side_number = other._side_number;
3405  return *this;
3406  }
3407 
3408  // unary op*
3409  Elem *& operator*() const
3410  {
3411  // Set the std::unique_ptr
3412  this->_update_side_ptr();
3413 
3414  // Return a reference to _side_ptr
3415  return this->_side_ptr;
3416  }
3417 
3418  // op++
3420  {
3421  ++_side_number;
3422  return *this;
3423  }
3424 
3425  // op== Two side iterators are equal if they have
3426  // the same side number and the same parent element.
3427  bool operator == (const SideIter & other) const
3428  {
3429  return (this->_side_number == other._side_number &&
3430  this->_parent == other._parent);
3431  }
3432 
3433 
3434  // Consults the parent Elem to determine if the side
3435  // is a boundary side. Note: currently side N is a
3436  // boundary side if neighbor N is nullptr. Be careful,
3437  // this could possibly change in the future?
3438  bool side_on_boundary() const
3439  {
3440  return this->_parent->neighbor_ptr(_side_number) == nullptr;
3441  }
3442 
3443 private:
3444  // Update the _side pointer by building the correct side.
3445  // This has to be called before dereferencing.
3446  void _update_side_ptr() const
3447  {
3448  // Construct new side, store in std::unique_ptr
3449  this->_side = this->_parent->build_side_ptr(this->_side_number);
3450 
3451  // Also set our internal naked pointer. Memory is still owned
3452  // by the std::unique_ptr.
3453  this->_side_ptr = _side.get();
3454  }
3455 
3456  // std::unique_ptr to the actual side, handles memory management for
3457  // the sides which are created during the course of iteration.
3458  mutable std::unique_ptr<Elem> _side;
3459 
3460  // Raw pointer needed to facilitate passing back to the user a
3461  // reference to a non-temporary raw pointer in order to conform to
3462  // the variant_filter_iterator interface. It points to the same
3463  // thing the std::unique_ptr "_side" above holds. What happens if the user
3464  // calls delete on the pointer passed back? Well, this is an issue
3465  // which is not addressed by the iterators in libMesh. Basically it
3466  // is a bad idea to ever call delete on an iterator from the library.
3467  mutable Elem * _side_ptr;
3468 
3469  // Pointer to the parent Elem class which generated this iterator
3471 
3472  // A counter variable which keeps track of the side number
3473  unsigned int _side_number;
3474 };
3475 
3476 
3477 
3478 
3479 
3480 
3481 // Private implementation functions in the Elem class for the side iterators.
3482 // They have to come after the definition of the SideIter class.
3483 inline
3485 {
3486  return SideIter(0, this);
3487 }
3488 
3489 
3490 
3491 inline
3493 {
3494  return SideIter(this->n_neighbors(), this);
3495 }
3496 
3497 
3498 
3499 
3503 struct
3505 {
3506  // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
3507  template <typename PredType, typename IterType>
3508  side_iterator (const IterType & d,
3509  const IterType & e,
3510  const PredType & p ) :
3512 };
3513 
3514 
3515 
3516 inline
3518 {
3519  return {_elemlinks+1, _elemlinks + 1 + this->n_neighbors()};
3520 }
3521 
3522 
3523 inline
3525 {
3526  return {_elemlinks+1, _elemlinks + 1 + this->n_neighbors()};
3527 }
3528 
3529 } // namespace libMesh
3530 
3531 
3532 // Helper function for default caches in Elem subclasses
3533 
3534 #define LIBMESH_ENABLE_TOPOLOGY_CACHES \
3535  virtual \
3536  std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> & \
3537  _get_bracketing_node_cache() const override \
3538  { \
3539  static std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> c; \
3540  return c; \
3541  } \
3542  \
3543  virtual \
3544  std::vector<std::vector<std::vector<signed char>>> & \
3545  _get_parent_indices_cache() const override \
3546  { \
3547  static std::vector<std::vector<std::vector<signed char>>> c; \
3548  return c; \
3549  }
3550 
3551 
3552 
3553 
3554 
3555 
3556 #endif // LIBMESH_ELEM_H
virtual Point true_centroid() const
Definition: elem.C:575
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:2306
bool has_neighbor(const Elem *elem) const
Definition: elem.h:2642
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:3150
virtual bool is_vertex_on_parent(unsigned int c, unsigned int n) const
Definition: elem.C:3532
std::unique_ptr< Elem > simple_build_side_ptr(const unsigned int i)
An implementation for simple (all sides equal) elements.
Definition: elem.h:2786
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:990
RefinementState refinement_flag() const
Definition: elem.h:3224
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:3595
virtual Point quasicircumcenter() const
Definition: elem.h:1046
unsigned char _map_type
Mapping function type; currently either 0 (LAGRANGE) or 1 (RATIONAL_BERNSTEIN).
Definition: elem.h:2303
unsigned char _map_data
Mapping function data; currently used when needed to store the RATIONAL_BERNSTEIN nodal weight data i...
Definition: elem.h:2309
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:1740
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i, bool proxy)
Definition: elem.h:926
const Elem * parent() const
Definition: elem.h:3044
virtual const std::vector< std::pair< dof_id_type, dof_id_type > > bracketing_nodes(unsigned int c, unsigned int n) const
Definition: elem.C:2684
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:2948
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:484
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:2194
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:2564
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:3023
Node ** _nodes
Pointers to the nodes we are connected to.
Definition: elem.h:2251
Elem * child_neighbor(Elem *elem)
Definition: elem.h:2654
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:3352
Predicates::multi_predicate Predicate
Useful iterator typedefs.
Definition: elem.h:1866
virtual Order default_side_order() const
Definition: elem.h:1011
virtual Point origin() const
Definition: elem.h:1920
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:303
void set_parent(Elem *p)
Sets the pointer to the element&#39;s parent.
Definition: elem.h:3060
unsigned int get_node_index(const Node *node_ptr) const
Definition: elem.h:2551
std::string get_info() const
Prints relevant information about the element to a string.
Definition: elem.C:2956
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:678
Original Authors: Corwin Joy * Michael Gradman cjoy@houston.rr.com * Michael.Gradman@caminus.com 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:1160
const Elem * topological_neighbor(const unsigned int i, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
Definition: elem.C:1287
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:3300
void set_mapping_type(const ElemMappingType type)
Sets the value of the mapping type for the element.
Definition: elem.h:3142
virtual bool is_face(const unsigned int i) const =0
bool is_semilocal(const processor_id_type my_pid) const
Definition: elem.C:840
unsigned char _pflag
p refinement flag.
Definition: elem.h:2286
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:2296
IntRange< unsigned short > side_index_range() const
Definition: elem.h:2724
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:1345
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i)=0
virtual dof_id_type key() const
Definition: elem.C:738
static constexpr Real TOLERANCE
const Elem * top_parent() const
Definition: elem.h:3070
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:2057
unsigned int which_side_am_i(const Elem *e) const
This function tells you which side the boundary element e is.
Definition: elem.C:855
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:3373
virtual ~Elem()=default
Destructor.
RefinementState p_refinement_flag() const
Definition: elem.h:3240
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:1188
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:1146
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:628
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:2248
bool operator==(const SideIter &other) const
Definition: elem.h:3427
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:2110
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:2053
virtual BoundingBox loose_bounding_box() const
Definition: elem.C:3498
SideIter & operator=(const SideIter &other)
Definition: elem.h:3401
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:2379
RefinementState
Enumeration of possible element refinement states.
Definition: elem.h:1443
void set_refinement_flag(const RefinementState rflag)
Sets the value of the refinement flag for the element.
Definition: elem.h:3232
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:2142
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:3579
virtual unsigned int n_children() const =0
ChildRefIter(Elem *const *childpp)
Definition: elem.h:2338
unsigned int _side_number
Definition: elem.h:3473
unsigned int p_level() const
Definition: elem.h:3122
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:1057
side_iterator boundary_sides_end()
Definition: elem.C:3453
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:1542
The libMesh namespace provides an interface to certain functionality in the library.
SideIter & operator++()
Definition: elem.h:3419
virtual Real hmax() const
Definition: elem.C:707
virtual bool is_linear() const
Definition: elem.h:1204
unsigned int min_p_level_by_neighbor(const Elem *neighbor, unsigned int current_min) const
Definition: elem.C:2350
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:1222
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:643
bool contains_vertex_of(const Elem *e, bool mesh_connection=false) const
Definition: elem.C:908
uint8_t processor_id_type
Definition: id_types.h:104
This is the MeshBase class.
Definition: mesh_base.h:80
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
Definition: elem.h:2352
bool ancestor() const
Definition: elem.C:2019
bool has_topological_neighbor(const Elem *elem, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
Definition: elem.C:1324
IntRange< unsigned short > edge_index_range() const
Definition: elem.h:2706
void swap3neighbors(unsigned int n1, unsigned int n2, unsigned int n3)
Swaps three neighbor_ptrs, "rotating" them.
Definition: elem.h:2139
side_iterator boundary_sides_begin()
Iterator accessor functions.
Definition: elem.C:3444
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:3409
virtual void refine(MeshRefinement &mesh_refinement)
Refine the element.
const Elem *const * ConstNeighborPtrIter
Definition: elem.h:335
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:2130
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:2158
void replace_child(Elem *elem, unsigned int c)
Replaces the child pointer at the specified index in the child array.
Definition: elem.C:2099
void swap4nodes(unsigned int n1, unsigned int n2, unsigned int n3, unsigned int n4)
Swaps four node_ptrs, "rotating" them.
Definition: elem.h:2149
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:2268
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:1648
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:2229
Elem *const * NeighborPtrIter
Nested "classes" for use iterating over all neighbors of an element.
Definition: elem.h:334
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const
Definition: elem.C:2784
Implements (adaptive) mesh refinement algorithms for a MeshBase.
virtual Order supported_nodal_order() const
Definition: elem.h:1004
Real length(const unsigned int n1, const unsigned int n2) const
Definition: elem.C:727
IntRange< unsigned short > face_index_range() const
Definition: elem.h:2715
ElemMappingType mapping_type() const
Definition: elem.h:3134
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:1429
void swap2nodes(unsigned int n1, unsigned int n2)
Swaps two node_ptrs.
Definition: elem.h:2098
const Node & node_ref(const unsigned int i) const
Definition: elem.h:2535
dof_id_type id() const
Definition: dof_object.h:819
virtual Real hmin() const
Definition: elem.C:683
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:473
virtual unsigned int n_nodes() const =0
virtual unsigned int local_side_node(unsigned int side, unsigned int side_node) const =0
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:742
bool contains_edge_of(const Elem *e) const
Definition: elem.C:946
unsigned int which_neighbor_am_i(const Elem *e) const
This function tells you which neighbor e is.
Definition: elem.h:2933
virtual unsigned int as_parent_node(unsigned int c, unsigned int n) const
Definition: elem.C:2413
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:3564
virtual std::pair< unsigned short int, unsigned short int > second_order_child_vertex(const unsigned int n) const
Definition: elem.C:3091
static constexpr bool infinite()
Definition: elem.h:1924
Elem ** _elemlinks
Pointers to this element&#39;s parent and neighbors, and for lower-dimensional elements&#39; interior_parent...
Definition: elem.h:2257
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:967
void set_mapping_data(const unsigned char data)
Sets the value of the mapping data for the element.
Definition: elem.h:3158
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:3503
const Node *const * get_nodes() const
Definition: elem.h:2505
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:2821
void _update_side_ptr() const
Definition: elem.h:3446
bool side_on_boundary() const
Definition: elem.h:3438
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:3519
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:1357
virtual bool is_remote() const
Definition: elem.h:596
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:3073
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:3289
SideIter _last_side()
Definition: elem.h:3492
static constexpr Real affine_tol
Default tolerance to use in has_affine_map().
Definition: elem.h:2067
bool positive_edge_orientation(const unsigned int i) const
Definition: elem.C:3634
void set_neighbor(const unsigned int i, Elem *n)
Assigns n as the neighbor.
Definition: elem.h:2632
This class implements reference counting.
bool operator!=(const Elem &rhs) const
Definition: elem.h:2604
subdomain_id_type _sbd_id
The subdomain to which this element belongs.
Definition: elem.h:2273
static ElemType second_order_equivalent_type(const ElemType et, const bool full_ordered=true)
Definition: elem.C:3168
bool on_boundary() const
Definition: elem.h:2923
Elem(const unsigned int n_nodes, const unsigned int n_sides, Elem *parent, Elem **elemlinkdata, Node **nodelinkdata)
Constructor.
Definition: elem.h:2384
unsigned int which_child_am_i(const Elem *e) const
Definition: elem.h:3206
unsigned int max_descendant_p_level() const
Definition: elem.h:3260
unsigned char _rflag
h refinement flag.
Definition: elem.h:2280
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:2108
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:2288
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:2230
SimpleRange< NodeRefIter > node_ref_range()
Returns a range with all nodes of an element, usable in range-based for loops.
Definition: elem.h:2679
Defines a Cartesian bounding box by the two corner extremum.
Definition: bounding_box.h:40
std::unique_ptr< Elem > _side
Definition: elem.h:3458
ElemMappingType
Enumeration of possible element master->physical mapping types.
ConstNodeRefIter(const Node *const *nodepp)
Definition: elem.h:2329
virtual unsigned int n_sides() const =0
bool topologically_equal(const Elem &rhs) const
Definition: elem.C:788
const Elem * neighbor_ptr(unsigned int i) const
Definition: elem.h:2612
virtual bool close_to_point(const Point &p, Real tol) const
Definition: elem.C:2809
unsigned int level() const
Definition: elem.h:3088
const Elem * raw_child_ptr(unsigned int i) const
Definition: elem.h:3168
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:1837
subdomain_id_type subdomain_id() const
Definition: elem.h:2588
virtual bool is_singular_node(unsigned int) const
Definition: elem.h:1844
virtual unsigned short dim() const =0
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:2513
SideIter(const SideIter &other)
Definition: elem.h:3392
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:713
virtual Real quality(const ElemQuality q) const
Definition: elem.C:1783
virtual unsigned short int second_order_adjacent_vertex(const unsigned int n, const unsigned int v) const
Definition: elem.C:3081
bool subactive() const
Definition: elem.h:2973
virtual Real volume() const
Definition: elem.C:3462
void swap4neighbors(unsigned int n1, unsigned int n2, unsigned int n3, unsigned int n4)
Swaps four neighbor_ptrs, "rotating" them.
Definition: elem.h:2159
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:176
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:3196
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:3007
virtual bool has_invertible_map(Real tol=TOLERANCE *TOLERANCE) const
Definition: elem.C:2914
IntRange< unsigned short > node_index_range() const
Definition: elem.h:2697
bool positive_face_orientation(const unsigned int i) const
Definition: elem.C:3643
void total_family_tree_by_side(std::vector< const Elem *> &family, unsigned int side, bool reset=true) const
Same as the total_family_tree() member, but only adds elements which are next to side.
Definition: elem.C:2176
unsigned int local_node(const dof_id_type i) const
Definition: elem.h:2493
virtual bool is_vertex_on_child(unsigned int, unsigned int n) const
Definition: elem.h:773
void nullify_neighbors()
Replaces this element with nullptr for all of its neighbors.
Definition: elem.C:3047
SimpleRange< NeighborPtrIter > neighbor_ptr_range()
Returns a range with all neighbors of an element, usable in range-based for loops.
Definition: elem.h:3517
void set_p_refinement_flag(const RefinementState pflag)
Sets the value of the p-refinement flag for the element.
Definition: elem.h:3248
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:3353
virtual bool infinite() const =0
virtual std::pair< Real, Real > qual_bounds(const ElemQuality) const
Definition: elem.h:1106
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:2830
static dof_id_type compute_key(dof_id_type n0)
Definition: elem.h:3308
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:2126
std::unique_ptr< const Elem > build_side_ptr(const unsigned int i, bool proxy) const
Definition: elem.h:929
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:2212
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:2346
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:2880
virtual const std::vector< std::pair< unsigned char, unsigned char > > & parent_bracketing_nodes(unsigned int c, unsigned int n) const
Definition: elem.C:2481
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:2215
virtual unsigned int opposite_side(const unsigned int s) const
Definition: elem.C:3556
bool active() const
Definition: elem.h:2955
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:3278
static ElemType first_order_equivalent_type(const ElemType et)
Definition: elem.C:3099
processor_id_type processor_id() const
Definition: dof_object.h:881
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:2481
const Point & point(const unsigned int i) const
Definition: elem.h:2459
bool operator==(const Elem &rhs) const
Definition: elem.C:756
side_iterator(const IterType &d, const IterType &e, const PredType &p)
Definition: elem.h:3508
bool has_children() const
Definition: elem.h:2993
virtual unsigned int center_node_on_side(const unsigned short side) const
Definition: elem.C:3572
void ErrorVector unsigned int
Definition: adjoints_ex3.C:360
NodeRefIter(Node *const *nodepp)
Definition: elem.h:2321
std::unique_ptr< Elem *[]> _children
unique_ptr to array of this element&#39;s children.
Definition: elem.h:2267
virtual bool is_child_on_edge(const unsigned int c, const unsigned int e) const
Definition: elem.C:2333
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:667
Point vertex_average() const
Definition: elem.C:669
static const unsigned int max_n_nodes
The maximum number of nodes any element can contain.
Definition: elem.h:654
const Elem * child_ptr(unsigned int i) const
Definition: elem.h:3177
bool relative_edge_face_order(const unsigned int e, const unsigned int s) const
Definition: elem.C:3664
uint8_t dof_id_type
Definition: id_types.h:67
The definition of the protected nested SideIter class.
Definition: elem.h:3369
virtual bool is_mid_infinite_edge_node(const unsigned int) const
Definition: elem.h:1911
bool is_internal(const unsigned int i) const
Definition: elem.C:3611
SideIter _first_side()
Side iterator helper functions.
Definition: elem.h:3484