18 #include "libmesh/cell_polyhedron.h"    21 #include "libmesh/face_polygon.h"    22 #include "libmesh/enum_elem_quality.h"    23 #include "libmesh/hashword.h"    27 #include <unordered_map>    28 #include <unordered_set>    44     Cell( 0, sides.size(), p, nullptr, nullptr),
    45     _elemlinks_data(sides.size()+2), 
    47     _sidelinks_data(sides.size())
    54     std::unordered_map<Node *, unsigned int> local_node_number;
    55     std::unordered_set<std::pair<const Node *, const Node *>,
    57     std::unique_ptr<const Elem> edge;
    62         std::get<0>(side_tuple) = sides[s];
    67             Node * node = side.node_ptr(n);
    68             if (
auto it = local_node_number.find(node);
    69                 it != local_node_number.end())
    71                 std::get<2>(side_tuple).push_back(it->second);
    75                 std::get<2>(side_tuple).push_back(nn);
    76                 local_node_number[node] = nn++;
    81         for (
unsigned int e : 
make_range(side.n_edges()))
    83             side.build_edge_ptr(edge, e);
    84             auto edge_vertices = std::make_pair(edge->node_ptr(0), edge->node_ptr(1));
    85             if (edge_vertices.first > edge_vertices.second)
    86               std::swap(edge_vertices.first, edge_vertices.second);
    88             if (!edges_seen.count(edge_vertices))
    90                 edges_seen.insert(edge_vertices);
   103     libmesh_assert_equal_to(nn, this->
n_nodes());
   112     center /= 
static_cast<Real>(nn);
   116         const Polygon & side = *sides[s];
   123         inward_normal = (n_i * (center - x_i) > 
TOLERANCE);
   131         const Polygon & side = *sides[s];
   138           (inward_normal ? -1 : 1);
   142             const Point d_n = node - x_i;
   144               libmesh_not_implemented_msg
   145                 (
"Cannot create a non-convex polyhedron");
   159 #ifdef LIBMESH_ENABLE_AMR   172   return this->
point(i);
   188         (inward_normal ? -1 : 1);
   192           const Point d_n = node - x_i;
   203                                       const Real eps)
 const   205   const unsigned int ns = this->
n_sides();
   226         (inward_normal ? -1 : 1);
   233           const Point d_j = x_j - x_i;
   234           if (std::abs(d_j * n_i) > eps * d_j.
norm())
   235             libmesh_not_implemented_msg
   236               (
"Polyhedra with non-flat sides are not fully supported.");
   240       if (n_i * (p - x_i) > eps)
   251   libmesh_assert_less (s, this->
n_sides());
   262   libmesh_assert_less (s, this->
n_sides());
   267   std::vector<dof_id_type> vertex_ids(nv);
   269     vertex_ids[v] = face.
node_id(v);
   277                                          unsigned int side_node)
 const   279   libmesh_assert_less (side, this->
n_sides());
   281   const std::vector<unsigned int> & node_map =
   283   libmesh_assert_less (side_node, node_map.size());
   285   return node_map[side_node];
   291                                          unsigned int edge_node)
 const   293   libmesh_assert_less (edge, this->
n_edges());
   300   const std::vector<unsigned int> & node_map =
   310   std::vector<dof_id_type> node_ids;
   312     node_ids.push_back(n.id());
   328   libmesh_assert_less (i, this->
n_sides());
   333     face_copy->set_node(n, face.
node_ptr(n));
   341                            const unsigned int i)
   343   libmesh_assert_less (i, this->
n_sides());
   355   returnval->set_interior_parent(
this);
   356   returnval->inherit_data_from(*
this);
   363                                  const unsigned int i)
   366   side->set_interior_parent(
this);
   367   side->inherit_data_from(*
this);
   382                                  const unsigned int i)
   392                                   const unsigned int )
 const   394   libmesh_not_implemented();
   403   libmesh_not_implemented();
   410                                        const unsigned int )
 const   413   libmesh_not_implemented();
   434 std::vector<unsigned int>
   437   libmesh_assert_less(n, this->
n_nodes());
   443   const unsigned int ne = this->
n_edges();
   446   std::vector<unsigned int> adjacent_edges;
   448   unsigned int next_edge = 0;
   456       const std::vector<unsigned int> & node_map =
   463             return adjacent_edges;
   472       libmesh_assert_equal_to(fnv, face.
n_edges());
   473       libmesh_assert_equal_to(fnv, face.
n_sides());
   474       libmesh_assert_less_equal(fnv, node_map.size());
   479           libmesh_assert_equal_to (
_edge_lookup[next_edge].first, t);
   489                 return adjacent_edges;
   495           const unsigned int vn = node_map[v];
   496           const unsigned int vnp = node_map[(v+1)%fnv];
   499           if (vn == n || vnp == n)
   500             adjacent_edges.push_back(next_edge);
   504   return adjacent_edges;
   510   std::pair<Real, Real> bounds;
   521       bounds.second = 180.;
   526       bounds.second = 180.;
   536       libMesh::out << 
"Warning: Invalid quality measure chosen." << std::endl;
   546 std::vector<std::shared_ptr<Polygon>>
   549   const auto ns = this->
n_sides();
   553   std::vector<std::shared_ptr<Polygon>> cloned_sides(ns);
   560       Polygon * polygon_clone = cast_ptr<Polygon *>(clone);
   561       cloned_sides[i] = std::shared_ptr<Polygon>(polygon_clone);
   570           (n, const_cast<Node *>(face.
node_ptr(n)));
   579                                      unsigned int min_node,
   580                                      unsigned int max_node)
 const   583   const std::vector<unsigned int> & node_map =
   606 std::vector<unsigned int>
   609   std::vector<unsigned int> returnval(2);
   614   const std::vector<unsigned int> & node_map =
   647                                  const unsigned int s)
 const   656   const std::vector<unsigned int> & node_map =
   658   std::vector<unsigned int> nodes_on_edge1 =
   660   libmesh_assert_equal_to(nodes_on_edge1.size(), 2);
   662   nodes_on_edge1[0] = node_map[nodes_on_edge1[0]];
   663   nodes_on_edge1[1] = node_map[nodes_on_edge1[1]];
   664   if (nodes_on_edge1[0] > nodes_on_edge1[1])
   665     std::swap(nodes_on_edge1[0], nodes_on_edge1[1]);
   687 std::tuple<unsigned int, Real, Real, Real>
   690   std::tuple<unsigned int, Real, Real, Real> returnval =
   693   Real best_bad_coord = -1;
   697       const std::array<Point, 4> subtet =
   701       const Point v0 = p - subtet[0];
   704       const Point v01 = subtet[1] - subtet[0];
   705       const Point v02 = subtet[2] - subtet[0];
   706       const Point v03 = subtet[3] - subtet[0];
   718       const Real xi   = tp1 / six_vol;
   719       const Real eta  = tp2 / six_vol;
   720       const Real zeta = tp3 / six_vol;
   722       if (xi>=0 && eta>=0 && zeta>=0 && xi+eta+zeta<=1)
   723         return { s, xi, eta, zeta };
   725       const Real my_best_bad_coord =
   726         std::min(std::min(std::min(xi, eta), zeta), 1-xi-eta-zeta);
   728       if (my_best_bad_coord > best_bad_coord)
   730           best_bad_coord = my_best_bad_coord;
   731           returnval = { s, xi, eta, zeta };
   735   if (best_bad_coord > -tol)
 
void set_p_level(const unsigned int p)
Sets the value of the p-refinement level for the element. 
unsigned char mapping_data() const
virtual unsigned int n_nodes() const override
virtual unsigned int n_nodes() const override
unsigned char _map_type
Mapping function type; currently either 0 (LAGRANGE) or 1 (RATIONAL_BERNSTEIN). 
unsigned char _map_data
Mapping function data; currently used when needed to store the RATIONAL_BERNSTEIN nodal weight data i...
std::vector< Elem * > _elemlinks_data
Data for links to parent/neighbor/interior_parent elements. 
virtual Node *& set_node(const unsigned int i)
A Node is like a Point, but with more information. 
Node ** _nodes
Pointers to the nodes we are connected to. 
The Polyhedron is an element in 3D with an arbitrary number of polygonal faces. 
virtual bool is_child_on_side(const unsigned int c, const unsigned int s) const override
auto norm() const -> decltype(std::norm(T()))
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
std::vector< Node * > _nodelinks_data
Data for links to nodes. 
virtual unsigned int opposite_side(const unsigned int s) const override final
Throws an error. 
virtual dof_id_type key() const override
virtual unsigned int local_edge_node(unsigned int edge, unsigned int edge_node) const override
Similar to Elem::local_side_node(), but instead of a side id, takes an edge id and a node id on that ...
static constexpr Real TOLERANCE
virtual std::array< Point, 4 > master_subelement(unsigned int i) const
std::vector< std::tuple< std::shared_ptr< Polygon >, bool, std::vector< unsigned int > > > _sidelinks_data
Data for links to sides. 
virtual std::pair< Real, Real > qual_bounds(const ElemQuality q) const override
virtual bool on_reference_element(const Point &p, const Real eps=TOLERANCE) const override final
This is the base class from which all geometric element types are derived. 
static const int num_children
unsigned int p_level() const
Polyhedron(const std::vector< std::shared_ptr< Polygon >> &sides, Elem *p)
Arbitrary polyhedral element, takes a vector of shared pointers to sides (which should already be con...
The libMesh namespace provides an interface to certain functionality in the library. 
virtual unsigned int local_edge_node(unsigned int edge, unsigned int edge_node) const override
Calls local_side_node(edge, edge_node). 
virtual unsigned int n_sides() const override final
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i) override final
void set_interior_parent(Elem *p)
Sets the pointer to the element's interior_parent. 
void add(const TypeVector< T2 > &)
Add to this vector without creating a temporary. 
std::vector< std::pair< unsigned int, unsigned int > > _edge_lookup
One entry for each polyhedron edge, a pair indicating the side number and the edge-of-side number whi...
virtual unsigned int n_edges() const override final
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 ...
bool side_has_edge_nodes(unsigned int side, unsigned int min_node, unsigned int max_node) const
Helper method for finding the non-cached side that shares an edge, by examining the local node ids th...
T triple_product(const TypeVector< T > &a, const TypeVector< T > &b, const TypeVector< T > &c)
TypeVector< T > unit() const
std::tuple< unsigned int, Real, Real, Real > subelement_coordinates(const Point &p, Real tol=TOLERANCE *TOLERANCE) const
ElemMappingType mapping_type() const
virtual bool is_flipped() const override final
virtual bool is_edge_on_side(const unsigned int e, const unsigned int s) const override final
unsigned int n_subelements() const
virtual dof_id_type low_order_key(const unsigned int s) const override
The Polygon is an element in 2D with an arbitrary (but fixed) number of sides. 
Elem ** _elemlinks
Pointers to this element's parent and neighbors, and for lower-dimensional elements' interior_parent...
The Cell is an abstract element type that lives in three dimensions. 
virtual unsigned int opposite_node(const unsigned int n, const unsigned int s) const override final
Throws an error - opposite_side(s) is too hard to define in general on polyhedra. ...
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i) override
Copies the Polygon side coincident with side i. 
ElemQuality
Defines an enum for element quality metrics. 
virtual std::unique_ptr< Elem > disconnected_clone() const
virtual dof_id_type key() const override
virtual std::vector< unsigned int > nodes_on_edge(const unsigned int) const =0
SimpleRange< NodeRefIter > node_ref_range()
Returns a range with all nodes of an element, usable in range-based for loops. 
std::vector< std::shared_ptr< Polygon > > side_clones() const
virtual Point master_point(const unsigned int i) const override
virtual unsigned int n_edges() const override final
virtual unsigned int local_side_node(unsigned int side, unsigned int side_node) const override
virtual unsigned int n_vertices() const =0
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual unsigned int n_vertices() const override final
subdomain_id_type subdomain_id() const
const Node * node_ptr(const unsigned int i) const
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...
virtual std::vector< unsigned int > edges_adjacent_to_node(const unsigned int n) const override
IntRange< unsigned short > node_index_range() const
virtual unsigned int n_sides() const override final
virtual std::unique_ptr< Elem > side_ptr(const unsigned int i) override final
std::vector< std::array< int, 4 > > _triangulation
Data for a triangulation (tetrahedralization) of the polyhedron. 
processor_id_type processor_id() const
virtual std::vector< unsigned int > sides_on_edge(const unsigned int e) const override final
A Point defines a location in LIBMESH_DIM dimensional Real space. 
dof_id_type node_id(const unsigned int i) const
const Point & point(const unsigned int i) const
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
virtual std::vector< unsigned int > nodes_on_side(const unsigned int) const =0
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i) override final
build_side and build_edge are identical for faces.