libMesh
face_inf_quad4.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 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/side.h"
29 #include "libmesh/edge_edge2.h"
30 #include "libmesh/edge_inf_edge2.h"
31 #include "libmesh/enum_io_package.h"
32 #include "libmesh/enum_order.h"
33 #include "libmesh/inf_fe_map.h"
34 
35 namespace libMesh
36 {
37 
38 
39 
40 // ------------------------------------------------------------
41 // InfQuad4 class static member initializations
42 const int InfQuad4::num_nodes;
43 const int InfQuad4::num_sides;
44 const int InfQuad4::num_children;
45 const int InfQuad4::nodes_per_side;
46 
48  {
49  {0, 1}, // Side 0
50  {1, 3}, // Side 1
51  {0, 2} // Side 2
52  };
53 
54 
55 
56 #ifdef LIBMESH_ENABLE_AMR
57 
59  {
60  // embedding matrix for child 0
61  {
62  // 0 1 2 3rd parent node
63  {1.0, 0.0, 0.0, 0.0}, // 0th child node
64  {0.5, 0.5, 0.0, 0.0}, // 1
65  {0.0, 0.0, 1.0, 0.0}, // 2
66  {0.0, 0.0, 0.5, 0.5} // 3
67  },
68 
69  // embedding matrix for child 1
70  {
71  // 0 1 2 3
72  {0.5, 0.5, 0.0, 0.0}, // 0
73  {0.0, 1.0, 0.0, 0.0}, // 1
74  {0.0, 0.0, 0.5, 0.5}, // 2
75  {0.0, 0.0, 0.0, 1.0} // 3
76  }
77  };
78 
79 #endif
80 
81 
82 // ------------------------------------------------------------
83 // InfQuad4 class member functions
84 
85 bool InfQuad4::is_vertex(const unsigned int i) const
86 {
87  if (i < 2)
88  return true;
89  return false;
90 }
91 
92 bool InfQuad4::is_edge(const unsigned int i) const
93 {
94  if (i < 2)
95  return false;
96  return true;
97 }
98 
99 bool InfQuad4::is_face(const unsigned int) const
100 {
101  return false;
102 }
103 
104 bool InfQuad4::is_node_on_side(const unsigned int n,
105  const unsigned int s) const
106 {
107  libmesh_assert_less (s, n_sides());
108  return std::find(std::begin(side_nodes_map[s]),
110  n) != std::end(side_nodes_map[s]);
111 }
112 
113 std::vector<unsigned>
114 InfQuad4::nodes_on_side(const unsigned int s) const
115 {
116  libmesh_assert_less(s, n_sides());
117  return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s])};
118 }
119 
120 bool InfQuad4::contains_point (const Point & p, Real tol) const
121 {
122  /*
123  * make use of the fact that infinite elements do not
124  * live inside the envelope. Use a fast scheme to
125  * check whether point \p p is inside or outside
126  * our relevant part of the envelope. Note that
127  * this is not exclusive: the point may be outside
128  * the envelope, but contained in another infinite element.
129  * Therefore, if the distance is greater, do fall back
130  * to the scheme of using inverse_map().
131  */
132  const Point my_origin (this->origin());
133 
134  /*
135  * determine the minimal distance of the base from the origin
136  * use norm_sq() instead of norm(), it is slightly faster
137  */
138  const Real min_distance_sq = std::min((Point(this->point(0)-my_origin)).norm_sq(),
139  (Point(this->point(1)-my_origin)).norm_sq());
140 
141  /*
142  * work with 1% allowable deviation. Can still fall
143  * back to the InfFE::inverse_map()
144  */
145  const Real conservative_p_dist_sq = 1.01 * (Point(p-my_origin).norm_sq());
146 
147  if (conservative_p_dist_sq < min_distance_sq)
148  {
149  /*
150  * the physical point is definitely not contained
151  * in the element, return false.
152  */
153  return false;
154  }
155  else
156  {
157  /*
158  * cannot say anything, fall back to the inverse_map()
159  *
160  * Declare a basic FEType. Will use default in the base,
161  * and something else (not important) in radial direction.
162  */
163  FEType fe_type(default_order());
164 
165  const Point mapped_point = InfFEMap::inverse_map(dim(), this, p,
166  tol, false);
167 
168  return FEInterface::on_reference_element(mapped_point, this->type(), tol);
169  }
170 }
171 
172 
173 
174 
176 {
177  return FIRST;
178 }
179 
180 
181 
182 std::unique_ptr<Elem> InfQuad4::build_side_ptr (const unsigned int i,
183  bool proxy)
184 {
185  // libmesh_assert_less (i, this->n_sides());
186 
187  if (proxy)
188  {
189  switch (i)
190  {
191  // base
192  case 0:
193  return libmesh_make_unique<Side<Edge2,InfQuad4>>(this,i);
194 
195  // ifem edges
196  case 1:
197  case 2:
198  return libmesh_make_unique<Side<InfEdge2,InfQuad4>>(this,i);
199 
200  default:
201  libmesh_error_msg("Invalid side i = " << i);
202  }
203  }
204 
205  else
206  {
207  // Return value
208  std::unique_ptr<Elem> edge;
209 
210  switch (i)
211  {
212  case 0:
213  {
214  edge = libmesh_make_unique<Edge2>();
215  break;
216  }
217 
218  // adjacent to another infinite element
219  case 1:
220  case 2:
221  {
222  edge = libmesh_make_unique<InfEdge2>();
223  break;
224  }
225 
226  default:
227  libmesh_error_msg("Invalid side i = " << i);
228  }
229 
230  edge->subdomain_id() = this->subdomain_id();
231 
232  // Set the nodes
233  for (auto n : edge->node_index_range())
234  edge->set_node(n) = this->node_ptr(InfQuad4::side_nodes_map[i][n]);
235 
236  return edge;
237  }
238 }
239 
240 
241 
242 void InfQuad4::build_side_ptr (std::unique_ptr<Elem> & side,
243  const unsigned int i)
244 {
245  libmesh_assert_less (i, this->n_sides());
246 
247  // Think of a unit cube: (-1,1) x (-1,1) x (1,1)
248  switch (i)
249  {
250  // the base face
251  case 0:
252  {
253  if (!side.get() || side->type() != EDGE2)
254  {
255  side = this->build_side_ptr(i, false);
256  return;
257  }
258  break;
259  }
260 
261  // connecting to another infinite element
262  case 1:
263  case 2:
264  {
265  if (!side.get() || side->type() != INFEDGE2)
266  {
267  side = this->build_side_ptr(i, false);
268  return;
269  }
270  break;
271  }
272 
273  default:
274  libmesh_error_msg("Invalid side i = " << i);
275  }
276 
277  side->subdomain_id() = this->subdomain_id();
278 
279  // Set the nodes
280  for (auto n : side->node_index_range())
281  side->set_node(n) = this->node_ptr(InfQuad4::side_nodes_map[i][n]);
282 }
283 
284 
285 
286 void InfQuad4::connectivity(const unsigned int libmesh_dbg_var(sf),
287  const IOPackage iop,
288  std::vector<dof_id_type> & conn) const
289 {
290  libmesh_assert_less (sf, this->n_sub_elem());
291  libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
292 
293  conn.resize(4);
294 
295  switch (iop)
296  {
297  case TECPLOT:
298  {
299  conn[0] = this->node_id(0)+1;
300  conn[1] = this->node_id(1)+1;
301  conn[2] = this->node_id(3)+1;
302  conn[3] = this->node_id(2)+1;
303  return;
304  }
305  case VTK:
306  {
307  conn[0] = this->node_id(0);
308  conn[1] = this->node_id(1);
309  conn[2] = this->node_id(3);
310  conn[3] = this->node_id(2);
311  return;
312  }
313  default:
314  libmesh_error_msg("Unsupported IO package " << iop);
315  }
316 }
317 
318 } // namespace libMesh
319 
320 
321 #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
libMesh::FEInterface::on_reference_element
static bool on_reference_element(const Point &p, const ElemType t, const Real eps=TOLERANCE)
Definition: fe_interface.C:677
libMesh::InfQuad4::contains_point
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const override
Definition: face_inf_quad4.C:120
libMesh::InfQuad::n_sides
virtual unsigned int n_sides() const override final
Definition: face_inf_quad.h:102
libMesh::InfQuad4::is_face
virtual bool is_face(const unsigned int i) const override
Definition: face_inf_quad4.C:99
libMesh::InfQuad4::type
virtual ElemType type() const override
Definition: face_inf_quad4.h:77
libMesh::IOPackage
IOPackage
libMesh interfaces with several different software packages for the purposes of creating,...
Definition: enum_io_package.h:37
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::InfQuad4::n_sub_elem
virtual unsigned int n_sub_elem() const override
Definition: face_inf_quad4.h:82
libMesh::Order
Order
Definition: enum_order.h:40
libMesh::INVALID_IO_PACKAGE
Definition: enum_io_package.h:48
end
IterBase * end
Also have a polymorphic pointer to the end object, this prevents iterating past the end.
Definition: variant_filter_iterator.h:343
libMesh::InfQuad4::num_sides
static const int num_sides
Definition: face_inf_quad4.h:151
libMesh::InfQuad4::nodes_on_side
virtual std::vector< unsigned int > nodes_on_side(const unsigned int s) const override
Definition: face_inf_quad4.C:114
libMesh::INFEDGE2
Definition: enum_elem_type.h:57
libMesh::Elem::point
const Point & point(const unsigned int i) const
Definition: elem.h:1955
libMesh::InfQuad4::_embedding_matrix
static const float _embedding_matrix[num_children][num_nodes][num_nodes]
Matrix that computes new nodal locations/solution values from current nodes/solution.
Definition: face_inf_quad4.h:185
libMesh::InfQuad::origin
virtual Point origin() const override final
Definition: face_inf_quad.h:201
libMesh::InfQuad4::num_nodes
static const int num_nodes
Geometric constants for InfQuad4.
Definition: face_inf_quad4.h:150
libMesh::InfFEMap::inverse_map
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:88
libMesh::TypeVector::norm_sq
auto norm_sq() const -> decltype(std::norm(T()))
Definition: type_vector.h:986
libMesh::InfQuad4::default_order
virtual Order default_order() const override
Definition: face_inf_quad4.C:175
libMesh::InfQuad4::is_vertex
virtual bool is_vertex(const unsigned int i) const override
Definition: face_inf_quad4.C:85
libMesh::InfQuad4::is_edge
virtual bool is_edge(const unsigned int i) const override
Definition: face_inf_quad4.C:92
libMesh::Point
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
libMesh::InfQuad4::is_node_on_side
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const override
Definition: face_inf_quad4.C:104
libMesh::InfQuad4::connectivity
virtual void connectivity(const unsigned int sf, const IOPackage iop, std::vector< dof_id_type > &conn) const override
Definition: face_inf_quad4.C:286
libMesh::InfQuad4::build_side_ptr
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i, bool proxy=true) override
Definition: face_inf_quad4.C:182
libMesh::TensorTools::norm_sq
T norm_sq(std::complex< T > a)
Definition: tensor_tools.h:85
libMesh::FEType
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:178
libMesh::InfQuad::dim
virtual unsigned short dim() const override final
Definition: face_inf_quad.h:95
libMesh::Elem::subdomain_id
subdomain_id_type subdomain_id() const
Definition: elem.h:2069
libMesh::InfQuad4::side_nodes_map
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_inf_quad4.h:159
libMesh::VTK
Definition: enum_io_package.h:42
libMesh::Elem::node_id
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:1977
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::Elem::node_ptr
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:2009
libMesh::FIRST
Definition: enum_order.h:42
libMesh::TECPLOT
Definition: enum_io_package.h:39
libMesh::EDGE2
Definition: enum_elem_type.h:35
libMesh::InfQuad4::num_children
static const int num_children
Definition: face_inf_quad4.h:152
libMesh::InfQuad4::nodes_per_side
static const int nodes_per_side
Definition: face_inf_quad4.h:153