LifeV
IntegrateMatrixVolumeID.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 IntegrateMatrixVolumeID class.
31 
32  @date 06/2011
33  @author Paolo Tricerri <paolo.tricerri@epfl.ch>
34  */
35 
36 #ifndef INTEGRATE_MATRIX_VOLUME_ID_HPP
37 #define INTEGRATE_MATRIX_VOLUME_ID_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/ETMatrixElemental.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 SolutionSpaceType,
73  typename ExpressionType,
74  typename QRAdapterType >
75 class IntegrateMatrixVolumeID
76 {
77 public:
78 
79  //! @name Public Types
80  //@{
81 
82  //! Type of the Evaluation
83  typedef typename ExpressionToEvaluation < ExpressionType,
84  TestSpaceType::field_dim,
85  SolutionSpaceType::field_dim,
86  3 >::evaluation_Type evaluation_Type;
87 
88  typedef typename MeshType::element_Type element_Type;
89 
90  typedef std::shared_ptr<std::vector<element_Type*> > vectorVolumesPtr_Type;
91  typedef std::shared_ptr<std::vector<UInt> > vectorIndexPtr_Type;
92 
93  //@}
94 
95 
96  //! @name Constructors, destructor
97  //@{
98 
99  //! Full data constructor
100  IntegrateMatrixVolumeID (const vectorVolumesPtr_Type volumeList,
101  const vectorIndexPtr_Type indexList,
102  const QRAdapterType& qrAdapter,
103  const std::shared_ptr<TestSpaceType>& testSpace,
104  const std::shared_ptr<SolutionSpaceType>& solutionSpace,
105  const ExpressionType& expression);
106 
107  //! Copy constructor
108  IntegrateMatrixVolumeID ( const IntegrateMatrixVolumeID < MeshType, TestSpaceType, SolutionSpaceType, ExpressionType, QRAdapterType>& integrator);
109 
110  //! Destructor
111  ~IntegrateMatrixVolumeID();
112 
113  //@}
114 
115 
116  //! @name Operator
117  //@{
118 
119  //! Operator wrapping the addTo method
120  template <typename MatrixType>
121  inline void operator>> (MatrixType& mat)
122  {
123  addTo (mat);
124  }
125 
126  //! Operator wrapping the addTo method (for shared_ptr)
127  template <typename MatrixType>
128  inline void operator>> (std::shared_ptr<MatrixType> mat)
129  {
130  addTo (mat);
131  }
132 
133  //@}
134 
135 
136  //! @name Methods
137  //@{
138 
139  //! Ouput method
140  void check (std::ostream& out = std::cout);
141 
142  //! Method that performs the assembly
143  /*!
144  The loop over the elements is located right
145  in this method. Everything for the assembly is then
146  performed: update the values, update the local vector,
147  sum over the quadrature nodes, assemble in the global
148  vector.
149  */
150  template <typename MatrixType>
151  void addTo (MatrixType& mat);
152 
153  template <typename MatrixType>
154  inline void addTo (std::shared_ptr<MatrixType> mat)
155  {
156  ASSERT (mat != 0, " Cannot assemble with an empty matrix");
157  addTo (*mat);
158  }
159 
160  //@}
161 
162 private:
163 
164  //! @name Private Methods
165  //@{
166 
167  // No default constructor
168  IntegrateMatrixVolumeID();
169 
170  //@}
171 
172  //List of volumes with a marker
173  vectorVolumesPtr_Type M_volumeList;
174  vectorIndexPtr_Type M_indexList;
175 
176  // Quadrature to be used
177  QRAdapterType M_qrAdapter;
178 
179  // Shared pointer on the Space
180  std::shared_ptr<TestSpaceType> M_testSpace;
181  std::shared_ptr<SolutionSpaceType> M_solutionSpace;
182 
183  // Tree to compute the values for the assembly
184  evaluation_Type M_evaluation;
185 
186  ETCurrentFE<3, 1>* M_globalCFE_std;
187  ETCurrentFE<3, 1>* M_globalCFE_adapted;
188 
189  ETCurrentFE<3, TestSpaceType::field_dim>* M_testCFE_std;
190  ETCurrentFE<3, TestSpaceType::field_dim>* M_testCFE_adapted;
191 
192  ETCurrentFE<3, SolutionSpaceType::field_dim>* M_solutionCFE_std;
193  ETCurrentFE<3, SolutionSpaceType::field_dim>* M_solutionCFE_adapted;
194 
195  ETMatrixElemental M_elementalMatrix;
196 };
197 
198 
199 // ===================================================
200 // IMPLEMENTATION
201 // ===================================================
202 
203 // ===================================================
204 // Constructors & Destructor
205 // ===================================================
206 
207 template < typename MeshType, typename TestSpaceType, typename SolutionSpaceType, typename ExpressionType, typename QRAdapterType>
208 IntegrateMatrixVolumeID<MeshType, TestSpaceType, SolutionSpaceType, ExpressionType, QRAdapterType>::
209 IntegrateMatrixVolumeID (const vectorVolumesPtr_Type volumeList,
210  const vectorIndexPtr_Type indexList,
211  const QRAdapterType& qrAdapter,
212  const std::shared_ptr<TestSpaceType>& testSpace,
213  const std::shared_ptr<SolutionSpaceType>& solutionSpace,
214  const ExpressionType& expression)
215  : M_volumeList ( volumeList ),
216  M_indexList ( indexList ),
217  M_qrAdapter (qrAdapter),
218  M_testSpace (testSpace),
219  M_solutionSpace (solutionSpace),
220  M_evaluation (expression),
221 
222  M_globalCFE_std (new ETCurrentFE<3, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() ) ),
223  M_globalCFE_adapted (new ETCurrentFE<3, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() ) ),
224 
225  M_testCFE_std (new ETCurrentFE<3, TestSpaceType::field_dim> (testSpace->refFE(), testSpace->geoMap(), qrAdapter.standardQR() ) ),
226  M_testCFE_adapted (new ETCurrentFE<3, TestSpaceType::field_dim> (testSpace->refFE(), testSpace->geoMap(), qrAdapter.standardQR() ) ),
227 
228  M_solutionCFE_std (new ETCurrentFE<3, SolutionSpaceType::field_dim> (solutionSpace->refFE(), testSpace->geoMap(), qrAdapter.standardQR() ) ),
229  M_solutionCFE_adapted (new ETCurrentFE<3, SolutionSpaceType::field_dim> (solutionSpace->refFE(), testSpace->geoMap(), qrAdapter.standardQR() ) ),
230 
231  M_elementalMatrix (TestSpaceType::field_dim * testSpace->refFE().nbDof(),
232  SolutionSpaceType::field_dim * solutionSpace->refFE().nbDof() )
233 {
234  M_evaluation.setQuadrature (qrAdapter.standardQR() );
235  M_evaluation.setGlobalCFE (M_globalCFE_std);
236  M_evaluation.setTestCFE (M_testCFE_std);
237  M_evaluation.setSolutionCFE (M_solutionCFE_std);
238 }
239 
240 template < typename MeshType, typename TestSpaceType, typename SolutionSpaceType, typename ExpressionType, typename QRAdapterType>
241 IntegrateMatrixVolumeID<MeshType, TestSpaceType, SolutionSpaceType, ExpressionType, QRAdapterType>::
242 IntegrateMatrixVolumeID (const IntegrateMatrixVolumeID<MeshType, TestSpaceType, SolutionSpaceType, ExpressionType, QRAdapterType>& integrator)
243  : M_volumeList (integrator.M_volumeList),
244  M_indexList (integrator.M_indexList),
245  M_qrAdapter (integrator.M_qrAdapter),
246  M_testSpace (integrator.M_testSpace),
247  M_solutionSpace (integrator.M_solutionSpace),
248  M_evaluation (integrator.M_evaluation),
249 
250  M_globalCFE_std (new ETCurrentFE<3, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() ) ),
251  M_globalCFE_adapted (new ETCurrentFE<3, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() ) ),
252 
253  M_testCFE_std (new ETCurrentFE<3, TestSpaceType::field_dim> (M_testSpace->refFE(), M_testSpace->geoMap(), integrator.M_qrAdapter.standardQR() ) ),
254  M_testCFE_adapted (new ETCurrentFE<3, TestSpaceType::field_dim> (M_testSpace->refFE(), M_testSpace->geoMap(), integrator.M_qrAdapter.standardQR() ) ),
255 
256  M_solutionCFE_std (new ETCurrentFE<3, SolutionSpaceType::field_dim> (M_solutionSpace->refFE(), M_solutionSpace->geoMap(), integrator.M_qrAdapter.standardQR() ) ),
257  M_solutionCFE_adapted (new ETCurrentFE<3, SolutionSpaceType::field_dim> (M_solutionSpace->refFE(), M_solutionSpace->geoMap(), integrator.M_qrAdapter.standardQR() )
258  ),
259 
260  M_elementalMatrix (integrator.M_elementalMatrix)
261 {
262  M_evaluation.setQuadrature (integrator.M_qrAdapter.standardQR() );
263  M_evaluation.setGlobalCFE (M_globalCFE_std);
264  M_evaluation.setTestCFE (M_testCFE_std);
265  M_evaluation.setSolutionCFE (M_solutionCFE_std);
266 }
267 
268 template < typename MeshType, typename TestSpaceType, typename SolutionSpaceType, typename ExpressionType, typename QRAdapterType>
269 IntegrateMatrixVolumeID<MeshType, TestSpaceType, SolutionSpaceType, ExpressionType, QRAdapterType>::
270 ~IntegrateMatrixVolumeID()
271 {
272  delete M_globalCFE_std;
273  delete M_globalCFE_adapted;
274  delete M_testCFE_std;
275  delete M_testCFE_adapted;
276  delete M_solutionCFE_std;
277  delete M_solutionCFE_adapted;
278 
279 }
280 
281 // ===================================================
282 // Methods
283 // ===================================================
284 
285 template < typename MeshType, typename TestSpaceType, typename SolutionSpaceType, typename ExpressionType, typename QRAdapterType>
286 void
287 IntegrateMatrixVolumeID<MeshType, TestSpaceType, SolutionSpaceType, ExpressionType, QRAdapterType>::
288 check (std::ostream& out)
289 {
290  out << " Checking the integration : " << std::endl;
291  M_evaluation.display (out);
292  out << std::endl;
293  out << " Elemental matrix : " << std::endl;
294  M_elementalMatrix.showMe (out);
295  out << std::endl;
296 }
297 
298 
299 template < typename MeshType, typename TestSpaceType, typename SolutionSpaceType, typename ExpressionType, typename QRAdapterType>
300 template <typename MatrixType>
301 void
302 IntegrateMatrixVolumeID<MeshType, TestSpaceType, SolutionSpaceType, ExpressionType, QRAdapterType>::
303 addTo (MatrixType& mat)
304 {
305  // Defaulted to true for security
306  bool isPreviousAdapted (true);
307 
308  //number of volumes
309  UInt nbElements ( (*M_volumeList).size() );
310  UInt nbIndexes ( (*M_indexList).size() );
311 
312  ASSERT ( nbElements == nbIndexes, "The number of indexes is different from the number of volumes!!!");
313 
314  UInt nbQuadPt_std (M_qrAdapter.standardQR().nbQuadPt() );
315  UInt nbTestDof (M_testSpace->refFE().nbDof() );
316  UInt nbSolutionDof (M_solutionSpace->refFE().nbDof() );
317 
318  for (UInt iElement (0); iElement < nbElements; ++iElement)
319  {
320  // Zeros out the matrix
321  M_elementalMatrix.zero();
322 
323  // Update the quadrature rule adapter
324  M_qrAdapter.update ( (*M_indexList) [iElement] );
325 
326  if (M_qrAdapter.isAdaptedElement() )
327  {
328  // Set the quadrature rule everywhere
329  M_evaluation.setQuadrature ( M_qrAdapter.adaptedQR() );
330  M_globalCFE_adapted -> setQuadratureRule ( M_qrAdapter.adaptedQR() );
331  M_testCFE_adapted -> setQuadratureRule ( M_qrAdapter.adaptedQR() );
332  M_solutionCFE_adapted -> setQuadratureRule ( M_qrAdapter.adaptedQR() );
333 
334  // Reset the CurrentFEs in the evaluation
335  M_evaluation.setGlobalCFE ( M_globalCFE_adapted );
336  M_evaluation.setTestCFE ( M_testCFE_adapted );
337  M_evaluation.setSolutionCFE ( M_solutionCFE_adapted );
338 
339  M_evaluation.update ( (*M_indexList) [iElement] );
340 
341  // Update the CurrentFEs
342  M_globalCFE_adapted->update (* ( (*M_volumeList) [iElement]), evaluation_Type::S_globalUpdateFlag | ET_UPDATE_WDET);
343  M_testCFE_adapted->update (* ( (*M_volumeList) [iElement]), evaluation_Type::S_testUpdateFlag);
344  M_solutionCFE_adapted->update (* ( (*M_volumeList) [iElement]), evaluation_Type::S_solutionUpdateFlag);
345 
346 
347  // Assembly
348  for (UInt iblock (0); iblock < TestSpaceType::field_dim; ++iblock)
349  {
350  for (UInt jblock (0); jblock < SolutionSpaceType::field_dim; ++jblock)
351  {
352 
353  // Set the row global indices in the local matrix
354  for (UInt i (0); i < nbTestDof; ++i)
355  {
356  M_elementalMatrix.setRowIndex
357  (i + iblock * nbTestDof,
358  M_testSpace->dof().localToGlobalMap ( (*M_indexList) [iElement], i) + iblock * M_testSpace->dof().numTotalDof() );
359  }
360 
361  // Set the column global indices in the local matrix
362  for (UInt j (0); j < nbSolutionDof; ++j)
363  {
364  M_elementalMatrix.setColumnIndex
365  (j + jblock * nbSolutionDof,
366  M_solutionSpace->dof().localToGlobalMap ( (*M_indexList) [iElement], j) + jblock * M_solutionSpace->dof().numTotalDof() );
367  }
368 
369  for (UInt iQuadPt (0); iQuadPt < M_qrAdapter.adaptedQR().nbQuadPt(); ++iQuadPt)
370  {
371  for (UInt i (0); i < nbTestDof; ++i)
372  {
373  for (UInt j (0); j < nbSolutionDof; ++j)
374  {
375  M_elementalMatrix.element (i + iblock * nbTestDof, j + jblock * nbSolutionDof) +=
376  M_evaluation.value_qij (iQuadPt, i + iblock * nbTestDof, j + jblock * nbSolutionDof)
377  * M_globalCFE_adapted->wDet (iQuadPt);
378 
379  }
380  }
381  }
382  }
383  }
384 
385  isPreviousAdapted = true;
386 
387  }
388  else
389  {
390  // Change in the evaluation if needed
391  if (isPreviousAdapted)
392  {
393  M_evaluation.setQuadrature ( M_qrAdapter.standardQR() );
394  M_evaluation.setGlobalCFE ( M_globalCFE_std );
395  M_evaluation.setTestCFE ( M_testCFE_std );
396  M_evaluation.setSolutionCFE ( M_solutionCFE_std );
397 
398  isPreviousAdapted = false;
399  }
400 
401  // Update the currentFEs
402  M_globalCFE_std->update (* ( (*M_volumeList) [iElement]), evaluation_Type::S_globalUpdateFlag | ET_UPDATE_WDET);
403  M_testCFE_std->update (* ( (*M_volumeList) [iElement]), evaluation_Type::S_testUpdateFlag);
404  M_solutionCFE_std->update (* ( (*M_volumeList) [iElement]), evaluation_Type::S_solutionUpdateFlag);
405 
406  // Update the evaluation
407  M_evaluation.update ( (*M_indexList) [iElement] );
408 
409  // Loop on the blocks
410 
411  for (UInt iblock (0); iblock < TestSpaceType::field_dim; ++iblock)
412  {
413  for (UInt jblock (0); jblock < SolutionSpaceType::field_dim; ++jblock)
414  {
415 
416  // Set the row global indices in the local matrix
417  for (UInt i (0); i < nbTestDof; ++i)
418  {
419  M_elementalMatrix.setRowIndex
420  (i + iblock * nbTestDof,
421  M_testSpace->dof().localToGlobalMap ( (*M_indexList) [iElement], i) + iblock * M_testSpace->dof().numTotalDof() );
422  }
423 
424  // Set the column global indices in the local matrix
425  for (UInt j (0); j < nbSolutionDof; ++j)
426  {
427  M_elementalMatrix.setColumnIndex
428  (j + jblock * nbSolutionDof,
429  M_solutionSpace->dof().localToGlobalMap ( (*M_indexList) [iElement], j) + jblock * M_solutionSpace->dof().numTotalDof() );
430  }
431 
432  for (UInt iQuadPt (0); iQuadPt < nbQuadPt_std; ++iQuadPt)
433  {
434  for (UInt i (0); i < nbTestDof; ++i)
435  {
436  for (UInt j (0); j < nbSolutionDof; ++j)
437  {
438  M_elementalMatrix.element (i + iblock * nbTestDof, j + jblock * nbSolutionDof) +=
439  M_evaluation.value_qij (iQuadPt, i + iblock * nbTestDof, j + jblock * nbSolutionDof)
440  * M_globalCFE_std->wDet (iQuadPt);
441 
442  }
443  }
444  }
445  }
446  }
447 
448  }
449 
450  M_elementalMatrix.pushToGlobal (mat);
451  }
452 }
453 
454 } // Namespace ExpressionAssembly
455 
456 } // Namespace LifeV
457 
458 #endif
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90