libMesh
face_inf_quad.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 // Local includes
20 #include "libmesh/libmesh_config.h"
21 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
22 
23 // Local includes cont'd
24 #include "libmesh/face_inf_quad.h"
25 #include "libmesh/edge_edge2.h"
26 #include "libmesh/edge_inf_edge2.h"
27 #include "libmesh/face_inf_quad4.h"
28 #include "libmesh/enum_elem_quality.h"
29 
30 namespace libMesh
31 {
32 
33 
34 // ------------------------------------------------------------
35 // InfQuad class static member initializations
36 const int InfQuad::num_sides;
37 const int InfQuad::num_children;
38 
39 // Note: we can omit initialization of the third entry of each row because
40 // static variables are automatically zero-initialized.
41 const Real InfQuad::_master_points[6][3] =
42  {
43  {-1, 0},
44  {1, 0},
45  {-1, 1},
46  {1, 1},
47  {0, 0},
48  {0, 1}
49  };
50 
51 const unsigned int InfQuad::adjacent_sides_map[/*num_vertices*/4][/*max_adjacent_sides*/2] =
52  {
53  {0, 2}, // Sides adjacent to node 0
54  {0, 1}, // Sides adjacent to node 1
55  {2, 99}, // Sides adjacent to node 2
56  {1, 99} // Sides adjacent to node 3
57  };
58 
59 // ------------------------------------------------------------
60 // InfQuad class member functions
61 dof_id_type InfQuad::key (const unsigned int s) const
62 {
63  libmesh_assert_less (s, this->n_sides());
64 
65  // The order of the node ids does not matter, they are sorted by the
66  // compute_key() function.
67  return this->compute_key(this->node_id(InfQuad4::side_nodes_map[s][0]),
68  this->node_id(InfQuad4::side_nodes_map[s][1]));
69 }
70 
71 
72 
73 dof_id_type InfQuad::low_order_key (const unsigned int s) const
74 {
75  libmesh_assert_less (s, this->n_sides());
76 
77  // The order of the node ids does not matter, they are sorted by the
78  // compute_key() function.
79  return this->compute_key(this->node_id(InfQuad4::side_nodes_map[s][0]),
80  this->node_id(InfQuad4::side_nodes_map[s][1]));
81 }
82 
83 
84 
85 unsigned int InfQuad::local_side_node(unsigned int side,
86  unsigned int side_node) const
87 {
88  libmesh_assert_less (side, this->n_sides());
89  libmesh_assert_less (side_node, 2);
90 
91  return InfQuad4::side_nodes_map[side][side_node];
92 }
93 
94 
95 
96 unsigned int InfQuad::local_edge_node(unsigned int edge,
97  unsigned int edge_node) const
98 {
99  return local_side_node(edge, edge_node);
100 }
101 
102 
103 
104 std::unique_ptr<Elem> InfQuad::side_ptr (const unsigned int i)
105 {
106  libmesh_assert_less (i, this->n_sides());
107 
108  // Return value
109  std::unique_ptr<Elem> edge;
110 
111  switch (i)
112  {
113  case 0: // base face
114  {
115  edge = std::make_unique<Edge2>();
116  break;
117  }
118 
119  case 1: // adjacent to another infinite element
120  case 2: // adjacent to another infinite element
121  {
122  edge = std::make_unique<InfEdge2>();
123  break;
124  }
125 
126  default:
127  libmesh_error_msg("Invalid side i = " << i);
128  }
129 
130  // Set the nodes
131  for (auto n : edge->node_index_range())
132  edge->set_node(n, this->node_ptr(InfQuad4::side_nodes_map[i][n]));
133 
134  return edge;
135 }
136 
137 
138 
139 void InfQuad::side_ptr (std::unique_ptr<Elem> & side,
140  const unsigned int i)
141 {
142  libmesh_assert_less (i, this->n_sides());
143 
144  switch (i)
145  {
146  // the base face
147  case 0:
148  {
149  if (!side.get() || side->type() != EDGE2)
150  {
151  side = this->side_ptr(i);
152  return;
153  }
154  break;
155  }
156 
157  // connecting to another infinite element
158  case 1:
159  case 2:
160  {
161  if (!side.get() || side->type() != INFEDGE2)
162  {
163  side = this->side_ptr(i);
164  return;
165  }
166  break;
167  }
168 
169  default:
170  libmesh_error_msg("Invalid side i = " << i);
171  }
172 
173  side->subdomain_id() = this->subdomain_id();
174 
175  // Set the nodes
176  for (auto n : side->node_index_range())
177  side->set_node(n, this->node_ptr(InfQuad4::side_nodes_map[i][n]));
178 }
179 
180 
181 bool InfQuad::is_child_on_side(const unsigned int c,
182  const unsigned int s) const
183 {
184  libmesh_assert_less (c, this->n_children());
185  libmesh_assert_less (s, this->n_sides());
186 
187  return (s == 0 ||
188  (c == 0 && s == 2) ||
189  (c == 1 && s == 1));
190 }
191 
192 
193 bool
195 {
196  return (
197 #if LIBMESH_DIM > 2
198  // Don't bother outside the XY plane
199  this->point(0)(2) && this->point(1)(2) &&
200  this->point(2)(2) && this->point(3)(2) &&
201 #endif
202  ((this->point(1)(0)-this->point(0)(0))*
203  (this->point(2)(1)-this->point(0)(1)) >
204  (this->point(2)(0)-this->point(0)(0))*
205  (this->point(1)(1)-this->point(0)(1))));
206 }
207 
208 
209 std::vector<unsigned int>
210 InfQuad::edges_adjacent_to_node(const unsigned int n) const
211 {
212  libmesh_assert_less(n, this->n_nodes());
213 
214  // For vertices, we use the adjacent_sides_map, otherwise node
215  // 4 is on side 0 and node 5 is not any any side.
216  if (this->is_vertex(n))
217  {
218  auto trim = (n < 2) ? 0 : 1;
219  return {std::begin(adjacent_sides_map[n]), std::end(adjacent_sides_map[n]) - trim};
220  }
221  else if (n == 4)
222  return {0};
223  else
224  return {};
225 }
226 
227 
229 {
230  return Elem::quality(q); // Not implemented
231 }
232 
233 
234 
235 
236 std::pair<Real, Real> InfQuad::qual_bounds (const ElemQuality q) const
237 {
238  std::pair<Real, Real> bounds;
239 
240  switch (q)
241  {
242 
243  case ASPECT_RATIO:
244  bounds.first = 1.;
245  bounds.second = 4.;
246  break;
247 
248  case SKEW:
249  bounds.first = 0.;
250  bounds.second = 0.5;
251  break;
252 
253  case TAPER:
254  bounds.first = 0.;
255  bounds.second = 0.7;
256  break;
257 
258  case WARP:
259  bounds.first = 0.9;
260  bounds.second = 1.;
261  break;
262 
263  case STRETCH:
264  bounds.first = 0.25;
265  bounds.second = 1.;
266  break;
267 
268  case MIN_ANGLE:
269  bounds.first = 45.;
270  bounds.second = 90.;
271  break;
272 
273  case MAX_ANGLE:
274  bounds.first = 90.;
275  bounds.second = 135.;
276  break;
277 
278  case CONDITION:
279  bounds.first = 1.;
280  bounds.second = 4.;
281  break;
282 
283  case JACOBIAN:
284  case SCALED_JACOBIAN:
285  bounds.first = 0.5;
286  bounds.second = 1.;
287  break;
288 
289  case SHEAR:
290  case SHAPE:
291  case SIZE:
292  bounds.first = 0.3;
293  bounds.second = 1.;
294  break;
295 
296  case DISTORTION:
297  bounds.first = 0.6;
298  bounds.second = 1.;
299  break;
300 
301  default:
302  libMesh::out << "Warning: Invalid quality measure chosen." << std::endl;
303  bounds.first = -1;
304  bounds.second = -1;
305  }
306 
307  return bounds;
308 }
309 
310 
311 
313  const Real eps) const
314 {
315  const Real & xi = p(0);
316  const Real & eta = p(1);
317 
318  // The reference infquad is [-1,1]^2.
319  return ((xi >= -1.-eps) &&
320  (xi <= 1.+eps) &&
321  (eta >= -1.-eps) &&
322  (eta <= 1.+eps));
323 }
324 
325 
326 
327 } // namespace libMesh
328 
329 
330 
331 #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
virtual std::pair< Real, Real > qual_bounds(const ElemQuality q) const override
virtual std::vector< unsigned int > edges_adjacent_to_node(const unsigned int n) const override
virtual unsigned int local_side_node(unsigned int side, unsigned int side_node) const override
Definition: face_inf_quad.C:85
virtual bool on_reference_element(const Point &p, const Real eps=TOLERANCE) const override final
virtual dof_id_type key() const
Definition: elem.C:738
static const unsigned int side_nodes_map[num_sides][nodes_per_side]
This maps the node of the side to element node numbers.
static const Real _master_points[6][3]
Master element node locations.
virtual bool is_vertex(const unsigned int i) const override final
We number vertices first.
static const int num_sides
Geometric constants for all InfQuads.
Definition: face_inf_quad.h:95
The libMesh namespace provides an interface to certain functionality in the library.
virtual bool is_child_on_side(const unsigned int c, const unsigned int s) const override final
virtual unsigned int n_nodes() const =0
static const unsigned int adjacent_sides_map[4][2]
This maps the node to the one or two side id(s) adjacent to the node.
ElemQuality
Defines an enum for element quality metrics.
virtual Real quality(const ElemQuality q) const override
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
subdomain_id_type subdomain_id() const
Definition: elem.h:2588
virtual unsigned int n_sides() const override final
OStreamProxy out
virtual bool is_flipped() const override final
virtual Real quality(const ElemQuality q) const
Definition: elem.C:1783
virtual unsigned int n_children() const override final
virtual dof_id_type low_order_key(const unsigned int s) const override
Definition: face_inf_quad.C:73
static dof_id_type compute_key(dof_id_type n0)
Definition: elem.h:3308
static const int num_children
Definition: face_inf_quad.h:96
virtual unsigned int local_edge_node(unsigned int edge, unsigned int edge_node) const override
Calls local_side_node(edge, edge_node).
Definition: face_inf_quad.C:96
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:2481
const Point & point(const unsigned int i) const
Definition: elem.h:2459
virtual std::unique_ptr< Elem > side_ptr(const unsigned int i) override final
uint8_t dof_id_type
Definition: id_types.h:67