LifeV
IntegrateVectorElement.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 IntegrateVectorElement class.
31 
32  @date 06/2011
33  @author Samuel Quinodoz <samuel.quinodoz@epfl.ch>
34  */
35 
36 #ifndef INTEGRATE_VECTOR_ELEMENT_HPP
37 #define INTEGRATE_VECTOR_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 #include <lifev/eta/expression/EvaluationPhiI.hpp>
48 
49 #include <lifev/eta/array/ETVectorElemental.hpp>
50 
51 #include <boost/shared_ptr.hpp>
52 
53 
54 
55 namespace LifeV
56 {
57 
58 namespace ExpressionAssembly
59 {
60 
61 //! The class to actually perform the loop over the elements to assemble a vector
62 /*!
63  @author Samuel Quinodoz <samuel.quinodoz@epfl.ch>
64 
65  This class is used to store the data required for the assembly of a vector and
66  perform that assembly with a loop over the elements, and then, for each elements,
67  using the Evaluation corresponding to the Expression (this convertion is done
68  within a typedef).
69  */
70 template < typename MeshType, typename TestSpaceType, typename ExpressionType, typename QRAdapterType>
72 {
73 public:
74 
75  //! @name Public Types
76  //@{
77 
78  //! Type of the Evaluation
79  typedef typename ExpressionToEvaluation < ExpressionType,
80  TestSpaceType::field_dim,
81  0,
82  MeshType::S_geoDimensions >::evaluation_Type evaluation_Type;
83 
84  //@}
85 
86 
87  //! @name Constructors, destructor
88  //@{
89 
90  //! Full data constructor
91  IntegrateVectorElement (const std::shared_ptr<MeshType>& mesh,
92  const QRAdapterType& qrAdapter,
93  const std::shared_ptr<TestSpaceType>& testSpace,
94  const ExpressionType& expression,
95  const UInt offset = 0);
96 
97  //! Copy constructor
98  IntegrateVectorElement ( const IntegrateVectorElement < MeshType, TestSpaceType, ExpressionType, QRAdapterType>& integrator);
99 
100  //! Destructor
102 
103  //@}
104 
105 
106  //! @name Operator
107  //@{
108 
109  //! Operator wrapping the addTo method
110  template <typename VectorType>
111  inline void operator>> (VectorType& vector)
112  {
113  addTo (vector);
114  }
115 
116  //! Operator wrapping the addTo method (for shared_ptr)
117  template <typename VectorType>
118  inline void operator>> (std::shared_ptr<VectorType> vector)
119  {
120  addTo (*vector);
121  }
122 
123 
124  //@}
125 
126  //! @name Methods
127  //@{
128 
129  //! Ouput method
130  void check (std::ostream& out = std::cout);
131 
132  //! Method that performs the assembly
133  /*!
134  The loop over the elements is located right
135  in this method. Everything for the assembly is then
136  performed: update the values, update the local vector,
137  sum over the quadrature nodes, assemble in the global
138  vector.
139  */
140  template <typename VectorType>
141  void addTo (VectorType& vec);
142 
143  //@}
144 
145 private:
146 
147  //! @name Private Methods
148  //@{
149 
150  // No default constructor
152 
153  //@}
154 
155  // Pointer on the mesh
157 
158  // Quadrature to be used
159  QRAdapterType M_qrAdapter;
160 
161  // Shared pointer on the Space
163 
164  // Tree to compute the values for the assembly
166 
167  ETCurrentFE<MeshType::S_geoDimensions, 1>* M_globalCFE_std;
168  ETCurrentFE<MeshType::S_geoDimensions, 1>* M_globalCFE_adapted;
169 
170  ETCurrentFE<TestSpaceType::space_dim, TestSpaceType::field_dim>* M_testCFE_std;
171  ETCurrentFE<TestSpaceType::space_dim, TestSpaceType::field_dim>* M_testCFE_adapted;
172 
174 
175  // Offset
177 };
178 
179 
180 // ===================================================
181 // IMPLEMENTATION
182 // ===================================================
183 
184 // ===================================================
185 // Constructors & Destructor
186 // ===================================================
187 
188 template < typename MeshType, typename TestSpaceType, typename ExpressionType, typename QRAdapterType>
189 IntegrateVectorElement < MeshType, TestSpaceType, ExpressionType, QRAdapterType>::
190 IntegrateVectorElement (const std::shared_ptr<MeshType>& mesh,
191  const QRAdapterType& qrAdapter,
192  const std::shared_ptr<TestSpaceType>& testSpace,
193  const ExpressionType& expression,
194  const UInt offset)
195  : M_mesh (mesh),
196  M_qrAdapter (qrAdapter),
198  M_evaluation (expression),
199 
202 
204 
205  M_offset (offset)
206 {
207  switch (MeshType::geoShape_Type::BasRefSha::S_shape)
208  {
209  case LINE:
210  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feSegP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
211  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feSegP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
212  break;
213  case TRIANGLE:
214  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTriaP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
215  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTriaP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
216  break;
217  case QUAD:
218  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feQuadQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
219  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feQuadQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
220  break;
221  case TETRA:
222  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
223  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
224  break;
225  case HEXA:
226  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feHexaQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
227  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feHexaQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
228  break;
229  default:
230  ERROR_MSG ("Unrecognized element shape");
231  }
232  M_evaluation.setQuadrature ( qrAdapter.standardQR() );
233 
234  M_evaluation.setGlobalCFE (M_globalCFE_std);
235  M_evaluation.setTestCFE (M_testCFE_std);
236 }
237 
238 
239 template < typename MeshType, typename TestSpaceType, typename ExpressionType, typename QRAdapterType>
240 IntegrateVectorElement < MeshType, TestSpaceType, ExpressionType, QRAdapterType>::
241 IntegrateVectorElement ( const IntegrateVectorElement < MeshType, TestSpaceType, ExpressionType, QRAdapterType>& integrator)
243  M_qrAdapter (integrator.M_qrAdapter),
245  M_evaluation (integrator.M_evaluation),
246 
249 
251  M_offset (integrator.M_offset)
252 {
253  switch (MeshType::geoShape_Type::BasRefSha::S_shape)
254  {
255  case LINE:
256  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feSegP0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
257  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feSegP0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
258  break;
259  case TRIANGLE:
260  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTriaP0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
261  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTriaP0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
262  break;
263  case QUAD:
264  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feQuadQ0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
265  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feQuadQ0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
266  break;
267  case TETRA:
268  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
269  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
270  break;
271  case HEXA:
272  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feHexaQ0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
273  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feHexaQ0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
274  break;
275  default:
276  ERROR_MSG ("Unrecognized element shape");
277  }
278  M_evaluation.setQuadrature (integrator.M_qrAdapter.standardQR() );
279  M_evaluation.setGlobalCFE (M_globalCFE_std);
280  M_evaluation.setTestCFE (M_testCFE_std);
281 }
282 
283 
284 template < typename MeshType, typename TestSpaceType, typename ExpressionType, typename QRAdapterType>
285 IntegrateVectorElement < MeshType, TestSpaceType, ExpressionType, QRAdapterType>::
287 {
288  delete M_globalCFE_std;
289  delete M_globalCFE_adapted;
290  delete M_testCFE_std;
291  delete M_testCFE_adapted;
292 }
293 
294 // ===================================================
295 // Methods
296 // ===================================================
297 
298 template < typename MeshType, typename TestSpaceType, typename ExpressionType, typename QRAdapterType>
299 void
300 IntegrateVectorElement < MeshType, TestSpaceType, ExpressionType, QRAdapterType>::
301 check (std::ostream& out)
302 {
303  out << " Checking the integration : " << std::endl;
304  M_evaluation.display (out);
305  out << std::endl;
306  out << " Elemental vector : " << std::endl;
307  M_elementalVector.showMe (out);
308  out << std::endl;
309 }
310 
311 template < typename MeshType, typename TestSpaceType, typename ExpressionType, typename QRAdapterType>
312 template <typename VectorType>
313 void
314 IntegrateVectorElement < MeshType, TestSpaceType, ExpressionType, QRAdapterType>::
315 addTo (VectorType& vec)
316 {
317  UInt nbElements (M_mesh->numElements() );
318  UInt nbQuadPt_std (M_qrAdapter.standardQR().nbQuadPt() );
319  UInt nbTestDof (M_testSpace->refFE().nbDof() );
320 
321  // Defaulted to true for security
322  bool isPreviousAdapted (true);
323 
324  for (UInt iElement (0); iElement < nbElements; ++iElement)
325  {
326  // Zeros out the elemental vector
327  M_elementalVector.zero();
328 
329  // Update the quadrature rule adapter
330  M_qrAdapter.update (iElement);
331 
332 
333  if (M_qrAdapter.isAdaptedElement() )
334  {
335  // Reset the quadrature in the different structures
336  M_evaluation.setQuadrature ( M_qrAdapter.adaptedQR() );
337  M_globalCFE_adapted -> setQuadratureRule ( M_qrAdapter.adaptedQR() );
338  M_testCFE_adapted -> setQuadratureRule ( M_qrAdapter.adaptedQR() );
339 
340  // Reset the CurrentFEs in the evaluation
341  M_evaluation.setGlobalCFE ( M_globalCFE_adapted );
342  M_evaluation.setTestCFE ( M_testCFE_adapted );
343 
344  // Update with the correct element
345  M_evaluation.update (iElement);
346 
347  // Update the currentFEs
348  M_globalCFE_adapted->update (M_mesh->element (iElement), evaluation_Type::S_globalUpdateFlag | ET_UPDATE_WDET);
349  M_testCFE_adapted->update (M_mesh->element (iElement), evaluation_Type::S_testUpdateFlag);
350 
351 
352  // Assembly
353  for (UInt iblock (0); iblock < TestSpaceType::field_dim; ++iblock)
354  {
355  // Set the row global indices in the local vector
356  for (UInt i (0); i < nbTestDof; ++i)
357  {
358  M_elementalVector.setRowIndex
359  (i + iblock * nbTestDof,
360  M_testSpace->dof().localToGlobalMap (iElement, i) + iblock * M_testSpace->dof().numTotalDof() );
361  }
362 
363  // Make the assembly
364  for (UInt iQuadPt (0); iQuadPt < M_qrAdapter.adaptedQR().nbQuadPt(); ++iQuadPt)
365  {
366  for (UInt i (0); i < nbTestDof; ++i)
367  {
368  M_elementalVector.element (i + iblock * nbTestDof) +=
369  M_evaluation.value_qi (iQuadPt, i + iblock * nbTestDof)
370  * M_globalCFE_adapted->wDet (iQuadPt);
371 
372  }
373  }
374  }
375 
376  // Finally, set the flag
377  isPreviousAdapted = true;
378  }
379  else
380  {
381  // Check if the last one was adapted
382  if (isPreviousAdapted)
383  {
384  M_evaluation.setQuadrature ( M_qrAdapter.standardQR() );
385  M_evaluation.setGlobalCFE ( M_globalCFE_std );
386  M_evaluation.setTestCFE ( M_testCFE_std );
387 
388  isPreviousAdapted = false;
389  }
390 
391 
392  // Update the currentFEs
393  M_globalCFE_std->update (M_mesh->element (iElement), evaluation_Type::S_globalUpdateFlag | ET_UPDATE_WDET);
394  M_testCFE_std->update (M_mesh->element (iElement), evaluation_Type::S_testUpdateFlag);
395 
396  // Update the evaluation
397  M_evaluation.update (iElement);
398 
399  // Loop on the blocks
400  for (UInt iblock (0); iblock < TestSpaceType::field_dim; ++iblock)
401  {
402  // Set the row global indices in the local vector
403  for (UInt i (0); i < nbTestDof; ++i)
404  {
405  M_elementalVector.setRowIndex
406  (i + iblock * nbTestDof,
407  M_testSpace->dof().localToGlobalMap (iElement, i) + iblock * M_testSpace->dof().numTotalDof() + M_offset);
408  }
409 
410  // Make the assembly
411  for (UInt iQuadPt (0); iQuadPt < nbQuadPt_std; ++iQuadPt)
412  {
413  for (UInt i (0); i < nbTestDof; ++i)
414  {
415  M_elementalVector.element (i + iblock * nbTestDof) +=
416  M_evaluation.value_qi (iQuadPt, i + iblock * nbTestDof)
417  * M_globalCFE_std->wDet (iQuadPt);
418 
419  }
420  }
421  }
422 
423  }
424 
425  M_elementalVector.pushToGlobal (vec);
426  }
427 }
428 
429 
430 } // Namespace ExpressionAssembly
431 
432 } // Namespace LifeV
433 
434 #endif
void addTo(VectorType &vec)
Method that performs the assembly.
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)
class ETVectorElemental A class for describing an elemental vector
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)
ETCurrentFE< MeshType::S_geoDimensions, 1 > * M_globalCFE_std
ETCurrentFE< TestSpaceType::space_dim, TestSpaceType::field_dim > * M_testCFE_std
ETCurrentFE< MeshType::S_geoDimensions, 1 > * M_globalCFE_adapted
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
void operator>>(std::shared_ptr< VectorType > vector)
Operator wrapping the addTo method (for shared_ptr)
ETCurrentFE< TestSpaceType::space_dim, TestSpaceType::field_dim > * M_testCFE_adapted
class ExpressionToEvaluation A class to pass from an Expression (Tree) to the corresponding Evaluatio...
The class to actually perform the loop over the elements to assemble a vector.
void check(std::ostream &out=std::cout)
Ouput method.
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)
IntegrateVectorElement(const std::shared_ptr< MeshType > &mesh, const QRAdapterType &qrAdapter, const std::shared_ptr< TestSpaceType > &testSpace, const ExpressionType &expression, const UInt offset=0)
Full data constructor.
ExpressionToEvaluation< ExpressionType, TestSpaceType::field_dim, 0, MeshType::S_geoDimensions >::evaluation_Type evaluation_Type
Type of the Evaluation.
void operator>>(VectorType &vector)
Operator wrapping the addTo method.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
IntegrateVectorElement(const IntegrateVectorElement< MeshType, TestSpaceType, ExpressionType, QRAdapterType > &integrator)
Copy constructor.