libMesh
cell_tet.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2017 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 static member initializations
33 
34 
35 // We need to require C++11...
36 const Real Tet::_master_points[10][3] =
37  {
38  {0, 0, 0},
39  {1, 0, 0},
40  {0, 1, 0},
41  {0, 0, 1},
42  {0.5, 0, 0},
43  {0.5, 0.5, 0},
44  {0, 0.5, 0},
45  {0, 0, 0.5},
46  {0.5, 0, 0.5},
47  {0, 0.5, 0.5}
48  };
49 
50 
51 
52 
53 // ------------------------------------------------------------
54 // Tet class member functions
55 dof_id_type Tet::key (const unsigned int s) const
56 {
57  libmesh_assert_less (s, this->n_sides());
58 
59  return this->compute_key(this->node_id(Tet4::side_nodes_map[s][0]),
60  this->node_id(Tet4::side_nodes_map[s][1]),
61  this->node_id(Tet4::side_nodes_map[s][2]));
62 }
63 
64 
65 
66 unsigned int Tet::which_node_am_i(unsigned int side,
67  unsigned int side_node) const
68 {
69  libmesh_assert_less (side, this->n_sides());
70  libmesh_assert_less (side_node, 3);
71 
72  return Tet4::side_nodes_map[side][side_node];
73 }
74 
75 
76 
77 UniquePtr<Elem> Tet::side_ptr (const unsigned int i)
78 {
79  libmesh_assert_less (i, this->n_sides());
80 
81  Elem * face = new Tri3;
82 
83  for (unsigned n=0; n<face->n_nodes(); ++n)
84  face->set_node(n) = this->node_ptr(Tet4::side_nodes_map[i][n]);
85 
86  return UniquePtr<Elem>(face);
87 }
88 
89 
90 void Tet::select_diagonal (const Diagonal diag) const
91 {
92  libmesh_assert_equal_to (_diagonal_selection, INVALID_DIAG);
93  _diagonal_selection = diag;
94 }
95 
96 
97 
98 
99 
100 #ifdef LIBMESH_ENABLE_AMR
101 
102 
103 bool Tet::is_child_on_side_helper(const unsigned int c,
104  const unsigned int s,
105  const unsigned int checked_nodes[][3]) const
106 {
107  libmesh_assert_less (c, this->n_children());
108  libmesh_assert_less (s, this->n_sides());
109 
110  // For the 4 vertices, child c touches vertex c, so we can return
111  // true if that vertex is on side s
112  for (unsigned int i = 0; i != 3; ++i)
113  if (Tet4::side_nodes_map[s][i] == c)
114  return true;
115 
116  // If we are a "vertex child" and we didn't already return true,
117  // we must not be on the side in question
118  if (c < 4)
119  return false;
120 
121  // For the 4 non-vertex children, the child ordering depends on the
122  // diagonal selection. We'll let the embedding matrix figure that
123  // out: if this child has three nodes that don't depend on the
124  // position of the node_facing_side[s], then we're on side s. Which
125  // three nodes those are depends on the subclass, so their responsibility
126  // is to call this function with the proper check_nodes array
127  const unsigned int node_facing_side[4] = {3, 2, 0, 1};
128  const unsigned int n = node_facing_side[s];
129 
130  // Add up the absolute values of the entries of the embedding matrix for the
131  // nodes opposite node n. If it is equal to zero, then the child in question is
132  // on side s, so return true.
133  Real embedding_sum = 0.;
134  for (unsigned i=0; i<3; ++i)
135  embedding_sum += std::abs(this->embedding_matrix(c, checked_nodes[n][i], n));
136 
137  return ( std::abs(embedding_sum) < 1.e-3 );
138 }
139 
140 #else
141 
142 bool Tet::is_child_on_side_helper(const unsigned int /*c*/,
143  const unsigned int /*s*/,
144  const unsigned int /*checked_nodes*/[][3]) const
145 {
146  libmesh_not_implemented();
147  return false;
148 }
149 
150 #endif //LIBMESH_ENABLE_AMR
151 
152 
153 
154 
156 {
157  // Check for uninitialized diagonal selection
159  {
160  Real diag_01_23 = (this->point(0) + this->point(1) - this->point(2) - this->point(3)).norm_sq();
161  Real diag_02_13 = (this->point(0) - this->point(1) + this->point(2) - this->point(3)).norm_sq();
162  Real diag_03_12 = (this->point(0) - this->point(1) - this->point(2) + this->point(3)).norm_sq();
163 
165 
166  if (diag_01_23 < diag_02_13 || diag_03_12 < diag_02_13)
167  {
168  if (diag_01_23 < diag_03_12)
170 
171  else
173  }
174  }
175 }
176 
177 
178 
179 bool Tet::is_edge_on_side(const unsigned int e,
180  const unsigned int s) const
181 {
182  libmesh_assert_less (e, this->n_edges());
183  libmesh_assert_less (s, this->n_sides());
184 
185  return (is_node_on_side(Tet4::edge_nodes_map[e][0],s) &&
186  is_node_on_side(Tet4::edge_nodes_map[e][1],s));
187 }
188 
189 
190 
192 {
193  return Elem::quality(q); // Not implemented
194 }
195 
196 
197 
198 
199 std::pair<Real, Real> Tet::qual_bounds (const ElemQuality q) const
200 {
201  std::pair<Real, Real> bounds;
202 
203  switch (q)
204  {
205 
206  case ASPECT_RATIO_BETA:
207  case ASPECT_RATIO_GAMMA:
208  bounds.first = 1.;
209  bounds.second = 3.;
210  break;
211 
212  case SIZE:
213  case SHAPE:
214  bounds.first = 0.2;
215  bounds.second = 1.;
216  break;
217 
218  case CONDITION:
219  bounds.first = 1.;
220  bounds.second = 3.;
221  break;
222 
223  case DISTORTION:
224  bounds.first = 0.6;
225  bounds.second = 1.;
226  break;
227 
228  case JACOBIAN:
229  bounds.first = 0.5;
230  bounds.second = 1.414;
231  break;
232 
233  default:
234  libMesh::out << "Warning: Invalid quality measure chosen." << std::endl;
235  bounds.first = -1;
236  bounds.second = -1;
237  }
238 
239  return bounds;
240 }
241 
242 } // namespace libMesh
void choose_diagonal() const
Derived classes use this function to select an initial diagonal during refinement.
Definition: cell_tet.C:155
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
The Tri3 is an element in 2D composed of 3 nodes.
Definition: face_tri3.h:54
double abs(double a)
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:1941
virtual Real quality(const ElemQuality q) const libmesh_override
Definition: cell_tet.C:191
UniquePtr< Elem > side(const unsigned int i) const
Definition: elem.h:2105
Diagonal
This enumeration keeps track of which diagonal is selected during refinement.
Definition: cell_tet.h:138
virtual unsigned int n_children() const libmesh_override
Definition: cell_tet.h:88
virtual unsigned int which_node_am_i(unsigned int side, unsigned int side_node) const libmesh_override
Definition: cell_tet.C:66
void select_diagonal(const Diagonal diag) const
Allows the user to select the diagonal for the refinement.
Definition: cell_tet.C:90
This is the base class from which all geometric element types are derived.
Definition: elem.h:89
bool is_child_on_side_helper(const unsigned int c, const unsigned int s, const unsigned int checked_nodes[][3]) const
Called by descendant classes with appropriate data to determine if child c is on side s...
Definition: cell_tet.C:103
Diagonal _diagonal_selection
The currently-selected diagonal used during refinement.
Definition: cell_tet.h:202
The libMesh namespace provides an interface to certain functionality in the library.
virtual unsigned int n_sides() const libmesh_override
Definition: cell_tet.h:68
virtual bool is_edge_on_side(const unsigned int e, const unsigned int s) const libmesh_override
Definition: cell_tet.C:179
std::unique_ptr< T > UniquePtr
Definition: auto_ptr.h:46
virtual unsigned int n_nodes() const =0
virtual dof_id_type key() const
Definition: elem.C:503
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:1874
virtual Real quality(const ElemQuality q) const
Definition: elem.C:1547
static const Real _master_points[10][3]
Master element node locations.
Definition: cell_tet.h:188
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual std::pair< Real, Real > qual_bounds(const ElemQuality q) const libmesh_override
Definition: cell_tet.C:199
const Point & point(const unsigned int i) const
Definition: elem.h:1809
OStreamProxy out
virtual UniquePtr< Elem > side_ptr(const unsigned int i) libmesh_override
Definition: cell_tet.C:77
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:1831
ElemQuality
Defines an enum for element quality metrics.
static dof_id_type compute_key(dof_id_type n0)
Definition: elem.h:2621
uint8_t dof_id_type
Definition: id_types.h:64
virtual unsigned int n_edges() const libmesh_override
Definition: cell_tet.h:78
virtual float embedding_matrix(const unsigned int child_num, const unsigned int child_node_num, const unsigned int parent_node_num) const =0