LifeV
lifev/eta/tutorials/9_ETA_QRProvider/main.cpp
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 LifeV.
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 License
21  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23 *******************************************************************************
24 */
25 //@HEADER
26 
27 /*!
28  @file
29  @brief Tutorial about the quadrature rule in the ETA.
30 
31  @author Samuel Quinodoz <samuel.quinodoz@epfl.ch>
32  @date 28-06-2012
33 
34  In this tutorial, we show how to better select the
35  quadrature rule, via the dedicated class called
36  QuadratureRuleProvider. This is the right way to
37  access quadrature rules.
38 
39  Tutorial 1 should be read before, to understand the basic
40  concepts.
41  */
42 
43 // ---------------------------------------------------------------
44 // We include here exactly the same files that in tutorial 1,
45 // excepted a new one: the file containing the
46 // QuadratureRuleProvider
47 // ---------------------------------------------------------------
48 
49 #pragma GCC diagnostic ignored "-Wunused-variable"
50 #pragma GCC diagnostic ignored "-Wunused-parameter"
51 
52 #include <Epetra_ConfigDefs.h>
53 #ifdef EPETRA_MPI
54 #include <mpi.h>
55 #include <Epetra_MpiComm.h>
56 #else
57 #include <Epetra_SerialComm.h>
58 #endif
59 
60 #pragma GCC diagnostic warning "-Wunused-variable"
61 #pragma GCC diagnostic warning "-Wunused-parameter"
62 
63 
64 #include <lifev/core/LifeV.hpp>
65 
66 #include <lifev/core/fem/QuadratureRuleProvider.hpp>
67 
68 #include <lifev/core/mesh/MeshPartitioner.hpp>
69 #include <lifev/core/mesh/RegionMesh3DStructured.hpp>
70 #include <lifev/core/mesh/RegionMesh.hpp>
71 
72 #include <lifev/core/array/MatrixEpetra.hpp>
73 
74 #include <lifev/eta/fem/ETFESpace.hpp>
75 
76 #include <lifev/eta/expression/Integrate.hpp>
77 
78 #include <boost/shared_ptr.hpp>
79 
80 
81 // ---------------------------------------------------------------
82 // The beginning of the tutorial is exactly the same as the
83 // tutorial 1, so we refer to that tutorial for more comments.
84 // ---------------------------------------------------------------
85 
86 using namespace LifeV;
87 
89 typedef MatrixEpetra<Real> matrix_Type;
90 
91 
92 int main ( int argc, char** argv )
93 {
94 
95 #ifdef HAVE_MPI
96  MPI_Init (&argc, &argv);
97  std::shared_ptr<Epetra_Comm> Comm (new Epetra_MpiComm (MPI_COMM_WORLD) );
98 #else
99  std::shared_ptr<Epetra_Comm> Comm (new Epetra_SerialComm);
100 #endif
101 
102  const bool verbose (Comm->MyPID() == 0);
103 
104 
105  if (verbose)
106  {
107  std::cout << " -- Building and partitioning the mesh ... " << std::flush;
108  }
109 
110  const UInt Nelements (10);
111 
112  std::shared_ptr< mesh_Type > fullMeshPtr (new mesh_Type);
113 
114  regularMesh3D ( *fullMeshPtr, 1, Nelements, Nelements, Nelements, false,
115  2.0, 2.0, 2.0,
116  -1.0, -1.0, -1.0);
117 
118  MeshPartitioner< mesh_Type > meshPart (fullMeshPtr, Comm);
119 
120  fullMeshPtr.reset();
121 
122  if (verbose)
123  {
124  std::cout << " done ! " << std::endl;
125  }
126 
127 
128  if (verbose)
129  {
130  std::cout << " -- Building ETFESpaces ... " << std::flush;
131  }
132 
133  std::shared_ptr<ETFESpace< mesh_Type, MapEpetra, 3, 1 > > uSpace
134  ( new ETFESpace< mesh_Type, MapEpetra, 3, 1 > (meshPart, &feTetraP1, Comm) );
135 
136  if (verbose)
137  {
138  std::cout << " done ! " << std::endl;
139  }
140  if (verbose)
141  {
142  std::cout << " ---> Dofs: " << uSpace->dof().numTotalDof() << std::endl;
143  }
144 
145 
146  if (verbose)
147  {
148  std::cout << " -- Defining the matrix ... " << std::flush;
149  }
150 
151  std::shared_ptr<matrix_Type> systemMatrix (new matrix_Type ( uSpace->map() ) );
152 
153  *systemMatrix *= 0.0;
154 
155  if (verbose)
156  {
157  std::cout << " done! " << std::endl;
158  }
159 
160 
161  if (verbose)
162  {
163  std::cout << " -- Assembling the Laplace matrix ... " << std::flush;
164  }
165 
166 
167  {
168  using namespace ExpressionAssembly;
169 
170  // ---------------------------------------------------------------
171  // Now comes the interesting part. During the assembly, we need
172  // to specify which quadrature rule we want to use for the
173  // integration. In the tutorial 1, we used "quadRuleTetra4pt"
174  // as quadrature rule.
175  //
176  // This is not very convenient, since
177  // - One must know the quadrature rules available and their names
178  // - No information about the degrees of the quadrature is given.
179  //
180  // The QuadratureRuleProvider class was designed exactly to
181  // overcome these issues. The most useful method of that class
182  // is the provideExactness: this method returns, for a given
183  // element shape, a quadrature rule with the required exactness.
184  // That is what we use here.
185  //
186  // The required exactness here is 0, since the function to be
187  // integrated is constant in each element. To compute
188  // the mass matrix, we would have chosen 2 (the function to
189  // integrate would be quadratic in each element).
190  // ---------------------------------------------------------------
191 
192  integrate ( elements (uSpace->mesh() ),
193  QuadratureRuleProvider::provideExactness (TETRA, 0),
194  uSpace,
195  uSpace,
196  dot ( grad (phi_i) , grad (phi_j) )
197  )
198  >> systemMatrix;
199  }
200 
201  if (verbose)
202  {
203  std::cout << " done! " << std::endl;
204  }
205 
206 
207  // ---------------------------------------------------------------
208  // Remark that you can change the behaviour of the
209  // QuadratureRuleProvider with the setters that it has, e.g., to
210  // obtain a warning when the precise exactness was not found, we
211  // use the code
212  // ---------------------------------------------------------------
213 
214  if (verbose)
215  {
216  std::cout << " -- Changing the behaviour of the QRProvider ... " << std::flush;
217  }
218 
219  if (verbose)
220  {
221  QuadratureRuleProvider::setBehaviorNoPreciseExactness (QuadratureRuleProvider::WarningAndReturnSup );
222  }
223 
224  if (verbose)
225  {
226  std::cout << " done ! " << std::endl;
227  }
228 
229 
230  // ---------------------------------------------------------------
231  // We finish the test as in tutorial 1.
232  // ---------------------------------------------------------------
233 
234 
235  if (verbose)
236  {
237  std::cout << " -- Closing the matrix ... " << std::flush;
238  }
239 
240  systemMatrix->globalAssemble();
241 
242  if (verbose)
243  {
244  std::cout << " done ! " << std::endl;
245  }
246 
247 
248  Real matrixNorm ( systemMatrix->normInf() );
249 
250  if (verbose)
251  {
252  std::cout << " Matrix norm : " << matrixNorm << std::endl;
253  }
254 
255 
256 #ifdef HAVE_MPI
257  MPI_Finalize();
258 #endif
259 
260  Real matrixNormDiff (std::abs (matrixNorm - 3.2) );
261 
262  if (verbose)
263  {
264  std::cout << " Error : " << matrixNormDiff << std::endl;
265  }
266 
267  Real testTolerance (1e-10);
268 
269  if ( matrixNormDiff < testTolerance )
270  {
271  return ( EXIT_SUCCESS );
272  }
273  return ( EXIT_FAILURE );
274 
275 }
int main(int argc, char **argv)
MatrixEpetra< Real > matrix_Type
double Real
Generic real data.
Definition: LifeV.hpp:175
RegionMesh< LinearTetra > mesh_Type