cell_tet.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 
19 // C++ includes
20 
21 // Local includes
22 #include "libmesh/cell_tet.h"
23 #include "libmesh/cell_tet4.h"
24 #include "libmesh/face_tri3.h"
25 
26 namespace libMesh
27 {
28 
29 
30 
31 // ------------------------------------------------------------
32 // Tet class member functions
33 dof_id_type Tet::key (const unsigned int s) const
34 {
35  libmesh_assert_less (s, this->n_sides());
36 
37  switch (s)
38  {
39  case 0:
40  return
41  this->compute_key (this->node(0),
42  this->node(2),
43  this->node(1));
44 
45  case 1:
46  return
47  this->compute_key (this->node(0),
48  this->node(1),
49  this->node(3));
50 
51  case 2:
52  return
53  this->compute_key (this->node(1),
54  this->node(2),
55  this->node(3));
56 
57  case 3:
58  return
59  this->compute_key (this->node(2),
60  this->node(0),
61  this->node(3));
62  }
63 
64  // We'll never get here.
65  libmesh_error();
66  return 0;
67 }
68 
69 
70 
71 AutoPtr<Elem> Tet::side (const unsigned int i) const
72 {
73  libmesh_assert_less (i, this->n_sides());
74 
75 
76 
77  Elem* face = new Tri3;
78 
79  switch (i)
80  {
81  case 0:
82  {
83  face->set_node(0) = this->get_node(0);
84  face->set_node(1) = this->get_node(2);
85  face->set_node(2) = this->get_node(1);
86 
87  AutoPtr<Elem> ap_face(face);
88  return ap_face;
89  }
90  case 1:
91  {
92  face->set_node(0) = this->get_node(0);
93  face->set_node(1) = this->get_node(1);
94  face->set_node(2) = this->get_node(3);
95 
96  AutoPtr<Elem> ap_face(face);
97  return ap_face;
98  }
99  case 2:
100  {
101  face->set_node(0) = this->get_node(1);
102  face->set_node(1) = this->get_node(2);
103  face->set_node(2) = this->get_node(3);
104 
105  AutoPtr<Elem> ap_face(face);
106  return ap_face;
107  }
108  case 3:
109  {
110  face->set_node(0) = this->get_node(2);
111  face->set_node(1) = this->get_node(0);
112  face->set_node(2) = this->get_node(3);
113 
114  AutoPtr<Elem> ap_face(face);
115  return ap_face;
116  }
117  default:
118  {
119  libmesh_error();
120  }
121  }
122 
123  // We'll never get here.
124  libmesh_error();
125  AutoPtr<Elem> ap_face(face);
126  return ap_face;
127 }
128 
129 
130 void Tet::select_diagonal (const Diagonal diag) const
131 {
132  libmesh_assert_equal_to (_diagonal_selection, INVALID_DIAG);
133  _diagonal_selection = diag;
134 }
135 
136 
137 
138 
139 
140 #ifdef LIBMESH_ENABLE_AMR
141 
142 
143  bool Tet::is_child_on_side_helper(const unsigned int c,
144  const unsigned int s,
145  const unsigned int checked_nodes[][3]) const
146  {
147  libmesh_assert_less (c, this->n_children());
148  libmesh_assert_less (s, this->n_sides());
149 
150  // For the 4 vertices, child c touches vertex c, so we can return
151  // true if that vertex is on side s
152  for (unsigned int i = 0; i != 3; ++i)
153  if (Tet4::side_nodes_map[s][i] == c)
154  return true;
155 
156  // If we are a "vertex child" and we didn't already return true,
157  // we must not be on the side in question
158  if (c < 4)
159  return false;
160 
161  // For the 4 non-vertex children, the child ordering depends on the
162  // diagonal selection. We'll let the embedding matrix figure that
163  // out: if this child has three nodes that don't depend on the
164  // position of the node_facing_side[s], then we're on side s. Which
165  // three nodes those are depends on the subclass, so their responsibility
166  // is to call this function with the proper check_nodes array
167  const unsigned int node_facing_side[4] = {3, 2, 0, 1};
168  const unsigned int n = node_facing_side[s];
169 
170  // Add up the absolute values of the entries of the embedding matrix for the
171  // nodes opposite node n. If it is equal to zero, then the child in question is
172  // on side s, so return true.
173  Real embedding_sum = 0.;
174  for (unsigned i=0; i<3; ++i)
175  embedding_sum += std::abs(this->embedding_matrix(c, checked_nodes[n][i], n));
176 
177  return ( std::abs(embedding_sum) < 1.e-3 );
178  }
179 
180 #else
181 
182 bool Tet::is_child_on_side_helper(const unsigned int /*c*/,
183  const unsigned int /*s*/,
184  const unsigned int /*checked_nodes*/[][3]) const
185 {
186  libmesh_not_implemented();
187  return false;
188 }
189 
190 #endif //LIBMESH_ENABLE_AMR
191 
192 
193 
194 
196 {
197  // Check for uninitialized diagonal selection
199  {
200  Real diag_01_23 = (this->point(0)+this->point(1)-this->point(2)-this->point(3)).size_sq();
201  Real diag_02_13 = (this->point(0)-this->point(1)+this->point(2)-this->point(3)).size_sq();
202  Real diag_03_12 = (this->point(0)-this->point(1)-this->point(2)+this->point(3)).size_sq();
203 
205 
206  if (diag_01_23 < diag_02_13 || diag_03_12 < diag_02_13)
207  {
208  if (diag_01_23 < diag_03_12)
210 
211  else
213  }
214  }
215 }
216 
217 
218 
219 bool Tet::is_edge_on_side(const unsigned int e,
220  const unsigned int s) const
221 {
222  libmesh_assert_less (e, this->n_edges());
223  libmesh_assert_less (s, this->n_sides());
224 
225  return (is_node_on_side(Tet4::edge_nodes_map[e][0],s) &&
227 }
228 
229 
230 
232 {
233  return Elem::quality(q); // Not implemented
234 }
235 
236 
237 
238 
239 std::pair<Real, Real> Tet::qual_bounds (const ElemQuality q) const
240 {
241  std::pair<Real, Real> bounds;
242 
243  switch (q)
244  {
245 
246  case ASPECT_RATIO_BETA:
247  case ASPECT_RATIO_GAMMA:
248  bounds.first = 1.;
249  bounds.second = 3.;
250  break;
251 
252  case SIZE:
253  case SHAPE:
254  bounds.first = 0.2;
255  bounds.second = 1.;
256  break;
257 
258  case CONDITION:
259  bounds.first = 1.;
260  bounds.second = 3.;
261  break;
262 
263  case DISTORTION:
264  bounds.first = 0.6;
265  bounds.second = 1.;
266  break;
267 
268  case JACOBIAN:
269  bounds.first = 0.5;
270  bounds.second = 1.414;
271  break;
272 
273  default:
274  libMesh::out << "Warning: Invalid quality measure chosen." << std::endl;
275  bounds.first = -1;
276  bounds.second = -1;
277  }
278 
279  return bounds;
280 }
281 
282 } // namespace libMesh

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

Hosted By:
SourceForge.net Logo