LifeV
EvaluateNodalExpressionVectorElementFaceID.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 EVALUATENODALEXPRESSION_VECTOR_FACE_ID_HPP
37 #define EVALUATENODALEXPRESSION_VECTOR_FACE_ID_HPP
38 
39 #include <lifev/core/LifeV.hpp>
40 
41 #include <lifev/eta/fem/QuadratureBoundary.hpp>
42 #include <lifev/eta/fem/ETCurrentFE.hpp>
43 #include <lifev/eta/fem/ETCurrentBDFE.hpp>
44 #include <lifev/eta/fem/MeshGeometricMap.hpp>
45 
46 #include <lifev/eta/expression/ExpressionToEvaluation.hpp>
47 
48 #include <lifev/eta/array/ETVectorElemental.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 assemble a vector
59 /*!
60  @author Samuel Quinodoz <samuel.quinodoz@epfl.ch>
61 
62  This class is used to store the data required for the assembly of a vector 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 SolutionTestSpace, typename ExpressionType>
68 class EvaluateNodalExpressionVectorElementFaceID
69 {
70 public:
71 
72  //! @name Public Types
73  //@{
74 
75  //! Type of the Evaluation
76  typedef typename ExpressionToEvaluation < ExpressionType,
77  SolutionTestSpace::field_dim,
78  0,
79  3 >::evaluation_Type evaluation_Type;
80 
81  //@}
82 
83 
84  //! @name Constructors, destructor
85  //@{
86 
87  //! Full data constructor
88  EvaluateNodalExpressionVectorElementFaceID (const std::shared_ptr<MeshType>& mesh,
89  const UInt boundaryID,
90  const QuadratureBoundary& quadratureBD,
91  const std::shared_ptr<SolutionTestSpace>& testSpace,
92  const ExpressionType& expression);
93 
94  //! Copy constructor
95  EvaluateNodalExpressionVectorElementFaceID ( const EvaluateNodalExpressionVectorElementFaceID < MeshType, SolutionTestSpace, ExpressionType>& integrator);
96 
97  //! Destructor
98  ~EvaluateNodalExpressionVectorElementFaceID();
99 
100  //@}
101 
102 
103  //! @name Operator
104  //@{
105 
106  //! Operator wrapping the addTo method
107  template <typename VectorType>
108  inline void operator>> (VectorType& vector)
109  {
110  addTo (vector);
111  }
112 
113  //! Operator wrapping the addTo method (for shared_ptr)
114  template <typename VectorType>
115  inline void operator>> (std::shared_ptr<VectorType> vector)
116  {
117  addTo (*vector);
118  }
119 
120 
121  //@}
122 
123  //! @name Methods
124  //@{
125 
126  //! Ouput method
127  void check (std::ostream& out = std::cout);
128 
129  //! Method that performs the assembly
130  /*!
131  The loop over the elements is located right
132  in this method. Everything for the assembly is then
133  performed: update the values, update the local vector,
134  sum over the quadrature nodes, assemble in the global
135  vector.
136  */
137  template <typename VectorType>
138  void addTo (VectorType& vec);
139 
140  //@}
141 
142 private:
143 
144  //! @name Private Methods
145  //@{
146 
147  // No default constructor
148  EvaluateNodalExpressionVectorElementFaceID();
149 
150  //@}
151 
152  // Pointer on the mesh
153  std::shared_ptr<MeshType> M_mesh;
154 
155  // Identifier for the boundary
156  UInt M_boundaryId;
157 
158  // Quadrature to be used
159  QuadratureBoundary M_quadratureBoundary;
160 
161  // Shared pointer on the Space
162  std::shared_ptr<SolutionTestSpace> M_solutionSpace;
163 
164  // Tree to compute the values for the assembly
165  evaluation_Type M_evaluation;
166 
167  std::vector<ETCurrentBDFE<3>*> M_globalCFE;
168  std::vector<ETCurrentFE<3, SolutionTestSpace::field_dim>*> M_testCFE;
169 
170  ETVectorElemental M_elementalVector;
171 };
172 
173 
174 // ===================================================
175 // IMPLEMENTATION
176 // ===================================================
177 
178 // ===================================================
179 // Constructors & Destructor
180 // ===================================================
181 
182 template < typename MeshType, typename SolutionTestSpace, typename ExpressionType>
183 EvaluateNodalExpressionVectorElementFaceID < MeshType, SolutionTestSpace, ExpressionType>::
184 EvaluateNodalExpressionVectorElementFaceID (const std::shared_ptr<MeshType>& mesh,
185  const UInt boundaryID,
186  const QuadratureBoundary& quadratureBD,
187  const std::shared_ptr<SolutionTestSpace>& testSpace,
188  const ExpressionType& expression)
189  : M_mesh (mesh),
190  M_boundaryId (boundaryID),
191  M_quadratureBoundary (quadratureBD),
192  M_solutionSpace (testSpace),
193  M_evaluation (expression),
194 
195  M_globalCFE (4),
196  M_testCFE (4),
197 
198  M_elementalVector (SolutionTestSpace::field_dim * testSpace->refFE().nbDof() )
199 {
200  for (UInt i (0); i < 4; ++i)
201  {
202  M_globalCFE[i] = new ETCurrentBDFE<3> (geometricMapFromMesh<MeshType>()
203  , M_quadratureBoundary.qr (i) );
204  M_testCFE[i] = new ETCurrentFE<3, SolutionTestSpace::field_dim> (testSpace->refFE()
205  , testSpace->geoMap()
206  , M_quadratureBoundary.qr (i) );
207  }
208 
209  // Set the tangent on the different faces
210  std::vector< VectorSmall<3> > t0 (2, VectorSmall<3> (0.0, 0.0, 0.0) );
211  t0[0][0] = 1;
212  t0[0][1] = 0;
213  t0[0][2] = 0;
214  t0[1][0] = 0;
215  t0[1][1] = 1;
216  t0[1][2] = 0;
217  std::vector< VectorSmall<3> > t1 (2, VectorSmall<3> (0.0, 0.0, 0.0) );
218  t1[0][0] = 0;
219  t1[0][1] = 0;
220  t1[0][2] = 1;
221  t1[1][0] = 1;
222  t1[1][1] = 0;
223  t1[1][2] = 0;
224  std::vector< VectorSmall<3> > t2 (2, VectorSmall<3> (0.0, 0.0, 0.0) );
225  //t2[0][0]=-1/std::sqrt(6); t2[0][1]=-1/std::sqrt(6); t2[0][2]=2/std::sqrt(6);
226  //t2[1][0]=-1/std::sqrt(2); t2[1][1]=1/std::sqrt(2); t2[1][2]=0;
227  t2[0][0] = -1;
228  t2[0][1] = 0;
229  t2[0][2] = 1;
230  t2[1][0] = -1;
231  t2[1][1] = 1;
232  t2[1][2] = 0;
233 
234  std::vector< VectorSmall<3> > t3 (2, VectorSmall<3> (0.0, 0.0, 0.0) );
235  t3[0][0] = 0;
236  t3[0][1] = 1;
237  t3[0][2] = 0;
238  t3[1][0] = 0;
239  t3[1][1] = 0;
240  t3[1][2] = 1;
241 
242  M_globalCFE[0]->setRefTangents (t0);
243  M_globalCFE[1]->setRefTangents (t1);
244  M_globalCFE[2]->setRefTangents (t2);
245  M_globalCFE[3]->setRefTangents (t3);
246 
247 
248  M_evaluation.setQuadrature (M_quadratureBoundary.qr (0) );
249  M_evaluation.setGlobalCFE (M_globalCFE[0]);
250  M_evaluation.setTestCFE (M_testCFE[0]);
251 }
252 
253 
254 template < typename MeshType, typename SolutionTestSpace, typename ExpressionType>
255 EvaluateNodalExpressionVectorElementFaceID < MeshType, SolutionTestSpace, ExpressionType>::
256 EvaluateNodalExpressionVectorElementFaceID ( const EvaluateNodalExpressionVectorElementFaceID < MeshType, SolutionTestSpace, ExpressionType>& integrator)
257  : M_mesh (integrator.M_mesh),
258  M_boundaryId (integrator.M_boundaryId),
259  M_quadratureBoundary (integrator.M_quadratureBoundary),
260  M_solutionSpace (integrator.M_solutionSpace),
261  M_evaluation (integrator.M_evaluation),
262 
263  M_globalCFE (4),
264  M_testCFE (4),
265 
266  M_elementalVector (integrator.M_elementalVector)
267 {
268  for (UInt i (0); i < 4; ++i)
269  {
270  M_globalCFE[i] = new ETCurrentBDFE<3> (geometricMapFromMesh<MeshType>()
271  , M_quadratureBoundary.qr (i) );
272  M_testCFE[i] = new ETCurrentFE<3, SolutionTestSpace::field_dim> (M_solutionSpace->refFE()
273  , M_solutionSpace->geoMap()
274  , M_quadratureBoundary.qr (i) );
275  }
276 
277  // Set the tangent on the different faces
278  std::vector< VectorSmall<3> > t0 (2, VectorSmall<3> (0.0, 0.0, 0.0) );
279  t0[0][0] = 1;
280  t0[0][1] = 0;
281  t0[0][2] = 0;
282  t0[1][0] = 0;
283  t0[1][1] = 1;
284  t0[1][2] = 0;
285  std::vector< VectorSmall<3> > t1 (2, VectorSmall<3> (0.0, 0.0, 0.0) );
286  t1[0][0] = 0;
287  t1[0][1] = 0;
288  t1[0][2] = 1;
289  t1[1][0] = 1;
290  t1[1][1] = 0;
291  t1[1][2] = 0;
292  std::vector< VectorSmall<3> > t2 (2, VectorSmall<3> (0.0, 0.0, 0.0) );
293  //t2[0][0]=-1/std::sqrt(6); t2[0][1]=-1/std::sqrt(6); t2[0][2]=2/std::sqrt(6);
294  //t2[1][0]=-1/std::sqrt(2); t2[1][1]=1/std::sqrt(2); t2[1][2]=0;
295  t2[0][0] = -1;
296  t2[0][1] = 0;
297  t2[0][2] = 1;
298  t2[1][0] = -1;
299  t2[1][1] = 1;
300  t2[1][2] = 0;
301 
302  std::vector< VectorSmall<3> > t3 (2, VectorSmall<3> (0.0, 0.0, 0.0) );
303  t3[0][0] = 0;
304  t3[0][1] = 1;
305  t3[0][2] = 0;
306  t3[1][0] = 0;
307  t3[1][1] = 0;
308  t3[1][2] = 1;
309 
310  M_globalCFE[0]->setRefTangents (t0);
311  M_globalCFE[1]->setRefTangents (t1);
312  M_globalCFE[2]->setRefTangents (t2);
313  M_globalCFE[3]->setRefTangents (t3);
314 
315 
316  M_evaluation.setQuadrature (M_quadratureBoundary.qr (0) );
317  M_evaluation.setGlobalCFE (M_globalCFE[0]);
318  M_evaluation.setTestCFE (M_testCFE[0]);
319 }
320 
321 
322 template < typename MeshType, typename SolutionTestSpace, typename ExpressionType>
323 EvaluateNodalExpressionVectorElementFaceID < MeshType, SolutionTestSpace, ExpressionType>::
324 ~EvaluateNodalExpressionVectorElementFaceID()
325 {
326  for (UInt i (0); i < 4; ++i)
327  {
328  delete M_globalCFE[i];
329  delete M_testCFE[i];
330  }
331 }
332 
333 // ===================================================
334 // Methods
335 // ===================================================
336 
337 template < typename MeshType, typename SolutionTestSpace, typename ExpressionType>
338 void
339 EvaluateNodalExpressionVectorElementFaceID < MeshType, SolutionTestSpace, ExpressionType>::
340 check (std::ostream& out)
341 {
342  out << " Checking the integration : " << std::endl;
343  M_evaluation.display (out);
344  out << std::endl;
345  out << " Elemental vector : " << std::endl;
346  M_elementalVector.showMe (out);
347  out << std::endl;
348 }
349 
350 template < typename MeshType, typename SolutionTestSpace, typename ExpressionType>
351 template <typename VectorType>
352 void
353 EvaluateNodalExpressionVectorElementFaceID < MeshType, SolutionTestSpace, ExpressionType>::
354 addTo (VectorType& vec)
355 {
356  UInt nbBoundaryFaces (M_mesh->numBFaces() );
357  UInt nbTestDof (M_solutionSpace->refFE().nbDof() );
358 
359  /*CurrentBoundaryFE origFE(M_solutionSpace->refFE().boundaryFE(),
360  M_solutionSpace->geoMap().boundaryMap(),
361  quadRuleTria3pt);*/
362 
363  for (UInt iFace (0); iFace < nbBoundaryFaces; ++iFace)
364  {
365  // Check the identifier
366  if ( M_mesh->face (iFace).markerID() != M_boundaryId )
367  {
368  continue;
369  }
370 
371  //origFE.updateMeasNormalQuadPt(M_mesh->face(iFace));
372 
373  // Zeros out the elemental vector
374  M_elementalVector.zero();
375 
376  // Get the number of the face in the adjacent element
377  UInt faceIDinAdjacentElement (M_mesh->face (iFace).firstAdjacentElementPosition() );
378 
379  // Get the ID of the adjacent element
380  UInt adjacentElementID (M_mesh->face (iFace).firstAdjacentElementIdentity() );
381 
382  // Update the currentFEs
383  M_globalCFE[faceIDinAdjacentElement]
384  ->update (M_mesh->element (adjacentElementID) );
385  M_testCFE[faceIDinAdjacentElement]
386  ->update (M_mesh->element (adjacentElementID), evaluation_Type::S_testUpdateFlag);
387 
388  // Update the evaluation
389  M_evaluation.setQuadrature (M_quadratureBoundary.qr (faceIDinAdjacentElement) );
390  M_evaluation.setGlobalCFE (M_globalCFE[faceIDinAdjacentElement]);
391  M_evaluation.setTestCFE (M_testCFE[faceIDinAdjacentElement]);
392 
393  M_evaluation.update (adjacentElementID);
394 
395  // Loop on the blocks
396  for (UInt iblock (0); iblock < SolutionTestSpace::field_dim; ++iblock)
397  {
398  // Set the row global indices in the local vector
399  for (UInt i (0); i < nbTestDof; ++i)
400  {
401  M_elementalVector.setRowIndex
402  (i + iblock * nbTestDof,
403  M_solutionSpace->dof().localToGlobalMap (adjacentElementID, i) + iblock * M_solutionSpace->dof().numTotalDof() );
404  }
405 
406  // Make the assembly
407  for (UInt iQuadPt (0); iQuadPt < M_quadratureBoundary.qr (faceIDinAdjacentElement).nbQuadPt(); ++iQuadPt)
408  {
409  for (UInt i (0); i < nbTestDof; ++i)
410  {
411  M_elementalVector.element (i + iblock * nbTestDof) +=
412  M_evaluation.value_qi (iQuadPt, i + iblock * nbTestDof);
413 
414  }
415  }
416  }
417 
418  M_elementalVector.pushToGlobal (vec);
419  }
420 }
421 
422 
423 } // Namespace ExpressionAssembly
424 
425 } // Namespace LifeV
426 
427 #endif
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191