libMesh
face_tri3.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2026 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/edge_edge2.h"
20 #include "libmesh/face_tri3.h"
21 #include "libmesh/enum_io_package.h"
22 #include "libmesh/enum_order.h"
23 
24 namespace libMesh
25 {
26 
27 
28 
29 // ------------------------------------------------------------
30 // Tri3 class static member initializations
31 const int Tri3::num_nodes;
32 const int Tri3::nodes_per_side;
33 
35  {
36  {0, 1}, // Side 0
37  {1, 2}, // Side 1
38  {2, 0} // Side 2
39  };
40 
41 #ifdef LIBMESH_ENABLE_AMR
42 
44  {
45  // embedding matrix for child 0
46  {
47  // 0 1 2
48  {1.0, 0.0, 0.0}, // 0
49  {0.5, 0.5, 0.0}, // 1
50  {0.5, 0.0, 0.5} // 2
51  },
52 
53  // embedding matrix for child 1
54  {
55  // 0 1 2
56  {0.5, 0.5, 0.0}, // 0
57  {0.0, 1.0, 0.0}, // 1
58  {0.0, 0.5, 0.5} // 2
59  },
60 
61  // embedding matrix for child 2
62  {
63  // 0 1 2
64  {0.5, 0.0, 0.5}, // 0
65  {0.0, 0.5, 0.5}, // 1
66  {0.0, 0.0, 1.0} // 2
67  },
68 
69  // embedding matrix for child 3
70  {
71  // 0 1 2
72  {0.5, 0.5, 0.0}, // 0
73  {0.0, 0.5, 0.5}, // 1
74  {0.5, 0.0, 0.5} // 2
75  }
76  };
77 
78 #endif
79 
80 
81 
82 // ------------------------------------------------------------
83 // Tri3 class member functions
84 
85 bool Tri3::is_vertex(const unsigned int libmesh_dbg_var(n)) const
86 {
87  libmesh_assert_not_equal_to (n, invalid_uint);
88  return true;
89 }
90 
91 bool Tri3::is_edge(const unsigned int) const
92 {
93  return false;
94 }
95 
96 bool Tri3::is_face(const unsigned int) const
97 {
98  return false;
99 }
100 
101 bool Tri3::is_node_on_side(const unsigned int n,
102  const unsigned int s) const
103 {
104  libmesh_assert_less (s, n_sides());
105  return std::find(std::begin(side_nodes_map[s]),
106  std::end(side_nodes_map[s]),
107  n) != std::end(side_nodes_map[s]);
108 }
109 
110 std::vector<unsigned>
111 Tri3::nodes_on_side(const unsigned int s) const
112 {
113  libmesh_assert_less(s, n_sides());
114  return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s])};
115 }
116 
117 std::vector<unsigned>
118 Tri3::nodes_on_edge(const unsigned int e) const
119 {
120  return nodes_on_side(e);
121 }
122 
124 {
125  return FIRST;
126 }
127 
129 {
130  return this->volume() > tol;
131 }
132 
133 std::unique_ptr<Elem> Tri3::build_side_ptr (const unsigned int i)
134 {
135  return this->simple_build_side_ptr<Edge2, Tri3>(i);
136 }
137 
138 
139 
140 void Tri3::build_side_ptr (std::unique_ptr<Elem> & side,
141  const unsigned int i)
142 {
143  this->simple_build_side_ptr<Tri3>(side, i, EDGE2);
144 }
145 
146 
147 
148 void Tri3::connectivity(const unsigned int libmesh_dbg_var(sf),
149  const IOPackage iop,
150  std::vector<dof_id_type> & conn) const
151 {
152  libmesh_assert_less (sf, this->n_sub_elem());
153  libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
154 
155  switch (iop)
156  {
157  case TECPLOT:
158  {
159  conn.resize(4);
160  conn[0] = this->node_id(0)+1;
161  conn[1] = this->node_id(1)+1;
162  conn[2] = this->node_id(2)+1;
163  conn[3] = this->node_id(2)+1;
164  return;
165  }
166 
167  case VTK:
168  {
169  conn.resize(3);
170  conn[0] = this->node_id(0);
171  conn[1] = this->node_id(1);
172  conn[2] = this->node_id(2);
173  return;
174  }
175 
176  default:
177  libmesh_error_msg("Unsupported IO package " << iop);
178  }
179 }
180 
181 
182 
183 
184 
185 
187 {
188  return Elem::vertex_average();
189 }
190 
192 {
193  // This specialization is good for non-Lagrange mappings too! Even
194  // with differing vertex weights we've still got a p=1 planar face.
195 
196  // 3-node triangles have the following formula for computing the area
197  return 0.5 * cross_norm(point(1) - point(0),
198  point(2) - point(0));
199 }
200 
201 
202 
203 std::pair<Real, Real> Tri3::min_and_max_angle() const
204 {
205  Point v10 ( this->point(1) - this->point(0) );
206  Point v20 ( this->point(2) - this->point(0) );
207  Point v21 ( this->point(2) - this->point(1) );
208 
209  const Real
210  len_10=v10.norm(),
211  len_20=v20.norm(),
212  len_21=v21.norm();
213 
214  const Real
215  theta0=std::acos(( v10*v20)/len_10/len_20),
216  theta1=std::acos((-v10*v21)/len_10/len_21),
217  theta2=libMesh::pi - theta0 - theta1
218  ;
219 
220  libmesh_assert_greater (theta0, 0.);
221  libmesh_assert_greater (theta1, 0.);
222  libmesh_assert_greater (theta2, 0.);
223 
224  return std::make_pair(std::min(theta0, std::min(theta1,theta2)),
225  std::max(theta0, std::max(theta1,theta2)));
226 }
227 
228 bool Tri3::contains_point (const Point & p, Real tol) const
229 {
230  // See "Barycentric Technique" section at
231  // http://www.blackpawn.com/texts/pointinpoly for details.
232 
233  // Compute vectors
234  Point v0 = this->point(1) - this->point(0);
235  Point v1 = this->point(2) - this->point(0);
236  Point v2 = p - this->point(0);
237 
238  // Compute dot products
239  Real dot00 = v0 * v0;
240  Real dot01 = v0 * v1;
241  Real dot02 = v0 * v2;
242  Real dot11 = v1 * v1;
243  Real dot12 = v1 * v2;
244 
245  // Out of plane check
246  if (std::abs(triple_product(v2, v0, v1)) / std::max(dot00, dot11) > tol)
247  return false;
248 
249  // Compute barycentric coordinates
250  Real invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
251  Real u = (dot11 * dot02 - dot01 * dot12) * invDenom;
252  Real v = (dot00 * dot12 - dot01 * dot02) * invDenom;
253 
254  // Check if point is in triangle
255  return (u > -tol) && (v > -tol) && (u + v < 1 + tol);
256 }
257 
260 {
261  return Elem::loose_bounding_box();
262 }
263 
264 
265 void Tri3::permute(unsigned int perm_num)
266 {
267  libmesh_assert_less (perm_num, 3);
268 
269  for (unsigned int i = 0; i != perm_num; ++i)
270  {
271  swap3nodes(0,1,2);
272  swap3neighbors(0,1,2);
273  }
274 }
275 
276 
277 void Tri3::flip(BoundaryInfo * boundary_info)
278 {
279  libmesh_assert(boundary_info);
280 
281  swap2nodes(0,1);
282  swap2neighbors(1,2);
283  swap2boundarysides(1,2,boundary_info);
284  swap2boundaryedges(1,2,boundary_info);
285 }
286 
287 
288 ElemType
289 Tri3::side_type (const unsigned int libmesh_dbg_var(s)) const
290 {
291  libmesh_assert_less (s, 3);
292  return EDGE2;
293 }
294 
295 
296 Point
297 Tri3::side_vertex_average_normal(const unsigned int s) const
298 {
299  libmesh_assert_less (s, 3);
300  const Point side_t = this->point(side_nodes_map[s][1]) -
301  this->point(side_nodes_map[s][0]);
302  const unsigned int another_side = s > 1 ? 0 : s + 1;
303  const Point other_side_t = this->point(side_nodes_map[another_side][1]) -
304  this->point(side_nodes_map[another_side][0]);
305  const Point pointing_up = side_t.cross(other_side_t);
306  const Point v = side_t.cross(pointing_up);
307  return v.unit();
308 }
309 
310 
311 } // namespace libMesh
ElemType
Defines an enum for geometric element types.
void swap2boundaryedges(unsigned short e1, unsigned short e2, BoundaryInfo *boundary_info) const
Swaps two edges in boundary_info, if it is non-null.
Definition: elem.C:3595
Order
defines an enum for polynomial orders.
Definition: enum_order.h:40
auto norm() const
Definition: type_vector.h:908
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:303
static const int num_nodes
Geometric constants for Tri3.
Definition: face_tri3.h:162
virtual unsigned int n_sub_elem() const override
Definition: face_tri3.h:86
static const int num_sides
Geometric constants for all Tris.
Definition: face_tri.h:86
static const unsigned int side_nodes_map[num_sides][nodes_per_side]
This maps the node of the side to element node numbers.
Definition: face_tri3.h:169
virtual Point true_centroid() const override
The centroid of a 3-node triangle is simply given by the average of its vertex positions.
Definition: face_tri3.C:186
T cross_norm(const TypeVector< T > &b, const TypeVector< T > &c)
Calls cross_norm_sq() and takes the square root of the result.
Definition: type_vector.h:1132
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const override
Definition: face_tri3.C:101
IOPackage
libMesh interfaces with several different software packages for the purposes of creating, reading, and writing mesh files.
virtual BoundingBox loose_bounding_box() const
Definition: elem.C:3498
std::pair< Real, Real > min_and_max_angle() const
Definition: face_tri3.C:203
virtual std::vector< unsigned int > nodes_on_side(const unsigned int s) const override
Definition: face_tri3.C:111
void swap2boundarysides(unsigned short s1, unsigned short s2, BoundaryInfo *boundary_info) const
Swaps two sides in boundary_info, if it is non-null.
Definition: elem.C:3579
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i) override
Definition: face_tri3.C:133
virtual BoundingBox loose_bounding_box() const override
Builds a bounding box out of the nodal positions.
Definition: face_tri3.C:259
virtual bool has_invertible_map(Real tol) const override
Definition: face_tri3.C:128
The libMesh namespace provides an interface to certain functionality in the library.
static const int num_children
Definition: face_tri.h:87
virtual void connectivity(const unsigned int sf, const IOPackage iop, std::vector< dof_id_type > &conn) const override
Definition: face_tri3.C:148
ElemType side_type(const unsigned int s) const override final
Definition: face_tri3.C:289
virtual bool is_edge(const unsigned int i) const override
Definition: face_tri3.C:91
void swap3neighbors(unsigned int n1, unsigned int n2, unsigned int n3)
Swaps three neighbor_ptrs, "rotating" them.
Definition: elem.h:2139
virtual unsigned int n_sides() const override final
Definition: face_tri.h:98
void swap3nodes(unsigned int n1, unsigned int n2, unsigned int n3)
Swaps three node_ptrs, "rotating" them.
Definition: elem.h:2130
T triple_product(const TypeVector< T > &a, const TypeVector< T > &b, const TypeVector< T > &c)
Definition: type_vector.h:1032
TypeVector< T > unit() const
Definition: type_vector.h:1141
void swap2nodes(unsigned int n1, unsigned int n2)
Swaps two node_ptrs.
Definition: elem.h:2098
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
Definition: boundary_info.h:57
libmesh_assert(ctx)
virtual bool contains_point(const Point &p, Real tol) const override
Specialization for tri3 elements.
Definition: face_tri3.C:228
TypeVector< typename CompareTypes< T, T2 >::supertype > cross(const TypeVector< T2 > &v) const
Definition: type_vector.h:885
static const int nodes_per_side
Definition: face_tri3.h:163
void swap2neighbors(unsigned int n1, unsigned int n2)
Swaps two neighbor_ptrs.
Definition: elem.h:2108
Defines a Cartesian bounding box by the two corner extremum.
Definition: bounding_box.h:40
virtual bool is_vertex(const unsigned int i) const override
Definition: face_tri3.C:85
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual void permute(unsigned int perm_num) override final
Permutes the element (by swapping node and neighbor pointers) according to the specified index...
Definition: face_tri3.C:265
virtual Order default_order() const override
Definition: face_tri3.C:123
virtual Point side_vertex_average_normal(const unsigned int s) const override final
Definition: face_tri3.C:297
static const Real _embedding_matrix[num_children][num_nodes][num_nodes]
Matrix that computes new nodal locations/solution values from current nodes/solution.
Definition: face_tri3.h:231
virtual bool is_face(const unsigned int i) const override
Definition: face_tri3.C:96
virtual void flip(BoundaryInfo *) override final
Flips the element (by swapping node and neighbor pointers) to have a mapping Jacobian of opposite sig...
Definition: face_tri3.C:277
virtual Real volume() const override
An optimized method for computing the area of a 3-node triangle.
Definition: face_tri3.C:191
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:2481
const Point & point(const unsigned int i) const
Definition: elem.h:2459
Point vertex_average() const
Definition: elem.C:669
virtual std::vector< unsigned int > nodes_on_edge(const unsigned int e) const override
Definition: face_tri3.C:118
const Real pi
.
Definition: libmesh.h:292