face_inf_quad6.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 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/side.h"
28 #include "libmesh/edge_inf_edge2.h"
30 #include "libmesh/enum_order.h"
31 
32 namespace libMesh
33 {
34 
35 
36 
37 
38 // ------------------------------------------------------------
39 // InfQuad6 class static member initializations
40 const int InfQuad6::num_nodes;
41 const int InfQuad6::num_sides;
42 const int InfQuad6::num_children;
43 const int InfQuad6::nodes_per_side;
44 
46  {
47  {0, 1, 4}, // Side 0
48  {1, 3, 99}, // Side 1
49  {0, 2, 99} // Side 2
50  };
51 
52 
53 // ------------------------------------------------------------
54 // InfQuad6 class member functions
55 
56 bool InfQuad6::is_vertex(const unsigned int i) const
57 {
58  if (i < 2)
59  return true;
60  return false;
61 }
62 
63 bool InfQuad6::is_edge(const unsigned int i) const
64 {
65  if (i < 2)
66  return false;
67  return true;
68 }
69 
70 bool InfQuad6::is_face(const unsigned int) const
71 {
72  return false;
73 }
74 
75 bool InfQuad6::is_node_on_side(const unsigned int n,
76  const unsigned int s) const
77 {
78  libmesh_assert_less (s, n_sides());
79  return std::find(std::begin(side_nodes_map[s]),
81  n) != std::end(side_nodes_map[s]);
82 }
83 
84 std::vector<unsigned>
85 InfQuad6::nodes_on_side(const unsigned int s) const
86 {
87  libmesh_assert_less(s, n_sides());
88  auto trim = (s == 0) ? 0 : 1;
89  return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s]) - trim};
90 }
91 
92 #ifdef LIBMESH_ENABLE_AMR
93 
95  {
96  // embedding matrix for child 0
97  {
98  // 0 1 2 3 4 5th parent node
99  { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, // 0th child node
100  { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 }, // 1
101  { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0 }, // 2
102  { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0 }, // 3
103  { 0.375, -0.125, 0.0, 0.0, 0.75, 0.0 }, // 4
104  { 0.0, 0.0, 0.375, -0.125, 0.0, 0.75 } // 5
105  },
106 
107  // embedding matrix for child 1
108  {
109  // 0 1 2 3 4 5th parent node
110  { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 }, // 0th child node
111  { 0.0, 1.0, 0.0, 0.0, 0.0, 0.0 }, // 1
112  { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0 }, // 2
113  { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, // 3
114  { -0.125, 0.375, 0.0, 0.0, 0.75, 0.0 }, // 4
115  { 0.0, 0.0, -0.125, 0.375, 0.0, 0.75 } // 5
116  }
117  };
118 
119 #endif
120 
121 
122 
123 
125 {
126  return SECOND;
127 }
128 
129 
130 
131 dof_id_type InfQuad6::key (const unsigned int s) const
132 {
133  libmesh_assert_less (s, this->n_sides());
134 
135  switch (s)
136  {
137  // Edge3 side
138  case 0:
139  return this->compute_key (this->node_id(4));
140 
141  // InfEdge
142  case 1:
143  case 2:
144  return InfQuad::key(s);
145 
146  default:
147  libmesh_error_msg("Invalid side s = " << s);
148  }
149 }
150 
151 
152 
153 unsigned int InfQuad6::which_node_am_i(unsigned int side,
154  unsigned int side_node) const
155 {
156  libmesh_assert_less (side, this->n_sides());
157  libmesh_assert ((side == 0 && side_node < InfQuad6::nodes_per_side) || (side_node < 2));
158 
159  return InfQuad6::side_nodes_map[side][side_node];
160 }
161 
162 
163 
164 std::unique_ptr<Elem> InfQuad6::build_side_ptr (const unsigned int i,
165  bool proxy)
166 {
167  // libmesh_assert_less (i, this->n_sides());
168 
169  if (proxy)
170  {
171  switch (i)
172  {
173  case 0:
174  return libmesh_make_unique<Side<Edge3,InfQuad6>>(this,i);
175 
176  case 1:
177  case 2:
178  return libmesh_make_unique<Side<InfEdge2,InfQuad6>>(this,i);
179 
180  default:
181  libmesh_error_msg("Invalid side i = " << i);
182  }
183  }
184 
185  else
186  {
187  // Return value
188  std::unique_ptr<Elem> edge;
189 
190  switch (i)
191  {
192  case 0:
193  {
194  edge = libmesh_make_unique<Edge3>();
195  break;
196  }
197 
198  // adjacent to another infinite element
199  case 1:
200  case 2:
201  {
202  edge = libmesh_make_unique<InfEdge2>();
203  break;
204  }
205 
206  default:
207  libmesh_error_msg("Invalid side i = " << i);
208  }
209 
210  edge->subdomain_id() = this->subdomain_id();
211 
212  // Set the nodes
213  for (unsigned n=0; n<edge->n_nodes(); ++n)
214  edge->set_node(n) = this->node_ptr(InfQuad6::side_nodes_map[i][n]);
215 
216  return edge;
217  }
218 }
219 
220 
221 
222 void InfQuad6::build_side_ptr (std::unique_ptr<Elem> & side,
223  const unsigned int i)
224 {
225  libmesh_assert_less (i, this->n_sides());
226 
227  // Think of a unit cube: (-1,1) x (-1,1) x (1,1)
228  switch (i)
229  {
230  // the base face
231  case 0:
232  {
233  if (!side.get() || side->type() != EDGE3)
234  {
235  side = this->build_side_ptr(i, false);
236  return;
237  }
238  break;
239  }
240 
241  // connecting to another infinite element
242  case 1:
243  case 2:
244  {
245  if (!side.get() || side->type() != INFEDGE2)
246  {
247  side = this->build_side_ptr(i, false);
248  return;
249  }
250  break;
251  }
252 
253  default:
254  libmesh_error_msg("Invalid side i = " << i);
255  }
256 
257  side->subdomain_id() = this->subdomain_id();
258 
259  // Set the nodes
260  for (auto n : side->node_index_range())
261  side->set_node(n) = this->node_ptr(InfQuad6::side_nodes_map[i][n]);
262 }
263 
264 
265 
266 void InfQuad6::connectivity(const unsigned int sf,
267  const IOPackage iop,
268  std::vector<dof_id_type> & conn) const
269 {
270  libmesh_assert_less (sf, this->n_sub_elem());
271  libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
272 
273  conn.resize(4);
274 
275  switch (iop)
276  {
277  case TECPLOT:
278  {
279  switch(sf)
280  {
281  case 0:
282  // linear sub-quad 0
283  conn[0] = this->node_id(0)+1;
284  conn[1] = this->node_id(4)+1;
285  conn[2] = this->node_id(5)+1;
286  conn[3] = this->node_id(2)+1;
287 
288  return;
289 
290  case 1:
291  // linear sub-quad 1
292  conn[0] = this->node_id(4)+1;
293  conn[1] = this->node_id(1)+1;
294  conn[2] = this->node_id(3)+1;
295  conn[3] = this->node_id(5)+1;
296 
297  return;
298 
299  default:
300  libmesh_error_msg("Invalid sf = " << sf);
301  }
302  }
303 
304  default:
305  libmesh_error_msg("Unsupported IO package " << iop);
306  }
307 }
308 
309 
310 
311 
312 unsigned short int InfQuad6::second_order_adjacent_vertex (const unsigned int n,
313  const unsigned int v) const
314 {
315  libmesh_assert_greater_equal (n, this->n_vertices());
316  libmesh_assert_less (n, this->n_nodes());
317  libmesh_assert_less (v, 2);
318  return _second_order_adjacent_vertices[n-this->n_vertices()][v];
319 }
320 
321 
322 
323 const unsigned short int InfQuad6::_second_order_adjacent_vertices[2][2] =
324  {
325  {0, 1}, // vertices adjacent to node 4
326  {2, 3} // vertices adjacent to node 5
327  };
328 
329 
330 
331 std::pair<unsigned short int, unsigned short int>
332 InfQuad6::second_order_child_vertex (const unsigned int n) const
333 {
334  libmesh_assert_greater_equal (n, this->n_vertices());
335  libmesh_assert_less (n, this->n_nodes());
336 
337  return std::pair<unsigned short int, unsigned short int>
338  (0, 2*n-7);
339 }
340 
341 } // namespace libMesh
342 
343 
344 
345 
346 #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
virtual unsigned int which_node_am_i(unsigned int side, unsigned int side_node) const override
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const override
static const int nodes_per_side
static const unsigned int side_nodes_map[num_sides][nodes_per_side]
virtual bool is_face(const unsigned int i) const override
virtual Order default_order() const override
virtual dof_id_type key() const
Definition: elem.C:401
virtual unsigned short int second_order_adjacent_vertex(const unsigned int n, const unsigned int v) const override
unsigned short int side
Definition: xdr_io.C:50
virtual bool is_edge(const unsigned int i) const override
IterBase * end
virtual unsigned int n_nodes() const override
virtual bool is_vertex(const unsigned int i) const override
virtual unsigned int n_vertices() const override final
static const int num_sides
static const float _embedding_matrix[num_children][num_nodes][num_nodes]
virtual std::vector< unsigned int > nodes_on_side(const unsigned int s) const override
virtual unsigned int n_sub_elem() const override
static const unsigned short int _second_order_adjacent_vertices[2][2]
static const int num_nodes
subdomain_id_type subdomain_id() const
Definition: elem.h:2034
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:1957
virtual unsigned int n_sides() const override final
static const int num_children
virtual std::pair< unsigned short int, unsigned short int > second_order_child_vertex(const unsigned int n) const override
static dof_id_type compute_key(dof_id_type n0)
Definition: elem.h:2754
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i, bool proxy) override
virtual void connectivity(const unsigned int sf, const IOPackage iop, std::vector< dof_id_type > &conn) const override
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:1914
std::unique_ptr< Elem > side(const unsigned int i) const
Definition: elem.h:2202
uint8_t dof_id_type
Definition: id_types.h:64