LifeV
QuadratureRule.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 /*!
28  @file
29  @brief File for the implementation of the QuadratureRule class.
30 
31  @author Jean-Frederic Gerbeau
32  Samuel Quinodoz <samuel.quinodoz@epfl.ch>
33  @date 01-06-2010
34 
35  @contributor Samuel Quinodoz <samuel.quinodoz@epfl.ch>
36  @mantainer Samuel Quinodoz <samuel.quinodoz@epfl.ch>
37  */
38 
39 
40 #include <lifev/core/fem/QuadratureRule.hpp>
41 
42 namespace LifeV
43 {
44 
46 
47 // ===================================================
48 // Constructors & Destructor
49 // ===================================================
50 
52  : M_pt (0), M_shape (NONE), M_name (""), M_nbQuadPt (0), M_degOfExact (0), M_dimension (0)
53 {}
54 
55 QuadratureRule::QuadratureRule ( const QuadraturePoint* pt, int /*id*/, std::string name,
56  ReferenceShapes shape, UInt nbQuadPt, UInt degOfExact ) :
57  M_pt ( nbQuadPt),
58  M_shape ( shape ), M_name ( name ),
59  M_nbQuadPt ( nbQuadPt ), M_degOfExact ( degOfExact )
60 {
61  M_dimension = 3;
62  for (UInt i (0); i < nbQuadPt; ++i)
63  {
64  M_pt[i] = pt[i];
65  }
66 }
67 
69  M_pt ( qr.M_pt ), M_shape ( qr.M_shape ), M_name ( qr.M_name ),
71 {
72 }
73 
75  M_pt ( qr.M_nbQuadPt ), M_shape ( qr.M_shape ), M_name ( qr.M_name ),
77 {
78  ASSERT (dim >= shapeDimension (M_shape), " Downgrading quadrature rule is forbidden ")
79 
80  for (UInt i (0); i < M_nbQuadPt; ++i)
81  {
82  M_pt[i] = QuadraturePoint (qr.M_pt[i], dim);
83  }
84 
85 }
86 
87 QuadratureRule::QuadratureRule (std::string name, ReferenceShapes shape, UInt dimension, UInt degreeOfExactness, UInt nbQuadPt, ... ) :
88  M_pt ( nbQuadPt),
89  M_shape ( shape),
90  M_name ( name),
91  M_nbQuadPt ( nbQuadPt),
92  M_degOfExact ( degreeOfExactness),
93  M_dimension ( dimension)
94 {
95  ASSERT (dimension >= shapeDimension (shape), " Downgrading quadrature rule is forbidden ");
96 
97  va_list quadList;
98  va_start (quadList, nbQuadPt);
99  for (UInt iterArg (0); iterArg < nbQuadPt; ++iterArg)
100  {
101  GeoVector nextPoint (dimension);
102  for (UInt i (0); i < dimension ; ++i)
103  {
104  nextPoint[i] = va_arg (quadList, Real);
105  };
106  M_pt[iterArg] = QuadraturePoint (nextPoint, va_arg (quadList, double) );
107  }
108  va_end (quadList);
109 }
110 
112 {
113 }
114 
115 // ===================================================
116 // Operators
117 // ===================================================
118 
119 
120 std::ostream& operator << ( std::ostream& c, const QuadratureRule& qr )
121 {
122  c << " name: " << qr.M_name << std::endl;
123  c << " shape:" << ( int ) qr.M_shape << std::endl;
124  c << " nbQuadPt: " << qr.M_nbQuadPt << std::endl;
125  c << " Points: \n";
126  for ( UInt i (0); i < qr.M_nbQuadPt; ++i )
127  {
128  c << qr.M_pt[ i ] << std::endl;
129  }
130  return c;
131 }
132 
133 // ===================================================
134 // Methods
135 // ===================================================
136 
137 
138 void QuadratureRule::showMe ( std::ostream& output) const
139 {
140  output << " Name : " << M_name << std::endl;
141  output << " Shape : " << M_shape << std::endl;
142  output << " Size : " << M_nbQuadPt << std::endl;
143  output << " --- Points --- " << std::endl;
144  for (UInt i (0); i < M_nbQuadPt; ++i)
145  {
146  output << M_pt[i] << std::endl;
147  }
148 }
149 
151 {
152  switch (M_shape)
153  {
154  case LINE:
156  break;
157 
158  case TRIANGLE:
160  break;
161 
162  case TETRA:
163  return checkExactnessTetra();
164  break;
165 
166  default:
167  std::cerr << " No check for this shape ..." << std::endl;
168  return 0;
169  }
170 }
171 
172 void QuadratureRule::vtkExport ( const std::string& filename) const
173 {
174  std::ofstream output (filename.c_str() );
175  ASSERT (!output.fail(), " Unable to open the file for the export of the quadrature ");
176 
177  // Header
178  output << "# vtk DataFile Version 3.0" << std::endl;
179  output << "LifeV : Quadrature export" << std::endl;
180  output << "ASCII" << std::endl;
181  output << "DATASET POLYDATA" << std::endl;
182  output << "POINTS " << M_nbQuadPt << " float" << std::endl;
183 
184  for (UInt i (0); i < M_nbQuadPt; ++i)
185  {
186  output << M_pt[i].coor (0) << " " << M_pt[i].coor (1) << " " << M_pt[i].coor (2) << std::endl;
187  };
188 
189  output << "VERTICES " << M_nbQuadPt << " " << 2 * M_nbQuadPt << std::endl;
190 
191  for (UInt i (0); i < M_nbQuadPt; ++i)
192  {
193  output << 1 << " " << i << std::endl;
194  };
195 
196  output.close();
197 }
198 
199 // ===================================================
200 // Set Methods
201 // ===================================================
202 
203 void QuadratureRule::setPoints (const std::vector<QuadraturePoint>& pts)
204 {
205  M_pt.clear();
206  M_pt.resize (pts.size() );
207  for (UInt i (0); i < pts.size(); ++i)
208  {
209  M_pt[i] = QuadraturePoint (pts[i], M_dimension);
210  }
211 
212  M_nbQuadPt = pts.size();
213 }
214 
215 void QuadratureRule::setPoints (const std::vector<GeoVector>& coordinates, const std::vector<Real>& weights)
216 {
217  ASSERT (coordinates.size() == weights.size(), "Non matching length of the arguments");
218 
219  M_pt.clear();
220  M_pt.resize (coordinates.size() );
221  for (UInt i (0); i < M_pt.size(); ++i)
222  {
223  M_pt[i] = QuadraturePoint (coordinates[i], weights[i], M_dimension);
224  }
225 
226  M_nbQuadPt = M_pt.size();
227 }
228 
229 void QuadratureRule::setName (const std::string& newName)
230 {
231  M_name = newName;
232 }
233 
234 void QuadratureRule::setExactness (const UInt& exactness)
235 {
236  M_degOfExact = exactness;
237 }
238 
239 void QuadratureRule::setDimensionShape (const UInt& newDim, const ReferenceShapes& newShape)
240 {
241  ASSERT (newDim >= shapeDimension (newShape), " Impossible shape-dimension combinaison ");
242  M_dimension = newDim;
243  M_shape = newShape;
244 
245  // Change also the dimension of the points if they are already set!
246  for (UInt i (0); i < M_pt.size(); ++i)
247  {
248  M_pt[i] = QuadraturePoint (M_pt[i], newDim);
249  }
250 }
251 
252 // ===================================================
253 // Private Methods
254 // ===================================================
255 
257 {
258  // Degre 0: f=1 => exact value : 1/6
259  Real partialSum (0.0);
260 
261  for (UInt iterQ (0); iterQ < M_nbQuadPt; ++iterQ)
262  {
263  partialSum += weight (iterQ);
264  }
265 
266  if ( std::fabs (partialSum - 1.0 / 6.0) > S_exactnessTol)
267  {
268  return 0;
269  }
270 
271  // Degre 1: f=x+y+2z => exact value: 1/6
272  partialSum = 0.0;
273  for (UInt iterQ (0); iterQ < M_nbQuadPt; ++iterQ)
274  {
275  partialSum += (quadPointCoor (iterQ, 0) + quadPointCoor (iterQ, 1) + 2 * quadPointCoor (iterQ, 2) ) * weight (iterQ);
276  }
277 
278  if ( std::fabs (partialSum - 1.0 / 6.0) > S_exactnessTol)
279  {
280  return 0;
281  }
282 
283  // Degre 2: f=x*x + y*z + y*y => exact value: 1/24
284  partialSum = 0.0;
285  for (UInt iterQ (0); iterQ < M_nbQuadPt; ++iterQ)
286  {
287  partialSum += (quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 0)
288  + quadPointCoor (iterQ, 1) * quadPointCoor (iterQ, 2)
289  + quadPointCoor (iterQ, 1) * quadPointCoor (iterQ, 1)
290  ) * weight (iterQ);
291  }
292 
293  if ( std::fabs (partialSum - 1.0 / 24.0) > S_exactnessTol)
294  {
295  return 1;
296  }
297 
298  // Degre 3: f=x*x*x + y*y + y*y*z + x => exact value: 5/72
299  partialSum = 0.0;
300  for (UInt iterQ (0); iterQ < M_nbQuadPt; ++iterQ)
301  {
302  partialSum += (quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 0)
303  + quadPointCoor (iterQ, 1) * quadPointCoor (iterQ, 1)
304  + quadPointCoor (iterQ, 1) * quadPointCoor (iterQ, 1) * quadPointCoor (iterQ, 2)
305  + quadPointCoor (iterQ, 0)
306  ) * weight (iterQ);
307  }
308 
309  if ( std::fabs (partialSum - 5.0 / 72.0) > S_exactnessTol)
310  {
311  return 2;
312  }
313 
314  // Degre 4: f=x*x*x*x +y*y*z*z + z*z*z => exact value: 1/72
315  partialSum = 0.0;
316  for (UInt iterQ (0); iterQ < M_nbQuadPt; ++iterQ)
317  {
318  partialSum += (quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 0)
319  + quadPointCoor (iterQ, 1) * quadPointCoor (iterQ, 1) * quadPointCoor (iterQ, 2) * quadPointCoor (iterQ, 2)
320  + quadPointCoor (iterQ, 2) * quadPointCoor (iterQ, 2) * quadPointCoor (iterQ, 2)
321  ) * weight (iterQ);
322  }
323 
324  if ( std::fabs (partialSum - 1.0 / 72.0) > S_exactnessTol)
325  {
326  return 3;
327  }
328 
329  return 4;
330 
331 }
332 
334 {
335 
336  // Degre 0: f=1 => exact value : 1/2
337  Real partialSum (0.0);
338 
339  for (UInt iterQ (0); iterQ < M_nbQuadPt; ++iterQ)
340  {
341  partialSum += weight (iterQ);
342  }
343 
344  if ( std::fabs (partialSum - 0.5) > S_exactnessTol)
345  {
346  return 0;
347  }
348 
349  // Degre 1: f=x+y => exact value : 1/3
350  partialSum = 0.0;
351 
352  for (UInt iterQ (0); iterQ < M_nbQuadPt; ++iterQ)
353  {
354  partialSum += (quadPointCoor (iterQ, 0) + quadPointCoor (iterQ, 1) )
355  * weight (iterQ);
356  }
357 
358  if ( std::fabs (partialSum - 1.0 / 3.0) > S_exactnessTol)
359  {
360  return 0;
361  }
362 
363  // Degre 2: f=x*x+3*x*y => exact value : 5/24
364  partialSum = 0.0;
365 
366  for (UInt iterQ (0); iterQ < M_nbQuadPt; ++iterQ)
367  {
368  partialSum += (quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 0)
369  + 3 * quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 1) )
370  * weight (iterQ);
371  }
372 
373  if ( std::fabs (partialSum - 5.0 / 24.0) > S_exactnessTol)
374  {
375  return 1;
376  }
377 
378  // Degre 3: f=x*x*y-5*x*y => exact value :-23/120
379  partialSum = 0.0;
380 
381  for (UInt iterQ (0); iterQ < M_nbQuadPt; ++iterQ)
382  {
383  partialSum += (quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 1)
384  - 5 * quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 1) )
385  * weight (iterQ);
386  }
387 
388  if ( std::fabs (partialSum + 23.0 / 120.0) > S_exactnessTol)
389  {
390  return 2;
391  }
392 
393  // Degre 4: f=x*x*x*y - x*y*y + y*y*y*y => exact value : 1/40
394  partialSum = 0.0;
395 
396  for (UInt iterQ (0); iterQ < M_nbQuadPt; ++iterQ)
397  {
398  partialSum += (quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 1)
399  - quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 1) * quadPointCoor (iterQ, 1)
400  + quadPointCoor (iterQ, 1) * quadPointCoor (iterQ, 1) * quadPointCoor (iterQ, 1) * quadPointCoor (iterQ, 1) )
401  * weight (iterQ);
402  }
403 
404  if ( std::fabs (partialSum - 1.0 / 40.0) > S_exactnessTol)
405  {
406  return 3;
407  }
408 
409  // Degre 5: f= x^4*y - x*y^2 + y^5 => exact value : 1/84
410  partialSum = 0.0;
411 
412  for (UInt iterQ (0); iterQ < M_nbQuadPt; ++iterQ)
413  {
414  partialSum += ( std::pow (quadPointCoor (iterQ, 0), 4.0) * quadPointCoor (iterQ, 1)
415  - quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 1) * quadPointCoor (iterQ, 1)
416  + std::pow (quadPointCoor (iterQ, 1), 5.0)
417  ) * weight (iterQ);
418  }
419 
420  if ( std::fabs (partialSum - 1.0 / 84.0) > S_exactnessTol)
421  {
422  return 4;
423  }
424 
425 
426  return 5;
427 }
428 
430 {
431  // Degre 0: f=1 => exact value : 1
432  Real partialSum (0.0);
433 
434  for (UInt iterQ (0); iterQ < M_nbQuadPt; ++iterQ)
435  {
436  partialSum += weight (iterQ);
437  }
438 
439  if ( std::fabs (partialSum - 1.0) > S_exactnessTol)
440  {
441  return 0;
442  }
443 
444  // Degre 1: f=x => exact value: 1/2
445  partialSum = 0.0;
446  for (UInt iterQ (0); iterQ < M_nbQuadPt; ++iterQ)
447  {
448  partialSum += (quadPointCoor (iterQ, 0) ) * weight (iterQ);
449  }
450 
451  if ( std::fabs (partialSum - 1.0 / 2.0) > S_exactnessTol)
452  {
453  return 0;
454  }
455 
456  // Degre 2: f=x*x => exact value: 1/3
457  partialSum = 0.0;
458  for (UInt iterQ (0); iterQ < M_nbQuadPt; ++iterQ)
459  {
460  partialSum += (quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 0) ) * weight (iterQ);
461  }
462 
463  if ( std::fabs (partialSum - 1.0 / 3.0) > S_exactnessTol)
464  {
465  return 1;
466  }
467 
468  // Degre 3: f=x*x*x => exact value: 1/4
469  partialSum = 0.0;
470  for (UInt iterQ (0); iterQ < M_nbQuadPt; ++iterQ)
471  {
472  partialSum += (quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 0) ) * weight (iterQ);
473  }
474 
475  if ( std::fabs (partialSum - 1.0 / 4.0) > S_exactnessTol)
476  {
477  return 2;
478  }
479 
480  // Degre 4: f=x*x*x*x => exact value: 1/5
481  partialSum = 0.0;
482  for (UInt iterQ (0); iterQ < M_nbQuadPt; ++iterQ)
483  {
484  partialSum += (quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 0)
485  ) * weight (iterQ);
486  }
487 
488  if ( std::fabs (partialSum - 1.0 / 5.0) > S_exactnessTol)
489  {
490  return 3;
491  }
492 
493  // Degre 5: f=x*x*x*x*x => exact value: 1/6
494  partialSum = 0.0;
495  for (UInt iterQ (0); iterQ < M_nbQuadPt; ++iterQ)
496  {
497  partialSum += (quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 0)
498  * quadPointCoor (iterQ, 0) * quadPointCoor (iterQ, 0)
499  * quadPointCoor (iterQ, 0)
500  ) * weight (iterQ);
501  }
502 
503  if ( std::fabs (partialSum - 1.0 / 6.0) > S_exactnessTol)
504  {
505  return 4;
506  }
507 
508  return 5;
509 }
510 
511 
512 
513 }
UInt M_degOfExact
degree of exactness
const Real & weight(const UInt &ig) const
weight(ig) is the ig-th quadrature weight
UInt M_nbQuadPt
number of quadrature points
void setDimensionShape(const UInt &newDim, const ReferenceShapes &newShape)
Change the dimension and the shape.
UInt M_dimension
Dimension in which the quadrature is stored.
UInt checkExactnessTetra() const
Check the exactness for quadrature rules on tetrahedra.
virtual ~QuadratureRule()
Destructor.
boost::numeric::ublas::vector< Real > GeoVector
UInt checkExactness() const
Check for the exactness of the quadrature.
QuadratureRule(const QuadratureRule &qr)
Copy constructor.
void updateInverseJacobian(const UInt &iQuadPt)
ReferenceShapes M_shape
geometrical shape of the domain on which the quadrature rule can be used
UInt checkExactnessSegment() const
Check the exactness for quadrature rules on segments.
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
QuadratureRule(const QuadratureRule &qr, const UInt dim)
Copy constructor using a different dimension.
void vtkExport(const std::string &filename) const
VTK export for the quadrature.
QuadratureRule()
Empty constructor.
QuadraturePoint - Simple container for a point of a quadrature rule.
static Real S_exactnessTol
Tolerance for the test of exactness.
UInt checkExactnessTriangle() const
Check the exactness for quadrature rules on triangles.
double Real
Generic real data.
Definition: LifeV.hpp:175
std::string M_name
name of the quadrature rule
void setPoints(const std::vector< QuadraturePoint > &pts)
Change the quadrature points for the ones given here.
void showMe(std::ostream &output=std::cout) const
ShowMe method.
void setName(const std::string &newName)
Change the name of the quadrature.
void setPoints(const std::vector< GeoVector > &coordinates, const std::vector< Real > &weights)
Change the quadrature points for the one given here.
QuadratureRule - The basis class for storing and accessing quadrature rules.
void setExactness(const UInt &exactness)
Change the degree of exactness.
QuadratureRule(const QuadraturePoint *pt, int id, std::string name, ReferenceShapes shape, UInt nbQuadPt, UInt degOfExact)
Full constructor using pointers.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
const Real & quadPointCoor(const UInt &ig, const UInt &icoor) const
quadPointCoor(ig,icoor) is the coordinate icoor of the quadrature point ig
QuadratureRule(std::string name, ReferenceShapes shape, UInt dimension, UInt degreeOfExactness, UInt nbQuadPt,...)
Full constructor.