1 // Copyright(C) 1999-2020 National Technology & Engineering Solutions
2 // of Sandia, LLC (NTESS).  Under the terms of Contract DE-NA0003525 with
3 // NTESS, the U.S. Government retains certain rights in this software.
4 //
5 // See packages/seacas/LICENSE for details
6 
7 #ifndef IOSS_Ioss_Element_Topology_h
8 #define IOSS_Ioss_Element_Topology_h
9 
10 #include "vtk_ioss_mangle.h"
11 
12 #include <Ioss_CodeTypes.h>
13 #include <map>    // for map, map<>::value_compare
14 #include <string> // for string, operator<
15 #include <vector> // for vector
16 namespace Ioss {
17   class ElementTopology;
18 } // namespace Ioss
19 
20 namespace Ioss {
21   enum class ElementShape { UNKNOWN, POINT, LINE, TRI, QUAD, TET, PYRAMID, WEDGE, HEX };
22 
23   using ElementTopologyMap = std::map<std::string, ElementTopology *, std::less<std::string>>;
24   using ETM_VP             = ElementTopologyMap::value_type;
25 
26   class ETRegistry
27   {
28   public:
29     void                         insert(const Ioss::ETM_VP &value, bool delete_me);
begin()30     ElementTopologyMap::iterator begin() { return m_registry.begin(); }
end()31     ElementTopologyMap::iterator end() { return m_registry.end(); }
find(const std::string & type)32     ElementTopologyMap::iterator find(const std::string &type) { return m_registry.find(type); }
33 
34     ~ETRegistry();
35     std::map<std::string, std::string> customFieldTypes;
36 
37   private:
38     Ioss::ElementTopologyMap             m_registry;
39     std::vector<Ioss::ElementTopology *> m_deleteThese;
40   };
41 
42   // ========================================================================
43 
44   /** \brief Represents an element topology.
45    *
46    *  Defines node, edge, and face connectivity information of an element.
47    */
48   class ElementTopology
49   {
50   public:
51     void alias(const std::string &base, const std::string &syn);
52     bool is_alias(const std::string &my_alias) const;
53 
54     ElementTopology(const ElementTopology &) = delete;
55     ElementTopology &operator=(const ElementTopology &) = delete;
56 
57     virtual ~ElementTopology();
58 
name()59     const std::string &name() const { return name_; }
60 
61     //: Return the Sierra master element name corresponding to this
62     //: element topology.  Somewhat klugy coupling between IO subsystem
63     //: and Sierra, but least klugy I could think of...
master_element_name()64     std::string master_element_name() const { return masterElementName_; }
65 
66     //: Return basic shape...
67     virtual ElementShape shape() const = 0;
68 
69     //: Return whether the topology describes an "element". If it
70     //: isn't an element, then it is a component of an element.  For
71     // example, a quadrilater Shell is an element, but a QuadFace is
72     // not.
73     //
74     // Default implementation returns true if spatial_dimension() ==
75     // parametric_dimension(), otherwise returns false;
76     // "Structural" elements (shells, rods, trusses, particles) need
77     // to override.
78     virtual bool is_element() const;
79     virtual int  spatial_dimension() const    = 0;
80     virtual int  parametric_dimension() const = 0;
81     virtual int  order() const                = 0;
82 
83     virtual bool edges_similar() const; // true if all edges have same topology
84     virtual bool faces_similar() const; // true if all faces have same topology
85 
86     virtual int number_corner_nodes() const = 0;
87     virtual int number_nodes() const        = 0;
88     virtual int number_edges() const        = 0;
89     virtual int number_faces() const        = 0;
90     int         number_boundaries() const;
91 
92     virtual int number_nodes_edge(int edge = 0) const = 0;
93     virtual int number_nodes_face(int face = 0) const = 0;
94     virtual int number_edges_face(int face = 0) const = 0;
95 
96     IntVector         boundary_connectivity(int edge_number) const;
97     virtual IntVector edge_connectivity(int edge_number) const = 0;
98     virtual IntVector face_connectivity(int face_number) const = 0;
99     virtual IntVector element_connectivity() const             = 0;
100 
101     // These have default implementations in ElementTopology.
102     // The defaults simply fill in the vector with 0..num.
103     // For 'face_edge_connectivity', this is sufficient for 2d
104     // elements, 3d need to override.
105     // For 'element_edge_connectivity', this works for all elements.
106     virtual IntVector face_edge_connectivity(int face_number) const;
107     IntVector         element_edge_connectivity() const;
108 
109     ElementTopology *        boundary_type(int face_number = 0) const;
110     virtual ElementTopology *face_type(int face_number = 0) const = 0;
111     virtual ElementTopology *edge_type(int edge_number = 0) const = 0;
112 
113     static ElementTopology *factory(const std::string &type, bool ok_to_fail = false);
114     static ElementTopology *factory(unsigned int unique_id);
115     static unsigned int     get_unique_id(const std::string &type);
116     static int              describe(NameList *names);
117 
118     bool operator==(const Ioss::ElementTopology &rhs) const;
119     bool operator!=(const Ioss::ElementTopology &rhs) const;
120     bool equal(const Ioss::ElementTopology &rhs) const;
121 
122   protected:
123     ElementTopology(std::string type, std::string master_elem_name, bool delete_me = false);
124 
125   private:
126     bool              equal_(const Ioss::ElementTopology &rhs, bool quiet) const;
127     const std::string name_;
128     const std::string masterElementName_;
129 
130     static ETRegistry &registry();
131   };
132 } // namespace Ioss
133 #endif
134