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