libMesh
Loading...
Searching...
No Matches
face_inf_quad4.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
19
20#include "libmesh/libmesh_config.h"
21
22#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
23
24// Local includes
25#include "libmesh/face_inf_quad4.h"
26#include "libmesh/fe_interface.h"
27#include "libmesh/fe_type.h"
28#include "libmesh/edge_edge2.h"
29#include "libmesh/edge_inf_edge2.h"
30#include "libmesh/enum_io_package.h"
31#include "libmesh/enum_order.h"
32#include "libmesh/inf_fe_map.h"
33
34namespace libMesh
35{
36
37
38
39// ------------------------------------------------------------
40// InfQuad4 class static member initializations
41const int InfQuad4::num_nodes;
43
45 {
46 {0, 1}, // Side 0
47 {1, 3}, // Side 1
48 {0, 2} // Side 2
49 };
50
51#ifdef LIBMESH_ENABLE_AMR
52
54 {
55 // embedding matrix for child 0
56 {
57 // 0 1 2 3rd parent node
58 {1.0, 0.0, 0.0, 0.0}, // 0th child node
59 {0.5, 0.5, 0.0, 0.0}, // 1
60 {0.0, 0.0, 1.0, 0.0}, // 2
61 {0.0, 0.0, 0.5, 0.5} // 3
62 },
63
64 // embedding matrix for child 1
65 {
66 // 0 1 2 3
67 {0.5, 0.5, 0.0, 0.0}, // 0
68 {0.0, 1.0, 0.0, 0.0}, // 1
69 {0.0, 0.0, 0.5, 0.5}, // 2
70 {0.0, 0.0, 0.0, 1.0} // 3
71 }
72 };
73
74#endif
75
76
77// ------------------------------------------------------------
78// InfQuad4 class member functions
79
80bool InfQuad4::is_node_on_side(const unsigned int n,
81 const unsigned int s) const
82{
83 libmesh_assert_less (s, n_sides());
84 return std::find(std::begin(side_nodes_map[s]),
85 std::end(side_nodes_map[s]),
86 n) != std::end(side_nodes_map[s]);
87}
88
89std::vector<unsigned>
90InfQuad4::nodes_on_side(const unsigned int s) const
91{
92 libmesh_assert_less(s, n_sides());
93 return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s])};
94}
95
96std::vector<unsigned>
97InfQuad4::nodes_on_edge(const unsigned int e) const
98{
99 return nodes_on_side(e);
100}
101
102bool InfQuad4::contains_point (const Point & p, Real tol) const
103{
104 /*
105 * make use of the fact that infinite elements do not
106 * live inside the envelope. Use a fast scheme to
107 * check whether point \p p is inside or outside
108 * our relevant part of the envelope. Note that
109 * this is not exclusive: the point may be outside
110 * the envelope, but contained in another infinite element.
111 * Therefore, if the distance is greater, do fall back
112 * to the scheme of using inverse_map().
113 */
114 const Point my_origin (this->origin());
115
116 /*
117 * determine the minimal distance of the base from the origin
118 * use norm_sq() instead of norm(), it is slightly faster
119 */
120 const Real min_distance_sq = std::min((Point(this->point(0)-my_origin)).norm_sq(),
121 (Point(this->point(1)-my_origin)).norm_sq());
122
123 /*
124 * work with 1% allowable deviation. Can still fall
125 * back to the InfFE::inverse_map()
126 */
127 const Real conservative_p_dist_sq = 1.01 * (Point(p-my_origin).norm_sq());
128
129 if (conservative_p_dist_sq < min_distance_sq)
130 {
131 /*
132 * the physical point is definitely not contained
133 * in the element, return false.
134 */
135 return false;
136 }
137 else
138 {
139 /*
140 * cannot say anything, fall back to the inverse_map()
141 *
142 * Declare a basic FEType. Will use default in the base,
143 * and something else (not important) in radial direction.
144 */
145 FEType fe_type(default_order());
146
147 const Point mapped_point = InfFEMap::inverse_map(dim(), this, p,
148 tol, false);
149
150 return this->on_reference_element(mapped_point, tol);
151 }
152}
153
154
155
156
158{
159 return FIRST;
160}
161
162
163
164std::unique_ptr<Elem> InfQuad4::build_side_ptr (const unsigned int i)
165{
166 // libmesh_assert_less (i, this->n_sides());
167
168 std::unique_ptr<Elem> edge;
169
170 switch (i)
171 {
172 case 0:
173 {
174 edge = std::make_unique<Edge2>();
175 break;
176 }
177
178 // adjacent to another infinite element
179 case 1:
180 case 2:
181 {
182 edge = std::make_unique<InfEdge2>();
183 break;
184 }
185
186 default:
187 libmesh_error_msg("Invalid side i = " << i);
188 }
189
190 // Set the nodes
191 for (auto n : edge->node_index_range())
192 edge->set_node(n, this->node_ptr(InfQuad4::side_nodes_map[i][n]));
193
194 edge->set_interior_parent(this);
195 edge->inherit_data_from(*this);
196
197 return edge;
198}
199
200
201
202void InfQuad4::build_side_ptr (std::unique_ptr<Elem> & side,
203 const unsigned int i)
204{
205 this->side_ptr(side, i);
206 side->set_interior_parent(this);
207 side->inherit_data_from(*this);
208}
209
210
211
212void InfQuad4::connectivity(const unsigned int libmesh_dbg_var(sf),
213 const IOPackage iop,
214 std::vector<dof_id_type> & conn) const
215{
216 libmesh_assert_less (sf, this->n_sub_elem());
217 libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
218
219 conn.resize(4);
220
221 switch (iop)
222 {
223 case TECPLOT:
224 {
225 conn[0] = this->node_id(0)+1;
226 conn[1] = this->node_id(1)+1;
227 conn[2] = this->node_id(3)+1;
228 conn[3] = this->node_id(2)+1;
229 return;
230 }
231 case VTK:
232 {
233 conn[0] = this->node_id(0);
234 conn[1] = this->node_id(1);
235 conn[2] = this->node_id(3);
236 conn[3] = this->node_id(2);
237 return;
238 }
239 default:
240 libmesh_error_msg("Unsupported IO package " << iop);
241 }
242}
243
244
246InfQuad4::side_type (const unsigned int s) const
247{
248 libmesh_assert_less (s, 3);
249 if (s == 0)
250 return EDGE2;
251 return INFEDGE2;
252}
253
254
255void InfQuad4::flip(BoundaryInfo * boundary_info)
256{
257 libmesh_assert(boundary_info);
258
259 swap2nodes(0,1);
260 swap2nodes(2,3);
261 swap2neighbors(1,2);
262 swap2boundarysides(1,2,boundary_info);
263 swap2boundaryedges(1,2,boundary_info);
264}
265
266} // namespace libMesh
267
268
269#endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
The BoundaryInfo class contains information relevant to boundary conditions including storing faces,...
const Point & point(const unsigned int i) const
Definition elem.h:2462
void swap2nodes(unsigned int n1, unsigned int n2)
Swaps two node_ptrs.
Definition elem.h:2101
void swap2neighbors(unsigned int n1, unsigned int n2)
Swaps two neighbor_ptrs.
Definition elem.h:2111
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
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
dof_id_type node_id(const unsigned int i) const
Definition elem.h:2484
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition fe_type.h:197
static Point inverse_map(const unsigned int dim, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true)
Definition inf_fe_map.C:96
static const unsigned int side_nodes_map[num_sides][nodes_per_side]
This maps the node of the side to element node numbers.
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const override
static const int nodes_per_side
ElemType side_type(const unsigned int s) const override final
virtual std::vector< unsigned int > nodes_on_side(const unsigned int s) const override
virtual std::vector< unsigned int > nodes_on_edge(const unsigned int e) const override
static const Real _embedding_matrix[num_children][num_nodes][num_nodes]
Matrix that computes new nodal locations/solution values from current nodes/solution.
virtual void flip(BoundaryInfo *) override final
Flips the element (by swapping node and neighbor pointers) to have a mapping Jacobian of opposite sig...
virtual Order default_order() const override
static const int num_nodes
Geometric constants for InfQuad4.
virtual void connectivity(const unsigned int sf, const IOPackage iop, std::vector< dof_id_type > &conn) const override
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const override
virtual unsigned int n_sub_elem() const override
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i) override
static const int num_sides
Geometric constants for all InfQuads.
virtual Point origin() const override final
virtual bool on_reference_element(const Point &p, const Real eps=TOLERANCE) const override final
static const int num_children
virtual std::unique_ptr< Elem > side_ptr(const unsigned int i) override final
virtual unsigned int n_sides() const override final
virtual unsigned short dim() const override final
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
auto norm_sq() const
The libMesh namespace provides an interface to certain functionality in the library.
IOPackage
libMesh interfaces with several different software packages for the purposes of creating,...
ElemType
Defines an enum for geometric element types.
libmesh_assert(ctx)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real