LifeV
ETA_InterpolateGradient2DTest.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  @file ETA_InterpolateGradient2DTest.cpp
28  @author L. Pasquale <luca.pasquale@mail.polimi.it>
29  @date 2012-11-20
30  */
31 
32 // ===================================================
33 //! Includes
34 // ===================================================
35 
37 
38 #include <lifev/eta/fem/ETFESpace.hpp>
39 #include <lifev/eta/expression/Integrate.hpp>
40 
41 
42 // ===================================================
43 //! Namespaces & define
44 // ===================================================
45 
46 // ---------------------------------------------------------------
47 // We work in the LifeV namespace and define the mesh, matrix and
48 // vector types that we will need several times.
49 // ---------------------------------------------------------------
50 
51 using namespace LifeV;
52 
54 typedef MatrixEpetra<Real> matrix_Type;
55 typedef VectorEpetra vector_Type;
56 
57 // ===================================================
58 //! Functions
59 // ===================================================
60 
61 // ---------------------------------------------------------------
62 // We define a function whose gradient is
63 // (1 0)
64 // (0 2)
65 // ---------------------------------------------------------------
66 
67 Real uFct ( const Real& /* t */, const Real& x , const Real& y , const Real& /* z */, const ID& i )
68 {
69  if (i == 0)
70  {
71  return x;
72  }
73  return 2 * y;
74 }
75 
76 // ===================================================
77 //! Constructors
78 // ===================================================
79 
80 ETA_InterpolateGradient2DTest::ETA_InterpolateGradient2DTest ()
81 {
82 
83 #ifdef EPETRA_MPI
84  M_comm.reset ( new Epetra_MpiComm ( MPI_COMM_WORLD ) );
85 #else
86  M_comm.reset ( new Epetra_SerialComm() );
87 #endif
88 
89 }
90 
91 // ===================================================
92 //! Methods
93 // ===================================================
94 
95 Real
96 ETA_InterpolateGradient2DTest::run()
97 {
98  bool verbose (M_comm->MyPID() == 0);
99  // ---------------------------------------------------------------
100  // We define the mesh and parition it. We use the domain
101  // (-1,1)x(-1,1) and a structured mesh.
102  // ---------------------------------------------------------------
103 
104  if (verbose)
105  {
106  std::cout << " -- Building and partitioning the mesh ... " << std::flush;
107  }
108 
109  const UInt Nelements (10);
110 
111  std::shared_ptr< mesh_Type > fullMeshPtr (new mesh_Type);
112 
113  regularMesh2D ( *fullMeshPtr, 0, Nelements, Nelements, false,
114  2.0, 2.0,
115  -1.0, -1.0);
116 
117  std::shared_ptr< mesh_Type > meshPtr;
118  {
119  MeshPartitioner< mesh_Type > meshPart (fullMeshPtr, M_comm);
120  meshPtr = meshPart.meshPartition();
121  }
122 
123  fullMeshPtr.reset();
124 
125  if (verbose)
126  {
127  std::cout << " done ! " << std::endl;
128  }
129 
130 
131  // ---------------------------------------------------------------
132  // We start by defining the finite element spaces. We still need
133  // a FESpace because ETFESpace is still lacking some methods
134  // ---------------------------------------------------------------
135 
136  if (verbose)
137  {
138  std::cout << " -- Building FESpaces ... " << std::flush;
139  }
140 
141  std::string uOrder ("P1");
142 
143  std::shared_ptr<FESpace< mesh_Type, MapEpetra > > uSpace
144  ( new FESpace< mesh_Type, MapEpetra > (meshPtr, uOrder, 2, M_comm) );
145 
146  if (verbose)
147  {
148  std::cout << " done ! " << std::endl;
149  }
150  if (verbose)
151  {
152  std::cout << " ---> Dofs: " << uSpace->dof().numTotalDof() << std::endl;
153  }
154 
155  if (verbose)
156  {
157  std::cout << " -- Building ETFESpaces ... " << std::flush;
158  }
159 
160  std::shared_ptr<ETFESpace< mesh_Type, MapEpetra, 2, 2 > > ETuSpace
161  ( new ETFESpace< mesh_Type, MapEpetra, 2, 2 > (meshPtr, & (uSpace->refFE() ), & (uSpace->fe().geoMap() ), M_comm) );
162 
163  if (verbose)
164  {
165  std::cout << " done ! " << std::endl;
166  }
167  if (verbose)
168  {
169  std::cout << " ---> Dofs: " << ETuSpace->dof().numTotalDof() << std::endl;
170  }
171 
172 
173  // ---------------------------------------------------------------
174  // We interpolate then the function.
175  // This can only be performed with the classical FESpace.
176  // ---------------------------------------------------------------
177 
178  if (verbose)
179  {
180  std::cout << " -- Interpolating the function ... " << std::flush;
181  }
182 
183  vector_Type uInterpolated (uSpace->map(), Unique);
184  uSpace->interpolate (static_cast<FESpace< mesh_Type, MapEpetra >::function_Type> (uFct), uInterpolated, 0.0);
185  vector_Type uInterpolatedRepeated (uInterpolated, Repeated);
186 
187  if (verbose)
188  {
189  std::cout << " done! " << std::endl;
190  }
191 
192 
193  // ---------------------------------------------------------------
194  // We build the MatrixSmall used to extract the trace
195  // and a variable used to store the result of the integration
196  // ---------------------------------------------------------------
197 
198  MatrixSmall<2, 2> identityMatrix;
199  identityMatrix (0, 0) = 1;
200  identityMatrix (0, 1) = 0;
201  identityMatrix (1, 0) = 0;
202  identityMatrix (1, 1) = 1;
203 
204  Real ETintegral (0);
205 
206  if (verbose)
207  {
208  std::cout << " done! " << std::endl;
209  }
210 
211  // ---------------------------------------------------------------
212  // We integrate on the domain the gradient trace (1+2 in this case)
213  //
214  // ---------------------------------------------------------------
215 
216  LifeChrono ETChrono;
217  ETChrono.start();
218 
219  if (verbose)
220  {
221  std::cout << " -- ET assembly ... " << std::flush;
222  }
223 
224 
225  {
226  using namespace ExpressionAssembly;
227 
228  integrate ( elements (ETuSpace->mesh() ),
229  uSpace->qr(),
230 
231  dot ( grad (ETuSpace, uInterpolatedRepeated) , value (identityMatrix) )
232 
233  )
234  >> ETintegral;
235 
236  }
237 
238  ETChrono.stop();
239 
240  if (verbose)
241  {
242  std::cout << " done! " << std::endl;
243  }
244  if (verbose)
245  {
246  std::cout << " Time : " << ETChrono.diff() << std::endl;
247  }
248 
249  // ---------------------------------------------------------------
250  // Integrals computed on each processor must be summed together
251  // ---------------------------------------------------------------
252 
253  if (verbose)
254  {
255  std::cout << " -- Broadcasting and summing integrals across processes ... " << std::flush;
256  }
257 
258  Real globalIntegral (0.0);
259 
260  M_comm->Barrier();
261  M_comm->SumAll (&ETintegral, &globalIntegral, 1);
262 
263  if (verbose)
264  {
265  std::cout << " done ! " << std::endl;
266  }
267 
268  // ---------------------------------------------------------------
269  // We now compute the error as the difference between the integral
270  // computed and the exact value expected ( (1+2)*4 = 12 )
271  // ---------------------------------------------------------------
272 
273  if (verbose)
274  {
275  std::cout << " -- Computing the error ... " << std::flush;
276  }
277 
278  Real error = std::abs (globalIntegral - 12.0);
279 
280  if (verbose)
281  {
282  std::cout << "Error: " << error << std::endl;
283  }
284 
285  if (verbose)
286  {
287  std::cout << " done ! " << std::endl;
288  }
289 
290  return error;
291 
292 } // run
RegionMesh< LinearTriangle > mesh_Type
uint32_type ID
IDs.
Definition: LifeV.hpp:194
VectorEpetra vector_Type
MatrixEpetra< Real > matrix_Type
Real uFct(const Real &, const Real &x, const Real &y, const Real &z, const ID &i)
Functions.
double Real
Generic real data.
Definition: LifeV.hpp:175
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191