libMesh
Loading...
Searching...
No Matches
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
48namespace libMesh
49{
50
51// Forward declarations
52class BoundaryInfo;
53class Elem;
54class MeshBase;
55class MeshRefinement;
56#ifdef LIBMESH_ENABLE_PERIODIC
57class PeriodicBoundaries;
58class PointLocatorBase;
59#endif
60template <class SideType, class ParentType>
61class Side;
62enum ElemQuality : int;
63enum IOPackage : int;
64enum Order : int;
65
66
94class Elem : public ReferenceCountedObject<Elem>,
95 public DofObject
96{
97protected:
98
105 Elem (const unsigned int n_nodes,
106 const unsigned int n_sides,
107 Elem * parent,
108 Elem ** elemlinkdata,
109 Node ** nodelinkdata);
110
111public:
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
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
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
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
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
1099 virtual Real quality (const ElemQuality q) const;
1100
1109 virtual std::pair<Real,Real> qual_bounds (const ElemQuality) const
1110 { libmesh_not_implemented(); return std::make_pair(0.,0.); }
1111
1127 virtual bool contains_point (const Point & p, Real tol=TOLERANCE) const;
1128
1137 virtual bool on_reference_element(const Point & p,
1138 const Real eps = TOLERANCE) const = 0;
1139
1144 virtual bool close_to_point(const Point & p, Real tol) const;
1145
1151 bool positive_edge_orientation(const unsigned int i) const;
1152
1160 bool positive_face_orientation(const unsigned int i) const;
1161
1167 bool relative_edge_face_order(const unsigned int e, const unsigned int s) const;
1168
1175 void inherit_data_from(const Elem & src);
1176
1177private:
1184 bool point_test(const Point & p, Real box_tol, Real map_tol) const;
1185
1186public:
1191 virtual bool has_affine_map () const { return false; }
1192
1201 virtual bool has_invertible_map(Real tol = TOLERANCE*TOLERANCE) const;
1202
1207 virtual bool is_linear () const { return false; }
1208
1212 void print_info (std::ostream & os=libMesh::out) const;
1213
1217 std::string get_info () const;
1218
1225 bool active () const;
1226
1232 bool ancestor () const;
1233
1238 bool subactive () const;
1239
1244 bool has_children () const;
1245
1250 bool has_ancestor_children () const;
1251
1257 bool is_ancestor_of(const Elem * descendant) const;
1258
1263 const Elem * parent () const;
1264
1269 Elem * parent ();
1270
1275 void set_parent (Elem * p);
1276
1284 const Elem * top_parent () const;
1285
1300 const Elem * interior_parent () const;
1301
1302 Elem * interior_parent ();
1303
1308 void set_interior_parent (Elem * p);
1309
1315 Real length (const unsigned int n1,
1316 const unsigned int n2) const;
1317
1328 virtual unsigned int n_second_order_adjacent_vertices (const unsigned int n) const;
1329
1338 virtual unsigned short int second_order_adjacent_vertex (const unsigned int n,
1339 const unsigned int v) const;
1340
1356 virtual std::pair<unsigned short int, unsigned short int>
1357 second_order_child_vertex (const unsigned int n) const;
1358
1373 const bool full_ordered=true);
1374
1383
1397
1405 unsigned int level () const;
1406
1412 unsigned int p_level () const;
1413
1417 virtual bool is_child_on_side(const unsigned int c,
1418 const unsigned int s) const = 0;
1419
1424
1429
1433 unsigned char mapping_data () const;
1434
1438 void set_mapping_data (const unsigned char data);
1439
1440
1441#ifdef LIBMESH_ENABLE_AMR
1442
1454
1459 const Elem * raw_child_ptr (unsigned int i) const;
1460
1465 const Elem * child_ptr (unsigned int i) const;
1466
1471 Elem * child_ptr (unsigned int i);
1472
1477 class ChildRefIter;
1478 class ConstChildRefIter;
1479
1488
1490
1491private:
1496 void set_child (unsigned int c, Elem * elem);
1497
1498public:
1505 unsigned int which_child_am_i(const Elem * e) const;
1506
1510 virtual bool is_child_on_edge(const unsigned int c,
1511 const unsigned int e) const;
1512
1519 void add_child (Elem * elem);
1520
1527 void add_child (Elem * elem, unsigned int c);
1528
1532 void replace_child (Elem * elem, unsigned int c);
1533
1545 void family_tree (std::vector<const Elem *> & family,
1546 bool reset = true) const;
1547
1551 void family_tree (std::vector<Elem *> & family,
1552 bool reset = true);
1553
1558 void total_family_tree (std::vector<const Elem *> & family,
1559 bool reset = true) const;
1560
1564 void total_family_tree (std::vector<Elem *> & family,
1565 bool reset = true);
1566
1573 void active_family_tree (std::vector<const Elem *> & active_family,
1574 bool reset = true) const;
1575
1579 void active_family_tree (std::vector<Elem *> & active_family,
1580 bool reset = true);
1581
1586 void family_tree_by_side (std::vector<const Elem *> & family,
1587 unsigned int side,
1588 bool reset = true) const;
1589
1593 void family_tree_by_side (std::vector<Elem *> & family,
1594 unsigned int side,
1595 bool reset = true);
1596
1601 void total_family_tree_by_side (std::vector<const Elem *> & family,
1602 unsigned int side,
1603 bool reset = true) const;
1604
1608 void total_family_tree_by_side (std::vector<Elem *> & family,
1609 unsigned int side,
1610 bool reset = true);
1611
1616 void active_family_tree_by_side (std::vector<const Elem *> & family,
1617 unsigned int side,
1618 bool reset = true) const;
1619
1623 void active_family_tree_by_side (std::vector<Elem *> & family,
1624 unsigned int side,
1625 bool reset = true);
1626
1631 void family_tree_by_neighbor (std::vector<const Elem *> & family,
1632 const Elem * neighbor,
1633 bool reset = true) const;
1634
1638 void family_tree_by_neighbor (std::vector<Elem *> & family,
1639 Elem * neighbor,
1640 bool reset = true);
1641
1646 void total_family_tree_by_neighbor (std::vector<const Elem *> & family,
1647 const Elem * neighbor,
1648 bool reset = true) const;
1649
1653 void total_family_tree_by_neighbor (std::vector<Elem *> & family,
1654 Elem * neighbor,
1655 bool reset = true);
1656
1663 void family_tree_by_subneighbor (std::vector<const Elem *> & family,
1664 const Elem * neighbor,
1665 const Elem * subneighbor,
1666 bool reset = true) const;
1667
1671 void family_tree_by_subneighbor (std::vector<Elem *> & family,
1672 Elem * neighbor,
1673 Elem * subneighbor,
1674 bool reset = true);
1675
1680 void total_family_tree_by_subneighbor (std::vector<const Elem *> & family,
1681 const Elem * neighbor,
1682 const Elem * subneighbor,
1683 bool reset = true) const;
1684
1688 void total_family_tree_by_subneighbor (std::vector<Elem *> & family,
1689 Elem * neighbor,
1690 Elem * subneighbor,
1691 bool reset = true);
1692
1697 void active_family_tree_by_neighbor (std::vector<const Elem *> & family,
1698 const Elem * neighbor,
1699 bool reset = true) const;
1700
1704 void active_family_tree_by_neighbor (std::vector<Elem *> & family,
1705 Elem * neighbor,
1706 bool reset = true);
1707
1713 void active_family_tree_by_topological_neighbor (std::vector<const Elem *> & family,
1714 const Elem * neighbor,
1715 const MeshBase & mesh,
1716 const PointLocatorBase & point_locator,
1717 const PeriodicBoundaries * pb,
1718 bool reset = true) const;
1719
1723 void active_family_tree_by_topological_neighbor (std::vector<Elem *> & family,
1724 Elem * neighbor,
1725 const MeshBase & mesh,
1726 const PointLocatorBase & point_locator,
1727 const PeriodicBoundaries * pb,
1728 bool reset = true);
1729
1734
1738 void set_refinement_flag (const RefinementState rflag);
1739
1744
1748 void set_p_refinement_flag (const RefinementState pflag);
1749
1754 unsigned int max_descendant_p_level () const;
1755
1761 unsigned int min_p_level_by_neighbor (const Elem * neighbor,
1762 unsigned int current_min) const;
1763
1769 unsigned int min_new_p_level_by_neighbor (const Elem * neighbor,
1770 unsigned int current_min) const;
1771
1777 void set_p_level (const unsigned int p);
1778
1783 void hack_p_level (const unsigned int p);
1784
1791 void hack_p_level_and_refinement_flag (const unsigned int p,
1792 RefinementState pflag);
1793
1797 virtual void refine (MeshRefinement & mesh_refinement);
1798
1803 void coarsen ();
1804
1811 void contract ();
1812
1813#endif
1814
1815#ifndef NDEBUG
1819 void libmesh_assert_valid_neighbors() const;
1820
1826#endif // !NDEBUG
1827
1840 virtual unsigned int local_singular_node(const Point & /* p */, const Real /* tol */ = TOLERANCE*TOLERANCE) const
1841 { return invalid_uint; }
1842
1847 virtual bool is_singular_node(unsigned int /* node_i */) const { return false; }
1848
1855 virtual unsigned int center_node_on_side(const unsigned short side) const;
1856
1857protected:
1858
1869 class SideIter;
1870
1871public:
1876
1881 struct side_iterator;
1882
1888
1889private:
1896
1897public:
1898
1899#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
1900
1905 virtual bool infinite () const = 0;
1906
1914 virtual bool is_mid_infinite_edge_node(const unsigned int /* n */) const
1915 { libmesh_assert (!this->infinite()); return false; }
1916
1923 virtual Point origin () const { libmesh_not_implemented(); return Point(); }
1924
1925#else
1926
1927 static constexpr bool infinite () { return false; }
1928
1929#endif
1930
1934 static std::unique_ptr<Elem> build (const ElemType type,
1935 Elem * p=nullptr);
1936
1942 static std::unique_ptr<Elem> build_with_id (const ElemType type,
1943 dof_id_type id);
1944
1957 virtual std::unique_ptr<Elem> disconnected_clone () const;
1958
1968 virtual unsigned int n_permutations() const = 0;
1969
1982 virtual void permute(unsigned int perm_num) = 0;
1983
1995 virtual void flip(BoundaryInfo * boundary_info) = 0;
1996
2007 virtual bool is_flipped() const = 0;
2008
2015 void orient(BoundaryInfo * boundary_info);
2016
2017#ifdef LIBMESH_ENABLE_AMR
2018
2024 virtual unsigned int as_parent_node (unsigned int c,
2025 unsigned int n) const;
2026
2031 virtual
2032 const std::vector<std::pair<unsigned char, unsigned char>> &
2033 parent_bracketing_nodes(unsigned int c,
2034 unsigned int n) const;
2035
2040 virtual
2041 const std::vector<std::pair<dof_id_type, dof_id_type>>
2042 bracketing_nodes(unsigned int c,
2043 unsigned int n) const;
2044
2045
2049 virtual Real embedding_matrix (const unsigned int child_num,
2050 const unsigned int child_node_num,
2051 const unsigned int parent_node_num) const = 0;
2052
2060 virtual unsigned int embedding_matrix_version () const { return 0; }
2061
2062#endif // LIBMESH_ENABLE_AMR
2063
2064
2065protected:
2066
2071
2076
2081 dof_id_type n1);
2082
2087 dof_id_type n1,
2088 dof_id_type n2);
2089
2094 dof_id_type n1,
2095 dof_id_type n2,
2096 dof_id_type n3);
2097
2101 void swap2nodes(unsigned int n1, unsigned int n2)
2102 {
2103 Node * temp = this->node_ptr(n1);
2104 this->set_node(n1, this->node_ptr(n2));
2105 this->set_node(n2, temp);
2106 }
2107
2111 void swap2neighbors(unsigned int n1, unsigned int n2)
2112 {
2113 Elem * temp = this->neighbor_ptr(n1);
2114 this->set_neighbor(n1, this->neighbor_ptr(n2));
2115 this->set_neighbor(n2, temp);
2116 }
2117
2121 void swap2boundarysides(unsigned short s1, unsigned short s2,
2122 BoundaryInfo * boundary_info) const;
2123
2127 void swap2boundaryedges(unsigned short e1, unsigned short e2,
2128 BoundaryInfo * boundary_info) const;
2129
2133 void swap3nodes(unsigned int n1, unsigned int n2, unsigned int n3)
2134 {
2135 swap2nodes(n1, n2);
2136 swap2nodes(n2, n3);
2137 }
2138
2142 void swap3neighbors(unsigned int n1, unsigned int n2,
2143 unsigned int n3)
2144 {
2145 swap2neighbors(n1, n2);
2146 swap2neighbors(n2, n3);
2147 }
2148
2152 void swap4nodes(unsigned int n1, unsigned int n2, unsigned int n3,
2153 unsigned int n4)
2154 {
2155 swap3nodes(n1, n2, n3);
2156 swap2nodes(n3, n4);
2157 }
2158
2162 void swap4neighbors(unsigned int n1, unsigned int n2,
2163 unsigned int n3, unsigned int n4)
2164 {
2165 swap3neighbors(n1, n2, n3);
2166 swap2neighbors(n3, n4);
2167 }
2168
2169
2173 template <typename Sideclass, typename Subclass>
2174 std::unique_ptr<Elem>
2175 simple_build_side_ptr(const unsigned int i);
2176
2180 template <typename Subclass>
2181 void simple_build_side_ptr(std::unique_ptr<Elem> & side,
2182 const unsigned int i,
2183 ElemType sidetype);
2184
2188 template <typename Subclass, typename Mapclass>
2189 void simple_side_ptr(std::unique_ptr<Elem> & side,
2190 const unsigned int i,
2191 ElemType sidetype);
2192
2196 template <typename Edgeclass, typename Subclass>
2197 std::unique_ptr<Elem>
2198 simple_build_edge_ptr(const unsigned int i);
2199
2203 template <typename Subclass>
2204 void simple_build_edge_ptr(std::unique_ptr<Elem> & edge,
2205 const unsigned int i,
2206 ElemType edgetype);
2207
2208
2209#ifdef LIBMESH_ENABLE_AMR
2210
2216 virtual
2217 std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> &
2219 {
2220 static std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> c;
2221 libmesh_error();
2222 return c;
2223 }
2224
2230 virtual
2231 std::vector<std::vector<std::vector<signed char>>> &
2233 {
2234 static std::vector<std::vector<std::vector<signed char>>> c;
2235 libmesh_error();
2236 return c;
2237 }
2238
2239#endif // LIBMESH_ENABLE_AMR
2240
2241public:
2242
2247 void nullify_neighbors ();
2248
2249protected:
2250
2255
2261
2262#ifdef LIBMESH_ENABLE_AMR
2270 std::unique_ptr<Elem *[]> _children;
2271#endif
2272
2277
2278#ifdef LIBMESH_ENABLE_AMR
2283 unsigned char _rflag;
2284
2289 unsigned char _pflag;
2290
2299 unsigned char _p_level;
2300#endif
2301
2306 unsigned char _map_type;
2307
2312 unsigned char _map_data;
2313};
2314
2315
2316
2317// ------------------------------------------------------------
2318// Elem helper classes
2319//
2320class
2322{
2323public:
2324 NodeRefIter (Node * const * nodepp) : PointerToPointerIter<Node>(nodepp) {}
2325};
2326
2327
2328class
2330{
2331public:
2332 ConstNodeRefIter (const Node * const * nodepp) : PointerToPointerIter<const Node>(nodepp) {}
2333};
2334
2335
2336#ifdef LIBMESH_ENABLE_AMR
2337class
2339{
2340public:
2341 ChildRefIter (Elem * const * childpp) : PointerToPointerIter<Elem>(childpp) {}
2342};
2343
2344
2345class
2347{
2348public:
2349 ConstChildRefIter (const Elem * const * childpp) : PointerToPointerIter<const Elem>(childpp) {}
2350};
2351
2352
2353
2354inline
2360
2361
2362inline
2368#endif // LIBMESH_ENABLE_AMR
2369
2370
2371
2372
2373// ------------------------------------------------------------
2374// global Elem functions
2375
2376inline
2377std::ostream & operator << (std::ostream & os, const Elem & e)
2378{
2379 e.print_info(os);
2380 return os;
2381}
2382
2383
2384// ------------------------------------------------------------
2385// Elem class member functions
2386inline
2387Elem::Elem(const unsigned int nn,
2388 const unsigned int ns,
2389 Elem * p,
2390 Elem ** elemlinkdata,
2391 Node ** nodelinkdata) :
2392 _nodes(nodelinkdata),
2393 _elemlinks(elemlinkdata),
2394 _sbd_id(0),
2395#ifdef LIBMESH_ENABLE_AMR
2396 _rflag(Elem::DO_NOTHING),
2397 _pflag(Elem::DO_NOTHING),
2398 _p_level(0),
2399#endif
2400 _map_type(p ? p->mapping_type() : 0),
2401 _map_data(p ? p->mapping_data() : 0)
2402{
2404
2405 // If this ever legitimately fails we need to increase max_n_nodes
2406 libmesh_assert_less_equal(nn, max_n_nodes);
2407
2408 // We currently only support refinement of elements into child
2409 // elements of the same type. We can't test elem->type() here,
2410 // because that's virtual and we're still in the base class
2411 // constructor, but we can at least usually verify constency with
2412 // the arguments we were handed.
2413#ifndef NDEBUG
2414 if (p && !p->runtime_topology())
2415 {
2416 libmesh_assert_equal_to(nn, p->n_nodes());
2417 libmesh_assert_equal_to(ns, p->n_sides());
2418 }
2419#endif
2420
2421 // Initialize the nodes data structure if we're given a pointer to
2422 // memory for it.
2423 if (_nodes)
2424 {
2425 for (unsigned int n=0; n<nn; n++)
2426 _nodes[n] = nullptr;
2427 }
2428
2429 // Initialize the neighbors/parent data structure
2430 // _elemlinks = new Elem *[ns+1];
2431
2432 // Initialize the elements data structure if we're given a pointer
2433 // to memory for it. If we *weren't* given memory for it, e.g.
2434 // because a subclass like an arbitrary Polygon needs to
2435 // heap-allocate this memory, then that subclass will have to handle
2436 // this initialization too.
2437 if (_elemlinks)
2438 {
2439 _elemlinks[0] = p;
2440
2441 for (unsigned int n=1; n<ns+1; n++)
2442 _elemlinks[n] = nullptr;
2443
2444 // Optionally initialize data from the parent
2445 if (this->parent())
2446 {
2447 this->subdomain_id() = this->parent()->subdomain_id();
2448 this->processor_id() = this->parent()->processor_id();
2449 _map_type = this->parent()->_map_type;
2450 _map_data = this->parent()->_map_data;
2451
2452#ifdef LIBMESH_ENABLE_AMR
2453 this->set_p_level(this->parent()->p_level());
2454#endif
2455 }
2456 }
2457}
2458
2459
2460
2461inline
2462const Point & Elem::point (const unsigned int i) const
2463{
2464 libmesh_assert_less (i, this->n_nodes());
2466 libmesh_assert_not_equal_to (_nodes[i]->id(), Node::invalid_id);
2467
2468 return *_nodes[i];
2469}
2470
2471
2472
2473inline
2474Point & Elem::point (const unsigned int i)
2475{
2476 libmesh_assert_less (i, this->n_nodes());
2477
2478 return *_nodes[i];
2479}
2480
2481
2482
2483inline
2484dof_id_type Elem::node_id (const unsigned int i) const
2485{
2486 libmesh_assert_less (i, this->n_nodes());
2488 libmesh_assert_not_equal_to (_nodes[i]->id(), Node::invalid_id);
2489
2490 return _nodes[i]->id();
2491}
2492
2493
2494
2495inline
2496unsigned int Elem::local_node (const dof_id_type i) const
2497{
2498 for (auto n : make_range(this->n_nodes()))
2499 if (this->node_id(n) == i)
2500 return n;
2501
2502 return libMesh::invalid_uint;
2503}
2504
2505
2506
2507inline
2508const Node * const * Elem::get_nodes () const
2509{
2510 return _nodes;
2511}
2512
2513
2514
2515inline
2516const Node * Elem::node_ptr (const unsigned int i) const
2517{
2518 libmesh_assert_less (i, this->n_nodes());
2520
2521 return _nodes[i];
2522}
2523
2524
2525
2526inline
2527Node * Elem::node_ptr (const unsigned int i)
2528{
2529 libmesh_assert_less (i, this->n_nodes());
2531
2532 return _nodes[i];
2533}
2534
2535
2536
2537inline
2538const Node & Elem::node_ref (const unsigned int i) const
2539{
2540 return *this->node_ptr(i);
2541}
2542
2543
2544
2545inline
2546Node & Elem::node_ref (const unsigned int i)
2547{
2548 return *this->node_ptr(i);
2549}
2550
2551
2552
2553inline
2554unsigned int Elem::get_node_index (const Node * node_ptr) const
2555{
2556 for (auto n : make_range(this->n_nodes()))
2557 if (this->_nodes[n] == node_ptr)
2558 return n;
2559
2560 return libMesh::invalid_uint;
2561}
2562
2563
2564
2565#ifdef LIBMESH_ENABLE_DEPRECATED
2566inline
2567Node * & Elem::set_node (const unsigned int i)
2568{
2569 libmesh_assert_less (i, this->n_nodes());
2570
2571 libmesh_deprecated();
2572
2573 return _nodes[i];
2574}
2575#endif // LIBMESH_ENABLE_DEPRECATED
2576
2577
2578
2579inline
2580void Elem::set_node (const unsigned int i,
2581 Node * node)
2582{
2583 libmesh_assert_less (i, this->n_nodes());
2584
2585 _nodes[i] = node;
2586}
2587
2588
2589
2590inline
2592{
2593 return _sbd_id;
2594}
2595
2596
2597
2598inline
2600{
2601 return _sbd_id;
2602}
2603
2604
2605
2606inline
2607bool Elem::operator != (const Elem & rhs) const
2608{
2609 return !(*this == rhs);
2610}
2611
2612
2613
2614inline
2615const Elem * Elem::neighbor_ptr (unsigned int i) const
2616{
2617 libmesh_assert_less (i, this->n_neighbors());
2618
2619 return _elemlinks[i+1];
2620}
2621
2622
2623
2624inline
2625Elem * Elem::neighbor_ptr (unsigned int i)
2626{
2627 libmesh_assert_less (i, this->n_neighbors());
2628
2629 return _elemlinks[i+1];
2630}
2631
2632
2633
2634inline
2635void Elem::set_neighbor (const unsigned int i, Elem * n)
2636{
2637 libmesh_assert_less (i, this->n_neighbors());
2638
2639 _elemlinks[i+1] = n;
2640}
2641
2642
2643
2644inline
2645bool Elem::has_neighbor (const Elem * elem) const
2646{
2647 for (auto n : this->neighbor_ptr_range())
2648 if (n == elem)
2649 return true;
2650
2651 return false;
2652}
2653
2654
2655
2656inline
2658{
2659 for (auto n : elem->neighbor_ptr_range())
2660 if (n && n->parent() == this)
2661 return n;
2662
2663 return nullptr;
2664}
2665
2666
2667
2668inline
2669const Elem * Elem::child_neighbor (const Elem * elem) const
2670{
2671 for (auto n : elem->neighbor_ptr_range())
2672 if (n && n->parent() == this)
2673 return n;
2674
2675 return nullptr;
2676}
2677
2678
2679
2680inline
2683{
2684 return {_nodes, _nodes+this->n_nodes()};
2685}
2686
2687
2688
2689inline
2692{
2693 return {_nodes, _nodes+this->n_nodes()};
2694}
2695
2696
2697
2698inline
2701{
2702 return {0, cast_int<unsigned short>(this->n_nodes())};
2703}
2704
2705
2706
2707inline
2710{
2711 return {0, cast_int<unsigned short>(this->n_edges())};
2712}
2713
2714
2715
2716inline
2719{
2720 return {0, cast_int<unsigned short>(this->n_faces())};
2721}
2722
2723
2724
2725inline
2728{
2729 return {0, cast_int<unsigned short>(this->n_sides())};
2730}
2731
2732
2733
2734
2735inline
2736std::unique_ptr<const Elem> Elem::side_ptr (unsigned int i) const
2737{
2738 // Call the non-const version of this function, return the result as
2739 // a std::unique_ptr<const Elem>.
2740 Elem * me = const_cast<Elem *>(this);
2741 return me->side_ptr(i);
2742}
2743
2744
2745
2746inline
2747void
2748Elem::side_ptr (std::unique_ptr<const Elem> & elem,
2749 const unsigned int i) const
2750{
2751 // Hand off to the non-const version of this function
2752 Elem * me = const_cast<Elem *>(this);
2753 std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
2754 me->side_ptr(e, i);
2755 elem = std::move(e);
2756}
2757
2758
2759
2760inline
2761std::unique_ptr<const Elem>
2762Elem::build_side_ptr (const unsigned int i) const
2763{
2764 // Call the non-const version of this function, return the result as
2765 // a std::unique_ptr<const Elem>.
2766 Elem * me = const_cast<Elem *>(this);
2767 return me->build_side_ptr(i);
2768}
2769
2770
2771
2772inline
2773void
2774Elem::build_side_ptr (std::unique_ptr<const Elem> & elem,
2775 const unsigned int i) const
2776{
2777 // Hand off to the non-const version of this function
2778 Elem * me = const_cast<Elem *>(this);
2779 std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
2780 me->build_side_ptr(e, i);
2781 elem = std::move(e);
2782}
2783
2784
2785
2786template <typename Sideclass, typename Subclass>
2787inline
2788std::unique_ptr<Elem>
2789Elem::simple_build_side_ptr (const unsigned int i)
2790{
2791 libmesh_assert_less (i, this->n_sides());
2792
2793 std::unique_ptr<Elem> face = std::make_unique<Sideclass>();
2794 for (auto n : face->node_index_range())
2795 face->set_node(n, this->node_ptr(Subclass::side_nodes_map[i][n]));
2796
2797 face->set_interior_parent(this);
2798 face->inherit_data_from(*this);
2799
2800 return face;
2801}
2802
2803
2804
2805template <typename Subclass>
2806inline
2807void
2808Elem::simple_build_side_ptr (std::unique_ptr<Elem> & side,
2809 const unsigned int i,
2810 ElemType sidetype)
2811{
2812 libmesh_assert_less (i, this->n_sides());
2813
2814 if (!side.get() || side->type() != sidetype)
2815 {
2816 Subclass & real_me = cast_ref<Subclass&>(*this);
2817 side = real_me.Subclass::build_side_ptr(i);
2818 }
2819 else
2820 {
2821 side->set_interior_parent(this);
2822 side->inherit_data_from(*this);
2823 for (auto n : side->node_index_range())
2824 side->set_node(n, this->node_ptr(Subclass::side_nodes_map[i][n]));
2825 }
2826}
2827
2828
2829
2830template <typename Subclass, typename Mapclass>
2831inline
2832void
2833Elem::simple_side_ptr (std::unique_ptr<Elem> & side,
2834 const unsigned int i,
2835 ElemType sidetype)
2836{
2837 libmesh_assert_less (i, this->n_sides());
2838
2839 if (!side.get() || side->type() != sidetype)
2840 {
2841 Subclass & real_me = cast_ref<Subclass&>(*this);
2842 side = real_me.Subclass::side_ptr(i);
2843 }
2844 else
2845 {
2846 side->subdomain_id() = this->subdomain_id();
2847
2848 for (auto n : side->node_index_range())
2849 side->set_node(n, this->node_ptr(Mapclass::side_nodes_map[i][n]));
2850 }
2851}
2852
2853
2854
2855inline
2856std::unique_ptr<const Elem>
2857Elem::build_edge_ptr (const unsigned int i) const
2858{
2859 // Call the non-const version of this function, return the result as
2860 // a std::unique_ptr<const Elem>.
2861 Elem * me = const_cast<Elem *>(this);
2862 return me->build_edge_ptr(i);
2863}
2864
2865
2866
2867inline
2868void
2869Elem::build_edge_ptr (std::unique_ptr<const Elem> & elem,
2870 const unsigned int i) const
2871{
2872 // Hand off to the non-const version of this function
2873 Elem * me = const_cast<Elem *>(this);
2874 std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
2875 me->build_edge_ptr(e, i);
2876 elem = std::move(e);
2877}
2878
2879
2880template <typename Edgeclass, typename Subclass>
2881inline
2882std::unique_ptr<Elem>
2883Elem::simple_build_edge_ptr (const unsigned int i)
2884{
2885 libmesh_assert_less (i, this->n_edges());
2886
2887 std::unique_ptr<Elem> edge = std::make_unique<Edgeclass>();
2888
2889 for (auto n : edge->node_index_range())
2890 edge->set_node(n, this->node_ptr(Subclass::edge_nodes_map[i][n]));
2891
2892 edge->set_interior_parent(this);
2893 edge->inherit_data_from(*this);
2894
2895 return edge;
2896}
2897
2898
2899
2900
2901template <typename Subclass>
2902inline
2903void
2904Elem::simple_build_edge_ptr (std::unique_ptr<Elem> & edge,
2905 const unsigned int i,
2906 ElemType edgetype)
2907{
2908 libmesh_assert_less (i, this->n_edges());
2909
2910 if (!edge.get() || edge->type() != edgetype)
2911 {
2912 Subclass & real_me = cast_ref<Subclass&>(*this);
2913 edge = real_me.Subclass::build_edge_ptr(i);
2914 }
2915 else
2916 {
2917 edge->inherit_data_from(*this);
2918 for (auto n : edge->node_index_range())
2919 edge->set_node(n, this->node_ptr(Subclass::edge_nodes_map[i][n]));
2920 }
2921}
2922
2923
2924
2925inline
2927{
2928 // By convention, the element is on the boundary
2929 // if it has a nullptr neighbor.
2930 return this->has_neighbor(nullptr);
2931}
2932
2933
2934
2935inline
2936unsigned int Elem::which_neighbor_am_i (const Elem * e) const
2937{
2938 libmesh_assert(e);
2939
2940 const Elem * eparent = e;
2941
2942 while (eparent->level() > this->level())
2943 {
2944 eparent = eparent->parent();
2945 libmesh_assert(eparent);
2946 }
2947
2948 for (auto s : make_range(this->n_sides()))
2949 if (this->neighbor_ptr(s) == eparent)
2950 return s;
2951
2952 return libMesh::invalid_uint;
2953}
2954
2955
2956
2957inline
2958bool Elem::active() const
2959{
2960#ifdef LIBMESH_ENABLE_AMR
2961 if ((this->refinement_flag() == INACTIVE) ||
2962 (this->refinement_flag() == COARSEN_INACTIVE))
2963 return false;
2964 else
2965 return true;
2966#else
2967 return true;
2968#endif
2969}
2970
2971
2972
2973
2974
2975inline
2977{
2978#ifdef LIBMESH_ENABLE_AMR
2979 if (this->active())
2980 return false;
2981 if (!this->has_children())
2982 return true;
2983 for (const Elem * my_ancestor = this->parent();
2984 my_ancestor != nullptr;
2985 my_ancestor = my_ancestor->parent())
2986 if (my_ancestor->active())
2987 return true;
2988#endif
2989
2990 return false;
2991}
2992
2993
2994
2995inline
2997{
2998#ifdef LIBMESH_ENABLE_AMR
2999 if (!_children)
3000 return false;
3001 else
3002 return true;
3003#else
3004 return false;
3005#endif
3006}
3007
3008
3009inline
3011{
3012#ifdef LIBMESH_ENABLE_AMR
3013 if (!_children)
3014 return false;
3015 else
3016 for (auto & c : child_ref_range())
3017 if (c.has_children())
3018 return true;
3019#endif
3020 return false;
3021}
3022
3023
3024
3025inline
3027#ifdef LIBMESH_ENABLE_AMR
3028 descendant
3029#endif
3030 ) const
3031{
3032#ifdef LIBMESH_ENABLE_AMR
3033 const Elem * e = descendant;
3034 while (e)
3035 {
3036 if (this == e)
3037 return true;
3038 e = e->parent();
3039 }
3040#endif
3041 return false;
3042}
3043
3044
3045
3046inline
3047const Elem * Elem::parent () const
3048{
3049 return _elemlinks[0];
3050}
3051
3052
3053
3054inline
3056{
3057 return _elemlinks[0];
3058}
3059
3060
3061
3062inline
3064{
3065 // We no longer support using parent() as interior_parent()
3066 libmesh_assert_equal_to(this->dim(), p ? p->dim() : this->dim());
3067 _elemlinks[0] = p;
3068}
3069
3070
3071
3072inline
3073const Elem * Elem::top_parent () const
3074{
3075 const Elem * tp = this;
3076
3077 // Keep getting the element's parent
3078 // until that parent is at level-0
3079 while (tp->parent() != nullptr)
3080 tp = tp->parent();
3081
3082 libmesh_assert(tp);
3083 libmesh_assert_equal_to (tp->level(), 0);
3084
3085 return tp;
3086}
3087
3088
3089
3090inline
3091unsigned int Elem::level() const
3092{
3093#ifdef LIBMESH_ENABLE_AMR
3094
3095 // if I don't have a parent I was
3096 // created directly from file
3097 // or by the user, so I am a
3098 // level-0 element
3099 if (this->parent() == nullptr)
3100 return 0;
3101
3102 // if the parent and this element are of different
3103 // dimensionality we are at the same level as
3104 // the parent (e.g. we are the 2D side of a
3105 // 3D element)
3106 if (this->dim() != this->parent()->dim())
3107 return this->parent()->level();
3108
3109 // otherwise we are at a level one
3110 // higher than our parent
3111 return (this->parent()->level() + 1);
3112
3113#else
3114
3115 // Without AMR all elements are
3116 // at level 0.
3117 return 0;
3118
3119#endif
3120}
3121
3122
3123
3124inline
3125unsigned int Elem::p_level() const
3126{
3127#ifdef LIBMESH_ENABLE_AMR
3128 return _p_level;
3129#else
3130 return 0;
3131#endif
3132}
3133
3134
3135
3136inline
3138{
3139 return static_cast<ElemMappingType>(_map_type);
3140}
3141
3142
3143
3144inline
3146{
3147 _map_type = cast_int<unsigned char>(type);
3148}
3149
3150
3151
3152inline
3153unsigned char Elem::mapping_data () const
3154{
3155 return _map_data;
3156}
3157
3158
3159
3160inline
3161void Elem::set_mapping_data(const unsigned char data)
3162{
3163 _map_data = data;
3164}
3165
3166
3167
3168#ifdef LIBMESH_ENABLE_AMR
3169
3170inline
3171const Elem * Elem::raw_child_ptr (unsigned int i) const
3172{
3173 if (!_children)
3174 return nullptr;
3175
3176 return _children[i];
3177}
3178
3179inline
3180const Elem * Elem::child_ptr (unsigned int i) const
3181{
3184
3185 return _children[i];
3186}
3187
3188inline
3189Elem * Elem::child_ptr (unsigned int i)
3190{
3193
3194 return _children[i];
3195}
3196
3197
3198inline
3199void Elem::set_child (unsigned int c, Elem * elem)
3200{
3201 libmesh_assert (this->has_children());
3202
3203 _children[c] = elem;
3204}
3205
3206
3207
3208inline
3209unsigned int Elem::which_child_am_i (const Elem * e) const
3210{
3211 libmesh_assert(e);
3212 libmesh_assert (this->has_children());
3213
3214 unsigned int nc = this->n_children();
3215 for (unsigned int c=0; c != nc; c++)
3216 if (this->child_ptr(c) == e)
3217 return c;
3218
3219 libmesh_error_msg("ERROR: which_child_am_i() was called with a non-child!");
3220
3221 return libMesh::invalid_uint;
3222}
3223
3224
3225
3226inline
3228{
3229 return static_cast<RefinementState>(_rflag);
3230}
3231
3232
3233
3234inline
3236{
3237 _rflag = cast_int<unsigned char>(rflag);
3238}
3239
3240
3241
3242inline
3244{
3245 return static_cast<RefinementState>(_pflag);
3246}
3247
3248
3249
3250inline
3252{
3253 if (this->p_level() == 0)
3254 libmesh_assert_not_equal_to
3255 (pflag, Elem::JUST_REFINED);
3256
3257 _pflag = cast_int<unsigned char>(pflag);
3258}
3259
3260
3261
3262inline
3263unsigned int Elem::max_descendant_p_level () const
3264{
3265 // This is undefined for subactive elements,
3266 // which have no active descendants
3267 libmesh_assert (!this->subactive());
3268 if (this->active())
3269 return this->p_level();
3270
3271 unsigned int max_p_level = _p_level;
3272 for (auto & c : child_ref_range())
3273 max_p_level = std::max(max_p_level,
3274 c.max_descendant_p_level());
3275 return max_p_level;
3276}
3277
3278
3279
3280inline
3281void Elem::hack_p_level(unsigned int p)
3282{
3283 if (p == 0)
3284 libmesh_assert_not_equal_to
3286
3287 _p_level = cast_int<unsigned char>(p);
3288}
3289
3290
3291inline
3293 RefinementState pflag)
3294{
3295 _pflag = cast_int<unsigned char>(pflag);
3296 this->hack_p_level(p);
3297}
3298
3299#endif // ifdef LIBMESH_ENABLE_AMR
3300
3301
3302inline
3303void Elem::orient(BoundaryInfo * boundary_info)
3304{
3305 if (this->is_flipped())
3306 this->flip(boundary_info);
3307}
3308
3309
3310inline
3312{
3313 return n0;
3314}
3315
3316
3317
3318inline
3320 dof_id_type n1)
3321{
3322 // Order the two so that n0 < n1
3323 if (n0 > n1) std::swap (n0, n1);
3324
3325 return Utility::hashword2(n0, n1);
3326}
3327
3328
3329
3330inline
3332 dof_id_type n1,
3333 dof_id_type n2)
3334{
3335 std::array<dof_id_type, 3> array = {{n0, n1, n2}};
3336 std::sort(array.begin(), array.end());
3337 return Utility::hashword(array);
3338}
3339
3340
3341
3342inline
3344 dof_id_type n1,
3345 dof_id_type n2,
3346 dof_id_type n3)
3347{
3348 std::array<dof_id_type, 4> array = {{n0, n1, n2, n3}};
3349 std::sort(array.begin(), array.end());
3350 return Utility::hashword(array);
3351}
3352
3353
3354
3355inline
3357{
3358 this->set_mapping_type(src.mapping_type());
3359 this->set_mapping_data(src.mapping_data());
3360 this->subdomain_id() = src.subdomain_id();
3361 this->processor_id(src.processor_id());
3362#ifdef LIBMESH_ENABLE_AMR
3363 this->set_p_level(src.p_level());
3364#endif
3365}
3366
3367
3368
3373{
3374public:
3375 // Constructor with arguments.
3376 SideIter(const unsigned int side_number,
3377 Elem * parent)
3378 : _side(),
3379 _side_ptr(nullptr),
3380 _parent(parent),
3381 _side_number(side_number)
3382 {}
3383
3384
3385 // Empty constructor.
3387 : _side(),
3388 _side_ptr(nullptr),
3389 _parent(nullptr),
3391 {}
3392
3393
3394 // Copy constructor
3395 SideIter(const SideIter & other)
3396 : _side(),
3397 _side_ptr(nullptr),
3398 _parent(other._parent),
3400 {}
3401
3402
3403 // op=
3404 SideIter & operator=(const SideIter & other)
3405 {
3406 this->_parent = other._parent;
3407 this->_side_number = other._side_number;
3408 return *this;
3409 }
3410
3411 // unary op*
3412 Elem *& operator*() const
3413 {
3414 // Set the std::unique_ptr
3415 this->_update_side_ptr();
3416
3417 // Return a reference to _side_ptr
3418 return this->_side_ptr;
3419 }
3420
3421 // op++
3423 {
3424 ++_side_number;
3425 return *this;
3426 }
3427
3428 // op== Two side iterators are equal if they have
3429 // the same side number and the same parent element.
3430 bool operator == (const SideIter & other) const
3431 {
3432 return (this->_side_number == other._side_number &&
3433 this->_parent == other._parent);
3434 }
3435
3436
3437 // Consults the parent Elem to determine if the side
3438 // is a boundary side. Note: currently side N is a
3439 // boundary side if neighbor N is nullptr. Be careful,
3440 // this could possibly change in the future?
3441 bool side_on_boundary() const
3442 {
3443 return this->_parent->neighbor_ptr(_side_number) == nullptr;
3444 }
3445
3446private:
3447 // Update the _side pointer by building the correct side.
3448 // This has to be called before dereferencing.
3449 void _update_side_ptr() const
3450 {
3451 // Construct new side, store in std::unique_ptr
3452 this->_side = this->_parent->build_side_ptr(this->_side_number);
3453
3454 // Also set our internal naked pointer. Memory is still owned
3455 // by the std::unique_ptr.
3456 this->_side_ptr = _side.get();
3457 }
3458
3459 // std::unique_ptr to the actual side, handles memory management for
3460 // the sides which are created during the course of iteration.
3461 mutable std::unique_ptr<Elem> _side;
3462
3463 // Raw pointer needed to facilitate passing back to the user a
3464 // reference to a non-temporary raw pointer in order to conform to
3465 // the variant_filter_iterator interface. It points to the same
3466 // thing the std::unique_ptr "_side" above holds. What happens if the user
3467 // calls delete on the pointer passed back? Well, this is an issue
3468 // which is not addressed by the iterators in libMesh. Basically it
3469 // is a bad idea to ever call delete on an iterator from the library.
3470 mutable Elem * _side_ptr;
3471
3472 // Pointer to the parent Elem class which generated this iterator
3474
3475 // A counter variable which keeps track of the side number
3476 unsigned int _side_number;
3477};
3478
3479
3480
3481
3482
3483
3484// Private implementation functions in the Elem class for the side iterators.
3485// They have to come after the definition of the SideIter class.
3486inline
3488{
3489 return SideIter(0, this);
3490}
3491
3492
3493
3494inline
3496{
3497 return SideIter(this->n_neighbors(), this);
3498}
3499
3500
3501
3502
3506struct
3508{
3509 // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
3510 template <typename PredType, typename IterType>
3511 side_iterator (const IterType & d,
3512 const IterType & e,
3513 const PredType & p ) :
3515};
3516
3517
3518
3519inline
3524
3525
3526inline
3531
3532} // namespace libMesh
3533
3534
3535// Helper function for default caches in Elem subclasses
3536
3537#define LIBMESH_ENABLE_TOPOLOGY_CACHES \
3538 virtual \
3539 std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> & \
3540 _get_bracketing_node_cache() const override \
3541 { \
3542 static std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> c; \
3543 return c; \
3544 } \
3545 \
3546 virtual \
3547 std::vector<std::vector<std::vector<signed char>>> & \
3548 _get_parent_indices_cache() const override \
3549 { \
3550 static std::vector<std::vector<std::vector<signed char>>> c; \
3551 return c; \
3552 }
3553
3554
3555
3556
3557
3558
3559#endif // LIBMESH_ELEM_H
void ErrorVector unsigned int
The BoundaryInfo class contains information relevant to boundary conditions including storing faces,...
Defines a Cartesian bounding box by the two corner extremum.
The DofObject defines an abstract base class for objects that have degrees of freedom associated with...
Definition dof_object.h:55
processor_id_type processor_id() const
Definition dof_object.h:881
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition dof_object.h:473
dof_id_type id() const
Definition dof_object.h:819
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
ChildRefIter(Elem *const *childpp)
Definition elem.h:2341
ConstChildRefIter(const Elem *const *childpp)
Definition elem.h:2349
ConstNodeRefIter(const Node *const *nodepp)
Definition elem.h:2332
NodeRefIter(Node *const *nodepp)
Definition elem.h:2324
The definition of the protected nested SideIter class.
Definition elem.h:3373
bool side_on_boundary() const
Definition elem.h:3441
Elem *& operator*() const
Definition elem.h:3412
std::unique_ptr< Elem > _side
Definition elem.h:3461
bool operator==(const SideIter &other) const
Definition elem.h:3430
unsigned int _side_number
Definition elem.h:3476
SideIter & operator=(const SideIter &other)
Definition elem.h:3404
SideIter & operator++()
Definition elem.h:3422
void _update_side_ptr() const
Definition elem.h:3449
SideIter(const SideIter &other)
Definition elem.h:3395
SideIter(const unsigned int side_number, Elem *parent)
Definition elem.h:3376
This is the base class from which all geometric element types are derived.
Definition elem.h:96
bool has_ancestor_children() const
Definition elem.h:3010
virtual unsigned int n_nodes_in_child(unsigned int) const
Definition elem.h:667
void swap4nodes(unsigned int n1, unsigned int n2, unsigned int n3, unsigned int n4)
Swaps four node_ptrs, "rotating" them.
Definition elem.h:2152
bool operator!=(const Elem &rhs) const
Definition elem.h:2607
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
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
virtual std::unique_ptr< Elem > disconnected_clone() const
Definition elem.C:410
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
std::unique_ptr< const Elem > build_side_ptr(const unsigned int i, bool proxy) const
Definition elem.h:929
virtual Node *& set_node(const unsigned int i)
Definition elem.h:2567
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 Point quasicircumcenter() const
Definition elem.h:1046
const Elem * raw_child_ptr(unsigned int i) const
Definition elem.h:3171
virtual BoundingBox loose_bounding_box() const
Definition elem.C:3498
void set_p_refinement_flag(const RefinementState pflag)
Sets the value of the p-refinement flag for the element.
Definition elem.h:3251
static constexpr Real affine_tol
Default tolerance to use in has_affine_map().
Definition elem.h:2070
SimpleRange< NeighborPtrIter > neighbor_ptr_range()
Returns a range with all neighbors of an element, usable in range-based for loops.
Definition elem.h:3520
Elem(Elem &&)=delete
Elems are responsible for allocating and deleting space for storing pointers to their children during...
virtual void refine(MeshRefinement &mesh_refinement)
Refine the element.
virtual bool is_child_on_side(const unsigned int c, const unsigned int s) const =0
virtual std::vector< std::vector< std::vector< std::vector< std::pair< unsigned char, unsigned char > > > > > & _get_bracketing_node_cache() const
Elem subclasses which don't do their own bracketing node calculations will need to supply a static ca...
Definition elem.h:2218
void contract()
Contract an active element, i.e.
RefinementState refinement_flag() const
Definition elem.h:3227
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
virtual unsigned int center_node_on_side(const unsigned short side) const
Definition elem.C:3572
unsigned char _rflag
h refinement flag.
Definition elem.h:2283
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
bool active() const
Definition elem.h:2958
virtual std::pair< Real, Real > qual_bounds(const ElemQuality) const
Definition elem.h:1109
bool is_ancestor_of(const Elem *descendant) const
Definition elem.h:3026
unsigned char mapping_data() const
Definition elem.h:3153
bool has_neighbor(const Elem *elem) const
Definition elem.h:2645
void print_info(std::ostream &os=libMesh::out) const
Prints relevant information about the element.
Definition elem.C:2948
virtual unsigned int n_vertices() const =0
Elem * child_neighbor(Elem *elem)
Definition elem.h:2657
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:3292
const Point & point(const unsigned int i) const
Definition elem.h:2462
virtual unsigned int local_side_node(unsigned int side, unsigned int side_node) const =0
const Node & node_ref(const unsigned int i) const
Definition elem.h:2538
virtual Point true_centroid() const
Definition elem.C:575
virtual Point origin() const
Definition elem.h:1923
Elem & operator=(const Elem &)=delete
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
virtual bool is_child_on_edge(const unsigned int c, const unsigned int e) const
Definition elem.C:2333
void set_child(unsigned int c, Elem *elem)
Sets the pointer to the child for this element.
Definition elem.h:3199
bool has_children() const
Definition elem.h:2996
virtual std::unique_ptr< Elem > side_ptr(unsigned int i)=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's ...
Definition elem.C:556
bool topologically_equal(const Elem &rhs) const
Definition elem.C:788
virtual unsigned int n_nodes() const =0
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
const Elem * parent() const
Definition elem.h:3047
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
Elem(const Elem &)=delete
void swap2nodes(unsigned int n1, unsigned int n2)
Swaps two node_ptrs.
Definition elem.h:2101
virtual std::pair< unsigned short int, unsigned short int > second_order_child_vertex(const unsigned int n) const
Definition elem.C:3091
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
bool operator==(const Elem &rhs) const
Definition elem.C:756
void set_neighbor(const unsigned int i, Elem *n)
Assigns n as the neighbor.
Definition elem.h:2635
SideIter _last_side()
Definition elem.h:3495
static ElemType complete_order_equivalent_type(const ElemType et)
Definition elem.C:3352
virtual bool on_reference_element(const Point &p, const Real eps=TOLERANCE) const =0
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:3281
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
std::unique_ptr< Elem > simple_build_side_ptr(const unsigned int i)
An implementation for simple (all sides equal) elements.
Definition elem.h:2789
virtual unsigned int n_permutations() const =0
Returns the number of independent permutations of element nodes - e.g.
const Elem * child_ptr(unsigned int i) const
Definition elem.h:3180
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
bool positive_edge_orientation(const unsigned int i) const
Definition elem.C:3634
virtual void side_ptr(std::unique_ptr< Elem > &side, const unsigned int i)=0
Resets the loose element side, which may currently point to a different side than i or even a differe...
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
void swap3neighbors(unsigned int n1, unsigned int n2, unsigned int n3)
Swaps three neighbor_ptrs, "rotating" them.
Definition elem.h:2142
bool has_topological_neighbor(const Elem *elem, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
Definition elem.C:1324
bool ancestor() const
Definition elem.C:2019
unsigned int which_neighbor_am_i(const Elem *e) const
This function tells you which neighbor e is.
Definition elem.h:2936
virtual void connectivity(const unsigned int sc, const IOPackage iop, std::vector< dof_id_type > &conn) const =0
SideIter _first_side()
Side iterator helper functions.
Definition elem.h:3487
virtual dof_id_type low_order_key(const unsigned int s) 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
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
virtual bool is_flipped() const =0
unsigned int n_neighbors() const
Definition elem.h:713
virtual bool is_mid_infinite_edge_node(const unsigned int) const
Definition elem.h:1914
SimpleRange< NodeRefIter > node_ref_range()
Returns a range with all nodes of an element, usable in range-based for loops.
Definition elem.h:2682
virtual unsigned int opposite_node(const unsigned int n, const unsigned int s) const
Definition elem.C:3564
Node ** _nodes
Pointers to the nodes we are connected to.
Definition elem.h:2254
virtual bool is_vertex_on_parent(unsigned int c, unsigned int n) const
Definition elem.C:3532
RefinementState
Enumeration of possible element refinement states.
Definition elem.h:1446
@ COARSEN_INACTIVE
Definition elem.h:1452
@ INVALID_REFINEMENTSTATE
Definition elem.h:1453
@ JUST_COARSENED
Definition elem.h:1450
virtual Order default_order() const =0
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition elem.C:442
virtual void build_side_ptr(std::unique_ptr< Elem > &side, const unsigned int i)=0
Resets the loose element side, which may currently point to a different side than i or even a differe...
void swap2neighbors(unsigned int n1, unsigned int n2)
Swaps two neighbor_ptrs.
Definition elem.h:2111
virtual std::vector< unsigned int > nodes_on_side(const unsigned int) const =0
virtual Order supported_nodal_order() const
Definition elem.h:1004
void set_interior_parent(Elem *p)
Sets the pointer to the element's interior_parent.
Definition elem.C:1222
static ElemType first_order_equivalent_type(const ElemType et)
Definition elem.C:3099
void remove_links_to_me()
Resets this element's neighbors' appropriate neighbor pointers and its parent's and children's approp...
Definition elem.C:1648
bool positive_face_orientation(const unsigned int i) const
Definition elem.C:3643
virtual unsigned int n_second_order_adjacent_vertices(const unsigned int n) const
Definition elem.C:3073
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
side_iterator boundary_sides_end()
Definition elem.C:3453
virtual bool is_face(const unsigned int i) const =0
const Elem *const * ConstNeighborPtrIter
Definition elem.h:335
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
side_iterator boundary_sides_begin()
Iterator accessor functions.
Definition elem.C:3444
void nullify_neighbors()
Replaces this element with nullptr for all of its neighbors.
Definition elem.C:3047
virtual bool has_invertible_map(Real tol=TOLERANCE *TOLERANCE) const
Definition elem.C:2914
virtual ~Elem()=default
Destructor.
std::unique_ptr< Elem *[]> _children
unique_ptr to array of this element's children.
Definition elem.h:2270
unsigned int min_new_p_level_by_neighbor(const Elem *neighbor, unsigned int current_min) const
Definition elem.C:2379
unsigned int local_node(const dof_id_type i) const
Definition elem.h:2496
static constexpr subdomain_id_type invalid_subdomain_id
A static integral constant representing an invalid subdomain id.
Definition elem.h:246
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
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
unsigned char _map_data
Mapping function data; currently used when needed to store the RATIONAL_BERNSTEIN nodal weight data i...
Definition elem.h:2312
virtual Real embedding_matrix(const unsigned int child_num, const unsigned int child_node_num, const unsigned int parent_node_num) const =0
virtual bool is_singular_node(unsigned int) const
Definition elem.h:1847
bool contains_vertex_of(const Elem *e, bool mesh_connection=false) const
Definition elem.C:908
unsigned int which_child_am_i(const Elem *e) const
Definition elem.h:3209
virtual Real hmin() const
Definition elem.C:683
static ElemType second_order_equivalent_type(const ElemType et, const bool full_ordered=true)
Definition elem.C:3168
static constexpr bool infinite()
Definition elem.h:1927
bool is_semilocal(const processor_id_type my_pid) const
Definition elem.C:840
void libmesh_assert_valid_neighbors() const
Checks for consistent neighbor links on this element.
Definition elem.C:1357
subdomain_id_type _sbd_id
The subdomain to which this element belongs.
Definition elem.h:2276
virtual std::vector< unsigned int > nodes_on_edge(const unsigned int) const =0
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:3303
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const
Definition elem.C:2784
virtual unsigned short dim() const =0
virtual Real quality(const ElemQuality q) const
Definition elem.C:1783
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
virtual void flip(BoundaryInfo *boundary_info)=0
Flips the element (by swapping node and neighbor pointers) to have a mapping Jacobian of opposite sig...
virtual bool is_vertex_on_child(unsigned int, unsigned int n) const
Definition elem.h:773
virtual void permute(unsigned int perm_num)=0
Permutes the element (by swapping node and neighbor pointers) according to the specified index.
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 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 ...
subdomain_id_type subdomain_id() const
Definition elem.h:2591
virtual unsigned int n_sub_elem() const =0
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
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
Definition elem.h:2355
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
void make_links_to_me_remote()
Resets this element's neighbors' appropriate neighbor pointers and its parent's and children's approp...
Definition elem.C:1542
virtual bool is_edge(const unsigned int i) const =0
virtual dof_id_type key() const
Definition elem.C:738
Elem ** _elemlinks
Pointers to this element's parent and neighbors, and for lower-dimensional elements' interior_parent.
Definition elem.h:2260
Predicates::multi_predicate Predicate
Useful iterator typedefs.
Definition elem.h:1875
unsigned int level() const
Definition elem.h:3091
virtual Real hmax() const
Definition elem.C:707
unsigned char _map_type
Mapping function type; currently either 0 (LAGRANGE) or 1 (RATIONAL_BERNSTEIN).
Definition elem.h:2306
ElemMappingType mapping_type() const
Definition elem.h:3137
virtual bool is_remote() const
Definition elem.h:596
virtual bool runtime_topology() const
Definition elem.h:254
static const unsigned int max_n_nodes
The maximum number of nodes any element can contain.
Definition elem.h:654
void set_parent(Elem *p)
Sets the pointer to the element's parent.
Definition elem.h:3063
unsigned int min_p_level_by_neighbor(const Elem *neighbor, unsigned int current_min) const
Definition elem.C:2350
bool on_boundary() const
Definition elem.h:2926
std::string get_info() const
Prints relevant information about the element to a string.
Definition elem.C:2956
virtual Point side_vertex_average_normal(const unsigned int s) const
Definition elem.C:3519
virtual std::vector< std::vector< std::vector< signed char > > > & _get_parent_indices_cache() const
Elem subclasses which don't do their own child-to-parent node calculations will need to supply a stat...
Definition elem.h:2232
virtual unsigned int n_faces() const =0
virtual Order default_side_order() const
Definition elem.h:1011
static dof_id_type compute_key(dof_id_type n0)
Definition elem.h:3311
bool contains_edge_of(const Elem *e) const
Definition elem.C:946
virtual unsigned int opposite_side(const unsigned int s) const
Definition elem.C:3556
const Node * node_ptr(const unsigned int i) const
Definition elem.h:2516
void add_child(Elem *elem)
Adds a child pointer to the array of children of this element.
Definition elem.C:2053
void replace_child(Elem *elem, unsigned int c)
Replaces the child pointer at the specified index in the child array.
Definition elem.C:2099
unsigned char _p_level
p refinement level - the difference between the polynomial degree on this element and the minimum pol...
Definition elem.h:2299
virtual unsigned int as_parent_node(unsigned int c, unsigned int n) const
Definition elem.C:2413
virtual dof_id_type key(const unsigned int s) const =0
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
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
virtual std::vector< unsigned int > sides_on_edge(const unsigned int) const =0
const Elem * reference_elem() const
Definition elem.C:568
bool is_internal(const unsigned int i) const
Definition elem.C:3611
void swap3nodes(unsigned int n1, unsigned int n2, unsigned int n3)
Swaps three node_ptrs, "rotating" them.
Definition elem.h:2133
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i)=0
const Node *const * get_nodes() const
Definition elem.h:2508
IntRange< unsigned short > edge_index_range() const
Definition elem.h:2709
Real length(const unsigned int n1, const unsigned int n2) const
Definition elem.C:727
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
void coarsen()
Coarsen the element.
virtual Real volume() const
Definition elem.C:3462
virtual bool is_vertex(const unsigned int i) 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:2883
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i, bool proxy)
Definition elem.h:926
virtual unsigned int n_children() const =0
virtual unsigned int embedding_matrix_version() const
Definition elem.h:2060
unsigned int get_node_index(const Node *node_ptr) const
Definition elem.h:2554
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
unsigned int max_descendant_p_level() const
Definition elem.h:3263
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 void build_edge_ptr(std::unique_ptr< Elem > &edge, const unsigned int i)=0
Resets the loose element edge, which may currently point to a different edge than i or even a differe...
virtual ElemType type() const =0
IntRange< unsigned short > node_index_range() const
Definition elem.h:2700
virtual Point master_point(const unsigned int i) const =0
const Elem * interior_parent() const
Definition elem.C:1160
unsigned char _pflag
p refinement flag.
Definition elem.h:2289
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:2833
Elem *const * NeighborPtrIter
Nested "classes" for use iterating over all neighbors of an element.
Definition elem.h:334
void set_mapping_type(const ElemMappingType type)
Sets the value of the mapping type for the element.
Definition elem.h:3145
virtual bool is_node_on_edge(const unsigned int n, const unsigned int e) const =0
virtual bool is_linear() const
Definition elem.h:1207
bool relative_edge_face_order(const unsigned int e, const unsigned int s) const
Definition elem.C:3664
void set_refinement_flag(const RefinementState rflag)
Sets the value of the refinement flag for the element.
Definition elem.h:3235
virtual unsigned int n_edges() const =0
virtual ElemType side_type(const unsigned int s) const =0
virtual unsigned int n_sides() const =0
dof_id_type node_id(const unsigned int i) const
Definition elem.h:2484
bool subactive() const
Definition elem.h:2976
unsigned int p_level() const
Definition elem.h:3125
IntRange< unsigned short > face_index_range() const
Definition elem.h:2718
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
const Elem * topological_neighbor(const unsigned int i, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
Definition elem.C:1287
void swap4neighbors(unsigned int n1, unsigned int n2, unsigned int n3, unsigned int n4)
Swaps four neighbor_ptrs, "rotating" them.
Definition elem.h:2162
Elem(const unsigned int n_nodes, const unsigned int n_sides, Elem *parent, Elem **elemlinkdata, Node **nodelinkdata)
Constructor.
Definition elem.h:2387
virtual bool has_affine_map() const
Definition elem.h:1191
void set_mapping_data(const unsigned char data)
Sets the value of the mapping data for the element.
Definition elem.h:3161
RefinementState p_refinement_flag() const
Definition elem.h:3243
virtual unsigned int local_singular_node(const Point &, const Real=TOLERANCE *TOLERANCE) const
Definition elem.h:1840
virtual unsigned short int second_order_adjacent_vertex(const unsigned int n, const unsigned int v) const
Definition elem.C:3081
virtual bool close_to_point(const Point &p, Real tol) const
Definition elem.C:2809
virtual bool is_edge_on_side(const unsigned int e, const unsigned int s) const =0
void set_p_level(const unsigned int p)
Sets the value of the p-refinement level for the element.
const Elem * neighbor_ptr(unsigned int i) const
Definition elem.h:2615
virtual bool infinite() const =0
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
Point vertex_average() const
Definition elem.C:669
IntRange< unsigned short > side_index_range() const
Definition elem.h:2727
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:3356
virtual std::vector< unsigned int > edges_adjacent_to_node(const unsigned int) const =0
const Elem * top_parent() const
Definition elem.h:3073
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i)=0
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
Definition int_range.h:54
This is the MeshBase class.
Definition mesh_base.h:81
Implements (adaptive) mesh refinement algorithms for a MeshBase.
A Node is like a Point, but with more information.
Definition node.h:55
We're using a class instead of a typedef to allow forward declarations and future flexibility.
This is the base class for point locators.
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
The PointerToPointerIter templated class is intended to wrap pointer-to-pointer iterators in an inter...
This class implements reference counting.
The SimpleRange templated class is intended to make it easy to construct ranges from pairs of iterato...
Original Authors: Corwin Joy * Michael Gradman cjoy@houston.rr.com * Michael.Gradman@caminus....
MeshBase & mesh
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
uint32_t hashword(const uint32_t *k, size_t length, uint32_t initval=0)
The hashword function takes an array of uint32_t's of length 'length' and computes a single key from ...
Definition hashword.h:158
The libMesh namespace provides an interface to certain functionality in the library.
IOPackage
libMesh interfaces with several different software packages for the purposes of creating,...
ElemType
Defines an enum for geometric element types.
ElemMappingType
Enumeration of possible element master->physical mapping types.
libmesh_assert(ctx)
std::ostream & operator<<(std::ostream &os, const OrderWrapper &order)
Overload stream operators.
Definition fe_type.h:182
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
OStreamProxy out
ElemQuality
Defines an enum for element quality metrics.
static constexpr Real TOLERANCE
uint8_t dof_id_type
Definition id_types.h:67
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
uint8_t processor_id_type
Definition id_types.h:104
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
The definition of the struct used for iterating over sides.
Definition elem.h:3508
side_iterator(const IterType &d, const IterType &e, const PredType &p)
Definition elem.h:3511