Line data Source code
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_CELL_PYRAMID18_H
21 : #define LIBMESH_CELL_PYRAMID18_H
22 :
23 : // Local includes
24 : #include "libmesh/cell_pyramid.h"
25 : #include "libmesh/fe_reference_element_traits.h"
26 :
27 : namespace libMesh
28 : {
29 :
30 : /**
31 : * The \p Pyramid18 is an element in 3D composed of 18 nodes, designed
32 : * to interface with a QUAD9 element on the base and a TRI7 element on
33 : * each of the triangular faces. Cubit will generate hybrid meshes
34 : * with linear pyramids, but as of version 18 will not export
35 : * quadratic pyramids. Paraview may support 13-node pyramids, but
36 : * does not render 18-node pyramids correctly. So even if this
37 : * element works in libmesh, we are currently limited in what we can do
38 : * with it outside the library...
39 : *
40 : * The node numbering for the pyramid18 is given below:
41 : *
42 : * \verbatim
43 : * PYRAMID18:
44 : * o 4
45 : * //|\
46 : * // | \
47 : * // | \
48 : * // | \
49 : * 12 o/ | o 11
50 : * // | \
51 : * /o 9 o 10 \
52 : * // | \ zeta
53 : * // | \ ^ eta (into page)
54 : * 3 o/.......o.|........o 2 | /
55 : * ./ 7 | / |/
56 : * ./ | / o---> xi
57 : * ./ | /
58 : * ./ | /
59 : * 8 o/ o | o 6
60 : * ./ 13 | /
61 : * ./ | /
62 : * ./ |/
63 : * o--------o---------o
64 : * 0 5 1
65 : * \endverbatim
66 : *
67 : * And it also includes four triangle face nodes:
68 : * Node 14, centroid on side 0, arithmetic mean of 0/1/4 or 5/9/10
69 : * Node 15, centroid on side 1, arithmetic mean of 1/2/4 or 6/10/11
70 : * Node 16, centroid on side 2, arithmetic mean of 2/3/4 or 7/11/12
71 : * Node 17, centroid on side 3, arithmetic mean of 0/3/4 or 8/9/12
72 : *
73 : * (xi, eta, zeta): { zeta-1 <= xi <= 1-zeta
74 : * { zeta-1 <= eta <= 1-zeta
75 : * { 0 <= zeta <= 1
76 : * are the reference element coordinates associated with the given
77 : * numbering.
78 : *
79 : * \author Roy H. Stogner
80 : * \date 2022
81 : * \brief A 3D pyramid element with 18 nodes.
82 : */
83 : class Pyramid18 final : public Pyramid
84 : {
85 : public:
86 :
87 : /**
88 : * Constructor. By default this element has no parent.
89 : */
90 : explicit
91 11402 : Pyramid18 (Elem * p=nullptr) :
92 11402 : Pyramid(num_nodes, p, _nodelinks_data)
93 11402 : {}
94 :
95 : Pyramid18 (Pyramid18 &&) = delete;
96 : Pyramid18 (const Pyramid18 &) = delete;
97 : Pyramid18 & operator= (const Pyramid18 &) = delete;
98 : Pyramid18 & operator= (Pyramid18 &&) = delete;
99 20590 : virtual ~Pyramid18() = default;
100 :
101 : /**
102 : * \returns 18.
103 : */
104 11031721 : virtual unsigned int n_nodes() const override { return num_nodes; }
105 :
106 : /**
107 : * \returns \p PYRAMID18.
108 : */
109 47610192 : virtual ElemType type () const override { return PYRAMID18; }
110 :
111 : /**
112 : * FIXME: we don't yet have a refinement pattern for pyramids...
113 : * \returns 1.
114 : */
115 0 : virtual unsigned int n_sub_elem() const override { return 1; }
116 :
117 : /**
118 : * \returns \p true if the specified (local) node number is a vertex.
119 : */
120 : virtual bool is_vertex(const unsigned int i) const override;
121 :
122 : /**
123 : * \returns \p true if the specified (local) node number is an edge.
124 : */
125 : virtual bool is_edge(const unsigned int i) const override;
126 :
127 : /**
128 : * \returns \p true if the specified (local) node number is a face.
129 : */
130 : virtual bool is_face(const unsigned int i) const override;
131 :
132 : /**
133 : * \returns \p true if the specified (local) node number is on the
134 : * specified side.
135 : */
136 : virtual bool is_node_on_side(const unsigned int n,
137 : const unsigned int s) const override;
138 :
139 : virtual std::vector<unsigned int> nodes_on_side(const unsigned int s) const override;
140 :
141 : virtual std::vector<unsigned int> nodes_on_edge(const unsigned int e) const override;
142 :
143 : /**
144 : * \returns \p true if the specified (local) node number is on the
145 : * specified edge.
146 : */
147 : virtual bool is_node_on_edge(const unsigned int n,
148 : const unsigned int e) const override;
149 :
150 : /**
151 : * \returns \p true if the element map is definitely affine within
152 : * numerical tolerances.
153 : */
154 : virtual bool has_affine_map () const override;
155 :
156 : /**
157 : * \returns SECOND.
158 : */
159 : virtual Order default_order() const override;
160 :
161 : /**
162 : * Don't hide Pyramid::key() defined in the base class.
163 : */
164 : using Pyramid::key;
165 :
166 : /**
167 : * \returns An id associated with the \p s side of this element.
168 : * The id is not necessarily unique, but should be close.
169 : *
170 : * We reimplement this method here for the \p Pyramid18 since we can
171 : * use the center node of the base face to provide a perfect (unique)
172 : * key.
173 : */
174 : virtual dof_id_type key (const unsigned int s) const override;
175 :
176 : /**
177 : * \returns \p Pyramid18::side_nodes_map[side][side_node] after doing some range checking.
178 : */
179 : virtual unsigned int local_side_node(unsigned int side,
180 : unsigned int side_node) const override;
181 :
182 : /**
183 : * \returns \p Pyramid18::edge_nodes_map[edge][edge_node] after doing some range checking.
184 : */
185 : virtual unsigned int local_edge_node(unsigned int edge,
186 : unsigned int edge_node) const override;
187 :
188 : /**
189 : * Builds a \p QUAD9 or \p TRI7 coincident with face i.
190 : * The \p std::unique_ptr<Elem> handles the memory aspect.
191 : */
192 : virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i) override;
193 :
194 : /**
195 : * Rebuilds a \p QUAD9 or \p TRI7 built coincident with face i.
196 : */
197 : virtual void build_side_ptr (std::unique_ptr<Elem> & elem,
198 : const unsigned int i) override;
199 :
200 : // Avoid hiding deprecated version with different signature
201 : using Elem::build_side_ptr;
202 :
203 : /**
204 : * Builds a \p EDGE3 coincident with edge i.
205 : * The \p std::unique_ptr<Elem> handles the memory aspect.
206 : */
207 : virtual std::unique_ptr<Elem> build_edge_ptr (const unsigned int i) override;
208 :
209 : /**
210 : * Rebuilds a \p EDGE3 coincident with edge i.
211 : */
212 : virtual void build_edge_ptr (std::unique_ptr<Elem> & edge, const unsigned int i) override;
213 :
214 : virtual void connectivity(const unsigned int sc,
215 : const IOPackage iop,
216 : std::vector<dof_id_type> & conn) const override;
217 :
218 : /**
219 : * \returns 2 for all edge nodes, 4 for quad face nodes, 3 for tri
220 : * face nodes.
221 : */
222 : virtual unsigned int n_second_order_adjacent_vertices (const unsigned int n) const override;
223 :
224 : /**
225 : * \returns The element-local number of the \f$ v^{th} \f$ vertex
226 : * that defines the \f$ n^{th} \f$ second-order node.
227 : */
228 : virtual unsigned short int second_order_adjacent_vertex (const unsigned int n,
229 : const unsigned int v) const override;
230 :
231 : /**
232 : * Geometric constants for Pyramid18.
233 : */
234 : static const int num_nodes = 18;
235 : static const int nodes_per_side = 9;
236 : static const int nodes_per_edge = 3;
237 :
238 : /**
239 : * This maps the \f$ j^{th} \f$ node of the \f$ i^{th} \f$ side to
240 : * element node numbers.
241 : */
242 : static const ReferenceElementTable<num_sides, nodes_per_side> side_nodes_map;
243 :
244 : /**
245 : * This maps the \f$ j^{th} \f$ node of the \f$ i^{th} \f$ edge to
246 : * element node numbers.
247 : */
248 : static const ReferenceElementTable<num_edges, nodes_per_edge> edge_nodes_map;
249 :
250 : virtual void permute(unsigned int perm_num) override final;
251 :
252 : virtual void flip(BoundaryInfo *) override final;
253 :
254 : unsigned int center_node_on_side(const unsigned short side) const override final;
255 :
256 : ElemType side_type (const unsigned int s) const override final;
257 :
258 : protected:
259 :
260 : /**
261 : * Data for links to nodes.
262 : */
263 : Node * _nodelinks_data[num_nodes];
264 :
265 :
266 :
267 : #ifdef LIBMESH_ENABLE_AMR
268 :
269 : /**
270 : * Matrix used to create the elements children.
271 : */
272 0 : virtual Real embedding_matrix (const unsigned int,
273 : const unsigned int,
274 : const unsigned int) const override
275 0 : { libmesh_not_implemented(); return 0.; }
276 :
277 0 : LIBMESH_ENABLE_TOPOLOGY_CACHES;
278 :
279 : #endif // LIBMESH_ENABLE_AMR
280 :
281 : };
282 :
283 : } // namespace libMesh
284 :
285 :
286 : #endif // LIBMESH_CELL_PYRAMID18_H
|