LifeV
IntegrateMatrixElement.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 IntegrateMatrixElement class.
31 
32  @date 06/2011
33  @author Samuel Quinodoz <samuel.quinodoz@epfl.ch>
34  */
35 
36 #ifndef INTEGRATE_MATRIX_ELEMENT_HPP
37 #define INTEGRATE_MATRIX_ELEMENT_HPP
38 
39 #ifdef _OPENMP
40 #include <omp.h>
41 #endif
42 
43 #include <lifev/core/LifeV.hpp>
44 
45 #include <lifev/core/util/OpenMPParameters.hpp>
46 
47 #include <lifev/core/fem/QuadratureRule.hpp>
48 #include <lifev/eta/fem/ETCurrentFE.hpp>
49 #include <lifev/eta/fem/MeshGeometricMap.hpp>
50 #include <lifev/eta/fem/QRAdapterBase.hpp>
51 
52 #include <lifev/eta/expression/ExpressionToEvaluation.hpp>
53 
54 #include <lifev/eta/array/ETMatrixElemental.hpp>
55 
56 #include <boost/shared_ptr.hpp>
57 #include <boost/scoped_ptr.hpp>
58 
59 
60 
61 namespace LifeV
62 {
63 
64 namespace ExpressionAssembly
65 {
66 
67 
68 //! The class to actually perform the loop over the elements to assemble a matrix
69 /*!
70  @author Samuel Quinodoz <samuel.quinodoz@epfl.ch>
71 
72  This class is used to store the data required for the assembly of a matrix and
73  perform that assembly with a loop over the elements, and then, for each elements,
74  using the Evaluation corresponding to the Expression (This convertion is done
75  within a typedef).
76  */
77 template < typename MeshType,
78  typename TestSpaceType,
79  typename SolutionSpaceType,
80  typename ExpressionType,
81  typename QRAdapterType >
82 
84 {
85 public:
86 
87  //! @name Public Types
88  //@{
89 
90  //! Type of the Evaluation
91  typedef typename ExpressionToEvaluation < ExpressionType,
92  TestSpaceType::field_dim,
93  SolutionSpaceType::field_dim,
94  MeshType::S_geoDimensions >::evaluation_Type evaluation_Type;
95 
96  //@}
97 
98 
99  //! @name Constructors, destructor
100  //@{
101 
102  //! Full data constructor
103  IntegrateMatrixElement (const std::shared_ptr<MeshType>& mesh,
104  const QRAdapterType& qrAdapter,
105  const std::shared_ptr<TestSpaceType>& testSpace,
106  const std::shared_ptr<SolutionSpaceType>& solutionSpace,
107  const ExpressionType& expression,
108  const UInt offsetUp = 0,
109  const UInt offsetLeft = 0,
110  const UInt regionFlag = 0,
111  const UInt numVolumeElements = 0,
112  const UInt * const volumeElements = nullptr,
113  const bool subDomain = false );
114 
115  //! Full data constructor
116  IntegrateMatrixElement (const std::shared_ptr<MeshType>& mesh,
117  const QRAdapterType& qrAdapter,
118  const std::shared_ptr<TestSpaceType>& testSpace,
119  const std::shared_ptr<SolutionSpaceType>& solutionSpace,
120  const ExpressionType& expression,
121  const OpenMPParameters& ompParams,
122  const UInt offsetUp = 0,
123  const UInt offsetLeft = 0,
124  const UInt regionFlag = 0,
125  const UInt numVolumeElements = 0,
126  const UInt * const volumeElements = nullptr,
127  const bool subDomain = false );
128 
129  //! Copy constructor
130  IntegrateMatrixElement (const IntegrateMatrixElement<MeshType, TestSpaceType, SolutionSpaceType, ExpressionType, QRAdapterType>& integrator);
131 
132  //! Destructor
134 
135  //@}
136 
137 
138  //! @name Operators
139  //@{
140 
141  //! Operator wrapping the addTo method
142  template <typename MatrixType>
143  inline void operator>> (MatrixType& mat)
144  {
145  if ( mat.filled() )
146  {
147  addToClosed (mat);
148  }
149  else
150  {
152  {
153  addTo (mat);
154  }
155  else
156  {
157  addToSubdomain(mat);
158  }
159  }
160  }
161 
162  //! Operator wrapping the addTo method (for shared_ptr)
163  template <typename MatrixType>
164  inline void operator>> (std::shared_ptr<MatrixType> mat)
165  {
166  if (mat->filled() )
167  {
168  addToClosed (mat);
169  }
170  else
171  {
173  {
174  addTo (mat);
175  }
176  else
177  {
178  addToSubdomain(mat);
179  }
180  }
181  }
182 
183  //@}
184 
185 
186  //! @name Methods
187  //@{
188 
189  //! Ouput method
190  void check (std::ostream& out = std::cout);
191 
192  //! Method that performs the assembly
193  /*!
194  The loop over the elements is located right
195  in this method. Everything for the assembly is then
196  performed: update the values, update the local matrix,
197  sum over the quadrature nodes, assemble in the global
198  matrix.
199  */
200  template <typename MatrixType>
201  void addTo (MatrixType& mat);
202 
203  template <typename MatrixType>
204  void addToSubdomain (MatrixType& mat);
205 
206  //! Method that performs the assembly
207  /*!
208  The loop over the elements is located right
209  in this method. Everything for the assembly is then
210  performed: update the values, update the local matrix,
211  sum over the quadrature nodes, assemble in the global
212  matrix.
213  The method is used for closed matrices
214  */
215  template <typename MatrixType>
216  void addToClosed (MatrixType& mat);
217 
218  //! Method that performs the assembly
219  /*!
220  The loop over the elements is located right
221  in this method. Everything for the assembly is then
222  performed: update the values, update the local matrix,
223  sum over the quadrature nodes, assemble in the global
224  matrix.
225 
226  Specialized for the case where the matrix is passed as a shared_ptr
227  */
228  template <typename MatrixType>
229  inline void addTo (std::shared_ptr<MatrixType> mat)
230  {
231  ASSERT (mat != 0, " Cannot assemble with an empty matrix");
232  addTo (*mat);
233  }
234 
235 
236  template <typename MatrixType>
237  inline void addToSubdomain (boost::shared_ptr<MatrixType> mat)
238  {
239  ASSERT (mat != 0, " Cannot assemble with an empty matrix");
240  addToSubdomain (*mat);
241  }
242 
243  //! Method that performs the assembly
244  /*!
245  The loop over the elements is located right
246  in this method. Everything for the assembly is then
247  performed: update the values, update the local matrix,
248  sum over the quadrature nodes, assemble in the global
249  matrix.
250  This method is used with closed matrices.
251 
252  Specialized for the case where the matrix is passed as a shared_ptr
253  */
254  template <typename MatrixType>
255  inline void addToClosed (std::shared_ptr<MatrixType> mat)
256  {
257  ASSERT (mat != 0, " Cannot assemble with an empty matrix");
258  addToClosed (*mat);
259  }
260 
261 
262  //@}
263 
264 private:
265 
266  //! @name Private Methods
267  //@{
268 
269  //! No empty constructor
271 
272  //! Perform the computations for a single element
273  /*!
274  * This method computes the elemental matrix for a given element
275  * index
276  */
277  void integrateElement (const UInt iElement,
278  const UInt nbQuadPt,
279  const UInt nbTestDof,
280  const UInt nbSolutionDof,
281  ETMatrixElemental& elementalMatrix,
282  evaluation_Type& evaluation,
283  ETCurrentFE<MeshType::S_geoDimensions, 1>& globalCFE,
284  ETCurrentFE<TestSpaceType::space_dim, TestSpaceType::field_dim>& testCFE,
285  ETCurrentFE<SolutionSpaceType::space_dim, SolutionSpaceType::field_dim>& solutionCFE);
286  //@}
287 
288  // Pointer on the mesh
290 
291  // Quadrature to be used
292  QRAdapterType M_qrAdapter;
293 
294  // Shared pointer on the Spaces
297 
298  // Tree to compute the values for the assembly
300 
301  ETCurrentFE<MeshType::S_geoDimensions, 1>* M_globalCFE_std;
302  ETCurrentFE<MeshType::S_geoDimensions, 1>* M_globalCFE_adapted;
303 
304  ETCurrentFE<TestSpaceType::space_dim, TestSpaceType::field_dim>* M_testCFE_std;
305  ETCurrentFE<TestSpaceType::space_dim, TestSpaceType::field_dim>* M_testCFE_adapted;
306 
307  ETCurrentFE<TestSpaceType::space_dim, SolutionSpaceType::field_dim>* M_solutionCFE_std;
308  ETCurrentFE<TestSpaceType::space_dim, SolutionSpaceType::field_dim>* M_solutionCFE_adapted;
309 
312 
313  // Data for multi-threaded assembly
315 
316  // Data for integration on one subRegion, flag and elements on which perform the integration
321 
322 };
323 
324 
325 // ===================================================
326 // IMPLEMENTATION
327 // ===================================================
328 
329 // ===================================================
330 // Constructors & Destructor
331 // ===================================================
332 
333 template < typename MeshType, typename TestSpaceType, typename SolutionSpaceType, typename ExpressionType, typename QRAdapterType>
334 IntegrateMatrixElement<MeshType, TestSpaceType, SolutionSpaceType, ExpressionType, QRAdapterType>::
335 IntegrateMatrixElement (const std::shared_ptr<MeshType>& mesh,
336  const QRAdapterType& qrAdapter,
337  const std::shared_ptr<TestSpaceType>& testSpace,
338  const std::shared_ptr<SolutionSpaceType>& solutionSpace,
339  const ExpressionType& expression,
340  const UInt offsetUp,
341  const UInt offsetLeft,
342  const UInt regionFlag,
343  const UInt numVolumeElements,
344  const UInt * const volumeElements,
345  const bool subDomain )
346  : M_mesh (mesh),
347  M_qrAdapter (qrAdapter),
350  M_evaluation (expression),
351 
354 
357 
358  M_offsetUp (offsetUp),
359  M_offsetLeft (offsetLeft),
361  M_regionFlag( regionFlag ),
362  M_numVolumeElements( numVolumeElements ),
363  M_volumeElements( volumeElements ),
364  M_integrateOnSubdomains( subDomain )
365 {
366  switch (MeshType::geoShape_Type::BasRefSha::S_shape)
367  {
368  case LINE:
369  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
370  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() ) ;
371  break;
372  case TRIANGLE:
373  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTriaP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
374  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTriaP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
375  break;
376  case QUAD:
377  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feQuadQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
378  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feQuadQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
379  break;
380  case TETRA:
381  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
382  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
383  break;
384  case HEXA:
385  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feHexaQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
386  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feHexaQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
387  break;
388  default:
389  ERROR_MSG ("Unrecognized element shape");
390  }
391  M_evaluation.setQuadrature (qrAdapter.standardQR() );
392  M_evaluation.setGlobalCFE (M_globalCFE_std);
393  M_evaluation.setTestCFE (M_testCFE_std);
394  M_evaluation.setSolutionCFE (M_solutionCFE_std);
395 }
396 
397 
398 template < typename MeshType, typename TestSpaceType, typename SolutionSpaceType, typename ExpressionType, typename QRAdapterType>
399 IntegrateMatrixElement<MeshType, TestSpaceType, SolutionSpaceType, ExpressionType, QRAdapterType>::
400 IntegrateMatrixElement (const std::shared_ptr<MeshType>& mesh,
401  const QRAdapterType& qrAdapter,
402  const std::shared_ptr<TestSpaceType>& testSpace,
403  const std::shared_ptr<SolutionSpaceType>& solutionSpace,
404  const ExpressionType& expression,
405  const OpenMPParameters& ompParams,
406  const UInt offsetUp,
407  const UInt offsetLeft,
408  const UInt regionFlag,
409  const UInt numVolumeElements,
410  const UInt * const volumeElements,
411  const bool subDomain )
412  : M_mesh (mesh),
413  M_qrAdapter (qrAdapter),
416  M_evaluation (expression),
419 
422 
423  M_offsetUp (offsetUp),
424  M_offsetLeft (offsetLeft),
425  M_ompParams (ompParams),
426  M_regionFlag( regionFlag ),
427  M_numVolumeElements(numVolumeElements),
428  M_volumeElements( volumeElements ),
429  M_integrateOnSubdomains( subDomain )
430 {
431  switch (MeshType::geoShape_Type::BasRefSha::S_shape)
432  {
433  case LINE:
434  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feSegP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
435  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feSegP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
436  break;
437  case TRIANGLE:
438  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTriaP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
439  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTriaP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
440  break;
441  case QUAD:
442  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feQuadQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
443  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feQuadQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
444  break;
445  case TETRA:
446  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
447  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
448  break;
449  case HEXA:
450  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feHexaQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
451  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feHexaQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() );
452  break;
453  default:
454  ERROR_MSG ("Unrecognized element shape");
455  }
456  M_evaluation.setQuadrature (qrAdapter.standardQR() );
457  M_evaluation.setGlobalCFE (M_globalCFE_std);
458  M_evaluation.setTestCFE (M_testCFE_std);
459  M_evaluation.setSolutionCFE (M_solutionCFE_std);
460 }
461 
462 
463 
464 template < typename MeshType, typename TestSpaceType, typename SolutionSpaceType, typename ExpressionType, typename QRAdapterType>
465 IntegrateMatrixElement<MeshType, TestSpaceType, SolutionSpaceType, ExpressionType, QRAdapterType>::
466 IntegrateMatrixElement (const IntegrateMatrixElement<MeshType, TestSpaceType, SolutionSpaceType, ExpressionType, QRAdapterType>& integrator)
468  M_qrAdapter (integrator.M_qrAdapter),
471  M_evaluation (integrator.M_evaluation),
472 
475 
478 
479  M_offsetUp (integrator.M_offsetUp),
480  M_offsetLeft (integrator.M_offsetLeft),
481 
482  M_ompParams (integrator.M_ompParams),
483  M_regionFlag( integrator.M_regionFlag ),
484  M_numVolumeElements( integrator.M_numVolumeElements ),
485  M_volumeElements( integrator.M_volumeElements ),
486  M_integrateOnSubdomains( integrator.M_integrateOnSubdomains )
487 {
488  switch (MeshType::geoShape_Type::BasRefSha::S_shape)
489  {
490  case LINE:
491  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feSegP0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
492  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feSegP0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
493  break;
494  case TRIANGLE:
495  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTriaP0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
496  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTriaP0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
497  break;
498  case QUAD:
499  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feQuadQ0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
500  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feQuadQ0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
501  break;
502  case TETRA:
503  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
504  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
505  break;
506  case HEXA:
507  M_globalCFE_std = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feHexaQ0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
508  M_globalCFE_adapted = new ETCurrentFE<MeshType::S_geoDimensions, 1> (feHexaQ0, geometricMapFromMesh<MeshType>(), integrator.M_qrAdapter.standardQR() );
509  break;
510  default:
511  ERROR_MSG ("Unrecognized element shape");
512  }
513  M_evaluation.setQuadrature (integrator.M_qrAdapter.standardQR() );
514  M_evaluation.setGlobalCFE (M_globalCFE_std);
515  M_evaluation.setTestCFE (M_testCFE_std);
516  M_evaluation.setSolutionCFE (M_solutionCFE_std);
517 }
518 
519 template < typename MeshType, typename TestSpaceType, typename SolutionSpaceType, typename ExpressionType, typename QRAdapterType>
520 IntegrateMatrixElement<MeshType, TestSpaceType, SolutionSpaceType, ExpressionType, QRAdapterType>::
522 {
523  delete M_globalCFE_std;
524  delete M_globalCFE_adapted;
525  delete M_testCFE_std;
526  delete M_testCFE_adapted;
527  delete M_solutionCFE_std;
528  delete M_solutionCFE_adapted;
529 // delete M_volumeElements;
530  M_volumeElements = nullptr;
531 }
532 
533 // ===================================================
534 // Methods
535 // ===================================================
536 
537 template < typename MeshType, typename TestSpaceType, typename SolutionSpaceType, typename ExpressionType, typename QRAdapterType>
538 void
539 IntegrateMatrixElement<MeshType, TestSpaceType, SolutionSpaceType, ExpressionType, QRAdapterType>::
540 check (std::ostream& out)
541 {
542  out << " Checking the integration : " << std::endl;
543  M_evaluation.display (out);
544  out << std::endl;
545 }
546 
547 template < typename MeshType, typename TestSpaceType, typename SolutionSpaceType, typename ExpressionType, typename QRAdapterType>
548 void
549 IntegrateMatrixElement<MeshType, TestSpaceType, SolutionSpaceType, ExpressionType, QRAdapterType>::
550 integrateElement (const UInt iElement, const UInt nbQuadPt,
551  const UInt nbTestDof, const UInt nbSolutionDof,
552  ETMatrixElemental& elementalMatrix,
553  evaluation_Type& evaluation,
554  ETCurrentFE<MeshType::S_geoDimensions, 1>& globalCFE,
555  ETCurrentFE<TestSpaceType::space_dim, TestSpaceType::field_dim>& testCFE,
556  ETCurrentFE<SolutionSpaceType::space_dim, SolutionSpaceType::field_dim>& solutionCFE)
557 {
558  // Zeros out the matrix
559  elementalMatrix.zero();
560 
561  evaluation.update (iElement);
562 
563  // Update the currentFEs
564  globalCFE.update (M_mesh->element (iElement), evaluation_Type::S_globalUpdateFlag | ET_UPDATE_WDET);
565  testCFE.update (M_mesh->element (iElement), evaluation_Type::S_testUpdateFlag);
566  solutionCFE.update (M_mesh->element (iElement), evaluation_Type::S_solutionUpdateFlag);
567 
568 
569  // Loop on the blocks
570 
571  for (UInt iblock (0); iblock < TestSpaceType::field_dim; ++iblock)
572  {
573  for (UInt jblock (0); jblock < SolutionSpaceType::field_dim; ++jblock)
574  {
575 
576  // Set the row global indices in the local matrix
577  for (UInt i (0); i < nbTestDof; ++i)
578  {
579  elementalMatrix.setRowIndex
580  (i + iblock * nbTestDof,
581  M_testSpace->dof().localToGlobalMap (iElement, i) + iblock * M_testSpace->dof().numTotalDof() + M_offsetUp);
582  }
583 
584  // Set the column global indices in the local matrix
585  for (UInt j (0); j < nbSolutionDof; ++j)
586  {
587  elementalMatrix.setColumnIndex
588  (j + jblock * nbSolutionDof,
589  M_solutionSpace->dof().localToGlobalMap (iElement, j) + jblock * M_solutionSpace->dof().numTotalDof() + M_offsetLeft);
590  }
591 
592  for (UInt iQuadPt (0); iQuadPt < nbQuadPt; ++iQuadPt)
593  {
594  for (UInt i (0); i < nbTestDof; ++i)
595  {
596  for (UInt j (0); j < nbSolutionDof; ++j)
597  {
598  elementalMatrix.element (i + iblock * nbTestDof, j + jblock * nbSolutionDof) +=
599  evaluation.value_qij (iQuadPt, i + iblock * nbTestDof, j + jblock * nbSolutionDof)
600  * globalCFE.wDet (iQuadPt);
601 
602  }
603  }
604  }
605  }
606  }
607 }
608 
609 
610 template < typename MeshType, typename TestSpaceType, typename SolutionSpaceType, typename ExpressionType, typename QRAdapterType>
611 template <typename MatrixType>
612 void
613 IntegrateMatrixElement<MeshType, TestSpaceType, SolutionSpaceType, ExpressionType, QRAdapterType>::
614 addTo (MatrixType& mat)
615 {
616  UInt nbElements (M_mesh->numElements() );
617  //UInt nbQuadPt_std (M_qrAdapter.standardQR().nbQuadPt() );
618  UInt nbTestDof (M_testSpace->refFE().nbDof() );
619  UInt nbSolutionDof (M_solutionSpace->refFE().nbDof() );
620 
621  // TODO: Shall these be members or not? I think it depends on OMP
622  // globalCFE => if yes: move the above cases here
623  // elementalMatrix => if no, add back the member and remove the variable
624  // Including a copy of evaluation: if no, use the member
625 
626  ETMatrixElemental elementalMatrix (TestSpaceType::field_dim * M_testSpace->refFE().nbDof(),
627  SolutionSpaceType::field_dim * M_solutionSpace->refFE().nbDof() );
628 
629  evaluation_Type evaluation (M_evaluation);
630 
631  // Defaulted to true for security
632  bool isPreviousAdapted (true);
633 
634  for (UInt iElement (0); iElement < nbElements; ++iElement)
635  {
636 
637  elementalMatrix.zero();
638 
639  // Update the quadrature rule adapter
640  M_qrAdapter.update (iElement);
641 
642  if (M_qrAdapter.isAdaptedElement() )
643  {
644  // Set the quadrature rule everywhere
645  evaluation.setQuadrature ( M_qrAdapter.adaptedQR() );
646  M_globalCFE_adapted -> setQuadratureRule ( M_qrAdapter.adaptedQR() );
647  M_testCFE_adapted -> setQuadratureRule ( M_qrAdapter.adaptedQR() );
648  M_solutionCFE_adapted -> setQuadratureRule ( M_qrAdapter.adaptedQR() );
649 
650  // Reset the CurrentFEs in the evaluation
651  evaluation.setGlobalCFE ( M_globalCFE_adapted );
652  evaluation.setTestCFE ( M_testCFE_adapted );
653  evaluation.setSolutionCFE ( M_solutionCFE_adapted );
654 
655  integrateElement (iElement, M_qrAdapter.adaptedQR().nbQuadPt(), nbTestDof, nbSolutionDof,
656  elementalMatrix, evaluation, *M_globalCFE_adapted , //*globalCFE,
658 
659  isPreviousAdapted = true;
660 
661  }
662  else
663  {
664  // Change in the evaluation if needed
665  if (isPreviousAdapted)
666  {
667  M_evaluation.setQuadrature ( M_qrAdapter.standardQR() );
668  M_evaluation.setGlobalCFE ( M_globalCFE_std );
669  M_evaluation.setTestCFE ( M_testCFE_std );
670  M_evaluation.setSolutionCFE ( M_solutionCFE_std );
671 
672  isPreviousAdapted = false;
673  }
674 
675  integrateElement (iElement, M_qrAdapter.standardQR().nbQuadPt(), nbTestDof, nbSolutionDof,
676  elementalMatrix, evaluation, *M_globalCFE_std , //*globalCFE,
678 
679  }
680 
681  elementalMatrix.pushToGlobal (mat);
682  }
683 }
684 
685 template < typename MeshType, typename TestSpaceType, typename SolutionSpaceType, typename ExpressionType, typename QRAdapterType>
686 template <typename MatrixType>
687 void
688 IntegrateMatrixElement<MeshType, TestSpaceType, SolutionSpaceType, ExpressionType, QRAdapterType>::
689 addToClosed (MatrixType& mat)
690 {
691  UInt nbElements (M_mesh->numElements() );
692  //UInt nbQuadPt (M_qrAdapter.standardQR().nbQuadPt() );
693  UInt nbTestDof (M_testSpace->refFE().nbDof() );
694  UInt nbSolutionDof (M_solutionSpace->refFE().nbDof() );
695 
696  // OpenMP setup and pragmas around the loop
698 
699  #pragma omp parallel
700  {
701  QRAdapterType qrAdapter (M_qrAdapter);
702 
703 
704  // Update the currentFEs
705  std::unique_ptr<ETCurrentFE<MeshType::S_geoDimensions, 1> > globalCFE_std;
706  std::unique_ptr<ETCurrentFE<MeshType::S_geoDimensions, 1> > globalCFE_adapted;
707 
708  switch (MeshType::geoShape_Type::BasRefSha::S_shape)
709  {
710  case LINE:
711  globalCFE_std.reset ( new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() ) );
712  globalCFE_adapted.reset ( new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() ) );
713  break;
714  case TRIANGLE:
715  globalCFE_std.reset ( new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTriaP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() ) );
716  globalCFE_adapted.reset ( new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTriaP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() ) );
717  break;
718  case QUAD:
719  globalCFE_std.reset ( new ETCurrentFE<MeshType::S_geoDimensions, 1> (feQuadQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() ) );
720  globalCFE_adapted.reset ( new ETCurrentFE<MeshType::S_geoDimensions, 1> (feQuadQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() ) );
721  break;
722  case TETRA:
723  globalCFE_std.reset ( new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() ) );
724  globalCFE_adapted.reset ( new ETCurrentFE<MeshType::S_geoDimensions, 1> (feTetraP0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() ) );
725  break;
726  case HEXA:
727  globalCFE_std.reset ( new ETCurrentFE<MeshType::S_geoDimensions, 1> (feHexaQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() ) );
728  globalCFE_adapted.reset ( new ETCurrentFE<MeshType::S_geoDimensions, 1> (feHexaQ0, geometricMapFromMesh<MeshType>(), qrAdapter.standardQR() ) );
729  break;
730  default:
731  ERROR_MSG ("Unrecognized element shape");
732  }
733 
734  ETCurrentFE<TestSpaceType::space_dim, TestSpaceType::field_dim>
735  testCFE_std (M_testSpace->refFE(), M_testSpace->geoMap(), M_qrAdapter.standardQR() );
736 
737  ETCurrentFE<TestSpaceType::space_dim, TestSpaceType::field_dim>
738  testCFE_adapted (M_testSpace->refFE(), M_testSpace->geoMap(), M_qrAdapter.standardQR() );
739 
740 
741  ETCurrentFE<SolutionSpaceType::space_dim, SolutionSpaceType::field_dim>
742  solutionCFE_std (M_solutionSpace->refFE(), M_testSpace->geoMap(),
743  M_qrAdapter.standardQR() );
744 
745  ETCurrentFE<SolutionSpaceType::space_dim, SolutionSpaceType::field_dim>
746  solutionCFE_adapted (M_solutionSpace->refFE(), M_testSpace->geoMap(),
747  M_qrAdapter.standardQR() );
748 
749  evaluation_Type evaluation (M_evaluation);
750  // Update the evaluation is done within the if statement
751  /*
752  evaluation.setQuadrature (M_qrAdapter.standardQR());
753  evaluation.setGlobalCFE (&(*globalCFE));
754  evaluation.setTestCFE (&testCFE);
755  evaluation.setSolutionCFE (&solutionCFE);
756  */
757 
758  ETMatrixElemental elementalMatrix (TestSpaceType::field_dim * M_testSpace->refFE().nbDof(),
759  SolutionSpaceType::field_dim * M_solutionSpace->refFE().nbDof() );
760 
761  // Defaulted to true for security
762  bool isPreviousAdapted (true);
763 
764  #pragma omp for schedule(runtime)
765  for (UInt iElement = 0; iElement < nbElements; ++iElement)
766  {
767  // Update the quadrature rule adapter
768  qrAdapter.update (iElement);
769 
770  // TODO: move QRule choice inside a common method for AddTo and AddToClosed
771  // TODO: Remove the members repeated here
772  // TODO: use a policy to say if: 1) matrix open/closed (with graph) 2) with or without QR adapter
773 
774  if (qrAdapter.isAdaptedElement() )
775  {
776  // Set the quadrature rule everywhere
777  evaluation.setQuadrature ( qrAdapter.adaptedQR() );
778  globalCFE_adapted -> setQuadratureRule ( qrAdapter.adaptedQR() );
779  testCFE_adapted.setQuadratureRule ( qrAdapter.adaptedQR() );
780  solutionCFE_adapted. setQuadratureRule ( qrAdapter.adaptedQR() );
781 
782  // Reset the CurrentFEs in the evaluation
783  evaluation.setGlobalCFE ( globalCFE_adapted.get() );
784  evaluation.setTestCFE ( &testCFE_adapted );
785  evaluation.setSolutionCFE ( &solutionCFE_adapted );
786 
787  integrateElement (iElement, qrAdapter.adaptedQR().nbQuadPt(), nbTestDof, nbSolutionDof,
788  elementalMatrix, evaluation, *globalCFE_adapted ,
789  testCFE_adapted, solutionCFE_adapted);
790 
791  isPreviousAdapted = true;
792 
793  }
794  else
795  {
796  // Change in the evaluation if needed
797  if (isPreviousAdapted)
798  {
799  evaluation.setQuadrature ( qrAdapter.standardQR() );
800  evaluation.setGlobalCFE ( globalCFE_std.get() );
801  evaluation.setTestCFE ( &testCFE_std );
802  evaluation.setSolutionCFE ( &solutionCFE_std );
803 
804  isPreviousAdapted = false;
805  }
806 
807  integrateElement (iElement, M_qrAdapter.standardQR().nbQuadPt(), nbTestDof, nbSolutionDof,
808  elementalMatrix, evaluation, *globalCFE_std ,
809  testCFE_std, solutionCFE_std);
810 
811  }
812 
813  elementalMatrix.pushToGlobal (mat);
814  }
815 
817  }
818 }
819 
820 
821 
822 
823 template < typename MeshType, typename TestSpaceType, typename SolutionSpaceType, typename ExpressionType, typename QRAdapterType>
824 template <typename MatrixType>
825 void
826 IntegrateMatrixElement<MeshType, TestSpaceType, SolutionSpaceType, ExpressionType, QRAdapterType>::
827 addToSubdomain ( MatrixType& mat )
828 {
829  UInt nbElements ( M_numVolumeElements );
830  //UInt nbQuadPt_std (M_qrAdapter.standardQR().nbQuadPt() );
831  UInt nbTestDof (M_testSpace->refFE().nbDof() );
832  UInt nbSolutionDof (M_solutionSpace->refFE().nbDof() );
833 
834  ETMatrixElemental elementalMatrix (TestSpaceType::field_dim * M_testSpace->refFE().nbDof(),
835  SolutionSpaceType::field_dim * M_solutionSpace->refFE().nbDof() );
836 
837  evaluation_Type evaluation (M_evaluation);
838 
839  if( M_volumeElements != nullptr )
840  {
841 
842  std::stringstream convertNumbEl;
843  convertNumbEl << nbElements;
844 
845  // Defaulted to true for security
846  bool isPreviousAdapted (true);
847 
848  for (UInt iVolumeElement (0); iVolumeElement < nbElements; ++iVolumeElement)
849  {
850 
851  UInt iElement = M_volumeElements[iVolumeElement];
852 
853  // Extracting the marker
854  // UInt markerID = M_testSpace->mesh()->element ( iElement ).markerID( );
855 
856  // Update the quadrature rule adapter
857  M_qrAdapter.update (iElement);
858 
859  if (M_qrAdapter.isAdaptedElement() )
860  {
861  // Set the quadrature rule everywhere
862  evaluation.setQuadrature ( M_qrAdapter.adaptedQR() );
863  M_globalCFE_adapted -> setQuadratureRule ( M_qrAdapter.adaptedQR() );
864  M_testCFE_adapted -> setQuadratureRule ( M_qrAdapter.adaptedQR() );
865  M_solutionCFE_adapted -> setQuadratureRule ( M_qrAdapter.adaptedQR() );
866 
867  // Reset the CurrentFEs in the evaluation
868  evaluation.setGlobalCFE ( M_globalCFE_adapted );
869  evaluation.setTestCFE ( M_testCFE_adapted );
870  evaluation.setSolutionCFE ( M_solutionCFE_adapted );
871 
872  integrateElement (iElement, M_qrAdapter.adaptedQR().nbQuadPt(), nbTestDof, nbSolutionDof,
873  elementalMatrix, evaluation, *M_globalCFE_adapted , //*globalCFE,
875 
876  isPreviousAdapted = true;
877 
878  }
879  else
880  {
881  // Change in the evaluation if needed
882  if (isPreviousAdapted)
883  {
884  M_evaluation.setQuadrature ( M_qrAdapter.standardQR() );
885  M_evaluation.setGlobalCFE ( M_globalCFE_std );
886  M_evaluation.setTestCFE ( M_testCFE_std );
887  M_evaluation.setSolutionCFE ( M_solutionCFE_std );
888 
889  isPreviousAdapted = false;
890  }
891 
892  integrateElement (iElement, M_qrAdapter.standardQR().nbQuadPt(), nbTestDof, nbSolutionDof,
893  elementalMatrix, evaluation, *M_globalCFE_std , //*globalCFE,
895 
896  }
897 
898  elementalMatrix.pushToGlobal (mat);
899  }
900 
901  }
902 
903 }
904 
905 
906 
907 
908 
909 
910 
911 } // Namespace ExpressionAssembly
912 
913 } // Namespace LifeV
914 
915 #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 addTo(std::shared_ptr< MatrixType > mat)
Method that performs the assembly.
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)
The class to actually perform the loop over the elements to assemble a matrix.
ExpressionToEvaluation< ExpressionType, TestSpaceType::field_dim, SolutionSpaceType::field_dim, MeshType::S_geoDimensions >::evaluation_Type evaluation_Type
Type of the Evaluation.
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)
IntegrateMatrixElement(const std::shared_ptr< MeshType > &mesh, const QRAdapterType &qrAdapter, const std::shared_ptr< TestSpaceType > &testSpace, const std::shared_ptr< SolutionSpaceType > &solutionSpace, const ExpressionType &expression, const OpenMPParameters &ompParams, const UInt offsetUp=0, const UInt offsetLeft=0, const UInt regionFlag=0, const UInt numVolumeElements=0, const UInt *const volumeElements=nullptr, const bool subDomain=false)
Full data constructor.
ETCurrentFE< MeshType::S_geoDimensions, 1 > * M_globalCFE_adapted
OpenMP parameter class.
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)
void integrateElement(const UInt iElement, const UInt nbQuadPt, const UInt nbTestDof, const UInt nbSolutionDof, ETMatrixElemental &elementalMatrix, evaluation_Type &evaluation, ETCurrentFE< MeshType::S_geoDimensions, 1 > &globalCFE, ETCurrentFE< TestSpaceType::space_dim, TestSpaceType::field_dim > &testCFE, ETCurrentFE< SolutionSpaceType::space_dim, SolutionSpaceType::field_dim > &solutionCFE)
Perform the computations for a single element.
#define ERROR_MSG(A)
Definition: LifeAssert.hpp:69
ETCurrentFE< MeshType::S_geoDimensions, 1 > * M_globalCFE_std
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
IntegrateMatrixElement(const IntegrateMatrixElement< MeshType, TestSpaceType, SolutionSpaceType, ExpressionType, QRAdapterType > &integrator)
Copy constructor.
void addTo(MatrixType &mat)
Method that performs the assembly.
void zero()
Put zero all the data stored.
void addToClosed(std::shared_ptr< MatrixType > mat)
Method that performs the assembly.
void check(std::ostream &out=std::cout)
Ouput method.
class ExpressionToEvaluation A class to pass from an Expression (Tree) to the corresponding Evaluatio...
void addToClosed(MatrixType &mat)
Method that performs the assembly.
ETCurrentFE< TestSpaceType::space_dim, TestSpaceType::field_dim > * M_testCFE_std
void operator>>(std::shared_ptr< MatrixType > mat)
Operator wrapping the addTo method (for shared_ptr)
std::shared_ptr< SolutionSpaceType > M_solutionSpace
void addToSubdomain(boost::shared_ptr< MatrixType > mat)
ETCurrentFE< TestSpaceType::space_dim, SolutionSpaceType::field_dim > * M_solutionCFE_std
IntegrateMatrixElement(const std::shared_ptr< MeshType > &mesh, const QRAdapterType &qrAdapter, const std::shared_ptr< TestSpaceType > &testSpace, const std::shared_ptr< SolutionSpaceType > &solutionSpace, const ExpressionType &expression, const UInt offsetUp=0, const UInt offsetLeft=0, const UInt regionFlag=0, const UInt numVolumeElements=0, const UInt *const volumeElements=nullptr, const bool subDomain=false)
Full data constructor.
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)
void operator>>(MatrixType &mat)
Operator wrapping the addTo method.
ETCurrentFE< TestSpaceType::space_dim, SolutionSpaceType::field_dim > * M_solutionCFE_adapted
Real & element(const UInt &iloc, const UInt &jloc)
Setter for the value in the local position (iloc,jloc)
ETCurrentFE< TestSpaceType::space_dim, TestSpaceType::field_dim > * M_testCFE_adapted
class ETMatrixElemental A class for describing an elemental matrix
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191