libMesh
face_quad9.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2025 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 // Local includes
19 #include "libmesh/edge_edge3.h"
20 #include "libmesh/face_quad9.h"
21 #include "libmesh/enum_io_package.h"
22 #include "libmesh/enum_order.h"
23 
24 namespace libMesh
25 {
26 
27 
28 
29 
30 // ------------------------------------------------------------
31 // Quad9 class static member initializations
32 const int Quad9::num_nodes;
33 const int Quad9::nodes_per_side;
34 
36  {
37  {0, 1, 4}, // Side 0
38  {1, 2, 5}, // Side 1
39  {2, 3, 6}, // Side 2
40  {3, 0, 7} // Side 3
41  };
42 
43 
44 #ifdef LIBMESH_ENABLE_AMR
45 
47  {
48  // embedding matrix for child 0
49  {
50  // 0 1 2 3 4 5 6 7 8
51  { 1.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000 }, // 0
52  { 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000, 0.00000 }, // 1
53  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000 }, // 2
54  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000 }, // 3
55  { 0.375000, -0.125000, 0.00000, 0.00000, 0.750000, 0.00000, 0.00000, 0.00000, 0.00000 }, // 4
56  { 0.00000, 0.00000, 0.00000, 0.00000, 0.375000, 0.00000, -0.125000, 0.00000, 0.750000 }, // 5
57  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, -0.125000, 0.00000, 0.375000, 0.750000 }, // 6
58  { 0.375000, 0.00000, 0.00000, -0.125000, 0.00000, 0.00000, 0.00000, 0.750000, 0.00000 }, // 7
59  { 0.140625, -0.0468750, 0.0156250, -0.0468750, 0.281250, -0.0937500, -0.0937500, 0.281250, 0.562500 } // 8
60  },
61 
62  // embedding matrix for child 1
63  {
64  // 0 1 2 3 4 5 6 7 8
65  { 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000, 0.00000 }, // 0
66  { 0.00000, 1.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000 }, // 1
67  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000 }, // 2
68  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000 }, // 3
69  { -0.125000, 0.375000, 0.00000, 0.00000, 0.750000, 0.00000, 0.00000, 0.00000, 0.00000 }, // 4
70  { 0.00000, 0.375000, -0.125000, 0.00000, 0.00000, 0.750000, 0.00000, 0.00000, 0.00000 }, // 5
71  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.375000, 0.00000, -0.125000, 0.750000 }, // 6
72  { 0.00000, 0.00000, 0.00000, 0.00000, 0.375000, 0.00000, -0.125000, 0.00000, 0.750000 }, // 7
73  { -0.0468750, 0.140625, -0.0468750, 0.0156250, 0.281250, 0.281250, -0.0937500, -0.0937500, 0.562500 } // 8
74  },
75 
76  // embedding matrix for child 2
77  {
78  // 0 1 2 3 4 5 6 7 8
79  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000 }, // 0
80  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000 }, // 1
81  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000 }, // 2
82  { 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000 }, // 3
83  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, -0.125000, 0.00000, 0.375000, 0.750000 }, // 4
84  { 0.00000, 0.00000, 0.00000, 0.00000, -0.125000, 0.00000, 0.375000, 0.00000, 0.750000 }, // 5
85  { 0.00000, 0.00000, -0.125000, 0.375000, 0.00000, 0.00000, 0.750000, 0.00000, 0.00000 }, // 6
86  { -0.125000, 0.00000, 0.00000, 0.375000, 0.00000, 0.00000, 0.00000, 0.750000, 0.00000 }, // 7
87  { -0.0468750, 0.0156250, -0.0468750, 0.140625, -0.0937500, -0.0937500, 0.281250, 0.281250, 0.562500 } // 8
88  },
89 
90  // embedding matrix for child 3
91  {
92  // 0 1 2 3 4 5 6 7 8
93  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000 }, // 0
94  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000 }, // 1
95  { 0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000 }, // 2
96  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000 }, // 3
97  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.375000, 0.00000, -0.125000, 0.750000 }, // 4
98  { 0.00000, -0.125000, 0.375000, 0.00000, 0.00000, 0.750000, 0.00000, 0.00000, 0.00000 }, // 5
99  { 0.00000, 0.00000, 0.375000, -0.125000, 0.00000, 0.00000, 0.750000, 0.00000, 0.00000 }, // 6
100  { 0.00000, 0.00000, 0.00000, 0.00000, -0.125000, 0.00000, 0.375000, 0.00000, 0.750000 }, // 7
101  { 0.0156250, -0.0468750, 0.140625, -0.0468750, -0.0937500, 0.281250, 0.281250, -0.0937500, 0.562500 } // 8
102  }
103  };
104 
105 #endif
106 
107 
108 
109 // ------------------------------------------------------------
110 // Quad9 class member functions
111 
112 bool Quad9::is_vertex(const unsigned int i) const
113 {
114  if (i < 4)
115  return true;
116  return false;
117 }
118 
119 bool Quad9::is_edge(const unsigned int i) const
120 {
121  if (i < 4)
122  return false;
123  if (i > 7)
124  return false;
125  return true;
126 }
127 
128 bool Quad9::is_face(const unsigned int i) const
129 {
130  if (i > 7)
131  return true;
132  return false;
133 }
134 
135 bool Quad9::is_node_on_side(const unsigned int n,
136  const unsigned int s) const
137 {
138  libmesh_assert_less (s, n_sides());
139  return std::find(std::begin(side_nodes_map[s]),
140  std::end(side_nodes_map[s]),
141  n) != std::end(side_nodes_map[s]);
142 }
143 
144 std::vector<unsigned>
145 Quad9::nodes_on_side(const unsigned int s) const
146 {
147  libmesh_assert_less(s, n_sides());
148  return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s])};
149 }
150 
151 std::vector<unsigned>
152 Quad9::nodes_on_edge(const unsigned int e) const
153 {
154  return nodes_on_side(e);
155 }
156 
158 {
159  // make sure corners form a parallelogram
160  Point v = this->point(1) - this->point(0);
161  if (!v.relative_fuzzy_equals(this->point(2) - this->point(3), affine_tol))
162  return false;
163  // make sure "horizontal" sides are straight
164  v /= 2;
165  if (!v.relative_fuzzy_equals(this->point(4) - this->point(0), affine_tol) ||
166  !v.relative_fuzzy_equals(this->point(6) - this->point(3), affine_tol))
167  return false;
168  // make sure "vertical" sides are straight
169  // and the center node is centered
170  v = (this->point(3) - this->point(0))/2;
171  if (!v.relative_fuzzy_equals(this->point(7) - this->point(0), affine_tol) ||
172  !v.relative_fuzzy_equals(this->point(5) - this->point(1), affine_tol) ||
173  !v.relative_fuzzy_equals(this->point(8) - this->point(4), affine_tol))
174  return false;
175  return true;
176 }
177 
178 
179 
181 {
182  return SECOND;
183 }
184 
185 
186 
187 dof_id_type Quad9::key (const unsigned int s) const
188 {
189  libmesh_assert_less (s, this->n_sides());
190 
191  switch (s)
192  {
193  case 0:
194 
195  return
196  this->compute_key (this->node_id(4));
197 
198  case 1:
199 
200  return
201  this->compute_key (this->node_id(5));
202 
203  case 2:
204 
205  return
206  this->compute_key (this->node_id(6));
207 
208  case 3:
209 
210  return
211  this->compute_key (this->node_id(7));
212 
213  default:
214  libmesh_error_msg("Invalid side s = " << s);
215  }
216 }
217 
218 
219 
221 {
222  return this->compute_key(this->node_id(8));
223 }
224 
225 
226 
227 unsigned int Quad9::local_side_node(unsigned int side,
228  unsigned int side_node) const
229 {
230  libmesh_assert_less (side, this->n_sides());
231  libmesh_assert_less (side_node, Quad9::nodes_per_side);
232 
233  return Quad9::side_nodes_map[side][side_node];
234 }
235 
236 
237 
238 std::unique_ptr<Elem> Quad9::build_side_ptr (const unsigned int i)
239 {
240  return this->simple_build_side_ptr<Edge3, Quad9>(i);
241 }
242 
243 
244 
245 void Quad9::build_side_ptr (std::unique_ptr<Elem> & side,
246  const unsigned int i)
247 {
248  this->simple_build_side_ptr<Quad9>(side, i, EDGE3);
249 }
250 
251 
252 
253 void Quad9::connectivity(const unsigned int sf,
254  const IOPackage iop,
255  std::vector<dof_id_type> & conn) const
256 {
257  libmesh_assert_less (sf, this->n_sub_elem());
258  libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
259 
260  conn.resize(4);
261 
262  switch (iop)
263  {
264  case TECPLOT:
265  {
266  switch(sf)
267  {
268  case 0:
269  // linear sub-quad 0
270  conn[0] = this->node_id(0)+1;
271  conn[1] = this->node_id(4)+1;
272  conn[2] = this->node_id(8)+1;
273  conn[3] = this->node_id(7)+1;
274  return;
275 
276  case 1:
277  // linear sub-quad 1
278  conn[0] = this->node_id(4)+1;
279  conn[1] = this->node_id(1)+1;
280  conn[2] = this->node_id(5)+1;
281  conn[3] = this->node_id(8)+1;
282  return;
283 
284  case 2:
285  // linear sub-quad 2
286  conn[0] = this->node_id(7)+1;
287  conn[1] = this->node_id(8)+1;
288  conn[2] = this->node_id(6)+1;
289  conn[3] = this->node_id(3)+1;
290  return;
291 
292  case 3:
293  // linear sub-quad 3
294  conn[0] = this->node_id(8)+1;
295  conn[1] = this->node_id(5)+1;
296  conn[2] = this->node_id(2)+1;
297  conn[3] = this->node_id(6)+1;
298  return;
299 
300  default:
301  libmesh_error_msg("Invalid sf = " << sf);
302  }
303  }
304 
305  case VTK:
306  {
307  conn.resize(Quad9::num_nodes);
308  for (auto i : index_range(conn))
309  conn[i] = this->node_id(i);
310  return;
311  }
312 
313  default:
314  libmesh_error_msg("Unsupported IO package " << iop);
315  }
316 }
317 
318 
319 
321 {
322  // This might have curved edges, or might be a curved surface in
323  // 3-space, in which case the full bounding box can be larger than
324  // the bounding box of just the nodes.
325  //
326  //
327  // FIXME - I haven't yet proven the formula below to be correct for
328  // biquadratics - RHS
329  Point pmin, pmax;
330 
331  for (unsigned d=0; d<LIBMESH_DIM; ++d)
332  {
333  const Real center = this->point(8)(d);
334  Real hd = std::abs(center - this->point(0)(d));
335  for (unsigned int p=0; p != 8; ++p)
336  hd = std::max(hd, std::abs(center - this->point(p)(d)));
337 
338  pmin(d) = center - hd;
339  pmax(d) = center + hd;
340  }
341 
342  return BoundingBox(pmin, pmax);
343 }
344 
345 
346 
348 {
349  // This specialization is good for Lagrange mappings only
350  if (this->mapping_type() != LAGRANGE_MAP)
351  return this->Elem::volume();
352 
353  // Make copies of our points. It makes the subsequent calculations a bit
354  // shorter and avoids dereferencing the same pointer multiple times.
355  Point
356  x0 = point(0), x1 = point(1), x2 = point(2),
357  x3 = point(3), x4 = point(4), x5 = point(5),
358  x6 = point(6), x7 = point(7), x8 = point(8);
359 
360  // Construct constant data vectors.
361  // \vec{x}_{\xi} = \vec{a1}*xi*eta^2 + \vec{b1}*eta**2 + \vec{c1}*xi*eta + \vec{d1}*xi + \vec{e1}*eta + \vec{f1}
362  // \vec{x}_{\eta} = \vec{a2}*xi^2*eta + \vec{b2}*xi**2 + \vec{c2}*xi*eta + \vec{d2}*xi + \vec{e2}*eta + \vec{f2}
363  // This is copy-pasted directly from the output of a Python script.
364  Point
365  a1 = x0/2 + x1/2 + x2/2 + x3/2 - x4 - x5 - x6 - x7 + 2*x8,
366  b1 = -x0/4 + x1/4 + x2/4 - x3/4 - x5/2 + x7/2,
367  c1 = -x0/2 - x1/2 + x2/2 + x3/2 + x4 - x6,
368  d1 = x5 + x7 - 2*x8,
369  e1 = x0/4 - x1/4 + x2/4 - x3/4,
370  f1 = x5/2 - x7/2,
371  a2 = a1,
372  b2 = -x0/4 - x1/4 + x2/4 + x3/4 + x4/2 - x6/2,
373  c2 = -x0/2 + x1/2 + x2/2 - x3/2 - x5 + x7,
374  d2 = x0/4 - x1/4 + x2/4 - x3/4,
375  e2 = x4 + x6 - 2*x8,
376  f2 = -x4/2 + x6/2;
377 
378  // 3x3 quadrature, exact for bi-quintics
379  const unsigned int N = 3;
380  const Real q[N] = {-std::sqrt(15)/5., 0., std::sqrt(15)/5.};
381  const Real w[N] = {5./9, 8./9, 5./9};
382 
383  Real vol=0.;
384  for (unsigned int i=0; i<N; ++i)
385  for (unsigned int j=0; j<N; ++j)
386  vol += w[i] * w[j] *
387  cross_norm(q[i]*q[j]*q[j]*a1 + q[j]*q[j]*b1 + q[j]*q[i]*c1 + q[i]*d1 + q[j]*e1 + f1,
388  q[i]*q[i]*q[j]*a2 + q[i]*q[i]*b2 + q[j]*q[i]*c2 + q[i]*d2 + q[j]*e2 + f2);
389 
390  return vol;
391 }
392 
393 
394 
395 
396 unsigned int Quad9::n_second_order_adjacent_vertices (const unsigned int n) const
397 {
398  switch (n)
399  {
400  case 4:
401  case 5:
402  case 6:
403  case 7:
404  return 2;
405 
406  case 8:
407  return 4;
408 
409  default:
410  libmesh_error_msg("Invalid n = " << n);
411  }
412 }
413 
414 
415 
416 unsigned short int Quad9::second_order_adjacent_vertex (const unsigned int n,
417  const unsigned int v) const
418 {
419  libmesh_assert_greater_equal (n, this->n_vertices());
420  libmesh_assert_less (n, this->n_nodes());
421 
422  switch (n)
423  {
424  case 8:
425  {
426  libmesh_assert_less (v, 4);
427  return static_cast<unsigned short int>(v);
428  }
429 
430  default:
431  {
432  libmesh_assert_less (v, 2);
433  // use the matrix that we inherited from \p Quad
434  return _second_order_adjacent_vertices[n-this->n_vertices()][v];
435  }
436  }
437 }
438 
439 
440 
441 std::pair<unsigned short int, unsigned short int>
442 Quad9::second_order_child_vertex (const unsigned int n) const
443 {
444  libmesh_assert_greater_equal (n, this->n_vertices());
445  libmesh_assert_less (n, this->n_nodes());
446  /*
447  * the _second_order_vertex_child_* vectors are
448  * stored in face_quad.C, since they are identical
449  * for Quad8 and Quad9 (for the first 4 higher-order nodes)
450  */
451  return std::pair<unsigned short int, unsigned short int>
454 }
455 
456 
457 void Quad9::permute(unsigned int perm_num)
458 {
459  libmesh_assert_less (perm_num, 4);
460 
461  for (unsigned int i = 0; i != perm_num; ++i)
462  {
463  swap4nodes(0,1,2,3);
464  swap4nodes(4,5,6,7);
465  swap4neighbors(0,1,2,3);
466  }
467 }
468 
469 
470 void Quad9::flip(BoundaryInfo * boundary_info)
471 {
472  libmesh_assert(boundary_info);
473 
474  swap2nodes(0,1);
475  swap2nodes(2,3);
476  swap2nodes(5,7);
477  swap2neighbors(1,3);
478  swap2boundarysides(1,3,boundary_info);
479  swap2boundaryedges(1,3,boundary_info);
480 }
481 
482 
483 unsigned int Quad9::center_node_on_side(const unsigned short side) const
484 {
485  libmesh_assert_less (side, Quad9::num_sides);
486  return side + 4;
487 }
488 
489 
490 ElemType Quad9::side_type (const unsigned int libmesh_dbg_var(s)) const
491 {
492  libmesh_assert_less (s, 4);
493  return EDGE3;
494 }
495 
496 
497 } // namespace libMesh
ElemType
Defines an enum for geometric element types.
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:3550
virtual unsigned int n_sub_elem() const override
Definition: face_quad9.h:81
virtual void connectivity(const unsigned int sf, const IOPackage iop, std::vector< dof_id_type > &conn) const override
Definition: face_quad9.C:253
virtual unsigned int n_vertices() const override final
Definition: face_quad.h:102
Order
defines an enum for polynomial orders.
Definition: enum_order.h:40
static const unsigned int side_nodes_map[num_sides][nodes_per_side]
This maps the node of the side to element node numbers.
Definition: face_quad9.h:204
virtual unsigned short int second_order_adjacent_vertex(const unsigned int n, const unsigned int v) const override
Definition: face_quad9.C:416
virtual std::pair< unsigned short int, unsigned short int > second_order_child_vertex(const unsigned int n) const override
Definition: face_quad9.C:442
virtual std::vector< unsigned int > nodes_on_side(const unsigned int s) const override
Definition: face_quad9.C:145
T cross_norm(const TypeVector< T > &b, const TypeVector< T > &c)
Calls cross_norm_sq() and takes the square root of the result.
Definition: type_vector.h:1096
IOPackage
libMesh interfaces with several different software packages for the purposes of creating, reading, and writing mesh files.
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:3534
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i) override
Definition: face_quad9.C:238
virtual void permute(unsigned int perm_num) override final
Permutes the element (by swapping node and neighbor pointers) according to the specified index...
Definition: face_quad9.C:457
ElemType side_type(const unsigned int s) const override final
Definition: face_quad9.C:490
virtual void flip(BoundaryInfo *) override final
Flips the element (by swapping node and neighbor pointers) to have a mapping Jacobian of opposite sig...
Definition: face_quad9.C:470
virtual unsigned int local_side_node(unsigned int side, unsigned int side_node) const override
Definition: face_quad9.C:227
The libMesh namespace provides an interface to certain functionality in the library.
virtual bool is_edge(const unsigned int i) const override
Definition: face_quad9.C:119
virtual dof_id_type key() const override
Compute a unique key for this element which is suitable for hashing (not necessarily unique...
Definition: face_quad9.C:220
virtual bool has_affine_map() const override
Definition: face_quad9.C:157
void swap4nodes(unsigned int n1, unsigned int n2, unsigned int n3, unsigned int n4)
Swaps four node_ptrs, "rotating" them.
Definition: elem.h:2143
ElemMappingType mapping_type() const
Definition: elem.h:3120
void swap2nodes(unsigned int n1, unsigned int n2)
Swaps two node_ptrs.
Definition: elem.h:2092
virtual bool is_vertex(const unsigned int i) const override
Definition: face_quad9.C:112
virtual Order default_order() const override
Definition: face_quad9.C:180
static const unsigned short int _second_order_vertex_child_index[9]
Vector that names the child vertex index for each second order node.
Definition: face_quad.h:234
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
Definition: boundary_info.h:57
libmesh_assert(ctx)
static const unsigned short int _second_order_vertex_child_number[9]
Vector that names a child sharing each second order node.
Definition: face_quad.h:229
static constexpr Real affine_tol
Default tolerance to use in has_affine_map().
Definition: elem.h:2061
virtual unsigned int n_nodes() const override
Definition: face_quad9.h:76
static const unsigned short int _second_order_adjacent_vertices[4][2]
Matrix that tells which vertices define the location of mid-side (or second-order) nodes...
Definition: face_quad.h:224
virtual bool is_face(const unsigned int i) const override
Definition: face_quad9.C:128
virtual unsigned int n_sides() const override final
Definition: face_quad.h:97
void swap2neighbors(unsigned int n1, unsigned int n2)
Swaps two neighbor_ptrs.
Definition: elem.h:2102
virtual std::vector< unsigned int > nodes_on_edge(const unsigned int e) const override
Definition: face_quad9.C:152
Defines a Cartesian bounding box by the two corner extremum.
Definition: bounding_box.h:40
virtual unsigned int n_second_order_adjacent_vertices(const unsigned int n) const override
Definition: face_quad9.C:396
static const int num_sides
Geometric constants for Quad4.
Definition: face_quad.h:85
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
unsigned int center_node_on_side(const unsigned short side) const override final
Definition: face_quad9.C:483
virtual Real volume() const
Definition: elem.C:3429
void swap4neighbors(unsigned int n1, unsigned int n2, unsigned int n3, unsigned int n4)
Swaps four neighbor_ptrs, "rotating" them.
Definition: elem.h:2153
virtual Real volume() const override
An optimized method for approximating the area of a QUAD9 using quadrature.
Definition: face_quad9.C:347
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const override
Definition: face_quad9.C:135
static dof_id_type compute_key(dof_id_type n0)
Definition: elem.h:3294
static const int num_nodes
Geometric constants for Quad9.
Definition: face_quad9.h:197
static const Real _embedding_matrix[num_children][num_nodes][num_nodes]
Matrix that computes new nodal locations/solution values from current nodes/solution.
Definition: face_quad9.h:249
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:2475
const Point & point(const unsigned int i) const
Definition: elem.h:2453
bool relative_fuzzy_equals(const TypeVector< T > &rhs, Real tol=TOLERANCE) const
Definition: type_vector.h:981
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:117
static const int num_children
Definition: face_quad.h:86
static const int nodes_per_side
Definition: face_quad9.h:198
uint8_t dof_id_type
Definition: id_types.h:67
virtual BoundingBox loose_bounding_box() const override
Definition: face_quad9.C:320