libMesh
face_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 // Local includes
19 #include "libmesh/side.h"
20 #include "libmesh/edge_edge2.h"
21 #include "libmesh/face_quad4.h"
22 #include "libmesh/enum_io_package.h"
23 #include "libmesh/enum_order.h"
24 
25 namespace libMesh
26 {
27 
28 
29 
30 
31 // ------------------------------------------------------------
32 // Quad4 class static member initialization
33 const int Quad4::num_nodes;
34 const int Quad4::num_sides;
35 const int Quad4::num_children;
36 const int Quad4::nodes_per_side;
37 
39  {
40  {0, 1}, // Side 0
41  {1, 2}, // Side 1
42  {2, 3}, // Side 2
43  {3, 0} // Side 3
44  };
45 
46 
47 #ifdef LIBMESH_ENABLE_AMR
48 
50  {
51  // embedding matrix for child 0
52  {
53  // 0 1 2 3
54  {1.0, 0.0, 0.0, 0.0}, // 0
55  {0.5, 0.5, 0.0, 0.0}, // 1
56  {.25, .25, .25, .25}, // 2
57  {0.5, 0.0, 0.0, 0.5} // 3
58  },
59 
60  // embedding matrix for child 1
61  {
62  // 0 1 2 3
63  {0.5, 0.5, 0.0, 0.0}, // 0
64  {0.0, 1.0, 0.0, 0.0}, // 1
65  {0.0, 0.5, 0.5, 0.0}, // 2
66  {.25, .25, .25, .25} // 3
67  },
68 
69  // embedding matrix for child 2
70  {
71  // 0 1 2 3
72  {0.5, 0.0, 0.0, 0.5}, // 0
73  {.25, .25, .25, .25}, // 1
74  {0.0, 0.0, 0.5, 0.5}, // 2
75  {0.0, 0.0, 0.0, 1.0} // 3
76  },
77 
78  // embedding matrix for child 3
79  {
80  // 0 1 2 3
81  {.25, .25, .25, .25}, // 0
82  {0.0, 0.5, 0.5, 0.0}, // 1
83  {0.0, 0.0, 1.0, 0.0}, // 2
84  {0.0, 0.0, 0.5, 0.5} // 3
85  }
86  };
87 
88 #endif
89 
90 
91 
92 
93 
94 // ------------------------------------------------------------
95 // Quad4 class member functions
96 
97 bool Quad4::is_vertex(const unsigned int) const
98 {
99  return true;
100 }
101 
102 bool Quad4::is_edge(const unsigned int) const
103 {
104  return false;
105 }
106 
107 bool Quad4::is_face(const unsigned int) const
108 {
109  return false;
110 }
111 
112 bool Quad4::is_node_on_side(const unsigned int n,
113  const unsigned int s) const
114 {
115  libmesh_assert_less (s, n_sides());
116  return std::find(std::begin(side_nodes_map[s]),
118  n) != std::end(side_nodes_map[s]);
119 }
120 
121 std::vector<unsigned>
122 Quad4::nodes_on_side(const unsigned int s) const
123 {
124  libmesh_assert_less(s, n_sides());
125  return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s])};
126 }
127 
129 {
130  Point v = this->point(3) - this->point(0);
131  return (v.relative_fuzzy_equals(this->point(2) - this->point(1)));
132 }
133 
134 
135 
137 {
138  return FIRST;
139 }
140 
141 
142 
143 std::unique_ptr<Elem> Quad4::build_side_ptr (const unsigned int i,
144  bool proxy)
145 {
146  libmesh_assert_less (i, this->n_sides());
147 
148  if (proxy)
149  return libmesh_make_unique<Side<Edge2,Quad4>>(this,i);
150 
151  else
152  {
153  std::unique_ptr<Elem> edge = libmesh_make_unique<Edge2>();
154  edge->subdomain_id() = this->subdomain_id();
155 
156  // Set the nodes
157  for (auto n : edge->node_index_range())
158  edge->set_node(n) = this->node_ptr(Quad4::side_nodes_map[i][n]);
159 
160  return edge;
161  }
162 }
163 
164 
165 
166 void Quad4::build_side_ptr (std::unique_ptr<Elem> & side,
167  const unsigned int i)
168 {
169  libmesh_assert_less (i, this->n_sides());
170 
171  if (!side.get() || side->type() != EDGE2)
172  side = this->build_side_ptr(i, false);
173  else
174  {
175  side->subdomain_id() = this->subdomain_id();
176 
177  for (auto n : side->node_index_range())
178  side->set_node(n) = this->node_ptr(Quad4::side_nodes_map[i][n]);
179  }
180 }
181 
182 
183 
184 void Quad4::connectivity(const unsigned int libmesh_dbg_var(sf),
185  const IOPackage iop,
186  std::vector<dof_id_type> & conn) const
187 {
188  libmesh_assert_less (sf, this->n_sub_elem());
189  libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
190 
191  // Create storage.
192  conn.resize(4);
193 
194  switch (iop)
195  {
196  case TECPLOT:
197  {
198  conn[0] = this->node_id(0)+1;
199  conn[1] = this->node_id(1)+1;
200  conn[2] = this->node_id(2)+1;
201  conn[3] = this->node_id(3)+1;
202  return;
203  }
204 
205  case VTK:
206  {
207  conn[0] = this->node_id(0);
208  conn[1] = this->node_id(1);
209  conn[2] = this->node_id(2);
210  conn[3] = this->node_id(3);
211  return;
212  }
213 
214  default:
215  libmesh_error_msg("Unsupported IO package " << iop);
216  }
217 }
218 
219 
220 
222 {
223  // Make copies of our points. It makes the subsequent calculations a bit
224  // shorter and avoids dereferencing the same pointer multiple times.
225  Point
226  x0 = point(0), x1 = point(1),
227  x2 = point(2), x3 = point(3);
228 
229  // Construct constant data vectors.
230  // \vec{x}_{\xi} = \vec{a1}*eta + \vec{b1}
231  // \vec{x}_{\eta} = \vec{a2}*xi + \vec{b2}
232  // This is copy-pasted directly from the output of a Python script.
233  Point
234  a1 = x0/4 - x1/4 + x2/4 - x3/4,
235  b1 = -x0/4 + x1/4 + x2/4 - x3/4,
236  a2 = a1,
237  b2 = -x0/4 - x1/4 + x2/4 + x3/4;
238 
239  // Check for quick return for parallelogram QUAD4.
240  if (a1.relative_fuzzy_equals(Point(0,0,0)))
241  return 4. * b1.cross(b2).norm();
242 
243  // Otherwise, use 2x2 quadrature to approximate the surface area.
244 
245  // 4-point rule, exact for bi-cubics. The weights for this rule are
246  // all equal to 1.
247  const Real q[2] = {-std::sqrt(3.)/3, std::sqrt(3.)/3.};
248 
249  Real vol=0.;
250  for (unsigned int i=0; i<2; ++i)
251  for (unsigned int j=0; j<2; ++j)
252  vol += cross_norm(q[j]*a1 + b1,
253  q[i]*a2 + b2);
254 
255  return vol;
256 }
257 
260 {
261  return Elem::loose_bounding_box();
262 }
263 
264 
265 } // namespace libMesh
libMesh::Quad4::volume
virtual Real volume() const override
An optimized method for computing the area of a 4-node quad with straight sides, but not necessarily ...
Definition: face_quad4.C:221
libMesh::Quad4::is_vertex
virtual bool is_vertex(const unsigned int i) const override
Definition: face_quad4.C:97
libMesh::Quad4::loose_bounding_box
virtual BoundingBox loose_bounding_box() const override
Builds a bounding box out of the nodal positions.
Definition: face_quad4.C:259
libMesh::IOPackage
IOPackage
libMesh interfaces with several different software packages for the purposes of creating,...
Definition: enum_io_package.h:37
libMesh::BoundingBox
Defines a Cartesian bounding box by the two corner extremum.
Definition: bounding_box.h:40
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::Quad4::default_order
virtual Order default_order() const override
Definition: face_quad4.C:136
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
std::sqrt
MetaPhysicL::DualNumber< T, D > sqrt(const MetaPhysicL::DualNumber< T, D > &in)
libMesh::Quad4::nodes_per_side
static const int nodes_per_side
Definition: face_quad4.h:140
libMesh::Quad4::is_node_on_side
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const override
Definition: face_quad4.C:112
libMesh::Elem::point
const Point & point(const unsigned int i) const
Definition: elem.h:1955
libMesh::cross_norm
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:1150
libMesh::Quad4::n_sub_elem
virtual unsigned int n_sub_elem() const override
Definition: face_quad4.h:76
libMesh::Quad4::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_quad4.h:146
libMesh::Quad4::is_edge
virtual bool is_edge(const unsigned int i) const override
Definition: face_quad4.C:102
libMesh::Point
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
libMesh::Quad4::num_children
static const int num_children
Definition: face_quad4.h:139
libMesh::Elem::loose_bounding_box
virtual BoundingBox loose_bounding_box() const
Definition: elem.C:2649
libMesh::Quad4::is_face
virtual bool is_face(const unsigned int i) const override
Definition: face_quad4.C:107
libMesh::Quad4::connectivity
virtual void connectivity(const unsigned int sf, const IOPackage iop, std::vector< dof_id_type > &conn) const override
Definition: face_quad4.C:184
libMesh::Quad4::nodes_on_side
virtual std::vector< unsigned int > nodes_on_side(const unsigned int s) const override
Definition: face_quad4.C:122
libMesh::Quad::n_sides
virtual unsigned int n_sides() const override final
Definition: face_quad.h:91
libMesh::Elem::subdomain_id
subdomain_id_type subdomain_id() const
Definition: elem.h:2069
libMesh::VTK
Definition: enum_io_package.h:42
libMesh::TypeVector::cross
TypeVector< typename CompareTypes< T, T2 >::supertype > cross(const TypeVector< T2 > &v) const
Definition: type_vector.h:920
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::Quad4::build_side_ptr
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i, bool proxy=true) override
Definition: face_quad4.C:143
libMesh::Quad4::num_sides
static const int num_sides
Definition: face_quad4.h:138
libMesh::Quad4::num_nodes
static const int num_nodes
Geometric constants for Quad4.
Definition: face_quad4.h:137
libMesh::Elem::node_ptr
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:2009
libMesh::Quad4::_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_quad4.h:183
libMesh::FIRST
Definition: enum_order.h:42
libMesh::TypeVector::relative_fuzzy_equals
bool relative_fuzzy_equals(const TypeVector< T > &rhs, Real tol=TOLERANCE) const
Definition: type_vector.h:1042
libMesh::TECPLOT
Definition: enum_io_package.h:39
libMesh::EDGE2
Definition: enum_elem_type.h:35
libMesh::Quad4::has_affine_map
virtual bool has_affine_map() const override
Definition: face_quad4.C:128