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