fe_xyz_map.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 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 #include "libmesh/fe_xyz_map.h"
19 #include "libmesh/elem.h"
20 
21 namespace libMesh
22 {
23 
24 void FEXYZMap::compute_face_map(int dim, const std::vector<Real> & qw, const Elem * side)
25 {
26  libmesh_assert(side);
27 
28  LOG_SCOPE("compute_face_map()", "FEXYZMap");
29 
30  // The number of quadrature points.
31  const unsigned int n_qp = cast_int<unsigned int>(qw.size());
32 
33  switch(dim)
34  {
35  case 2:
36  {
37 
38  // Resize the vectors to hold data at the quadrature points
39  {
40  this->xyz.resize(n_qp);
41  this->dxyzdxi_map.resize(n_qp);
42  this->d2xyzdxi2_map.resize(n_qp);
43  this->tangents.resize(n_qp);
44  this->normals.resize(n_qp);
45  this->curvatures.resize(n_qp);
46 
47  this->JxW.resize(n_qp);
48  }
49 
50  // Clear the entities that will be summed
51  // Compute the tangent & normal at the quadrature point
52  for (unsigned int p=0; p<n_qp; p++)
53  {
54  this->tangents[p].resize(LIBMESH_DIM-1); // 1 Tangent in 2D, 2 in 3D
55  this->xyz[p].zero();
56  this->dxyzdxi_map[p].zero();
57  this->d2xyzdxi2_map[p].zero();
58  }
59 
60  // compute x, dxdxi at the quadrature points
61  for (unsigned int i=0,
62  n_psi_map = cast_int<unsigned int>(this->psi_map.size());
63  i != n_psi_map; i++) // sum over the nodes
64  {
65  const Point & side_point = side->point(i);
66 
67  for (unsigned int p=0; p<n_qp; p++) // for each quadrature point...
68  {
69  this->xyz[p].add_scaled (side_point, this->psi_map[i][p]);
70  this->dxyzdxi_map[p].add_scaled (side_point, this->dpsidxi_map[i][p]);
71  this->d2xyzdxi2_map[p].add_scaled(side_point, this->d2psidxi2_map[i][p]);
72  }
73  }
74 
75  // Compute the tangent & normal at the quadrature point
76  for (unsigned int p=0; p<n_qp; p++)
77  {
78  const Point n(this->dxyzdxi_map[p](1), -this->dxyzdxi_map[p](0), 0.);
79 
80  this->normals[p] = n.unit();
81  this->tangents[p][0] = this->dxyzdxi_map[p].unit();
82 #if LIBMESH_DIM == 3 // Only good in 3D space
83  this->tangents[p][1] = this->dxyzdxi_map[p].cross(n).unit();
84 #endif
85  // The curvature is computed via the familiar Frenet formula:
86  // curvature = [d^2(x) / d (xi)^2] dot [normal]
87  // For a reference, see:
88  // F.S. Merritt, Mathematics Manual, 1962, McGraw-Hill, p. 310
89  //
90  // Note: The sign convention here is different from the
91  // 3D case. Concave-upward curves (smiles) have a positive
92  // curvature. Concave-downward curves (frowns) have a
93  // negative curvature. Be sure to take that into account!
94  const Real numerator = this->d2xyzdxi2_map[p] * this->normals[p];
95  const Real denominator = this->dxyzdxi_map[p].norm_sq();
96  libmesh_assert_not_equal_to (denominator, 0);
97  this->curvatures[p] = numerator / denominator;
98  }
99 
100  // compute the jacobian at the quadrature points
101  for (unsigned int p=0; p<n_qp; p++)
102  {
103  const Real the_jac = std::sqrt(this->dxdxi_map(p)*this->dxdxi_map(p) +
104  this->dydxi_map(p)*this->dydxi_map(p));
105 
106  libmesh_assert_greater (the_jac, 0.);
107 
108  this->JxW[p] = the_jac*qw[p];
109  }
110 
111  break;
112  }
113 
114  case 3:
115  {
116  // Resize the vectors to hold data at the quadrature points
117  {
118  this->xyz.resize(n_qp);
119  this->dxyzdxi_map.resize(n_qp);
120  this->dxyzdeta_map.resize(n_qp);
121  this->d2xyzdxi2_map.resize(n_qp);
122  this->d2xyzdxideta_map.resize(n_qp);
123  this->d2xyzdeta2_map.resize(n_qp);
124  this->tangents.resize(n_qp);
125  this->normals.resize(n_qp);
126  this->curvatures.resize(n_qp);
127 
128  this->JxW.resize(n_qp);
129  }
130 
131  // Clear the entities that will be summed
132  for (unsigned int p=0; p<n_qp; p++)
133  {
134  this->tangents[p].resize(LIBMESH_DIM-1); // 1 Tangent in 2D, 2 in 3D
135  this->xyz[p].zero();
136  this->dxyzdxi_map[p].zero();
137  this->dxyzdeta_map[p].zero();
138  this->d2xyzdxi2_map[p].zero();
139  this->d2xyzdxideta_map[p].zero();
140  this->d2xyzdeta2_map[p].zero();
141  }
142 
143  // compute x, dxdxi at the quadrature points
144  for (unsigned int i=0,
145  n_psi_map = cast_int<unsigned int>(this->psi_map.size());
146  i != n_psi_map; i++) // sum over the nodes
147  {
148  const Point & side_point = side->point(i);
149 
150  for (unsigned int p=0; p<n_qp; p++) // for each quadrature point...
151  {
152  this->xyz[p].add_scaled (side_point, this->psi_map[i][p]);
153  this->dxyzdxi_map[p].add_scaled (side_point, this->dpsidxi_map[i][p]);
154  this->dxyzdeta_map[p].add_scaled (side_point, this->dpsideta_map[i][p]);
155  this->d2xyzdxi2_map[p].add_scaled (side_point, this->d2psidxi2_map[i][p]);
156  this->d2xyzdxideta_map[p].add_scaled(side_point, this->d2psidxideta_map[i][p]);
157  this->d2xyzdeta2_map[p].add_scaled (side_point, this->d2psideta2_map[i][p]);
158  }
159  }
160 
161  // Compute the tangents, normal, and curvature at the quadrature point
162  for (unsigned int p=0; p<n_qp; p++)
163  {
164  const Point n = this->dxyzdxi_map[p].cross(this->dxyzdeta_map[p]);
165  this->normals[p] = n.unit();
166  this->tangents[p][0] = this->dxyzdxi_map[p].unit();
167  this->tangents[p][1] = n.cross(this->dxyzdxi_map[p]).unit();
168 
169  // Compute curvature using the typical nomenclature
170  // of the first and second fundamental forms.
171  // For reference, see:
172  // 1) http://mathworld.wolfram.com/MeanCurvature.html
173  // (note -- they are using inward normal)
174  // 2) F.S. Merritt, Mathematics Manual, 1962, McGraw-Hill
175  const Real L = -this->d2xyzdxi2_map[p] * this->normals[p];
176  const Real M = -this->d2xyzdxideta_map[p] * this->normals[p];
177  const Real N = -this->d2xyzdeta2_map[p] * this->normals[p];
178  const Real E = this->dxyzdxi_map[p].norm_sq();
179  const Real F = this->dxyzdxi_map[p] * this->dxyzdeta_map[p];
180  const Real G = this->dxyzdeta_map[p].norm_sq();
181 
182  const Real numerator = E*N -2.*F*M + G*L;
183  const Real denominator = E*G - F*F;
184  libmesh_assert_not_equal_to (denominator, 0.);
185  this->curvatures[p] = 0.5*numerator/denominator;
186  }
187 
188  // compute the jacobian at the quadrature points, see
189  // http://sp81.msi.umn.edu:999/fluent/fidap/help/theory/thtoc.htm
190  for (unsigned int p=0; p<n_qp; p++)
191  {
192  const Real g11 = (this->dxdxi_map(p)*this->dxdxi_map(p) +
193  this->dydxi_map(p)*this->dydxi_map(p) +
194  this->dzdxi_map(p)*this->dzdxi_map(p));
195 
196  const Real g12 = (this->dxdxi_map(p)*this->dxdeta_map(p) +
197  this->dydxi_map(p)*this->dydeta_map(p) +
198  this->dzdxi_map(p)*this->dzdeta_map(p));
199 
200  const Real g21 = g12;
201 
202  const Real g22 = (this->dxdeta_map(p)*this->dxdeta_map(p) +
203  this->dydeta_map(p)*this->dydeta_map(p) +
204  this->dzdeta_map(p)*this->dzdeta_map(p));
205 
206 
207  const Real the_jac = std::sqrt(g11*g22 - g12*g21);
208 
209  libmesh_assert_greater (the_jac, 0.);
210 
211  this->JxW[p] = the_jac*qw[p];
212  }
213 
214  break;
215  }
216  default:
217  libmesh_error_msg("Invalid dim = " << dim);
218 
219  } // switch(dim)
220 }
221 
222 } // namespace libMesh
Real dzdeta_map(const unsigned int p) const
Definition: fe_map.h:589
std::vector< std::vector< Real > > dpsideta_map
Definition: fe_map.h:823
std::vector< std::vector< Real > > psi_map
Definition: fe_map.h:811
std::vector< std::vector< Real > > d2psideta2_map
Definition: fe_map.h:844
Real dxdeta_map(const unsigned int p) const
Definition: fe_map.h:573
unsigned short int side
Definition: xdr_io.C:50
Real dzdxi_map(const unsigned int p) const
Definition: fe_map.h:565
The base class for all geometric element types.
Definition: elem.h:100
std::vector< std::vector< Real > > d2psidxideta_map
Definition: fe_map.h:837
std::vector< RealGradient > d2xyzdxideta_map
Definition: fe_map.h:648
std::vector< RealGradient > dxyzdxi_map
Definition: fe_map.h:624
TypeVector< T > unit() const
Definition: type_vector.C:37
std::vector< RealGradient > d2xyzdeta2_map
Definition: fe_map.h:654
std::vector< RealGradient > d2xyzdxi2_map
Definition: fe_map.h:642
TypeVector< typename CompareTypes< T, T2 >::supertype > cross(const TypeVector< T2 > &v) const
Definition: type_vector.h:882
std::vector< Real > curvatures
Definition: fe_map.h:861
std::vector< std::vector< Real > > d2psidxi2_map
Definition: fe_map.h:830
virtual void compute_face_map(int dim, const std::vector< Real > &qw, const Elem *side) override
Definition: fe_xyz_map.C:24
std::vector< Real > JxW
Definition: fe_map.h:871
std::vector< Point > normals
Definition: fe_map.h:854
std::vector< Point > xyz
Definition: fe_map.h:618
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Real dydeta_map(const unsigned int p) const
Definition: fe_map.h:581
std::vector< std::vector< Real > > dpsidxi_map
Definition: fe_map.h:817
std::vector< std::vector< Point > > tangents
Definition: fe_map.h:849
std::vector< RealGradient > dxyzdeta_map
Definition: fe_map.h:630
Real dxdxi_map(const unsigned int p) const
Definition: fe_map.h:549
Real dydxi_map(const unsigned int p) const
Definition: fe_map.h:557
A geometric point in (x,y,z) space.
Definition: point.h:38