face_quad8.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2014 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 // C++ includes
19 
20 // Local includes
21 #include "libmesh/side.h"
22 #include "libmesh/edge_edge3.h"
23 #include "libmesh/face_quad8.h"
24 
25 namespace libMesh
26 {
27 
28 
29 
30 
31 // ------------------------------------------------------------
32 // Quad8 class static member initializations
33 const unsigned int Quad8::side_nodes_map[4][3] =
34 {
35  {0, 1, 4}, // Side 0
36  {1, 2, 5}, // Side 1
37  {2, 3, 6}, // Side 2
38  {3, 0, 7} // Side 3
39 };
40 
41 
42 #ifdef LIBMESH_ENABLE_AMR
43 
44 const float Quad8::_embedding_matrix[4][8][8] =
45 {
46  // embedding matrix for child 0
47  {
48  // 0 1 2 3 4 5 6 7
49  { 1.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000 }, // 0
50  { 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000 }, // 1
51  { -0.250000, -0.250000, -0.250000, -0.250000, 0.500000, 0.500000, 0.500000, 0.500000 }, // 2
52  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000 }, // 3
53  { 0.375000, -0.125000, 0.00000, 0.00000, 0.750000, 0.00000, 0.00000, 0.00000 }, // 4
54  { -0.187500, -0.187500, -0.187500, -0.187500, 0.750000, 0.375000, 0.250000, 0.375000 }, // 5
55  { -0.187500, -0.187500, -0.187500, -0.187500, 0.375000, 0.250000, 0.375000, 0.750000 }, // 6
56  { 0.375000, 0.00000, 0.00000, -0.125000, 0.00000, 0.00000, 0.00000, 0.750000 } // 7
57  },
58 
59  // embedding matrix for child 1
60  {
61  // 0 1 2 3 4 5 6 7
62  { 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000 }, // 0
63  { 0.00000, 1.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000 }, // 1
64  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000 }, // 2
65  { -0.250000, -0.250000, -0.250000, -0.250000, 0.500000, 0.500000, 0.500000, 0.500000 }, // 3
66  { -0.125000, 0.375000, 0.00000, 0.00000, 0.750000, 0.00000, 0.00000, 0.00000 }, // 4
67  { 0.00000, 0.375000, -0.125000, 0.00000, 0.00000, 0.750000, 0.00000, 0.00000 }, // 5
68  { -0.187500, -0.187500, -0.187500, -0.187500, 0.375000, 0.750000, 0.375000, 0.250000 }, // 6
69  { -0.187500, -0.187500, -0.187500, -0.187500, 0.750000, 0.375000, 0.250000, 0.375000 } // 7
70  },
71 
72  // embedding matrix for child 2
73  {
74  // 0 1 2 3 4 5 6 7
75  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000 }, // 0
76  { -0.250000, -0.250000, -0.250000, -0.250000, 0.500000, 0.500000, 0.500000, 0.500000 }, // 1
77  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000 }, // 2
78  { 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000, 0.00000 }, // 3
79  { -0.187500, -0.187500, -0.187500, -0.187500, 0.375000, 0.250000, 0.375000, 0.750000 }, // 4
80  { -0.187500, -0.187500, -0.187500, -0.187500, 0.250000, 0.375000, 0.750000, 0.375000 }, // 5
81  { 0.00000, 0.00000, -0.125000, 0.375000, 0.00000, 0.00000, 0.750000, 0.00000 }, // 6
82  { -0.125000, 0.00000, 0.00000, 0.375000, 0.00000, 0.00000, 0.00000, 0.750000 } // 7
83  },
84 
85  // embedding matrix for child 3
86  {
87  // 0 1 2 3 4 5 6 7
88  { -0.250000, -0.250000, -0.250000, -0.250000, 0.500000, 0.500000, 0.500000, 0.500000 }, // 0
89  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.00000 }, // 1
90  { 0.00000, 0.00000, 1.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000 }, // 2
91  { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000 }, // 3
92  { -0.187500, -0.187500, -0.187500, -0.187500, 0.375000, 0.750000, 0.375000, 0.250000 }, // 4
93  { 0.00000, -0.125000, 0.375000, 0.00000, 0.00000, 0.750000, 0.00000, 0.00000 }, // 5
94  { 0.00000, 0.00000, 0.375000, -0.125000, 0.00000, 0.00000, 0.750000, 0.00000 }, // 6
95  { -0.187500, -0.187500, -0.187500, -0.187500, 0.250000, 0.375000, 0.750000, 0.375000 } // 7
96  }
97 };
98 
99 
100 #endif
101 
102 
103 // ------------------------------------------------------------
104 // Quad8 class member functions
105 
106 bool Quad8::is_vertex(const unsigned int i) const
107 {
108  if (i < 4)
109  return true;
110  return false;
111 }
112 
113 bool Quad8::is_edge(const unsigned int i) const
114 {
115  if (i < 4)
116  return false;
117  return true;
118 }
119 
120 bool Quad8::is_face(const unsigned int) const
121 {
122  return false;
123 }
124 
125 bool Quad8::is_node_on_side(const unsigned int n,
126  const unsigned int s) const
127 {
128  libmesh_assert_less (s, n_sides());
129  for (unsigned int i = 0; i != 3; ++i)
130  if (side_nodes_map[s][i] == n)
131  return true;
132  return false;
133 }
134 
135 
136 
138 {
139  // make sure corners form a parallelogram
140  Point v = this->point(1) - this->point(0);
141  if (!v.relative_fuzzy_equals(this->point(2) - this->point(3)))
142  return false;
143  // make sure sides are straight
144  v /= 2;
145  if (!v.relative_fuzzy_equals(this->point(4) - this->point(0)) ||
146  !v.relative_fuzzy_equals(this->point(6) - this->point(3)))
147  return false;
148  v = (this->point(3) - this->point(0))/2;
149  if (!v.relative_fuzzy_equals(this->point(7) - this->point(0)) ||
150  !v.relative_fuzzy_equals(this->point(5) - this->point(1)))
151  return false;
152  return true;
153 }
154 
155 
156 
157 dof_id_type Quad8::key (const unsigned int s) const
158 {
159  libmesh_assert_less (s, this->n_sides());
160 
161  switch (s)
162  {
163  case 0:
164 
165  return
166  this->compute_key (this->node(4));
167 
168  case 1:
169 
170  return
171  this->compute_key (this->node(5));
172 
173  case 2:
174 
175  return
176  this->compute_key (this->node(6));
177 
178  case 3:
179 
180  return
181  this->compute_key (this->node(7));
182  }
183 
184 
185  // We will never get here... Look at the code above.
186  libmesh_error();
187  return 0;
188 }
189 
190 
191 
192 AutoPtr<Elem> Quad8::build_side (const unsigned int i,
193  bool proxy) const
194 {
195  libmesh_assert_less (i, this->n_sides());
196 
197  if (proxy)
198  {
199  AutoPtr<Elem> ap(new Side<Edge3,Quad8>(this,i));
200  return ap;
201  }
202 
203  else
204  {
205  AutoPtr<Elem> edge(new Edge3);
206  edge->subdomain_id() = this->subdomain_id();
207 
208  switch (i)
209  {
210  case 0:
211  {
212  edge->set_node(0) = this->get_node(0);
213  edge->set_node(1) = this->get_node(1);
214  edge->set_node(2) = this->get_node(4);
215 
216  return edge;
217  }
218  case 1:
219  {
220  edge->set_node(0) = this->get_node(1);
221  edge->set_node(1) = this->get_node(2);
222  edge->set_node(2) = this->get_node(5);
223 
224  return edge;
225  }
226  case 2:
227  {
228  edge->set_node(0) = this->get_node(2);
229  edge->set_node(1) = this->get_node(3);
230  edge->set_node(2) = this->get_node(6);
231 
232  return edge;
233  }
234  case 3:
235  {
236  edge->set_node(0) = this->get_node(3);
237  edge->set_node(1) = this->get_node(0);
238  edge->set_node(2) = this->get_node(7);
239 
240  return edge;
241  }
242  default:
243  {
244  libmesh_error();
245  }
246  }
247  }
248 
249  // We will never get here...
250  AutoPtr<Elem> ap(NULL); return ap;
251 }
252 
253 
254 
255 
256 
257 
258 void Quad8::connectivity(const unsigned int sf,
259  const IOPackage iop,
260  std::vector<dof_id_type>& conn) const
261 {
262  libmesh_assert_less (sf, this->n_sub_elem());
263  libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
264 
265  switch (iop)
266  {
267  // Note: TECPLOT connectivity is output as four triangles with
268  // a central quadrilateral. Therefore, the first four connectivity
269  // arrays are degenerate quads (triangles in Tecplot).
270  case TECPLOT:
271  {
272  // Create storage
273  conn.resize(4);
274 
275  switch(sf)
276  {
277  case 0:
278  // linear sub-tri 0
279  conn[0] = this->node(0)+1;
280  conn[1] = this->node(4)+1;
281  conn[2] = this->node(7)+1;
282  conn[3] = this->node(7)+1;
283 
284  return;
285 
286  case 1:
287  // linear sub-tri 1
288  conn[0] = this->node(4)+1;
289  conn[1] = this->node(1)+1;
290  conn[2] = this->node(5)+1;
291  conn[3] = this->node(5)+1;
292 
293  return;
294 
295  case 2:
296  // linear sub-tri 2
297  conn[0] = this->node(5)+1;
298  conn[1] = this->node(2)+1;
299  conn[2] = this->node(6)+1;
300  conn[3] = this->node(6)+1;
301 
302  return;
303 
304  case 3:
305  // linear sub-tri 3
306  conn[0] = this->node(7)+1;
307  conn[1] = this->node(6)+1;
308  conn[2] = this->node(3)+1;
309  conn[3] = this->node(3)+1;
310 
311  return;
312 
313  case 4:
314  // linear sub-quad
315  conn[0] = this->node(4)+1;
316  conn[1] = this->node(5)+1;
317  conn[2] = this->node(6)+1;
318  conn[3] = this->node(7)+1;
319 
320  return;
321 
322  default:
323  libmesh_error();
324  }
325  }
326 
327 
328  // Note: VTK connectivity is output as four triangles with
329  // a central quadrilateral. Therefore most of the connectivity
330  // arrays have length three.
331  case VTK:
332  {
333  // Create storage
334  conn.resize(8);
335  conn[0] = this->node(0);
336  conn[1] = this->node(1);
337  conn[2] = this->node(2);
338  conn[3] = this->node(3);
339  conn[4] = this->node(4);
340  conn[5] = this->node(5);
341  conn[6] = this->node(6);
342  conn[7] = this->node(7);
343  return;
344  /*
345  conn.resize(3);
346 
347  switch (sf)
348  {
349  case 0:
350  // linear sub-tri 0
351  conn[0] = this->node(0);
352  conn[1] = this->node(4);
353  conn[2] = this->node(7);
354 
355  return;
356 
357  case 1:
358  // linear sub-tri 1
359  conn[0] = this->node(4);
360  conn[1] = this->node(1);
361  conn[2] = this->node(5);
362 
363  return;
364 
365  case 2:
366  // linear sub-tri 2
367  conn[0] = this->node(5);
368  conn[1] = this->node(2);
369  conn[2] = this->node(6);
370 
371  return;
372 
373  case 3:
374  // linear sub-tri 3
375  conn[0] = this->node(7);
376  conn[1] = this->node(6);
377  conn[2] = this->node(3);
378 
379  return;
380 
381  case 4:
382  conn.resize(4);
383 
384  // linear sub-quad
385  conn[0] = this->node(4);
386  conn[1] = this->node(5);
387  conn[2] = this->node(6);
388  conn[3] = this->node(7);
389  */
390 // return;
391 
392 // default:
393 // libmesh_error();
394 // }
395  }
396 
397  default:
398  libmesh_error();
399  }
400 
401  libmesh_error();
402 }
403 
404 
405 
406 
407 unsigned short int Quad8::second_order_adjacent_vertex (const unsigned int n,
408  const unsigned int v) const
409 {
410  libmesh_assert_greater_equal (n, this->n_vertices());
411  libmesh_assert_less (n, this->n_nodes());
412  libmesh_assert_less (v, 2);
413  // use the matrix from \p face_quad.C
414  return _second_order_adjacent_vertices[n-this->n_vertices()][v];
415 }
416 
417 
418 
419 std::pair<unsigned short int, unsigned short int>
420 Quad8::second_order_child_vertex (const unsigned int n) const
421 {
422  libmesh_assert_greater_equal (n, this->n_vertices());
423  libmesh_assert_less (n, this->n_nodes());
424  /*
425  * the _second_order_vertex_child_* vectors are
426  * stored in face_quad.C, since they are identical
427  * for Quad8 and Quad9 (for the first 4 higher-order nodes)
428  */
429  return std::pair<unsigned short int, unsigned short int>
432 }
433 
434 } // namespace libMesh

Site Created By: libMesh Developers
Last modified: February 07 2014 16:57:04 UTC

Hosted By:
SourceForge.net Logo