LifeV
lifev/eta/tutorials/11_ETA_LaplacianPhiI/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 for gradient interpolation.
30 
31  @author Luca Pasquale <luca.pasquale@mail.polimi.it>
32  @date 2013-05
33 
34  In this tutorial we use two expressions available when
35  integrating with Expression Templates:
36  - interpoaltion of the gradient of a given function
37  - multiplication by a MatrixSmall
38  We do this by multiplying the gradient by the identity matrix
39  (i.e. we're integrating the divergence)
40 
41  Tutorials that should be read before: 1,3
42 
43  */
44 
45 // ---------------------------------------------------------------
46 // We reuse the same files as in the previous tutorial. We add the
47 // chrono to measure the timings.
48 // ---------------------------------------------------------------
49 
50 
51 #include <Epetra_ConfigDefs.h>
52 #ifdef EPETRA_MPI
53 #include <mpi.h>
54 #include <Epetra_MpiComm.h>
55 #else
56 #include <Epetra_SerialComm.h>
57 #endif
58 
59 
60 #include <lifev/core/LifeV.hpp>
61 
62 #include <lifev/core/mesh/MeshPartitioner.hpp>
63 #include <lifev/core/mesh/RegionMesh3DStructured.hpp>
64 #include <lifev/core/mesh/RegionMesh.hpp>
65 #include <lifev/core/mesh/MeshData.hpp>
66 
67 #include <lifev/core/array/MatrixEpetra.hpp>
68 #include <lifev/core/array/VectorEpetra.hpp>
69 
70 #include <lifev/eta/fem/ETFESpace.hpp>
71 #include <lifev/eta/expression/Integrate.hpp>
72 
73 #include <lifev/core/fem/FESpace.hpp>
74 
75 #include <lifev/core/util/LifeChrono.hpp>
76 
77 using namespace LifeV;
78 
80 typedef MatrixEpetra<Real> matrix_Type;
81 typedef VectorEpetra vector_Type;
82 
83 Real uOne ( const Real& /* t */, const Real& x , const Real& y , const Real& z , const ID& i )
84 {
85  return 1.0;
86 }
87 
88 Real uTestFunctions ( const Real& /* t */, const Real& x , const Real& y , const Real& z , const ID& i )
89 {
90  if ( i == 0 )
91  return x*x*0.5;
92  else if ( i == 1)
93  return y*y*0.5;
94  else
95  return z*z*0.5;
96 }
97 
98 int main ( int argc, char** argv )
99 {
100 
101 #ifdef HAVE_MPI
102  MPI_Init (&argc, &argv);
103  std::shared_ptr<Epetra_Comm> Comm (new Epetra_MpiComm (MPI_COMM_WORLD) );
104 #else
105  std::shared_ptr<Epetra_Comm> Comm (new Epetra_SerialComm);
106 #endif
107 
108  const bool verbose (Comm->MyPID() == 0);
109 
110  const UInt Nelements (10);
111 
112  std::shared_ptr< mesh_Type > fullMeshPtr (new mesh_Type);
113 
114  Real length = 3.0;
115 
116  regularMesh3D ( *fullMeshPtr, 1, Nelements, Nelements, Nelements, false,
117  length, length, length,
118  0.0, 0.0, 0.0);
119 
120  MeshPartitioner< mesh_Type > meshPart (fullMeshPtr, Comm);
121  std::shared_ptr< mesh_Type > meshPtr (meshPart.meshPartition() );
122 
123  fullMeshPtr.reset();
124 
125  std::string uOrder ("P2");
126 
127  ///////////////////////////////////
128  // Testing the scalar field case //
129  ///////////////////////////////////
130 
131  std::shared_ptr<FESpace< mesh_Type, MapEpetra > > uSpace ( new FESpace< mesh_Type, MapEpetra > (meshPtr, uOrder, 1, Comm) );
132 
133  std::shared_ptr<ETFESpace< mesh_Type, MapEpetra, 3, 1 > > ETuSpace ( new ETFESpace< mesh_Type, MapEpetra, 3, 1 > (meshPtr, & (uSpace->refFE() ), & (uSpace->fe().geoMap() ), Comm) );
134 
135  vector_Type vectorTestFunctions (uSpace->map(), Unique);
136  uSpace->interpolate (static_cast<FESpace< mesh_Type, MapEpetra >::function_Type> (uTestFunctions), vectorTestFunctions, 0.0);
137  vector_Type vectorTestFunctionsRepeated (vectorTestFunctions, Repeated);
138 
139  vector_Type vectorOnes (uSpace->map(), Repeated);
140  vectorOnes.zero();
141  vectorOnes += 1;
142 
143  vector_Type integral (uSpace->map() );
144 
145  {
146  using namespace ExpressionAssembly;
147 
148  integrate ( elements (ETuSpace->mesh() ),
149  uSpace->qr(),
150  ETuSpace,
151  value(ETuSpace,vectorOnes) * laplacian(phi_i)
152  )
153  >> integral;
154  }
155 
156  integral.globalAssemble();
157 
158  Real result = 0.0;
159 
160  result = integral.dot(vectorTestFunctions);
161 
162  if ( Comm->MyPID() == 0 )
163  {
164  std::cout << "\n\nSCALAR CASE " << std::endl;
165  std::cout << "\nThe volume is = " << length*length*length << std::endl;
166  std::cout << "\nThe result is = " << result << std::endl;
167  std::cout << "\nThe error is = " << result-(length*length*length) << std::endl;
168  }
169 
170  Real error_scalar = result-length*length*length;
171 
172  ///////////////////////////////////
173  // Testing the vector field case //
174  ///////////////////////////////////
175 
176  std::shared_ptr<FESpace< mesh_Type, MapEpetra > > uSpaceVec
177  ( new FESpace< mesh_Type, MapEpetra > (meshPtr, uOrder, 3, Comm) );
178 
179  std::shared_ptr<ETFESpace< mesh_Type, MapEpetra, 3, 3 > > ETuSpaceVec
180  ( new ETFESpace< mesh_Type, MapEpetra, 3, 3 > (meshPtr, & (uSpaceVec->refFE() ), & (uSpaceVec->fe().geoMap() ), Comm) );
181 
182  vector_Type vectorTestFunctionsVec (uSpaceVec->map(), Unique);
183  uSpaceVec->interpolate (static_cast<FESpace< mesh_Type, MapEpetra >::function_Type> (uTestFunctions), vectorTestFunctionsVec, 0.0);
184  vector_Type vectorTestFunctionsRepeatedVec (vectorTestFunctionsVec, Repeated);
185 
186  vector_Type vectorOnesVec (uSpaceVec->map(), Repeated );
187  vectorOnesVec.zero();
188  vectorOnesVec += 1;
189 
190  vector_Type integralVec (uSpaceVec->map() );
191 
192  {
193  using namespace ExpressionAssembly;
194 
195  integrate ( elements (ETuSpaceVec->mesh() ),
196  uSpaceVec->qr(),
197  ETuSpaceVec,
198  dot ( value(ETuSpaceVec,vectorOnesVec), laplacian(phi_i) )
199  )
200  >> integralVec;
201  }
202 
203  integralVec.globalAssemble();
204 
205  result = 0.0;
206  result = integralVec.dot(vectorTestFunctionsVec);
207 
208  if ( Comm->MyPID() == 0 )
209  {
210  std::cout << "\n\nVECTORIAL CASE " << std::endl;
211  std::cout << "\nThe volume is = " << (length*length*length)*3 << std::endl;
212  std::cout << "\nThe result is = " << result << std::endl;
213  std::cout << "\nThe error is = " << result-((length*length*length)*3) << "\n\n";
214  }
215 
216  Real error_vectorial = result-3*length*length*length;
217 
218 #ifdef HAVE_MPI
219  MPI_Finalize();
220 #endif
221 
222  if ( std::fabs(error_scalar) < 1e-9 && std::fabs(error_vectorial) < 1e-9 )
223  {
224  return ( EXIT_SUCCESS );
225  }
226 
227  return ( EXIT_FAILURE );
228 }
int main(int argc, char **argv)
MatrixEpetra< Real > matrix_Type
Real uOne(const Real &, const Real &x, const Real &y, const Real &z, const ID &i)
uint32_type ID
IDs.
Definition: LifeV.hpp:194
Real uTestFunctions(const Real &, const Real &x, const Real &y, const Real &z, const ID &i)
double Real
Generic real data.
Definition: LifeV.hpp:175
RegionMesh< LinearTetra > mesh_Type