1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2020 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_CELL_INF_HEX16_H
21 #define LIBMESH_CELL_INF_HEX16_H
22 
23 #include "libmesh/libmesh_config.h"
24 
25 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
26 
27 // Local includes
28 #include "libmesh/cell_inf_hex.h"
29 
30 namespace libMesh
31 {
32 
33 /**
34  * The \p InfHex16 is an infinite element in 3D composed of 16 nodes.
35  * It is numbered like this:
36  * \verbatim
37  *   INFHEX16:   7              14             6
38  *               o              o              o      closer to infinity
39  *               :              :              |
40  *               :              :              |
41  *               :              :              |
42  *         15    :              :        13    |
43  *          o    :              :         o    |
44  *          :    :              :         |    |
45  *          :    :              :         |    |
46  *          :    :              :         |    |
47  *     4    :    :    12        :    5    |    |
48  *     o    :    :    o         :    o    |    |
49  *     |    :    :    |         :    |    |    |
50  *     |    :    :    |         :    |    |    |
51  *     |    :    :    |         :10  |    |    |
52  *     |    :   3o....|.........o....|....|....o
53  *     |    :   .     |              |    |   / 2
54  *     |    :  .      |              |    |  /
55  *     |    : .       |              |    | /
56  *     |    :.        |              |    |/
57  *     |  11o         |              |    o           base face
58  *     |   .          |              |   / 9
59  *     |  .           |              |  /
60  *     | .            |              | /
61  *     |.             |              |/
62  *     o--------------o--------------o
63  *     0              8              1
64  * \endverbatim
65  *
66  * \author Daniel Dreyer
67  * \date 2002
68  * \brief A 3D infinite hexahedral element with 16 nodes.
69  */
70 class InfHex16 final : public InfHex
71 {
72 public:
73 
74   /**
75    * Constructor.  By default this element has no parent.
76    */
77   explicit
78   InfHex16 (Elem * p=nullptr) :
InfHex(InfHex16::n_nodes (),p,_nodelinks_data)79     InfHex(InfHex16::n_nodes(), p, _nodelinks_data)
80   {}
81 
82   InfHex16 (InfHex16 &&) = delete;
83   InfHex16 (const InfHex16 &) = delete;
84   InfHex16 & operator= (const InfHex16 &) = delete;
85   InfHex16 & operator= (InfHex16 &&) = delete;
86   virtual ~InfHex16() = default;
87 
88   /**
89    * \returns 16.  The \p InfHex16 has 16 nodes.
90    */
n_nodes()91   virtual unsigned int n_nodes() const override { return num_nodes; }
92 
93   /**
94    * \returns \p INFHEX16.
95    */
type()96   virtual ElemType type () const override { return INFHEX16; }
97 
98   /**
99    * \returns The number of sub elements for this element type.
100    */
n_sub_elem()101   virtual unsigned int n_sub_elem() const override { return 1; }
102 
103   /**
104    * \returns \p true if the specified (local) node number is a vertex.
105    */
106   virtual bool is_vertex(const unsigned int i) const override;
107 
108   /**
109    * \returns \p true if the specified (local) node number is an edge.
110    */
111   virtual bool is_edge(const unsigned int i) const override;
112 
113   /**
114    * \returns \p true if the specified (local) node number is a face.
115    */
116   virtual bool is_face(const unsigned int i) const override;
117 
118   /**
119    * \returns \p true if the specified (local) node number is on the
120    * specified side.
121    */
122   virtual bool is_node_on_side(const unsigned int n,
123                                const unsigned int s) const override;
124 
125   virtual std::vector<unsigned int> nodes_on_side(const unsigned int s) const override;
126 
127   virtual std::vector<unsigned int> nodes_on_edge(const unsigned int e) const override;
128 
129   /**
130    * \returns \p true if the specified (local) node number is on the
131    * specified edge.
132    */
133   virtual bool is_node_on_edge(const unsigned int n,
134                                const unsigned int e) const override;
135 
136   /**
137    * \returns SECOND.
138    */
139   virtual Order default_order() const override;
140 
141   /**
142    * \returns \p InfHex16::side_nodes_map[side][side_node] after doing some range checking.
143    */
144   virtual unsigned int local_side_node(unsigned int side,
145                                        unsigned int side_node) const override;
146 
147   /**
148    * \returns \p InfHex16::edge_nodes_map[edge][edge_node] after doing some range checking.
149    */
150   virtual unsigned int local_edge_node(unsigned int edge,
151                                        unsigned int edge_node) const override;
152 
153   /**
154    * \returns A \p QUAD8 built coincident with face 0, or an \p
155    * INFQUAD6 built coincident with faces 1 to 4.
156    *
157    * \note The \p std::unique_ptr<Elem> takes care of freeing memory.
158    */
159   virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i,
160                                                 bool proxy=true) override;
161 
162   /**
163    * Rebuilds a \p QUAD8 built coincident with face 0, or an \p
164    * INFQUAD6 built coincident with faces 1 to 4.
165    */
166   virtual void build_side_ptr (std::unique_ptr<Elem> & elem,
167                                const unsigned int i) override;
168 
169   /**
170    * \returns An \p EDGE3 built coincident with edges 0 to 3, or \p
171    * INFEDGE2 built coincident with edges 4 to 11.
172    *
173    * \note The \p std::unique_ptr<Elem> takes care of freeing memory.
174    */
175   virtual std::unique_ptr<Elem> build_edge_ptr (const unsigned int i) override;
176 
177   virtual void connectivity(const unsigned int sc,
178                             const IOPackage iop,
179                             std::vector<dof_id_type> & conn) const override;
180 
vtk_element_type(const unsigned int)181   unsigned int vtk_element_type (const unsigned int) const
182   { return 12; }
183 
184   /**
185    * \returns 2 for all \p n.
186    */
n_second_order_adjacent_vertices(const unsigned int)187   virtual unsigned int n_second_order_adjacent_vertices (const unsigned int) const override
188   { return 2; }
189 
190   /**
191    * \returns The element-local number of the \f$ v^{th} \f$ vertex
192    * that defines the \f$ n^{th} \f$ second-order node.
193    *
194    * \note \p n is counted as depicted above, \f$ 8 \le n < 16 \f$.
195    */
196   virtual unsigned short int second_order_adjacent_vertex (const unsigned int n,
197                                                            const unsigned int v) const override;
198 
199   /**
200    * \returns The child number \p c and element-local index \p v of the
201    * \f$ n^{th} \f$ second-order node on the parent element.  See
202    * elem.h for further details.
203    */
204   virtual std::pair<unsigned short int, unsigned short int>
205   second_order_child_vertex (const unsigned int n) const override;
206 
207   /**
208    * Geometric constants for InfHex16.
209    */
210   static const int num_nodes = 16;
211   static const int num_sides = 5;
212   static const int num_edges = 8;
213   static const int num_children = 4;
214   static const int nodes_per_side = 8;
215   static const int nodes_per_edge = 3;
216 
217   /**
218    * This maps the \f$ j^{th} \f$ node of the \f$ i^{th} \f$ side to
219    * element node numbers.
220    */
221   static const unsigned int side_nodes_map[num_sides][nodes_per_side];
222 
223   /**
224    * This maps the \f$ j^{th} \f$ node of the \f$ i^{th} \f$ edge to
225    * element node numbers.
226    */
227   static const unsigned int edge_nodes_map[num_edges][nodes_per_edge];
228 
229   /**
230    * This maps each edge to the sides that contain said edge.
231    */
232   static const unsigned int edge_sides_map[num_edges][2];
233 
234 protected:
235 
236   /**
237    * Data for links to nodes.
238    */
239   Node * _nodelinks_data[num_nodes];
240 
241 
242 #ifdef LIBMESH_ENABLE_AMR
243 
244   /**
245    * Matrix used to create the elements children.
246    */
embedding_matrix(const unsigned int i,const unsigned int j,const unsigned int k)247   virtual float embedding_matrix (const unsigned int i,
248                                   const unsigned int j,
249                                   const unsigned int k) const override
250   { return _embedding_matrix[i][j][k]; }
251 
252   /**
253    * Matrix that computes new nodal locations/solution values
254    * from current nodes/solution.
255    */
256   static const float _embedding_matrix[num_children][num_nodes][num_nodes];
257 
258   LIBMESH_ENABLE_TOPOLOGY_CACHES;
259 
260 #endif // LIBMESH_ENABLE_AMR
261 
262 };
263 
264 } // namespace libMesh
265 
266 #endif  // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
267 
268 
269 #endif // LIBMESH_CELL_INF_HEX16_H
270