LifeV
lifev/eta/testsuite/boundary_integrals/main.cpp
Go to the documentation of this file.
1 /* -*- mode: c++ -*-
2 
3  This file is part of the LifeV Applications.
4 
5  Author(s): Claudia Colciago <claudia.colciago@epfl.ch>
6  Date: 2013-07-29
7 
8  Copyright (C) 2005 EPFL
9 
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2.1 of the License, or
13  (at your option) any later version.
14 
15  This program is distributed in the hope that it will be useful, but
16  WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with this program; if not, write to the Free Software
22  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23  USA
24 */
25 /**
26  \file main.cpp
27  \author Claudia Colciago<claudia.colciago@epfl.ch>
28  \date 2013-07-29
29 
30  */
31 
32 
33 // Tell the compiler to ignore specific kind of warnings:
34 #pragma GCC diagnostic ignored "-Wunused-variable"
35 #pragma GCC diagnostic ignored "-Wunused-parameter"
36 
37 #include <Epetra_ConfigDefs.h>
38 #ifdef EPETRA_MPI
39 #include <mpi.h>
40 #include <Epetra_MpiComm.h>
41 #else
42 #include <Epetra_SerialComm.h>
43 #endif
44 
45 
46 #include <Teuchos_ParameterList.hpp>
47 #include <Teuchos_XMLParameterListHelpers.hpp>
48 #include <Teuchos_RCP.hpp>
49 
50 //Tell the compiler to restore the warning previously silented
51 #pragma GCC diagnostic warning "-Wunused-variable"
52 #pragma GCC diagnostic warning "-Wunused-parameter"
53 
54 #include <lifev/core/LifeV.hpp>
55 
56 
57 #include <lifev/core/algorithm/PreconditionerIfpack.hpp>
58 #include <lifev/core/algorithm/PreconditionerML.hpp>
59 #include <lifev/core/algorithm/SolverAztecOO.hpp>
60 #include <lifev/core/algorithm/LinearSolver.hpp>
61 
62 #include <lifev/core/array/MatrixBlockMonolithicEpetra.hpp>
63 #include <lifev/core/array/VectorBlockMonolithicEpetra.hpp>
64 
65 #include <lifev/core/util/LifeChrono.hpp>
66 
67 #include <lifev/eta/expression/Integrate.hpp>
68 
69 #include <lifev/core/fem/BCHandler.hpp>
70 #include <lifev/core/fem/BCManage.hpp>
71 #include <lifev/eta/fem/ETFESpace.hpp>
72 #include <lifev/core/fem/DOFInterface3Dto3D.hpp>
73 #include <lifev/core/fem/GradientRecovery.hpp>
74 
75 #include <lifev/core/filter/ExporterEnsight.hpp>
76 #include <lifev/core/filter/ExporterHDF5.hpp>
77 
78 #include <lifev/core/mesh/MeshPartitioner.hpp>
79 #include <lifev/core/mesh/RegionMesh3DStructured.hpp>
80 #include <lifev/core/mesh/RegionMesh.hpp>
81 #include <lifev/core/mesh/MeshUtility.hpp>
82 #include <lifev/core/mesh/MeshData.hpp>
83 
84 #include <lifev/level_set/fem/LevelSetQRAdapter.hpp>
85 #include <iostream>
86 
87 using namespace LifeV;
88 
89 const Real pi = 3.141592653589793;
90 
91 // Coefficients
92 Real beta ( 1.0 );
93 Real alpha ( 1.0 );
94 Real nu ( 1.0 );
95 UInt wall ( 30 );
96 
97 Real uExact ( const Real& /*t*/, const Real& x , const Real& y, const Real& z , const ID& /*i*/)
98 {
99  return std::sin ( pi * y ) * std::cos ( pi * x ) * std::exp ( z ) ;
100 }
101 
102 Real laplacianExact ( const Real& /*t*/, const Real& x , const Real& y, const Real& z , const ID& /*i*/)
103 {
104  return ( - pi * pi * std::sin (pi * y) * std::cos (pi * x ) * std::exp ( z )
105  - pi * pi * std::sin (pi * y) * std::cos (pi * x ) * std::exp ( z )
106  + std::sin (pi * y) * cos (pi * x ) * exp ( z ) );
107 }
108 
109 Real gRobinRhs ( const Real& /*t*/, const Real& x , const Real& y, const Real& z , const ID& /*i*/)
110 {
111  MatrixSmall<3, 3> hessian;
112 
113  hessian[0][0] = - pi * pi * std::sin ( pi * y ) * std::cos ( pi * x ) * std::exp ( z );
114 
115  hessian[0][1] = - pi * pi * std::sin (pi * x ) * std::cos (pi * y) * std::exp ( z );
116  hessian[1][0] = hessian[0][1];
117 
118  hessian[0][2] = - pi * std::sin ( pi * y ) * std::sin ( pi * x ) * std::exp ( z );
119  hessian[2][0] = hessian[0][2];
120 
121  hessian[1][1] = - pi * pi * std::sin ( pi * y ) * std::cos ( pi * x ) * std::exp ( z );
122  hessian[2][2] = std::sin ( pi * y ) * cos ( pi * x ) * exp ( z );
123 
124  hessian[1][2] = pi * std::cos ( pi * y ) * std::cos ( pi * x ) * std::exp ( z );
125  hessian[2][1] = hessian[1][2];
126 
127  VectorSmall<3> gradient;
128  gradient[0] = - pi * std::sin ( pi * y ) * std::sin ( pi * x ) * std::exp ( z );
129  gradient[1] = pi * std::cos ( pi * y ) * std::cos ( pi * x ) * std::exp ( z );
130  gradient[2] = std::sin ( pi * y ) * std::cos ( pi * x ) * std::exp ( z );
131 
132  VectorSmall<3> normal;
133 
134  Real traceHessian = hessian[0][0] + hessian[1][1] + hessian[2][2];
135 
136  normal[0] = 0;
137  normal[1] = 0;
138  normal[2] = 1;
139 
140  normal.normalize();
141 
142  return ( nu * gradient.dot ( normal ) + alpha * uExact ( 0, x, y, z, 0 )
143  - beta * ( traceHessian - ( hessian * normal ).dot ( normal ) ) );
144 }
145 
146 /* LaplacianRhs */
148 {
149 public:
150  typedef Real return_Type;
151 
152  return_Type operator() ( const VectorSmall<3> spaceCoordinates )
153  {
154  return laplacianExact ( 0, spaceCoordinates[0], spaceCoordinates[1], spaceCoordinates[2] , 0 ) ;
155  }
156 
160 };
161 
163 {
164 public:
165  typedef Real return_Type;
166 
167  return_Type operator() ( const VectorSmall<3> spaceCoordinates )
168  {
169  return uExact ( 0, spaceCoordinates[0], spaceCoordinates[1], spaceCoordinates[2] , 0 ) ;
170  }
171 
175 };
176 
178 {
179 public:
181 
182  return_Type operator() ( const VectorSmall<3> spaceCoordinates )
183  {
184  VectorSmall<3> gradient;
185  Real x = spaceCoordinates[0];
186  Real y = spaceCoordinates[1];
187  Real z = spaceCoordinates[2];
188  gradient[0] = - pi * std::sin ( pi * y ) * std::sin ( pi * x ) * std::exp ( z );
189  gradient[1] = pi * std::cos ( pi * y ) * std::cos ( pi * x ) * std::exp ( z );
190  gradient[2] = std::sin ( pi * y ) * std::cos ( pi * x ) * std::exp ( z );
191 
192  return gradient;
193  }
194 
198 };
199 
201 {
202 public:
203  typedef Real return_Type;
204 
205  return_Type operator() ( const VectorSmall<3> spaceCoordinates )
206  {
207  return gRobinRhs ( 0, spaceCoordinates[0], spaceCoordinates[1], spaceCoordinates[2] , 0 ) ;
208  }
209 
213 };
214 
215 /* Register the preconditioner */
216 namespace
217 {
218 static bool regIF = (PRECFactory::instance().registerProduct ( "Ifpack", &createIfpack ) );
219 static bool regML = (PRECFactory::instance().registerProduct ( "ML", &createML ) );
220 }
221 
222 /* Some typedef */
228 
233 
234 int main ( int argc, char** argv )
235 {
236 
237 #ifdef HAVE_MPI
238  MPI_Init (&argc, &argv);
239  std::shared_ptr<Epetra_Comm> Comm (new Epetra_MpiComm (MPI_COMM_WORLD) );
240 #else
241  std::shared_ptr<Epetra_Comm> Comm (new Epetra_SerialComm);
242 #endif
243 
244  // a flag to see who's the leader for output purposes
245  bool verbose = (Comm->MyPID() == 0);
246 
247  // Open and read the data file
248  GetPot command_line (argc, argv);
249  std::string data_file_name = command_line.follow ("data", 2, "-f", "--file");
250  GetPot dataFile ( data_file_name );
251 
252  // Load the mesh
253  MeshData dataMesh;
254  dataMesh.setup (dataFile, "mesh");
255  std::shared_ptr < mesh_Type > fullMeshPtr (new mesh_Type);
256  readMesh (*fullMeshPtr, dataMesh);
257 
258  // Partition the mesh
259  MeshPartitioner< mesh_Type > meshPart (fullMeshPtr, Comm);
260  std::shared_ptr < mesh_Type > localMeshPtr (new mesh_Type);
261  localMeshPtr = meshPart.meshPartition();
262 
263  // Free the global mesh
264  fullMeshPtr.reset();
265 
266  if (verbose)
267  {
268  std::cout << " Building FESpaces " << std::endl;
269  }
270 
271  std::string uOrder ("P1");
272 
273  std::shared_ptr<FESpace< mesh_Type, MapEpetra > > uFESpace ( new FESpace< mesh_Type, MapEpetra > (localMeshPtr, uOrder, 1, Comm) );
274 
275  if (verbose)
276  {
277  std::cout << std::endl << " ### Dof Summary ###: " << std::endl;
278  }
279  if (verbose)
280  {
281  std::cout << " u : " << uFESpace->map().map (Unique)->NumGlobalElements() << std::endl;
282  }
283 
284  if (verbose)
285  {
286  std::cout << " Building EA FESpaces " << std::endl;
287  }
288 
289  std::shared_ptr<ETFESpace< mesh_Type, MapEpetra, 3, 1 > > ETuFESpace ( new ETFESpace< mesh_Type, MapEpetra, 3, 1 > (localMeshPtr, & (uFESpace->refFE() ), Comm) );
290 
291  vectorPtr_Type uSolution ( new vector_Type ( ETuFESpace->map() , Unique) );
292 
293  if (verbose)
294  {
295  std::cout << " Building the solvers " << std::endl;
296  }
297 
298 
299  if ( verbose )
300  {
301  std::cout << "Setting up LinearSolver (AztecOO)... " << std::flush;
302  }
303 
304  prec_Type* precRawPtr;
305  basePrecPtr_Type precPtr;
306  precRawPtr = new prec_Type;
307  precRawPtr->setDataFromGetPot ( dataFile, "prec" );
308  precPtr.reset ( precRawPtr );
309 
310  Teuchos::RCP< Teuchos::ParameterList > belosList = Teuchos::rcp ( new Teuchos::ParameterList );
311  belosList = Teuchos::getParametersFromXmlFile ( "SolverParamList.xml" );
312 
313  LinearSolver linearSolver;
314  linearSolver.setCommunicator ( Comm );
315  linearSolver.setParameters ( *belosList );
316  linearSolver.setPreconditioner ( precPtr );
317  if ( verbose )
318  {
319  std::cout << "done" << std::endl;
320  }
321 
322  if (verbose)
323  {
324  std::cout << " Building the exporter " << std::endl;
325  }
326 
327  std::string const exporterFileName = dataFile ( "exporter/filename", "cube");
328  ExporterHDF5<mesh_Type> exporter ( dataFile, meshPart.meshPartition(), exporterFileName, Comm->MyPID() );
329  exporter.setMultimesh (false);
330 
331  std::shared_ptr<vector_Type> uExported ( new vector_Type (ETuFESpace->map(), exporter.mapType() ) );
332  std::shared_ptr<vector_Type> errorExported ( new vector_Type (ETuFESpace->map(), exporter.mapType() ) );
333 
334  exporter.addVariable ( ExporterData<mesh_Type>::ScalarField, "u", uFESpace, uExported, UInt (0) );
335  exporter.addVariable ( ExporterData<mesh_Type>::ScalarField, "err", uFESpace, errorExported, UInt (0) );
336 
337  LifeChrono ChronoItem;
338  ChronoItem.start();
339  if (verbose)
340  {
341  std::cout << " Assembling the matrix ... " << std::flush;
342  }
343 
344  QuadratureBoundary myBDQR (buildTetraBDQR (quadRuleTria4pt) );
345 
346  matrixPtr_Type systemMatrix (new matrix_Type ( ETuFESpace->map() ) );
347  *systemMatrix *= 0.0;
348 
349  {
350  using namespace ExpressionAssembly;
351 
352  integrate (
353  elements (ETuFESpace->mesh() ), // Mesh
354 
355  uFESpace->qr(), // QR
356 
357  ETuFESpace,
358  ETuFESpace,
359 
360  value (nu) * dot (grad (phi_i) , grad (phi_j) )
361 
362  )
363  >> *systemMatrix;
364 
365  integrate ( boundary (ETuFESpace->mesh(), wall),
366  myBDQR,
367 
368  ETuFESpace,
369  ETuFESpace,
370 
371  value ( alpha ) * phi_j * phi_i
372 
373  + value ( beta ) * dot ( ( grad (phi_j) - dot ( grad (phi_j) , Nface ) * Nface ) ,
374  ( grad (phi_i) - dot ( grad (phi_i) , Nface ) * Nface ) )
375 
376  )
377  >> *systemMatrix;
378  }
379 
380  ChronoItem.stop();
381  if (verbose)
382  {
383  std::cout << ChronoItem.diff() << " s" << std::endl;
384  }
385 
386  if (verbose)
387  {
388  std::cout << " Assembling the rhs ... " << std::flush;
389  }
390 
391  ChronoItem.start();
392 
393  std::shared_ptr<LaplacianExactFunctor> laplacianFctRhs ( new LaplacianExactFunctor );
394  std::shared_ptr<GRobinRhsFunctor> gRobinFctRhs ( new GRobinRhsFunctor );
395 
396  vector_Type uRhs ( ETuFESpace->map() , Repeated );
397  uRhs *= 0.0;
398 
399  {
400  using namespace ExpressionAssembly;
401 
402  integrate ( elements (ETuFESpace->mesh() ), // Mesh
403 
404  uFESpace->qr(), // QR
405 
406  ETuFESpace,
407 
408  value (-nu) * eval ( laplacianFctRhs, X ) * phi_i
409 
410  )
411  >> uRhs;
412 
413 
414  integrate ( boundary (ETuFESpace->mesh(), wall),
415  myBDQR,
416 
417  ETuFESpace,
418 
419  eval ( gRobinFctRhs, X ) * phi_i
420 
421  )
422  >> uRhs;
423  }
424 
425  ChronoItem.stop();
426  if (verbose)
427  {
428  std::cout << ChronoItem.diff() << " s" << std::endl;
429  }
430 
431  vectorPtr_Type uRhsUnique ( new vector_Type ( uRhs, Unique ) );
432 
433  systemMatrix->globalAssemble();
434 
435  if (verbose)
436  {
437  std::cout << "[Navier-Stokes] Applying Dirichlet boundary conditions ... " << std::flush;
438  }
439 
440  ChronoItem.start();
441  BCHandler bcHandler;
442  BCFunctionBase uexBCFct ( uExact );
443 
444  bcHandler.addBC ("Wall2", 31, Essential, Full, uexBCFct, 1);
445  bcHandler.addBC ("Corners", 32, EssentialEdges, Full, uexBCFct, 1);
446 
447  bcHandler.bcUpdate ( *meshPart.meshPartition(), uFESpace->feBd(), uFESpace->dof() );
448  bcManage (*systemMatrix, *uRhsUnique,
449  *uFESpace->mesh(), uFESpace->dof(),
450  bcHandler, uFESpace->feBd(), 1.0, Real (0.0) );
451 
452  ChronoItem.stop();
453 
454  if (verbose)
455  {
456  std::cout << ChronoItem.diff() << " s" << std::endl;
457  }
458 
459  if (verbose)
460  {
461  std::cout << " Solving the system " << std::endl;
462  }
463 
464 
465  linearSolver.setOperator ( systemMatrix );
466  linearSolver.setRightHandSide ( uRhsUnique );
467  linearSolver.solve ( uSolution );
468 
469  *uExported = *uSolution;
470  vector_Type errorVector ( ETuFESpace->map() , Unique , Zero);
471  vector_Type uexVector ( uFESpace->map(), Unique);
472  uFESpace->interpolate ( uExact, uexVector, 0);
473  errorVector = uexVector - *uSolution;
474  *errorExported = errorVector;
475  exporter.postProcess ( 1.0 );
476 
477  if (verbose)
478  {
479  std::cout << " Evaluate Errors " << std::endl;
480  }
481 
482  Real errorL2SquaredLocal ( 0.0 );
483  Real errorH1SquaredLocal ( 0.0 );
484  Real errorL2Squared ( 0.0 );
485  Real errorH1Squared ( 0.0 );
486  Real errorH1BoundarySquared ( 0.0 );
487 
488  vector_Type errorH1BoundaryVector ( ETuFESpace->map(), Repeated );
489  vector_Type errorH1BoundaryVectorUnique ( ETuFESpace->map() );
490 
491  std::shared_ptr<uExactFunctor> uExactFct ( new uExactFunctor );
492  std::shared_ptr<gradExactFunctor> gradExactFct ( new gradExactFunctor );
493 
494  {
495  using namespace ExpressionAssembly;
496  integrate (
497  elements (ETuFESpace->mesh() ), // Mesh
498 
499  uFESpace->qr(), // QR
500 
501  dot ( ( eval ( gradExactFct, X ) - grad ( ETuFESpace , *uSolution ) ) ,
502  ( eval ( gradExactFct, X ) - grad ( ETuFESpace , *uSolution ) ) ) /** phi_i*/
503 
504  )
505  >> errorH1SquaredLocal;
506 
507 
508  integrate (
509  elements (ETuFESpace->mesh() ), // Mesh
510 
511  uFESpace->qr(), // QR
512 
513  ( eval ( uExactFct, X ) - value ( ETuFESpace , *uSolution ) ) * ( eval ( uExactFct, X ) - value ( ETuFESpace , *uSolution ) )
514 
515  )
516  >> errorL2SquaredLocal;
517 
518  integrate ( boundary (ETuFESpace->mesh(), wall),
519  myBDQR,
520 
521  ETuFESpace,
522 
523  dot ( ( eval ( gradExactFct, X ) - dot ( eval ( gradExactFct, X ) , Nface ) * Nface )
524  - ( grad ( ETuFESpace , *uSolution ) - dot ( grad ( ETuFESpace , *uSolution ) , Nface ) * Nface ) ,
525  ( eval ( gradExactFct, X ) - dot ( eval ( gradExactFct, X ) , Nface ) * Nface )
526  - ( grad ( ETuFESpace , *uSolution ) - dot ( grad ( ETuFESpace , *uSolution ) , Nface ) * Nface )
527  ) * phi_i +
528  ( eval ( uExactFct, X ) - value ( ETuFESpace , *uSolution ) )
529  * ( eval ( uExactFct, X ) - value ( ETuFESpace , *uSolution ) ) * phi_i
530 
531  )
532 
533  >> errorH1BoundaryVector;
534 
535  }
536 
537  Comm->Barrier();
538  Comm->SumAll (&errorH1SquaredLocal, &errorH1Squared, 1);
539  Comm->SumAll (&errorL2SquaredLocal, &errorL2Squared, 1);
540 
541  vector_Type oneVector ( ETuFESpace->map(), Unique );
542  errorH1BoundaryVectorUnique = errorH1BoundaryVector;
543  oneVector *= 0;
544  oneVector += 1;
545  errorH1BoundarySquared = errorH1BoundaryVectorUnique.dot ( oneVector );
546 
547  if (verbose)
548  {
549  std::cout << " l2 error norm " << std::sqrt ( errorL2Squared ) << std::endl;
550 
551  std::cout << " H1 error norm " << sqrt ( errorH1Squared ) << std::endl;
552 
553  std::cout << " H1 Gamma error norm " << std::sqrt ( errorH1BoundarySquared ) << std::endl;
554  }
555 
556  exporter.closeFile();
557 
558  Real tolerance (1e-5);
559  bool success ( false );
560 
561  if ( ( abs ( sqrt (errorL2Squared) - 0.0768669 ) < tolerance )
562  && ( abs ( sqrt (errorH1Squared) - 1.76249 ) < tolerance )
563  && ( abs ( sqrt (errorH1BoundarySquared) - 2.35064 ) < tolerance )
564  )
565  {
566  success = true ;
567  }
568 
569  if (!success)
570  {
571  if (verbose)
572  {
573  std::cout << "End Result: TEST NOT PASSED" << std::endl;
574  }
575  }
576  else
577  {
578  if (verbose)
579  {
580  std::cout << "End Result: TEST PASSED" << std::endl;
581  }
582  }
583 
584 #ifdef HAVE_MPI
585  MPI_Finalize();
586 #endif
587 
588  if ( !success )
589  {
590  return ( EXIT_FAILURE );
591  }
592  else
593  {
594  return ( EXIT_SUCCESS );
595  }
596 
597 
598 }
VectorEpetra - The Epetra Vector format Wrapper.
Real gRobinRhs(const Real &, const Real &x, const Real &y, const Real &z, const ID &)
std::shared_ptr< matrix_Type > matrixPtr_Type
LifeV::Preconditioner basePrec_Type
std::shared_ptr< vector_Type > vectorPtr_Type
Real uExact(const Real &, const Real &x, const Real &y, const Real &z, const ID &)
return_Type operator()(const VectorSmall< 3 > spaceCoordinates)
void importFromHDF5(std::string const &fileName, std::string const &matrixName="matrix")
Read a matrix from a HDF5 (.h5) file.
Real const & operator[](UInt const &i) const
Operator [].
UInt wall(30)
void updateInverseJacobian(const UInt &iQuadPt)
void normalize()
Normalize vector.
Real alpha(1.0)
PreconditionerIfpack(std::shared_ptr< Epetra_Comm > comm=std::shared_ptr< Epetra_Comm >(new Epetra_MpiComm(MPI_COMM_WORLD)))
Empty constructor.
Real & operator[](UInt const &i)
Operator [].
uint32_type ID
IDs.
Definition: LifeV.hpp:194
RegionMesh< LinearTetra > mesh_Type
LaplacianExactFunctor(const LaplacianExactFunctor &)
return_Type operator()(const VectorSmall< 3 > spaceCoordinates)
Real laplacianExact(const Real &, const Real &x, const Real &y, const Real &z, const ID &)
std::shared_ptr< prec_Type > precPtr_Type
LifeV::PreconditionerIfpack prec_Type
std::shared_ptr< basePrec_Type > basePrecPtr_Type
return_Type operator()(const VectorSmall< 3 > spaceCoordinates)
double Real
Generic real data.
Definition: LifeV.hpp:175
Preconditioner - Abstract preconditioner class.
int main(int argc, char **argv)
MatrixEpetra< Real > matrix_Type
Real nu(1.0)
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
Real beta(1.0)
return_Type operator()(const VectorSmall< 3 > spaceCoordinates)