LifeV
lifev/eta/examples/laplacian/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 Laplacian problem
30 
31  @author Antonello Gerbi <antonello.gerbi@epfl.ch>
32  @maintainer Niccolo' Dal Santo <niccolo.dalsanto@epfl.ch>
33  @date 10-11-2014
34 
35  */
36 
37 #include <Epetra_ConfigDefs.h>
38 #ifdef EPETRA_MPI
39 #include <Epetra_MpiComm.h>
40 #else
41 #include <Epetra_SerialComm.h>
42 #endif
43 
44 #include <lifev/core/LifeV.hpp>
45 #include <lifev/core/util/LifeChronoManager.hpp>
46 
47 #include <lifev/core/mesh/MeshPartitioner.hpp>
48 #include <lifev/core/mesh/RegionMesh3DStructured.hpp>
49 #include <lifev/core/mesh/RegionMesh.hpp>
50 #include <lifev/core/array/MatrixEpetra.hpp>
51 
52 #include <lifev/core/fem/BCManage.hpp>
53 #include <lifev/eta/fem/ETFESpace.hpp>
54 #include <lifev/eta/expression/BuildGraph.hpp>
55 #include <lifev/eta/expression/Integrate.hpp>
56 #include <Epetra_FECrsGraph.h>
57 
58 #include <Teuchos_ParameterList.hpp>
59 #include <Teuchos_XMLParameterListHelpers.hpp>
60 #include <Teuchos_RCP.hpp>
61 #include <lifev/core/algorithm/LinearSolver.hpp>
62 #include <lifev/core/algorithm/PreconditionerIfpack.hpp>
63 
64 #include <lifev/core/filter/ExporterHDF5.hpp>
65 
66 #include <boost/shared_ptr.hpp>
67 
68 #include <lifev/eta/examples/laplacian/laplacianFunctor.hpp>
69 #include <lifev/core/mesh/RegionMesh.hpp>
70 #include <lifev/core/mesh/ElementShapes.hpp>
71 #include <lifev/core/mesh/MeshEntityContainer.hpp>
72 #include <lifev/core/mesh/MeshData.hpp>
73 
74 using namespace LifeV;
75 
76 // Dirichlet BC functions
77 Real nonZeroFunction (const Real& t, const Real& /*x*/, const Real& /*y*/, const Real& /*z*/, const ID& /*i*/)
78 {
79  return 100.;
80 }
81 
82 Real zeroFunction (const Real& /*t*/, const Real& /*x*/, const Real& /*y*/, const Real& /*z*/, const ID& /*i*/)
83 {
84  return 0.;
85 }
86 
87 Real sourceFunction (const Real& /*t*/, const Real& x, const Real& y, const Real& z, const ID& /*i*/)
88 {
89  return 3 * M_PI * M_PI * sin( M_PI * x ) * sin( M_PI * y ) * sin( M_PI * z );
90 }
91 
92 Real uExactFunction (const Real& /*t*/, const Real& x, const Real& y, const Real& z, const ID& /*i*/)
93 {
94  return sin( M_PI * y ) * sin( M_PI * z ) * sin ( M_PI * x );
95 }
96 
97 VectorSmall< 3 > uGradExactFunction (const Real& /*t*/, const Real& x, const Real& y, const Real& z, const ID& /*i*/)
98 {
99  VectorSmall< 3 > v;
100 
101  v[0] = M_PI * cos( M_PI * x ) * sin( M_PI * y ) * sin( M_PI * z );
102  v[1] = M_PI * sin( M_PI * x ) * cos( M_PI * y ) * sin( M_PI * z );
103  v[2] = M_PI * sin( M_PI * x ) * sin( M_PI * y ) * cos( M_PI * z );
104 
105  return v;
106 }
107 
108 // Cube's walls identifiers
109 const int BACK = 1;
110 const int FRONT = 2;
111 const int LEFT = 3;
112 const int RIGHT = 4;
113 const int BOTTOM = 5;
114 const int TOP = 6;
115 
116 
117 int main ( int argc, char** argv )
118 {
119 
120  // MPI initialization
121 #ifdef HAVE_MPI
122  MPI_Init ( &argc, &argv );
123  std::shared_ptr< Epetra_Comm > Comm ( new Epetra_MpiComm ( MPI_COMM_WORLD ) );
124 #else
125  std::shared_ptr< Epetra_Comm > Comm ( new Epetra_SerialComm );
126 #endif
127 
128  // Initializing chronometers
129  LifeChrono globalChrono;
130  LifeChrono initChrono;
131 
132  globalChrono.start();
133 
134 
135  // Reading parameters through GetPot
136  GetPot command_line ( argc, argv );
137  const std::string dataFileName = command_line.follow ( "data", 2, "-f", "--file" );
138  GetPot dataFile ( dataFileName );
139 
140  const bool verbose ( Comm->MyPID() == 0 );
141 
142  if ( verbose )
143  {
144  std::cout << "-- Building and partitioning the mesh... " << std::flush;
145  }
146 
147  initChrono.start();
148 
149 
150 
151  // +-----------------------------------------------+
152  // | Building mesh |
153  // +-----------------------------------------------+
154 
155  typedef RegionMesh< LinearTetra > mesh_Type;
156 
157  std::shared_ptr< mesh_Type > fullMeshPtr ( new mesh_Type ( Comm ) );
158 
159 
160  // Building structured mesh (in this case a cube)
161  regularMesh3D ( *fullMeshPtr, 0,
162  dataFile( "mesh/nx", 15 ), dataFile( "mesh/ny", 15 ), dataFile( "mesh/nz", 15 ),
163  dataFile ( "mesh/verbose", false ),
164  2.0, 2.0, 2.0, -1.0, -1.0, -1.0 );
165 
166 
167  // Partitioning mesh, possibly with overlap
168  const UInt overlap ( dataFile( "mesh/overlap", 0 ) );
169 
170  std::shared_ptr< mesh_Type > localMeshPtr;
171 
172  MeshPartitioner< mesh_Type > meshPart;
173 
174  if ( overlap )
175  {
176  meshPart.setPartitionOverlap ( overlap );
177  }
178 
179  meshPart.doPartition ( fullMeshPtr, Comm );
180  localMeshPtr = meshPart.meshPartition();
181 
182  // Clearing global mesh
183  fullMeshPtr.reset();
184 
185  initChrono.stop();
186 
187  if ( verbose )
188  {
189  std::cout << " done in " << initChrono.diff() << " s!" << std::endl;
190  }
191 
192  initChrono.reset();
193  initChrono.start();
194 
195 
196 
197  // +-----------------------------------------------+
198  // | Building FE space and matrix |
199  // +-----------------------------------------------+
200 
201  typedef FESpace< mesh_Type, MapEpetra > uSpaceStd_Type;
202  typedef std::shared_ptr< uSpaceStd_Type > uSpaceStdPtr_Type;
203 
204  typedef ETFESpace< mesh_Type, MapEpetra, 3, 1 > uSpaceETA_Type;
205  typedef std::shared_ptr< uSpaceETA_Type > uSpaceETAPtr_Type;
206 
207  typedef FESpace<mesh_Type, MapEpetra>::function_Type function_Type;
208 
209  if ( verbose )
210  {
211  std::cout << "-- Building finite elements spaces... " << std::flush;
212  }
213 
214  // Defining finite elements standard and ET spaces
215  uSpaceStdPtr_Type uFESpace ( new uSpaceStd_Type ( localMeshPtr, dataFile( "finite_element/degree", "P1" ), 1, Comm ) );
216  uSpaceETAPtr_Type ETuFESpace ( new uSpaceETA_Type ( localMeshPtr, & ( uFESpace->refFE() ), & ( uFESpace->fe().geoMap() ), Comm ) );
217 
218  initChrono.stop();
219 
220  if ( verbose )
221  {
222  std::cout << " done in " << initChrono.diff() << " s! (Dofs: " << uFESpace->dof().numTotalDof() << ")" << std::endl;
223  }
224 
225  typedef Epetra_FECrsGraph graph_Type;
226  typedef std::shared_ptr<Epetra_FECrsGraph> graphPtr_Type;
227 
228  typedef MatrixEpetra< Real > matrix_Type;
229  typedef std::shared_ptr< MatrixEpetra< Real > > matrixPtr_Type;
230  typedef VectorEpetra vector_Type;
231  typedef std::shared_ptr<VectorEpetra> vectorPtr_Type;
232 
233  // Declaring the problem's graph and matrix
234  graphPtr_Type systemGraph;
235  matrixPtr_Type systemMatrix;
236 
237  initChrono.reset();
238  initChrono.start();
239 
240  if ( overlap )
241  {
242  systemGraph.reset ( new graph_Type ( Copy, * ( uFESpace->map().map( Unique ) ), 50, true ) );
243  }
244  else
245  {
246  systemGraph.reset ( new graph_Type ( Copy, * ( uFESpace->map().map( Unique ) ), 50 ) );
247  }
248 
249 
250  if ( verbose )
251  {
252  std::cout << "-- Assembling matrix graph... " << std::flush;
253  }
254 
255  {
256 
257  using namespace ExpressionAssembly;
258 
259  buildGraph (
260  elements ( localMeshPtr ),
261  uFESpace->qr(),
262  ETuFESpace,
263  ETuFESpace,
264  dot ( grad ( phi_i ) , grad ( phi_j ) )
265  )
266  >> systemGraph;
267 
268  }
269 
270  systemGraph->GlobalAssemble();
271 
272 
273  if ( overlap )
274  {
275 
276  systemMatrix.reset( new matrix_Type ( ETuFESpace->map(), *systemGraph, true ) );
277 
278  }
279  else
280  {
281 
282  systemMatrix.reset( new matrix_Type ( ETuFESpace->map(), *systemGraph ) );
283 
284  }
285 
286  initChrono.stop();
287 
288  if ( verbose )
289  {
290  std::cout << " done in " << initChrono.diff() << " s!" << std::endl;
291  }
292 
293  // Clearing problem's matrix
294  systemMatrix->zero();
295 
296  initChrono.reset();
297  initChrono.start();
298 
299  if ( verbose )
300  {
301  std::cout << "-- Assembling the Laplace matrix... " << std::flush;
302  }
303 
304  {
305  using namespace ExpressionAssembly;
306 
307  integrate (
308  elements ( localMeshPtr ),
309  uFESpace->qr(),
310  ETuFESpace,
311  ETuFESpace,
312  dot ( grad ( phi_i ) , grad ( phi_j ) )
313  )
314  >> systemMatrix;
315  }
316 
317  initChrono.stop();
318 
319  if (verbose)
320  {
321  std::cout << " done in " << initChrono.diff() << " s!" << std::endl;
322  }
323 
324  // +-----------------------------------------------+
325  // | Initializing vectors and exporter |
326  // +-----------------------------------------------+
327 
328  vectorPtr_Type rhsLap;
329  vectorPtr_Type solutionLap;
330 
331  if ( overlap )
332  {
333 
334  rhsLap.reset ( new vector_Type ( uFESpace->map(), Unique, Zero ) );
335  solutionLap.reset ( new vector_Type ( uFESpace->map(), Unique, Zero ) );
336 
337  }
338  else
339  {
340 
341  rhsLap.reset ( new vector_Type ( uFESpace->map(), Unique ) );
342  solutionLap.reset ( new vector_Type ( uFESpace->map(), Unique ) );
343 
344  }
345 
346  rhsLap->zero();
347  solutionLap->zero();
348 
349 
350  std::shared_ptr<laplacianFunctor< Real > > laplacianSourceFunctor ( new laplacianFunctor< Real >( sourceFunction ) );
351 
352  {
353  using namespace ExpressionAssembly;
354 
355  integrate (
356  elements ( localMeshPtr ),
357  uFESpace->qr(),
358  ETuFESpace,
359  eval(laplacianSourceFunctor, X) * phi_i
360  )
361  >> rhsLap;
362 
363  }
364 
365 
366 
367  // Setting exporter
368  ExporterHDF5< mesh_Type > exporter ( dataFile, "exporter" );
369  exporter.setMeshProcId( localMeshPtr, Comm->MyPID() );
370  exporter.setPrefix( "laplace" );
371  exporter.setPostDir( "./" );
372 
373  exporter.addVariable ( ExporterData< mesh_Type >::ScalarField, "temperature", uFESpace, solutionLap, UInt ( 0 ) );
374 
375 
376  // +-----------------------------------------------+
377  // | Setting BCs |
378  // +-----------------------------------------------+
379 
380  if (verbose)
381  {
382  std::cout << "-- Setting boundary conditions... " << std::flush;
383  }
384  systemMatrix->globalAssemble();
385  rhsLap->globalAssemble();
386 
387  initChrono.reset();
388  initChrono.start();
389 
390  BCHandler bcHandler;
391 
392  BCFunctionBase ZeroBC ( zeroFunction );
393  BCFunctionBase OneBC ( nonZeroFunction );
394 
395  bcHandler.addBC( "Back", BACK, Essential, Full, ZeroBC, 1 );
396  bcHandler.addBC( "Left", LEFT, Essential, Full, ZeroBC, 1 );
397  bcHandler.addBC( "Top", TOP, Essential, Full, ZeroBC, 1 );
398 
399  bcHandler.addBC( "Front", FRONT, Essential, Full, ZeroBC, 1 );
400  bcHandler.addBC( "Right", RIGHT, Essential, Full, ZeroBC, 1 );
401  bcHandler.addBC( "Bottom", BOTTOM, Essential, Full, ZeroBC, 1 );
402 
403  bcHandler.bcUpdate( *uFESpace->mesh(), uFESpace->feBd(), uFESpace->dof() );
404 
405 
406  bcManage ( *systemMatrix, *rhsLap, *uFESpace->mesh(), uFESpace->dof(), bcHandler, uFESpace->feBd(), 1.0, 0.0 );
407 
408  initChrono.stop();
409 
410  if (verbose)
411  {
412  std::cout << " done in " << initChrono.diff() << " s!" << std::endl;
413  }
414 
415  // +-----------------------------------------------+
416  // | Setting solver and preconditioner |
417  // +-----------------------------------------------+
418 
419  typedef LinearSolver::SolverType solver_Type;
420 
421  typedef LifeV::Preconditioner basePrec_Type;
422  typedef std::shared_ptr<basePrec_Type> basePrecPtr_Type;
423  typedef PreconditionerIfpack prec_Type;
424  typedef std::shared_ptr<prec_Type> precPtr_Type;
425 
426 
427  if (verbose)
428  {
429  std::cout << "-- Setting up the solver ... " << std::flush;
430  }
431 
432  initChrono.reset();
433  initChrono.start();
434 
435  LinearSolver linearSolver ( Comm );
436  linearSolver.setOperator ( systemMatrix );
437 
438  Teuchos::RCP< Teuchos::ParameterList > aztecList = Teuchos::rcp ( new Teuchos::ParameterList );
439  aztecList = Teuchos::getParametersFromXmlFile ( "SolverParamList.xml" );
440 
441  linearSolver.setParameters ( *aztecList );
442 
443  prec_Type* precRawPtr;
444  basePrecPtr_Type precPtr;
445  precRawPtr = new prec_Type;
446  precRawPtr->setDataFromGetPot ( dataFile, "prec" );
447  precPtr.reset ( precRawPtr );
448 
449  linearSolver.setPreconditioner ( precPtr );
450 
451  initChrono.stop();
452 
453  if (verbose)
454  {
455  std::cout << " done in " << initChrono.diff() << " s!" << std::endl;
456  }
457 
458 
459  // +-----------------------------------------------+
460  // | Solving problem |
461  // +-----------------------------------------------+
462 
463  if (verbose)
464  {
465  std::cout << "-- Solving problem ... " << std::flush;
466  }
467 
468  initChrono.reset();
469  initChrono.start();
470 
471  linearSolver.setRightHandSide( rhsLap );
472  linearSolver.solve( solutionLap );
473 
474  initChrono.stop();
475 
476 
477  function_Type uEx(uExactFunction);
478 
479  // Save exact solution
480  vectorPtr_Type uExPtrInterpolated( new vector_Type (uFESpace->map(), Repeated) );
481 
482  uExPtrInterpolated->zero();
483 
484  uFESpace->interpolate (uEx, *uExPtrInterpolated, 0.0);
485 
486  exporter.addVariable ( ExporterData< mesh_Type >::ScalarField, "realTemperature", uFESpace, uExPtrInterpolated, UInt ( 0 ) );
487 
488  // using general functors
489 
490  Real L2ErrorLap = 0.0;
491  Real TotL2ErrorLap = 0.0;
492 
493  Real H1SeminormLap = 0.0;
494  Real TotH1SeminormLap = 0.0;
495 
496  std::shared_ptr<laplacianFunctor< Real > > laplacianExactFunctor ( new laplacianFunctor< Real >( uExactFunction ) );
497  std::shared_ptr<laplacianFunctor< VectorSmall<3> > > laplacianExactGradientFunctor ( new laplacianFunctor< VectorSmall<3> >( uGradExactFunction ) );
498 
499  {
500  using namespace ExpressionAssembly;
501 
502  integrate (
503  elements ( localMeshPtr ),
504  uFESpace->qr(),
505  ( eval(laplacianExactFunctor, X) - value (ETuFESpace, *solutionLap) )
506  * ( eval(laplacianExactFunctor, X) - value (ETuFESpace, *solutionLap) )
507  ) >> L2ErrorLap;
508 
509  }
510 
511  {
512  using namespace ExpressionAssembly;
513 
514  integrate (
515  elements ( localMeshPtr ),
516  uFESpace->qr(),
517  dot( eval(laplacianExactGradientFunctor, X) - grad( ETuFESpace, *solutionLap ),
518  eval(laplacianExactGradientFunctor, X) - grad( ETuFESpace, *solutionLap ) )
519  ) >> H1SeminormLap;
520 
521  }
522 
523  Comm->Barrier();
524  Comm->SumAll (&L2ErrorLap, &TotL2ErrorLap, 1);
525  Comm->SumAll (&H1SeminormLap, &TotH1SeminormLap, 1);
526 
527  if (verbose)
528  {
529  std::cout << "TotError General in L2 norm is " << sqrt( TotL2ErrorLap ) << std::endl;
530  std::cout << "TotError General in H1 norm is " << sqrt( TotL2ErrorLap + TotH1SeminormLap ) << std::endl;
531 
532  }
533 
534  if (verbose)
535  {
536  std::cout << " done in " << initChrono.diff() << " s!" << std::endl;
537  }
538 
539  exporter.postProcess( 0 );
540  exporter.closeFile();
541 
542  globalChrono.stop();
543 
544  if (verbose)
545  {
546  std::cout << std::endl << "Problem solved in " << globalChrono.diff() << " s!" << std::endl;
547  }
548 
549 #ifdef HAVE_MPI
550  MPI_Finalize();
551 #endif
552 
553  return ( EXIT_SUCCESS );
554 }
int main(int argc, char **argv)
#define M_PI
Definition: winmath.h:20
VectorSmall< 3 > uGradExactFunction(const Real &, const Real &x, const Real &y, const Real &z, const ID &)
Real & operator[](UInt const &i)
Operator [].
uint32_type ID
IDs.
Definition: LifeV.hpp:194
Real sourceFunction(const Real &, const Real &x, const Real &y, const Real &z, const ID &)
Real uExactFunction(const Real &, const Real &x, const Real &y, const Real &z, const ID &)
double Real
Generic real data.
Definition: LifeV.hpp:175
Real zeroFunction(const Real &, const Real &, const Real &, const Real &, const ID &)
Real nonZeroFunction(const Real &t, const Real &, const Real &, const Real &, const ID &)