cell_inf_hex8.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 // Local includes
19 #include "libmesh/libmesh_config.h"
20 
21 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
22 
23 // C++ includes
24 
25 // Local includes cont'd
26 #include "libmesh/cell_inf_hex8.h"
27 #include "libmesh/edge_edge2.h"
28 #include "libmesh/edge_inf_edge2.h"
29 #include "libmesh/face_quad4.h"
30 #include "libmesh/face_inf_quad4.h"
31 #include "libmesh/fe_interface.h"
32 #include "libmesh/fe_type.h"
33 #include "libmesh/side.h"
34 
35 namespace libMesh
36 {
37 
38 
39 // ------------------------------------------------------------
40 // InfHex8 class member functions
41 const unsigned int InfHex8::side_nodes_map[5][4] =
42 {
43  { 0, 1, 2, 3}, // Side 0
44  { 0, 1, 4, 5}, // Side 1
45  { 1, 2, 5, 6}, // Side 2
46  { 2, 3, 6, 7}, // Side 3
47  { 3, 0, 7, 4} // Side 4
48 };
49 
50 const unsigned int InfHex8::edge_nodes_map[8][2] =
51 {
52  { 0, 1}, // Side 0
53  { 1, 2}, // Side 1
54  { 2, 3}, // Side 2
55  { 0, 3}, // Side 3
56  { 0, 4}, // Side 4
57  { 1, 5}, // Side 5
58  { 2, 6}, // Side 6
59  { 3, 7} // Side 7
60 };
61 
62 
63 // ------------------------------------------------------------
64 // InfHex8 class member functions
65 
66 bool InfHex8::is_vertex(const unsigned int i) const
67 {
68  if (i < 4)
69  return true;
70  return false;
71 }
72 
73 bool InfHex8::is_edge(const unsigned int i) const
74 {
75  if (i < 4)
76  return false;
77  return true;
78 }
79 
80 bool InfHex8::is_face(const unsigned int) const
81 {
82  return false;
83 }
84 
85 bool InfHex8::is_node_on_side(const unsigned int n,
86  const unsigned int s) const
87 {
88  libmesh_assert_less (s, n_sides());
89  for (unsigned int i = 0; i != 4; ++i)
90  if (side_nodes_map[s][i] == n)
91  return true;
92  return false;
93 }
94 
95 bool InfHex8::is_node_on_edge(const unsigned int n,
96  const unsigned int e) const
97 {
98  libmesh_assert_less (e, n_edges());
99  for (unsigned int i = 0; i != 2; ++i)
100  if (edge_nodes_map[e][i] == n)
101  return true;
102  return false;
103 }
104 
105 AutoPtr<Elem> InfHex8::build_side (const unsigned int i,
106  bool proxy) const
107 {
108  libmesh_assert_less (i, this->n_sides());
109 
110  if (proxy)
111  {
112  switch (i)
113  {
114  // base
115  case 0:
116  {
117  AutoPtr<Elem> ap(new Side<Quad4,InfHex8>(this,i));
118  return ap;
119  }
120  // ifem sides
121  case 1:
122  case 2:
123  case 3:
124  case 4:
125  {
126  AutoPtr<Elem> ap(new Side<InfQuad4,InfHex8>(this,i));
127  return ap;
128  }
129  default:
130  libmesh_error();
131  }
132  }
133 
134  else
135  {
136  // Create NULL pointer to be initialized, returned later.
137  AutoPtr<Elem> face(NULL);
138 
139  // Think of a unit cube: (-1,1) x (-1,1) x (1,1)
140  switch (i)
141  {
142  case 0: // the base face
143  {
144  face.reset(new Quad4);
145 
146  // Only here, the face element's normal points inward
147  face->set_node(0) = this->get_node(0);
148  face->set_node(1) = this->get_node(1);
149  face->set_node(2) = this->get_node(2);
150  face->set_node(3) = this->get_node(3);
151 
152  break;
153  }
154 
155  case 1: // connecting to another infinite element
156  {
157  face.reset(new InfQuad4);
158 
159  face->set_node(0) = this->get_node(0);
160  face->set_node(1) = this->get_node(1);
161  face->set_node(2) = this->get_node(4);
162  face->set_node(3) = this->get_node(5);
163 
164  break;
165  }
166 
167  case 2: // connecting to another infinite element
168  {
169  face.reset(new InfQuad4);
170 
171  face->set_node(0) = this->get_node(1);
172  face->set_node(1) = this->get_node(2);
173  face->set_node(2) = this->get_node(5);
174  face->set_node(3) = this->get_node(6);
175 
176  break;
177  }
178 
179  case 3: // connecting to another infinite element
180  {
181  face.reset(new InfQuad4);
182 
183  face->set_node(0) = this->get_node(2);
184  face->set_node(1) = this->get_node(3);
185  face->set_node(2) = this->get_node(6);
186  face->set_node(3) = this->get_node(7);
187 
188  break;
189  }
190 
191  case 4: // connecting to another infinite element
192  {
193  face.reset(new InfQuad4);
194 
195  face->set_node(0) = this->get_node(3);
196  face->set_node(1) = this->get_node(0);
197  face->set_node(2) = this->get_node(7);
198  face->set_node(3) = this->get_node(4);
199 
200  break;
201  }
202 
203  default:
204  {
205  libmesh_error();
206  }
207  }
208 
209  face->subdomain_id() = this->subdomain_id();
210  return face;
211  }
212 
213 
214  // We'll never get here.
215  libmesh_error();
216  AutoPtr<Elem> ap(NULL); return ap;
217 }
218 
219 
220 AutoPtr<Elem> InfHex8::build_edge (const unsigned int i) const
221 {
222  libmesh_assert_less (i, this->n_edges());
223 
224  if (i < 4) // base edges
225  return AutoPtr<Elem>(new SideEdge<Edge2,InfHex8>(this,i));
226  // infinite edges
227  return AutoPtr<Elem>(new SideEdge<InfEdge2,InfHex8>(this,i));
228 }
229 
230 bool InfHex8::contains_point (const Point& p, Real tol) const
231 {
232  /*
233  * For infinite elements with linear base interpolation:
234  *
235  * make use of the fact that infinite elements do not
236  * live inside the envelope. Use a fast scheme to
237  * check whether point \p p is inside or outside
238  * our relevant part of the envelope. Note that
239  * this is not exclusive: only when the distance is less,
240  * we are safe. Otherwise, we cannot say anything. The
241  * envelope may be non-spherical, the physical point may lie
242  * inside the envelope, outside the envelope, or even inside
243  * this infinite element. Therefore if this fails,
244  * fall back to the FEInterface::inverse_map()
245  */
246  const Point origin (this->origin());
247 
248  /*
249  * determine the minimal distance of the base from the origin
250  * Use size_sq() instead of size(), it is faster
251  */
252  const Real min_distance_sq = std::min((Point(this->point(0)-origin)).size_sq(),
253  std::min((Point(this->point(1)-origin)).size_sq(),
254  std::min((Point(this->point(2)-origin)).size_sq(),
255  (Point(this->point(3)-origin)).size_sq())));
256 
257  /*
258  * work with 1% allowable deviation. We can still fall
259  * back to the InfFE::inverse_map()
260  */
261  const Real conservative_p_dist_sq = 1.01 * (Point(p-origin).size_sq());
262 
263 
264 
265  if (conservative_p_dist_sq < min_distance_sq)
266  {
267  /*
268  * the physical point is definitely not contained in the element
269  */
270  return false;
271  }
272  else
273  {
274  /*
275  * Declare a basic FEType. Will use default in the base,
276  * and something else (not important) in radial direction.
277  */
278  FEType fe_type(default_order());
279 
280  const Point mapped_point = FEInterface::inverse_map(dim(),
281  fe_type,
282  this,
283  p,
284  tol,
285  false);
286 
287  return FEInterface::on_reference_element(mapped_point, this->type(), tol);
288  }
289 }
290 
291 
292 void InfHex8::connectivity(const unsigned int libmesh_dbg_var(sc),
293  const IOPackage iop,
294  std::vector<dof_id_type>& conn) const
295 {
297  libmesh_assert_less (sc, this->n_sub_elem());
298  libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
299 
300  switch (iop)
301  {
302  case TECPLOT:
303  {
304  conn.resize(8);
305  conn[0] = this->node(0)+1;
306  conn[1] = this->node(1)+1;
307  conn[2] = this->node(2)+1;
308  conn[3] = this->node(3)+1;
309  conn[4] = this->node(4)+1;
310  conn[5] = this->node(5)+1;
311  conn[6] = this->node(6)+1;
312  conn[7] = this->node(7)+1;
313  return;
314  }
315 
316 
317  default:
318  libmesh_error();
319  }
320 
321  libmesh_error();
322 }
323 
324 
325 
326 #ifdef LIBMESH_ENABLE_AMR
327 
328 const float InfHex8::_embedding_matrix[4][8][8] =
329 {
330  // embedding matrix for child 0
331  {
332  // 0 1 2 3 4 5 6 7 th parent N.(ode)
333  { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 0th child N.
334  { 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1
335  { 0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0}, // 2
336  { 0.5, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0}, // 3
337  { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, // 4
338  { 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0}, // 5
339  { 0.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25}, // 6
340  { 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5} // 7
341  },
342 
343  // embedding matrix for child 1
344  {
345  // 0 1 2 3 4 5 6 7 th parent N.(ode)
346  { 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 0th child N.
347  { 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1
348  { 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0}, // 2
349  { 0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0}, // 3
350  { 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0}, // 4
351  { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 5
352  { 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0}, // 6
353  { 0.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25} // 7
354  },
355 
356  // embedding matrix for child 2
357  {
358  // 0 1 2 3 4 5 6 7 th parent N.(ode)
359  { 0.5, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0}, // 0th child N.
360  { 0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0}, // 1
361  { 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0}, // 2
362  { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, // 3
363  { 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5}, // 4
364  { 0.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25}, // 5
365  { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5}, // 6
366  { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0} // 7
367  },
368 
369  // embedding matrix for child 3
370  {
371  // 0 1 2 3 4 5 6 7 th parent N.(ode)
372  { 0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0}, // 0th child N.
373  { 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1
374  { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 2
375  { 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0}, // 3
376  { 0.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25}, // 4
377  { 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0}, // 5
378  { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, // 6
379  { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5} // 7
380  }
381 };
382 
383 
384 
385 #endif
386 
387 } // namespace libMesh
388 
389 #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS

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

Hosted By:
SourceForge.net Logo