libMesh
Loading...
Searching...
No Matches
face_inf_quad6.C
Go to the documentation of this file.
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#include "libmesh/libmesh_config.h"
21
22#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
23
24// Local includes
25#include "libmesh/face_inf_quad6.h"
26#include "libmesh/edge_edge3.h"
27#include "libmesh/edge_inf_edge2.h"
28#include "libmesh/enum_io_package.h"
29#include "libmesh/enum_order.h"
30
31namespace libMesh
32{
33
34
35
36
37// ------------------------------------------------------------
38// InfQuad6 class static member initializations
39const int InfQuad6::num_nodes;
41
43 {
44 {0, 1, 4}, // Side 0
45 {1, 3, 99}, // Side 1
46 {0, 2, 99} // Side 2
47 };
48
49
50// ------------------------------------------------------------
51// InfQuad6 class member functions
52
53bool InfQuad6::is_node_on_side(const unsigned int n,
54 const unsigned int s) const
55{
56 libmesh_assert_less (s, n_sides());
57 return std::find(std::begin(side_nodes_map[s]),
58 std::end(side_nodes_map[s]),
59 n) != std::end(side_nodes_map[s]);
60}
61
62std::vector<unsigned>
63InfQuad6::nodes_on_side(const unsigned int s) const
64{
65 libmesh_assert_less(s, n_sides());
66 auto trim = (s == 0) ? 0 : 1;
67 return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s]) - trim};
68}
69
70std::vector<unsigned>
71InfQuad6::nodes_on_edge(const unsigned int e) const
72{
73 return nodes_on_side(e);
74}
75
76#ifdef LIBMESH_ENABLE_AMR
77
79 {
80 // embedding matrix for child 0
81 {
82 // 0 1 2 3 4 5th parent node
83 { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, // 0th child node
84 { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 }, // 1
85 { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0 }, // 2
86 { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0 }, // 3
87 { 0.375, -0.125, 0.0, 0.0, 0.75, 0.0 }, // 4
88 { 0.0, 0.0, 0.375, -0.125, 0.0, 0.75 } // 5
89 },
90
91 // embedding matrix for child 1
92 {
93 // 0 1 2 3 4 5th parent node
94 { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 }, // 0th child node
95 { 0.0, 1.0, 0.0, 0.0, 0.0, 0.0 }, // 1
96 { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0 }, // 2
97 { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, // 3
98 { -0.125, 0.375, 0.0, 0.0, 0.75, 0.0 }, // 4
99 { 0.0, 0.0, -0.125, 0.375, 0.0, 0.75 } // 5
100 }
101 };
102
103#endif
104
105
106
107
109{
110 return SECOND;
111}
112
113
114
115dof_id_type InfQuad6::key (const unsigned int s) const
116{
117 libmesh_assert_less (s, this->n_sides());
118
119 switch (s)
120 {
121 // Edge3 side
122 case 0:
123 return this->compute_key (this->node_id(4));
124
125 // InfEdge
126 case 1:
127 case 2:
128 return InfQuad::key(s);
129
130 default:
131 libmesh_error_msg("Invalid side s = " << s);
132 }
133}
134
135
136
137unsigned int InfQuad6::local_side_node(unsigned int side,
138 unsigned int side_node) const
139{
140 libmesh_assert_less (side, this->n_sides());
141 libmesh_assert ((side == 0 && side_node < InfQuad6::nodes_per_side) || (side_node < 2));
142
143 return InfQuad6::side_nodes_map[side][side_node];
144}
145
146
147
148std::unique_ptr<Elem> InfQuad6::build_side_ptr (const unsigned int i)
149{
150 // libmesh_assert_less (i, this->n_sides());
151
152 std::unique_ptr<Elem> edge;
153
154 switch (i)
155 {
156 case 0:
157 {
158 edge = std::make_unique<Edge3>();
159 break;
160 }
161
162 // adjacent to another infinite element
163 case 1:
164 case 2:
165 {
166 edge = std::make_unique<InfEdge2>();
167 break;
168 }
169
170 default:
171 libmesh_error_msg("Invalid side i = " << i);
172 }
173
174 // Set the nodes
175 for (auto n : edge->node_index_range())
176 edge->set_node(n, this->node_ptr(InfQuad6::side_nodes_map[i][n]));
177
178 edge->set_interior_parent(this);
179 edge->inherit_data_from(*this);
180
181 return edge;
182}
183
184
185
186void InfQuad6::build_side_ptr (std::unique_ptr<Elem> & side,
187 const unsigned int i)
188{
189 libmesh_assert_less (i, this->n_sides());
190
191 // Think of a unit cube: (-1,1) x (-1,1) x (1,1)
192 switch (i)
193 {
194 // the base face
195 case 0:
196 {
197 if (!side.get() || side->type() != EDGE3)
198 {
199 side = this->build_side_ptr(i);
200 return;
201 }
202 break;
203 }
204
205 // connecting to another infinite element
206 case 1:
207 case 2:
208 {
209 if (!side.get() || side->type() != INFEDGE2)
210 {
211 side = this->build_side_ptr(i);
212 return;
213 }
214 break;
215 }
216
217 default:
218 libmesh_error_msg("Invalid side i = " << i);
219 }
220
221 side->subdomain_id() = this->subdomain_id();
222 side->set_mapping_type(this->mapping_type());
223#ifdef LIBMESH_ENABLE_AMR
224 side->set_p_level(this->p_level());
225#endif
226 // Set the nodes
227 for (auto n : side->node_index_range())
228 side->set_node(n, this->node_ptr(InfQuad6::side_nodes_map[i][n]));
229}
230
231
232
233void InfQuad6::connectivity(const unsigned int sf,
234 const IOPackage iop,
235 std::vector<dof_id_type> & conn) const
236{
237 libmesh_assert_less (sf, this->n_sub_elem());
238 libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
239
240 conn.resize(4);
241
242 switch (iop)
243 {
244 case TECPLOT:
245 {
246 switch(sf)
247 {
248 case 0:
249 // linear sub-quad 0
250 conn[0] = this->node_id(0)+1;
251 conn[1] = this->node_id(4)+1;
252 conn[2] = this->node_id(5)+1;
253 conn[3] = this->node_id(2)+1;
254
255 return;
256
257 case 1:
258 // linear sub-quad 1
259 conn[0] = this->node_id(4)+1;
260 conn[1] = this->node_id(1)+1;
261 conn[2] = this->node_id(3)+1;
262 conn[3] = this->node_id(5)+1;
263
264 return;
265
266 default:
267 libmesh_error_msg("Invalid sf = " << sf);
268 }
269 }
270
271 default:
272 libmesh_error_msg("Unsupported IO package " << iop);
273 }
274}
275
276
277
278
279unsigned short int InfQuad6::second_order_adjacent_vertex (const unsigned int n,
280 const unsigned int v) const
281{
282 libmesh_assert_greater_equal (n, this->n_vertices());
283 libmesh_assert_less (n, this->n_nodes());
284 libmesh_assert_less (v, 2);
285 return _second_order_adjacent_vertices[n-this->n_vertices()][v];
286}
287
288
289
290const unsigned short int InfQuad6::_second_order_adjacent_vertices[2][2] =
291 {
292 {0, 1}, // vertices adjacent to node 4
293 {2, 3} // vertices adjacent to node 5
294 };
295
296
297
298std::pair<unsigned short int, unsigned short int>
299InfQuad6::second_order_child_vertex (const unsigned int n) const
300{
301 libmesh_assert_greater_equal (n, this->n_vertices());
302 libmesh_assert_less (n, this->n_nodes());
303
304 return std::pair<unsigned short int, unsigned short int>
305 (0, 2*n-7);
306}
307
308
310InfQuad6::side_type (const unsigned int s) const
311{
312 libmesh_assert_less (s, 3);
313 if (s == 0)
314 return EDGE3;
315 return INFEDGE2;
316}
317
318
319void InfQuad6::flip(BoundaryInfo * boundary_info)
320{
321 libmesh_assert(boundary_info);
322
323 swap2nodes(0,1);
324 swap2nodes(2,3);
325 swap2neighbors(1,2);
326 swap2boundarysides(1,2,boundary_info);
327 swap2boundaryedges(1,2,boundary_info);
328}
329
330
331} // namespace libMesh
332
333
334#endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
The BoundaryInfo class contains information relevant to boundary conditions including storing faces,...
void swap2nodes(unsigned int n1, unsigned int n2)
Swaps two node_ptrs.
Definition elem.h:2101
void swap2neighbors(unsigned int n1, unsigned int n2)
Swaps two neighbor_ptrs.
Definition elem.h:2111
void swap2boundarysides(unsigned short s1, unsigned short s2, BoundaryInfo *boundary_info) const
Swaps two sides in boundary_info, if it is non-null.
Definition elem.C:3579
subdomain_id_type subdomain_id() const
Definition elem.h:2591
ElemMappingType mapping_type() const
Definition elem.h:3137
static dof_id_type compute_key(dof_id_type n0)
Definition elem.h:3311
void swap2boundaryedges(unsigned short e1, unsigned short e2, BoundaryInfo *boundary_info) const
Swaps two edges in boundary_info, if it is non-null.
Definition elem.C:3595
dof_id_type node_id(const unsigned int i) const
Definition elem.h:2484
unsigned int p_level() const
Definition elem.h:3125
virtual std::pair< unsigned short int, unsigned short int > second_order_child_vertex(const unsigned int n) const override
static const int nodes_per_side
virtual unsigned short int second_order_adjacent_vertex(const unsigned int n, const unsigned int v) const override
virtual unsigned int n_nodes() const override
virtual std::vector< unsigned int > nodes_on_side(const unsigned int s) const override
virtual void connectivity(const unsigned int sf, const IOPackage iop, std::vector< dof_id_type > &conn) const override
virtual std::vector< unsigned int > nodes_on_edge(const unsigned int e) const override
virtual Order default_order() const override
virtual dof_id_type key() const
Don't hide Elem::key() defined in the base class.
Definition elem.C:738
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const override
virtual unsigned int local_side_node(unsigned int side, unsigned int side_node) const override
static const Real _embedding_matrix[num_children][num_nodes][num_nodes]
Matrix that computes new nodal locations/solution values from current nodes/solution.
ElemType side_type(const unsigned int s) const override final
static const unsigned int side_nodes_map[num_sides][nodes_per_side]
This maps the node of the side to element node numbers.
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i) override
virtual unsigned int n_sub_elem() const override
virtual void flip(BoundaryInfo *) override final
Flips the element (by swapping node and neighbor pointers) to have a mapping Jacobian of opposite sig...
static const unsigned short int _second_order_adjacent_vertices[2][2]
Matrix that tells which vertices define the location of mid-side (or second-order) nodes.
static const int num_nodes
Geometric constants for InfQuad6.
static const int num_sides
Geometric constants for all InfQuads.
virtual dof_id_type key() const
Don't hide Elem::key() defined in the base class.
Definition elem.C:738
static const int num_children
virtual unsigned int n_vertices() const override final
virtual unsigned int n_sides() const override final
The libMesh namespace provides an interface to certain functionality in the library.
IOPackage
libMesh interfaces with several different software packages for the purposes of creating,...
ElemType
Defines an enum for geometric element types.
libmesh_assert(ctx)
uint8_t dof_id_type
Definition id_types.h:67
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real