LifeV
CurrentFEManifold.cpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 *******************************************************************************
4 
5  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
6  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
7 
8  This file is part of LifeV.
9 
10  LifeV is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  LifeV is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23 *******************************************************************************
24 */
25 //@HEADER
26 
27 #include <lifev/core/fem/CurrentFEManifold.hpp>
28 
29 namespace LifeV
30 {
31 
32 // =================================================== //
33 // Constructor(s) & Destructor //
34 // =================================================== //
35 
36 CurrentFEManifold::CurrentFEManifold (const ReferenceFE& refFE, const GeometricMap& geoMap, const QuadratureRule& qr ) :
37  CurrentFE (refFE, geoMap, qr),
45  M_tangentsUpdated (false),
46  M_normalUpdated (false),
47  M_metricUpdated (false),
48  M_detMetricUpdated (false),
49  M_inverseMetricUpdated (false),
51 {
52  // Nothing to be done here
53 }
54 
56  CurrentFE (refFE, geoMap),
64  M_tangentsUpdated (false),
65  M_normalUpdated (false),
66  M_metricUpdated (false),
67  M_detMetricUpdated (false),
68  M_inverseMetricUpdated (false),
70 {
71  // Nothing to be done here
72 }
73 
75  const QuadratureRule& qr, const Real* refCoor,
76  UInt currentId, Real invArea ) :
77  CurrentFE (refFE, geoMap, qr),
85  M_tangentsUpdated (false),
86  M_normalUpdated (false),
87  M_metricUpdated (false),
88  M_detMetricUpdated (false),
89  M_inverseMetricUpdated (false),
91 {
92  M_currentId = currentId;
93 
94  for (UInt iterQuad (0); iterQuad < M_nbQuadPt; ++iterQuad)
95  {
96  for (UInt iDof (0); iDof < M_nbNode; ++iDof)
97  {
98  M_phi[iDof][0][iterQuad] *= invArea;
99  }
100 
101  for (UInt iGeoNode (0); iGeoNode < M_nbGeoNode; ++iGeoNode)
102  {
103  M_phiGeo[iGeoNode][iterQuad] = geoMap.phi (iGeoNode, M_quadRule->quadPointCoor (iterQuad) );
104  }
105  }
106 
107  for (UInt iNode (0); iNode < M_nbGeoNode; ++iNode)
108  for (UInt iCoor (0); iCoor < nDimensions; ++iCoor)
109  {
110  M_cellNodes[iNode][iCoor] = refCoor[nDimensions * iNode + iCoor];
111  }
112 
113  M_cellNodesUpdated = true;
114 
115  // This constructor is used for hybrid FE, where info about normals, tangents and metric
116  // are needed only on the reference element. So we update them on the given reference coordinates
117 
118  computeQuadNodes();
125 }
126 
128  CurrentFE (bdFE),
142 {
144 
145  if (bdFE.M_quadRule)
146  {
147  setQuadRule (*bdFE.M_quadRule);
148  }
149 }
150 
151 // =================================================== //
152 // Methods //
153 // =================================================== //
154 
155 void CurrentFEManifold::coorMap (Real& x, Real& y, Real& z, Real xi, Real eta) const
156 {
157  CurrentFE::coorMap (x, y, z, xi, eta, 0.);
158 }
159 
161 {
162  ASSERT (M_wRootDetMetricUpdated, "Weighted root of metric determinant is not updated!");
163 
164  Real meas = 0.0;
165  for (UInt quadNode (0); quadNode < M_nbQuadPt; ++quadNode)
166  {
167  meas += M_wRootDetMetric[quadNode];
168  }
169  return meas;
170 }
171 
172 void CurrentFEManifold::update (const std::vector<std::vector<Real> >& pts, flag_Type upFlag)
173 {
174  CurrentFE::update (pts, upFlag);
175 
176  M_tangentsUpdated = false;
177  if ( (upFlag & UPDATE_ONLY_TANGENTS) != 0)
178  {
180  };
181 
182  M_normalUpdated = false;
183  if ( (upFlag & UPDATE_ONLY_NORMALS) != 0)
184  {
186  };
187 
188  M_metricUpdated = false;
189  if ( (upFlag & UPDATE_ONLY_METRIC) != 0)
190  {
192  };
193 
194  M_detMetricUpdated = false;
195  if ( (upFlag & UPDATE_ONLY_DET_METRIC) != 0)
196  {
198  };
199 
200  M_inverseMetricUpdated = false;
201  if ( (upFlag & UPDATE_ONLY_INV_METRIC) != 0)
202  {
204  };
205 
206  M_wRootDetMetricUpdated = false;
207  if ( (upFlag & UPDATE_ONLY_W_ROOT_DET_METRIC) != 0)
208  {
210  };
211 }
212 
213 // =============================================== //
214 // Protected Methods //
215 // =============================================== //
216 
218 {
219  ASSERT (M_cellNodesUpdated, "Missing update: cellNodes\n");
220  ASSERT (M_dphiGeometricMapUpdated, "Missing update: dphiGeometricMap");
221 
222  for (UInt iq (0); iq < M_nbQuadPt; ++iq)
223  for (UInt iTangent (0); iTangent < M_nbLocalCoor; ++iTangent)
224  for (UInt iCoor (0); iCoor < nDimensions; ++iCoor)
225  {
226  M_tangents[iTangent][iCoor][iq] = 0.0;
227  for (UInt iNode (0); iNode < M_nbGeoNode; ++iNode)
228  {
229  M_tangents[iTangent][iCoor][iq] += M_cellNodes[iNode][iCoor] * M_dphiGeometricMap[iNode][iTangent][iq];
230  }
231  }
232 
233  M_tangentsUpdated = true;
234 }
235 
237 {
238  ASSERT (M_tangentsUpdated, "Missing update: tangents\n");
239 
240  Real norm, n1, n2;
241 
242  // So far I can't find a general method for dimension n, so we need to switch on M_nbLocalCoor
243  switch (M_nbLocalCoor)
244  {
245  case 1:
246  for (UInt iq (0); iq < M_nbQuadPt; ++iq)
247  {
248  n1 = M_tangents[0][1][iq];
249  n2 = - M_tangents[0][0][iq];
250 
251  norm = sqrt (n1 * n1 + n2 * n2);
252  ASSERT (norm > 0, "Error! Something went wrong while computing normals.\n");
253 
254  M_normal[0][iq] = n1 / norm;
255  M_normal[1][iq] = n2 / norm;
256  }
257  break;
258  case 2:
259  Real n3;
260  for (UInt iq (0); iq < M_nbQuadPt; ++iq)
261  {
262  n1 = M_tangents[0][1][iq] * M_tangents[1][2][iq] - M_tangents[0][2][iq] * M_tangents[1][1][iq];
263  n2 = M_tangents[0][2][iq] * M_tangents[1][0][iq] - M_tangents[0][0][iq] * M_tangents[1][2][iq];
264  n3 = M_tangents[0][0][iq] * M_tangents[1][1][iq] - M_tangents[0][1][iq] * M_tangents[1][0][iq];
265 
266  norm = sqrt (n1 * n1 + n2 * n2 + n3 * n3);
267  ASSERT (norm > 0, "Error! Something went wrong while computing normals.\n");
268 
269  M_normal[0][iq] = n1 / norm;
270  M_normal[1][iq] = n2 / norm;
271  M_normal[2][iq] = n3 / norm;
272  }
273  break;
274  default:
275  ASSERT (0, "No rule to compute normal vector for this dimension.");
276  }
277 
278  M_normalUpdated = true;
279 }
280 
282 {
283  ASSERT (M_tangentsUpdated, "Missing update: tangents\n");
284 
285  for (UInt iq (0); iq < M_nbQuadPt; ++iq)
286  for (UInt iTangent (0); iTangent < M_nbLocalCoor; ++iTangent)
287  {
288  // Diagonal part
289  M_metric[iTangent][iTangent][iq] = 0.0;
290  for (UInt iCoor (0); iCoor < M_nbLocalCoor + 1; ++iCoor)
291  {
292  M_metric[iTangent][iTangent][iq] += M_tangents[iTangent][iCoor][iq] * M_tangents[iTangent][iCoor][iq];
293  }
294 
295  // Extra diagonal part
296  for (UInt jTangent (0); jTangent < iTangent; ++jTangent)
297  {
298  M_metric[iTangent][jTangent][iq] = 0.0;
299  for (UInt iCoor (0); iCoor < M_nbLocalCoor + 1; ++iCoor)
300  {
301  M_metric[iTangent][jTangent][iq] += M_tangents[iTangent][iCoor][iq] * M_tangents[jTangent][iCoor][iq];
302  }
303  M_metric[jTangent][iTangent][iq] = M_metric[iTangent][jTangent][iq];
304  }
305  }
306 
307  M_metricUpdated = true;
308 }
309 
311 {
312  ASSERT (M_metricUpdated, "Missing update: metric\n");
313 
314  for (UInt iq (0); iq < M_nbQuadPt; ++iq)
315  {
316  switch (M_nbLocalCoor)
317  {
318  case 1:
319  M_detMetric[iq] = M_metric[0][0][iq];
320  break;
321  case 2:
322  M_detMetric[iq] = M_metric[0][0][iq] * M_metric[1][1][iq] - M_metric[0][1][iq] * M_metric[1][0][iq];
323  break;
324  default:
325  ASSERT (0, "No rule to compute determinant of the metric for this dimension.\n");
326  }
327  }
328  M_detMetricUpdated = true;
329 }
330 
332 {
333  ASSERT (M_metricUpdated, "Missing update: metric\n");
334  ASSERT (M_detMetricUpdated, "Missing update: detMetric\n");
335 
336  for (UInt iq (0); iq < M_nbQuadPt; ++iq)
337  {
338  switch (M_nbLocalCoor)
339  {
340  case 1:
341  M_inverseMetric[0][0][iq] = 1. / M_metric[0][0][iq];
342  break;
343  case 2:
344  // Diagonal part: switch the two diagonal entries and divide by determinant
345  M_inverseMetric[0][0][iq] = M_metric[1][1][iq] / M_detMetric[iq];
346  M_inverseMetric[1][1][iq] = M_metric[0][0][iq] / M_detMetric[iq];
347 
348  // Extradiagonal part: change sign and divide by determinant (matrix is symmetric, so do it once)
349  M_inverseMetric[0][1][iq] = M_inverseMetric[1][0][iq] = - M_metric[0][1][iq] / M_detMetric[iq];
350  break;
351  default:
352  ASSERT (0, "No rule to compute the inverse of the metric for this dimension.\n");
353  }
354  }
355 
356  M_inverseMetricUpdated = true;
357 }
358 
360 {
361  ASSERT (M_metricUpdated, "Missing update: metric\n");
362  ASSERT (M_detMetricUpdated, "Missing update: detMetric\n");
363 
364  for (UInt iq (0); iq < M_nbQuadPt; ++iq)
365  {
366  M_wRootDetMetric[iq] = std::sqrt (M_detMetric[iq]) * M_quadRule->weight (iq);
367  }
368 
370 }
371 
372 } // Namespace LifeV
GeometricMap - Structure for the geometrical mapping.
void computeNormal()
Computes the normal vectors in the quadrature nodes.
const UInt M_nbNode
Definition: CurrentFE.hpp:611
uint32_type flag_Type
bit-flag with up to 32 different flags
Definition: LifeV.hpp:197
QuadratureRule * M_quadRule
Definition: CurrentFE.hpp:627
Real measure() const
Compute the measure of the current element.
A class for a finite element on a manifold.
CurrentFEManifold(const ReferenceFE &refFE, const GeometricMap &geoMap)
Constructor without quadrature specification.
void computeDetMetric()
Computes the determinant of the metric tensor in the quadrature nodes.
const flag_Type UPDATE_ONLY_METRIC(65536)
const flag_Type UPDATE_ONLY_NORMALS(32768)
void updateInverseJacobian(const UInt &iQuadPt)
void computeWRootDetMetric()
Computes the square root of the determinant of the metric times the weight in the quadrature nodes...
CurrentFEManifold(const ReferenceFE &refFE, const GeometricMap &geoMap, const QuadratureRule &qr, const Real *refCoor, UInt currentId, Real invArea=1.)
Constructor used to create a static reference FE for hybrid elements.
void computeInverseMetric()
Computes the inverse of the metric tensor in the quadrature nodes.
const UInt M_nbLocalCoor
Definition: CurrentFE.hpp:612
const flag_Type UPDATE_ONLY_INV_METRIC(524288)
const flag_Type UPDATE_ONLY_W_ROOT_DET_METRIC(262144)
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
virtual void update(const std::vector< std::vector< Real > > &pts, flag_Type upFlag)
Update method using only point coordinates.
void computeMetric()
Computes the metric in the quadrature nodes.
const flag_Type UPDATE_ONLY_TANGENTS(16384)
double Real
Generic real data.
Definition: LifeV.hpp:175
CurrentFE - A primordial class for the assembly of the local matrices/vectors retaining the values on...
Definition: CurrentFE.hpp:243
CurrentFEManifold(const ReferenceFE &refFE, const GeometricMap &geoMap, const QuadratureRule &qr)
Full constructor with default quadrature.
The class for a reference Lagrangian finite element.
const UInt nDimensions(NDIM)
const flag_Type UPDATE_ONLY_DET_METRIC(131072)
CurrentFEManifold(const CurrentFEManifold &feManifold)
Copy constructor.
CurrentFE(const ReferenceFE &refFE, const GeometricMap &geoMap)
Constructor without quadrature specification.
Definition: CurrentFE.cpp:157
CurrentFE(const ReferenceFE &refFE, const GeometricMap &geoMap, const QuadratureRule &qr)
Full constructor with default quadrature.
Definition: CurrentFE.cpp:43
void computeTangents()
Computes the tangent vectors in the quadrature nodes.
QuadratureRule - The basis class for storing and accessing quadrature rules.
bool M_tangentsUpdated
Check variables.
void coorMap(Real &x, Real &y, Real &z, Real xi, Real eta) const
Maps a point from the reference element to the current element.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191