LifeV
IntegrateVectorVolumeID.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_VOLUMEID_HPP
37 #define INTEGRATE_VECTOR_VOLUMEID_HPP
38 
39 #include <lifev/core/LifeV.hpp>
40 
41 #include <lifev/core/fem/QuadratureRule.hpp>
42 #include <lifev/core/mesh/RegionMesh.hpp>
43 #include <lifev/eta/fem/ETCurrentFE.hpp>
44 #include <lifev/eta/fem/MeshGeometricMap.hpp>
45 #include <lifev/eta/fem/QRAdapterBase.hpp>
46 
47 #include <lifev/eta/expression/ExpressionToEvaluation.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,
71  typename TestSpaceType,
72  typename ExpressionType,
73  typename QRAdapterType >
74 class IntegrateVectorVolumeID
75 {
76 public:
77 
78  //! @name Public Types
79  //@{
80 
81  //! Type of the Evaluation
82  typedef typename ExpressionToEvaluation < ExpressionType,
83  TestSpaceType::field_dim,
84  0,
85  3 >::evaluation_Type evaluation_Type;
86 
87  typedef typename MeshType::element_Type element_Type;
88 
89 
90  typedef std::shared_ptr<std::vector<element_Type*> > vectorVolumesPtr_Type;
91  typedef std::shared_ptr<std::vector<UInt> > vectorIndexesPtr_Type;
92 
93  //@}
94 
95 
96  //! @name Constructors, destructor
97  //@{
98 
99  //! Full data constructor
100  IntegrateVectorVolumeID (const vectorVolumesPtr_Type volumeList,
101  const vectorIndexesPtr_Type indexList,
102  const QRAdapterType& qrAdapter,
103  const std::shared_ptr<TestSpaceType>& testSpace,
104  const ExpressionType& expression);
105 
106  //! Copy constructor
107  IntegrateVectorVolumeID ( const IntegrateVectorVolumeID < MeshType, TestSpaceType, ExpressionType, QRAdapterType>& integrator);
108 
109  //! Destructor
110  ~IntegrateVectorVolumeID();
111 
112  //@}
113 
114 
115  //! @name Operator
116  //@{
117 
118  //! Operator wrapping the addTo method
119  template <typename Vector>
120  inline void operator>> (Vector& vector)
121  {
122  addTo (vector);
123  }
124 
125  //! Operator wrapping the addTo method (for shared_ptr)
126  template <typename Vector>
127  inline void operator>> (std::shared_ptr<Vector> vector)
128  {
129  addTo (*vector);
130  }
131 
132 
133  //@}
134 
135  //! @name Methods
136  //@{
137 
138  //! Ouput method
139  void check (std::ostream& out = std::cout);
140 
141  //! Method that performs the assembly
142  /*!
143  The loop over the elements is located right
144  in this method. Everything for the assembly is then
145  performed: update the values, update the local vector,
146  sum over the quadrature nodes, assemble in the global
147  vector.
148  */
149  template <typename Vector>
150  void addTo (Vector& vec);
151 
152  //@}
153 
154 private:
155 
156  //! @name Private Methods
157  //@{
158 
159  // No default constructor
160  IntegrateVectorVolumeID();
161 
162  //@}
163 
164  //List of volumes with a marker
165  vectorVolumesPtr_Type M_volumeList;
166  vectorIndexesPtr_Type M_indexList;
167 
168  // Quadrature to be used
169  QRAdapterType M_qrAdapter;
170 
171  // Shared pointer on the Space
172  std::shared_ptr<TestSpaceType> M_testSpace;
173 
174  // Tree to compute the values for the assembly
175  evaluation_Type M_evaluation;
176 
177  ETCurrentFE<3, 1>* M_globalCFE_std;
178  ETCurrentFE<3, 1>* M_globalCFE_adapted;
179 
180  ETCurrentFE<3, TestSpaceType::field_dim>* M_testCFE_std;
181  ETCurrentFE<3, TestSpaceType::field_dim>* M_testCFE_adapted;
182 
183  ETVectorElemental M_elementalVector;
184 };
185 
186 
187 // ===================================================
188 // IMPLEMENTATION
189 // ===================================================
190 
191 // ===================================================
192 // Constructors & Destructor
193 // ===================================================
194 
195 template < typename MeshType, typename TestSpaceType, typename ExpressionType, typename QRAdapterType>
196 IntegrateVectorVolumeID < MeshType, TestSpaceType, ExpressionType, QRAdapterType>::
197 IntegrateVectorVolumeID (const vectorVolumesPtr_Type volumeList,
198  const vectorIndexesPtr_Type indexList,
199  const QRAdapterType& qrAdapter,
200  const std::shared_ptr<TestSpaceType>& testSpace,
201  const ExpressionType& expression)
202  : M_volumeList ( volumeList ),
203  M_indexList ( indexList ),
204  M_qrAdapter (qrAdapter),
205  M_testSpace (testSpace),
206  M_evaluation (expression),
207 
208  M_globalCFE_std (new ETCurrentFE<3, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() ) ),
209  M_globalCFE_adapted (new ETCurrentFE<3, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() ) ),
210 
211  M_testCFE_std (new ETCurrentFE<3, TestSpaceType::field_dim> (testSpace->refFE(), testSpace->geoMap(), qrAdapter.standardQR() ) ),
212  M_testCFE_adapted (new ETCurrentFE<3, TestSpaceType::field_dim> (testSpace->refFE(), testSpace->geoMap(), qrAdapter.standardQR() ) ),
213 
214  M_elementalVector (TestSpaceType::field_dim * testSpace->refFE().nbDof() )
215 {
216  M_evaluation.setQuadrature (qrAdapter.standardQR() );
217  M_evaluation.setGlobalCFE (M_globalCFE_std);
218  M_evaluation.setTestCFE (M_testCFE_std);
219 }
220 
221 
222 template <typename MeshType, typename TestSpaceType, typename ExpressionType, typename QRAdapterType>
223 IntegrateVectorVolumeID <MeshType, TestSpaceType, ExpressionType, QRAdapterType>::
224 IntegrateVectorVolumeID ( const IntegrateVectorVolumeID <MeshType, TestSpaceType, ExpressionType, QRAdapterType>& integrator)
225  : M_volumeList (integrator.M_volumeList),
226  M_indexList (integrator.M_indexList),
227  M_qrAdapter (integrator.M_qrAdapter),
228  M_testSpace (integrator.M_testSpace),
229  M_evaluation (integrator.M_evaluation),
230 
231  M_globalCFE_std (new ETCurrentFE<3, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() ) ),
232  M_globalCFE_adapted (new ETCurrentFE<3, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() ) ),
233 
234  M_testCFE_std (new ETCurrentFE<3, TestSpaceType::field_dim> (M_testSpace->refFE(), M_testSpace->geoMap(), integrator.M_qrAdapter.standardQR() ) ),
235  M_testCFE_adapted (new ETCurrentFE<3, TestSpaceType::field_dim> (M_testSpace->refFE(), M_testSpace->geoMap(), integrator.M_qrAdapter.standardQR() ) ),
236 
237  M_elementalVector (integrator.M_elementalVector)
238 {
239  M_evaluation.setQuadrature (integrator.M_qrAdapter.standardQR() );
240  M_evaluation.setGlobalCFE (M_globalCFE_std);
241  M_evaluation.setTestCFE (M_testCFE_std);
242 }
243 
244 
245 template < typename MeshType, typename TestSpaceType, typename ExpressionType, typename QRAdapterType>
246 IntegrateVectorVolumeID < MeshType, TestSpaceType, ExpressionType, QRAdapterType>::
247 ~IntegrateVectorVolumeID()
248 {
249  delete M_globalCFE_std;
250  delete M_globalCFE_adapted;
251  delete M_testCFE_std;
252  delete M_testCFE_adapted;
253 }
254 
255 // ===================================================
256 // Methods
257 // ===================================================
258 
259 template < typename MeshType, typename TestSpaceType, typename ExpressionType, typename QRAdapterType>
260 void
261 IntegrateVectorVolumeID <MeshType, TestSpaceType, ExpressionType, QRAdapterType>::
262 check (std::ostream& out)
263 {
264  out << " Checking the integration : " << std::endl;
265  M_evaluation.display (out);
266  out << std::endl;
267  out << " Elemental vector : " << std::endl;
268  M_elementalVector.showMe (out);
269  out << std::endl;
270 }
271 
272 template < typename MeshType, typename TestSpaceType, typename ExpressionType, typename QRAdapterType>
273 template <typename Vector>
274 void
275 IntegrateVectorVolumeID <MeshType, TestSpaceType, ExpressionType, QRAdapterType>::
276 addTo (Vector& vec)
277 {
278  // Defaulted to true for security
279  bool isPreviousAdapted (true);
280 
281  //number of volumes
282  UInt nbElements ( (*M_volumeList).size() );
283  UInt nbIndexes ( (*M_indexList).size() );
284 
285  ASSERT ( nbElements == nbIndexes, "The number of indexes is different from the number of volumes!!!");
286 
287  UInt nbQuadPt_std (M_qrAdapter.standardQR().nbQuadPt() );
288  UInt nbTestDof (M_testSpace->refFE().nbDof() );
289 
290  for (UInt iElement (0); iElement < nbElements; ++iElement)
291  {
292  // Zeros out the elemental vector
293  M_elementalVector.zero();
294 
295  // Update the quadrature rule adapter
296  M_qrAdapter.update ( (*M_indexList) [iElement] );
297 
298 
299  if (M_qrAdapter.isAdaptedElement() )
300  {
301  // Reset the quadrature in the different structures
302  M_evaluation.setQuadrature ( M_qrAdapter.adaptedQR() );
303  M_globalCFE_adapted -> setQuadratureRule ( M_qrAdapter.adaptedQR() );
304  M_testCFE_adapted -> setQuadratureRule ( M_qrAdapter.adaptedQR() );
305 
306  // Reset the CurrentFEs in the evaluation
307  M_evaluation.setGlobalCFE ( M_globalCFE_adapted );
308  M_evaluation.setTestCFE ( M_testCFE_adapted );
309 
310  // Update with the correct element
311  M_evaluation.update ( (*M_indexList) [iElement] );
312 
313  // Update the currentFEs
314  M_globalCFE_adapted->update (* ( (*M_volumeList) [iElement]), evaluation_Type::S_globalUpdateFlag | ET_UPDATE_WDET);
315  M_testCFE_adapted->update (* ( (*M_volumeList) [iElement]), evaluation_Type::S_testUpdateFlag);
316 
317 
318  // Assembly
319  for (UInt iblock (0); iblock < TestSpaceType::field_dim; ++iblock)
320  {
321  // Set the row global indices in the local vector
322  for (UInt i (0); i < nbTestDof; ++i)
323  {
324  M_elementalVector.setRowIndex
325  (i + iblock * nbTestDof,
326  M_testSpace->dof().localToGlobalMap ( (*M_indexList) [iElement], i) + iblock * M_testSpace->dof().numTotalDof() );
327  }
328 
329  // Make the assembly
330  for (UInt iQuadPt (0); iQuadPt < M_qrAdapter.adaptedQR().nbQuadPt(); ++iQuadPt)
331  {
332  for (UInt i (0); i < nbTestDof; ++i)
333  {
334  M_elementalVector.element (i + iblock * nbTestDof) +=
335  M_evaluation.value_qi (iQuadPt, i + iblock * nbTestDof)
336  * M_globalCFE_adapted->wDet (iQuadPt);
337 
338  }
339  }
340  }
341 
342  // Finally, set the flag
343  isPreviousAdapted = true;
344  }
345  else
346  {
347 
348  // Check if the last one was adapted
349  if (isPreviousAdapted)
350  {
351  M_evaluation.setQuadrature ( M_qrAdapter.standardQR() );
352  M_evaluation.setGlobalCFE ( M_globalCFE_std );
353  M_evaluation.setTestCFE ( M_testCFE_std );
354 
355  isPreviousAdapted = false;
356  }
357 
358 
359  // Update the currentFEs
360  M_globalCFE_std->update (* ( (*M_volumeList) [iElement]), evaluation_Type::S_globalUpdateFlag | ET_UPDATE_WDET);
361  M_testCFE_std->update (* ( (*M_volumeList) [iElement]), evaluation_Type::S_testUpdateFlag);
362 
363  // Update the evaluation
364  M_evaluation.update ( (*M_indexList) [iElement] );
365 
366  // Loop on the blocks
367  for (UInt iblock (0); iblock < TestSpaceType::field_dim; ++iblock)
368  {
369  // Set the row global indices in the local vector
370  for (UInt i (0); i < nbTestDof; ++i)
371  {
372  M_elementalVector.setRowIndex
373  (i + iblock * nbTestDof,
374  M_testSpace->dof().localToGlobalMap ( (*M_indexList) [iElement], i) + iblock * M_testSpace->dof().numTotalDof() );
375  }
376 
377  // Make the assembly
378  for (UInt iQuadPt (0); iQuadPt < nbQuadPt_std; ++iQuadPt)
379  {
380  for (UInt i (0); i < nbTestDof; ++i)
381  {
382  M_elementalVector.element (i + iblock * nbTestDof) +=
383  M_evaluation.value_qi (iQuadPt, i + iblock * nbTestDof) *
384  M_globalCFE_std->wDet (iQuadPt);
385 
386  }
387  }
388  }
389 
390  }
391  M_elementalVector.pushToGlobal (vec);
392  }
393 }
394 
395 
396 } // Namespace ExpressionAssembly
397 
398 } // Namespace LifeV
399 
400 #endif
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90