LifeV
IntegrateValueElement.hpp
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 the LifeV library
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
21  License along with this library; if not, see <http://www.gnu.org/licenses/>
22 
23 
24 *******************************************************************************
25 */
26 //@HEADER
27 
28 /*!
29  * @file
30  @brief This file contains the definition of the IntegrateValueElement class.
31 
32  @date 06/2011
33  @author Samuel Quinodoz <samuel.quinodoz@epfl.ch>
34  */
35 
36 #ifndef INTEGRATE_VALUE_ELEMENT_HPP
37 #define INTEGRATE_VALUE_ELEMENT_HPP
38 
39 #include <lifev/core/LifeV.hpp>
40 
41 #include <lifev/core/fem/QuadratureRule.hpp>
42 #include <lifev/eta/fem/ETCurrentFE.hpp>
43 #include <lifev/eta/fem/MeshGeometricMap.hpp>
44 #include <lifev/eta/fem/QRAdapterBase.hpp>
45 
46 #include <lifev/eta/expression/ExpressionToEvaluation.hpp>
47 
48 #include <boost/shared_ptr.hpp>
49 
50 
51 
52 namespace LifeV
53 {
54 
55 namespace ExpressionAssembly
56 {
57 
58 //! The class to actually perform the loop over the elements to compute a value
59 /*!
60  @author Samuel Quinodoz <samuel.quinodoz@epfl.ch>
61 
62  This class is used to store the data required for the integration of a value and
63  perform that assembly with a loop over the elements, and then, for each elements,
64  using the Evaluation corresponding to the Expression (This convertion is done
65  within a typedef).
66  */
67 template < typename MeshType, typename ExpressionType, typename QRAdapterType>
69 {
70 public:
71 
72  //! @name Public Types
73  //@{
74 
75  //! Evaluation type
76  typedef typename ExpressionToEvaluation < ExpressionType,
77  0,
78  0,
79  MeshType::S_geoDimensions >::evaluation_Type evaluation_Type;
80 
81  //@}
82 
83 
84  //! @name Constructors, destructor
85  //@{
86 
87  //! Full data constructor
88  IntegrateValueElement (const std::shared_ptr<MeshType>& mesh,
89  const QRAdapterType& qrAdapter,
90  const ExpressionType& expression);
91 
92  //! Copy constructor
93  IntegrateValueElement ( const IntegrateValueElement < MeshType, ExpressionType, QRAdapterType>& integrator);
94 
95  //! Destructor
97 
98  //@}
99 
100 
101  //! @name Operators
102  //@{
103 
104  //! Operator wrapping the addTo method
105  inline void operator>> (Real& value)
106  {
107  addTo (value);
108  }
109 
110  //@}
111 
112 
113  //! @name Methods
114  //@{
115 
116  //! Ouput method
117  void check (std::ostream& out = std::cout);
118 
119  //! Method that performs the assembly
120  /*!
121  The loop over the elements is located right
122  in this method. Everything for the assembly is then
123  performed: update the values, sum over the quadrature nodes,
124  sum into the global value.
125  */
126  void addTo (Real& value);
127 
128  //@}
129 
130 private:
131 
132  //! @name Private Methods
133  //@{
134 
135  //! No empty constructor
137 
138  //@}
139 
140  // Pointer on the mesh
142 
143  // Quadrature to be used
144  QRAdapterType M_qrAdapter;
145 
146  // Tree to compute the values for the assembly
148 
149  // CurrentFE for the unadapted quadrature
150  ETCurrentFE<MeshType::S_geoDimensions, 1>* M_globalCFE_std;
151 
152  // CurrentFE for the adapted quadrature
153  ETCurrentFE<MeshType::S_geoDimensions, 1>* M_globalCFE_adapted;
154 
155 };
156 
157 
158 // ===================================================
159 // IMPLEMENTATION
160 // ===================================================
161 
162 // ===================================================
163 // Constructors & Destructor
164 // ===================================================
165 
166 template < typename MeshType, typename ExpressionType, typename QRAdapterType>
167 IntegrateValueElement < MeshType, ExpressionType, QRAdapterType>::
168 IntegrateValueElement (const std::shared_ptr<MeshType>& mesh,
169  const QRAdapterType& qrAdapter,
170  const ExpressionType& expression)
171  : M_mesh (mesh),
172  M_qrAdapter (qrAdapter),
173  M_evaluation (expression)
174 
175 {
176  switch (MeshType::geoShape_Type::BasRefSha::S_shape)
177  {
178  case LINE:
179  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feSegP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
180  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feSegP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
181  break;
182  case TRIANGLE:
183  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTriaP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
184  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTriaP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
185  break;
186  case QUAD:
187  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feQuadQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
188  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feQuadQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
189  break;
190  case TETRA:
191  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
192  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
193  break;
194  case HEXA:
195  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feHexaQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
196  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feHexaQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
197  break;
198  default:
199  ERROR_MSG ("Unrecognized element shape");
200  }
201  M_evaluation.setQuadrature (qrAdapter.standardQR() );
202  M_evaluation.setGlobalCFE (M_globalCFE_std);
203 }
204 
205 
206 template < typename MeshType, typename ExpressionType, typename QRAdapterType>
207 IntegrateValueElement < MeshType, ExpressionType, QRAdapterType>::
208 IntegrateValueElement ( const IntegrateValueElement < MeshType, ExpressionType, QRAdapterType>& integrator)
210  M_qrAdapter (integrator.M_qrAdapter),
211  M_evaluation (integrator.M_evaluation)
212 {
213  switch (MeshType::geoShape_Type::BasRefSha::S_shape)
214  {
215  case LINE:
216  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feSegP0, geometricMapFromMesh<MeshType>(), M_qrAdapter.standardQR() );
217  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feSegP0, geometricMapFromMesh<MeshType>(), M_qrAdapter.standardQR() );
218  break;
219  case TRIANGLE:
220  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTriaP0, geometricMapFromMesh<MeshType>(), M_qrAdapter.standardQR() );
221  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTriaP0, geometricMapFromMesh<MeshType>(), M_qrAdapter.standardQR() );
222  break;
223  case QUAD:
224  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feQuadQ0, geometricMapFromMesh<MeshType>(), M_qrAdapter.standardQR() );
225  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feQuadQ0, geometricMapFromMesh<MeshType>(), M_qrAdapter.standardQR() );
226  break;
227  case TETRA:
228  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), M_qrAdapter.standardQR() );
229  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), M_qrAdapter.standardQR() );
230  break;
231  case HEXA:
232  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feHexaQ0, geometricMapFromMesh<MeshType>(), M_qrAdapter.standardQR() );
233  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feHexaQ0, geometricMapFromMesh<MeshType>(), M_qrAdapter.standardQR() );
234  break;
235  default:
236  ERROR_MSG ("Unrecognized element shape");
237 
238  }
239  M_evaluation.setQuadrature (M_qrAdapter.standardQR() );
240  M_evaluation.setGlobalCFE (M_globalCFE_std);
241 }
242 
243 
244 template < typename MeshType, typename ExpressionType, typename QRAdapterType>
245 IntegrateValueElement < MeshType, ExpressionType, QRAdapterType>::
247 {
248  delete M_globalCFE_std;
249  delete M_globalCFE_adapted;
250 }
251 
252 
253 // ===================================================
254 // Methods
255 // ===================================================
256 
257 template < typename MeshType, typename ExpressionType, typename QRAdapterType>
258 void
259 IntegrateValueElement < MeshType, ExpressionType, QRAdapterType>::
260 check (std::ostream& out)
261 {
262  out << " Checking the integration : " << std::endl;
263  M_evaluation.display (out);
264 }
265 
266 
267 template < typename MeshType, typename ExpressionType, typename QRAdapterType>
268 void
269 IntegrateValueElement < MeshType, ExpressionType, QRAdapterType>::
270 addTo (Real& value)
271 {
272  UInt nbElements (M_mesh->numElements() );
273  UInt nbQuadPt_std (M_qrAdapter.standardQR().nbQuadPt() );
274 
275  // This flag reports whether the previous element
276  // needed an adapted integration. It is set to true
277  // by default for security.
278  bool isPreviousAdapted (true);
279 
280  for (UInt iElement (0); iElement < nbElements; ++iElement)
281  {
282  // Update the quadrature adapter
283  M_qrAdapter.update (iElement);
284 
285  // Check if the current element needs an adapted
286  // quadrature rule.
287  if ( M_qrAdapter.isAdaptedElement() )
288  {
289 
290  // Set the adapted QR
291  M_evaluation.setQuadrature ( M_qrAdapter.adaptedQR() );
292  M_globalCFE_adapted->setQuadratureRule ( M_qrAdapter.adaptedQR() );
293 
294  // Set the right CFE (even if the previous one was
295  // adapted! The memory locations might have changed!
296  M_evaluation.setGlobalCFE ( M_globalCFE_adapted );
297 
298  // Update the currentFE
299  M_globalCFE_adapted->update (M_mesh->element (iElement), evaluation_Type::S_globalUpdateFlag | ET_UPDATE_WDET);
300 
301  // Update the evaluation
302  M_evaluation.update (iElement);
303 
304  // Make the assembly
305  for (UInt iQuadPt (0); iQuadPt < M_qrAdapter.adaptedQR().nbQuadPt(); ++iQuadPt)
306  {
307  value += M_evaluation.value_q (iQuadPt)
308  * M_globalCFE_adapted->wDet (iQuadPt);
309  }
310 
311  // Finally, set the flag
312  isPreviousAdapted = true;
313  }
314  else
315  {
316  // Check if the previous one was adapted
317  if (isPreviousAdapted)
318  {
319  M_evaluation.setQuadrature ( M_qrAdapter.standardQR() );
320  M_evaluation.setGlobalCFE ( M_globalCFE_std );
321  // Update the flag
322  isPreviousAdapted = false;
323  }
324 
325  // Update the currentFEs
326  M_globalCFE_std->update (M_mesh->element (iElement), evaluation_Type::S_globalUpdateFlag | ET_UPDATE_WDET);
327 
328  // Update the evaluation
329  M_evaluation.update (iElement);
330 
331 
332  // Make the assembly
333  for (UInt iQuadPt (0); iQuadPt < nbQuadPt_std; ++iQuadPt)
334  {
335  value += M_evaluation.value_q (iQuadPt)
336  * M_globalCFE_std->wDet (iQuadPt);
337  }
338  }
339  }
340 }
341 
342 
343 } // Namespace ExpressionAssembly
344 
345 } // Namespace LifeV
346 
347 #endif
const ReferenceFEScalar feHexaQ0("Lagrange Q0 on a hexaedra", FE_Q0_3D, HEXA, 0, 0, 0, 1, 1, 3, fct_Q0_3D, derfct_Q0_3D, der2fct_Q0_3D, refcoor_Q0_3D, STANDARD_PATTERN, &feQuadQ0, &lagrangianTransform)
void check(std::ostream &out=std::cout)
Ouput method.
const ReferenceFEScalar feSegP0("Lagrange P0 on a segment", FE_P0_1D, LINE, 0, 1, 0, 0, 1, 1, fct_P0_1D, derfct_P0_1D, der2fct_P0_1D, refcoor_P0_1D, STANDARD_PATTERN, &fePointP0, &lagrangianTransform)
ExpressionToEvaluation< ExpressionType, 0, 0, MeshType::S_geoDimensions >::evaluation_Type evaluation_Type
Evaluation type.
void operator>>(Real &value)
Operator wrapping the addTo method.
void updateInverseJacobian(const UInt &iQuadPt)
const ReferenceFEScalar feTetraP0("Lagrange P0 on a tetraedra", FE_P0_3D, TETRA, 0, 0, 0, 1, 1, 3, fct_P0_3D, derfct_P0_3D, der2fct_P0_3D, refcoor_P0_3D, STANDARD_PATTERN, &feTriaP0, &lagrangianTransform)
const ReferenceFEScalar feTriaP0("Lagrange P0 on a triangle", FE_P0_2D, TRIANGLE, 0, 0, 1, 0, 1, 2, fct_P0_2D, derfct_P0_2D, der2fct_P0_2D, refcoor_P0_2D, STANDARD_PATTERN, &feSegP0, &lagrangianTransform)
#define ERROR_MSG(A)
Definition: LifeAssert.hpp:69
IntegrateValueElement(const IntegrateValueElement< MeshType, ExpressionType, QRAdapterType > &integrator)
Copy constructor.
class ExpressionToEvaluation A class to pass from an Expression (Tree) to the corresponding Evaluatio...
double Real
Generic real data.
Definition: LifeV.hpp:175
ETCurrentFE< MeshType::S_geoDimensions, 1 > * M_globalCFE_std
const ReferenceFEScalar feQuadQ0("Lagrange Q0 on a quadrangle", FE_Q0_2D, QUAD, 0, 0, 1, 0, 1, 2, fct_Q0_2D, derfct_Q0_2D, der2fct_Q0_2D, refcoor_Q0_2D, STANDARD_PATTERN, &feSegP0, &lagrangianTransform)
ETCurrentFE< MeshType::S_geoDimensions, 1 > * M_globalCFE_adapted
IntegrateValueElement(const std::shared_ptr< MeshType > &mesh, const QRAdapterType &qrAdapter, const ExpressionType &expression)
Full data constructor.
The class to actually perform the loop over the elements to compute a value.
void addTo(Real &value)
Method that performs the assembly.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191