cell_tet.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 // Local includes
20 #include "libmesh/cell_tet.h"
21 #include "libmesh/cell_tet4.h"
22 #include "libmesh/face_tri3.h"
24 
25 namespace libMesh
26 {
27 
28 
29 
30 // ------------------------------------------------------------
31 // Tet class static member initializations
32 
33 
34 // We need to require C++11...
35 const Real Tet::_master_points[10][3] =
36  {
37  {0, 0, 0},
38  {1, 0, 0},
39  {0, 1, 0},
40  {0, 0, 1},
41  {0.5, 0, 0},
42  {0.5, 0.5, 0},
43  {0, 0.5, 0},
44  {0, 0, 0.5},
45  {0.5, 0, 0.5},
46  {0, 0.5, 0.5}
47  };
48 
49 
50 
51 
52 // ------------------------------------------------------------
53 // Tet class member functions
54 dof_id_type Tet::key (const unsigned int s) const
55 {
56  libmesh_assert_less (s, this->n_sides());
57 
58  return this->compute_key(this->node_id(Tet4::side_nodes_map[s][0]),
59  this->node_id(Tet4::side_nodes_map[s][1]),
60  this->node_id(Tet4::side_nodes_map[s][2]));
61 }
62 
63 
64 
65 unsigned int Tet::which_node_am_i(unsigned int side,
66  unsigned int side_node) const
67 {
68  libmesh_assert_less (side, this->n_sides());
69  libmesh_assert_less (side_node, 3);
70 
71  return Tet4::side_nodes_map[side][side_node];
72 }
73 
74 
75 
76 std::unique_ptr<Elem> Tet::side_ptr (const unsigned int i)
77 {
78  libmesh_assert_less (i, this->n_sides());
79 
80  std::unique_ptr<Elem> face = libmesh_make_unique<Tri3>();
81 
82  for (unsigned n=0; n<face->n_nodes(); ++n)
83  face->set_node(n) = this->node_ptr(Tet4::side_nodes_map[i][n]);
84 
85  return face;
86 }
87 
88 
89 
90 void Tet::side_ptr (std::unique_ptr<Elem> & side,
91  const unsigned int i)
92 {
93  this->simple_build_side_ptr<Tet4>(side, i, TRI3);
94 }
95 
96 
97 
98 void Tet::select_diagonal (const Diagonal diag) const
99 {
100  libmesh_assert_equal_to (_diagonal_selection, INVALID_DIAG);
101  _diagonal_selection = diag;
102 }
103 
104 
105 
106 
107 
108 #ifdef LIBMESH_ENABLE_AMR
109 
110 
111 bool Tet::is_child_on_side_helper(const unsigned int c,
112  const unsigned int s,
113  const unsigned int checked_nodes[][3]) const
114 {
115  libmesh_assert_less (c, this->n_children());
116  libmesh_assert_less (s, this->n_sides());
117 
118  // For the 4 vertices, child c touches vertex c, so we can return
119  // true if that vertex is on side s
120  for (unsigned int i = 0; i != 3; ++i)
121  if (Tet4::side_nodes_map[s][i] == c)
122  return true;
123 
124  // If we are a "vertex child" and we didn't already return true,
125  // we must not be on the side in question
126  if (c < 4)
127  return false;
128 
129  // For the 4 non-vertex children, the child ordering depends on the
130  // diagonal selection. We'll let the embedding matrix figure that
131  // out: if this child has three nodes that don't depend on the
132  // position of the node_facing_side[s], then we're on side s. Which
133  // three nodes those are depends on the subclass, so their responsibility
134  // is to call this function with the proper check_nodes array
135  const unsigned int node_facing_side[4] = {3, 2, 0, 1};
136  const unsigned int n = node_facing_side[s];
137 
138  // Add up the absolute values of the entries of the embedding matrix for the
139  // nodes opposite node n. If it is equal to zero, then the child in question is
140  // on side s, so return true.
141  Real embedding_sum = 0.;
142  for (unsigned i=0; i<3; ++i)
143  embedding_sum += std::abs(this->embedding_matrix(c, checked_nodes[n][i], n));
144 
145  return ( std::abs(embedding_sum) < 1.e-3 );
146 }
147 
148 #else
149 
150 bool Tet::is_child_on_side_helper(const unsigned int /*c*/,
151  const unsigned int /*s*/,
152  const unsigned int /*checked_nodes*/[][3]) const
153 {
154  libmesh_not_implemented();
155  return false;
156 }
157 
158 #endif //LIBMESH_ENABLE_AMR
159 
160 
161 
162 
164 {
165  // Check for uninitialized diagonal selection
167  {
168  Real diag_01_23 = (this->point(0) + this->point(1) - this->point(2) - this->point(3)).norm_sq();
169  Real diag_02_13 = (this->point(0) - this->point(1) + this->point(2) - this->point(3)).norm_sq();
170  Real diag_03_12 = (this->point(0) - this->point(1) - this->point(2) + this->point(3)).norm_sq();
171 
173 
174  if (diag_01_23 < diag_02_13 || diag_03_12 < diag_02_13)
175  {
176  if (diag_01_23 < diag_03_12)
178 
179  else
181  }
182  }
183 }
184 
185 
186 
187 bool Tet::is_edge_on_side(const unsigned int e,
188  const unsigned int s) const
189 {
190  libmesh_assert_less (e, this->n_edges());
191  libmesh_assert_less (s, this->n_sides());
192 
193  return (is_node_on_side(Tet4::edge_nodes_map[e][0],s) &&
195 }
196 
197 
198 
200 {
201  return Elem::quality(q); // Not implemented
202 }
203 
204 
205 
206 
207 std::pair<Real, Real> Tet::qual_bounds (const ElemQuality q) const
208 {
209  std::pair<Real, Real> bounds;
210 
211  switch (q)
212  {
213 
214  case ASPECT_RATIO_BETA:
215  case ASPECT_RATIO_GAMMA:
216  bounds.first = 1.;
217  bounds.second = 3.;
218  break;
219 
220  case SIZE:
221  case SHAPE:
222  bounds.first = 0.2;
223  bounds.second = 1.;
224  break;
225 
226  case CONDITION:
227  bounds.first = 1.;
228  bounds.second = 3.;
229  break;
230 
231  case DISTORTION:
232  bounds.first = 0.6;
233  bounds.second = 1.;
234  break;
235 
236  case JACOBIAN:
237  bounds.first = 0.5;
238  bounds.second = 1.414;
239  break;
240 
241  default:
242  libMesh::out << "Warning: Invalid quality measure chosen." << std::endl;
243  bounds.first = -1;
244  bounds.second = -1;
245  }
246 
247  return bounds;
248 }
249 
250 } // namespace libMesh
virtual bool is_edge_on_side(const unsigned int e, const unsigned int s) const override final
Definition: cell_tet.C:187
virtual Real quality(const ElemQuality q) const override
Definition: cell_tet.C:199
double abs(double a)
virtual unsigned int which_node_am_i(unsigned int side, unsigned int side_node) const override
Definition: cell_tet.C:65
virtual dof_id_type key() const
Definition: elem.C:401
static const unsigned int side_nodes_map[num_sides][nodes_per_side]
Definition: cell_tet4.h:178
virtual unsigned int n_sides() const override final
Definition: cell_tet.h:74
unsigned short int side
Definition: xdr_io.C:50
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
virtual float embedding_matrix(const unsigned int child_num, const unsigned int child_node_num, const unsigned int parent_node_num) const =0
virtual unsigned int n_children() const override final
Definition: cell_tet.h:94
Diagonal _diagonal_selection
Definition: cell_tet.h:213
virtual std::pair< Real, Real > qual_bounds(const ElemQuality q) const override
Definition: cell_tet.C:207
virtual std::unique_ptr< Elem > side_ptr(const unsigned int i) override final
Definition: cell_tet.C:76
virtual unsigned int n_edges() const override final
Definition: cell_tet.h:84
static const Real _master_points[10][3]
Definition: cell_tet.h:199
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:1957
virtual Real quality(const ElemQuality q) const
Definition: elem.C:1403
void select_diagonal(const Diagonal diag) const
Definition: cell_tet.C:98
void choose_diagonal() const
Definition: cell_tet.C:163
static const unsigned int edge_nodes_map[num_edges][nodes_per_edge]
Definition: cell_tet4.h:184
static dof_id_type compute_key(dof_id_type n0)
Definition: elem.h:2754
OStreamProxy out(std::cout)
bool is_child_on_side_helper(const unsigned int c, const unsigned int s, const unsigned int checked_nodes[][3]) const
Definition: cell_tet.C:111
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:1914
const Point & point(const unsigned int i) const
Definition: elem.h:1892
std::unique_ptr< Elem > side(const unsigned int i) const
Definition: elem.h:2202
uint8_t dof_id_type
Definition: id_types.h:64