LifeV
lifev/core/testsuite/adr_assembler/3d/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
30 
31  @author Samuel Quinodoz <samuel.quinodoz@epfl.ch>
32  @date 08-10-2010
33  */
34 
35 
36 #include <Epetra_ConfigDefs.h>
37 #ifdef EPETRA_MPI
38 #include <mpi.h>
39 #include <Epetra_MpiComm.h>
40 #else
41 #include <Epetra_SerialComm.h>
42 #endif
43 
44 
45 #include <lifev/core/LifeV.hpp>
46 
47 
48 #include <lifev/core/algorithm/PreconditionerIfpack.hpp>
49 #include <lifev/core/algorithm/PreconditionerML.hpp>
50 
51 #include <lifev/core/algorithm/SolverAztecOO.hpp>
52 #include <lifev/core/algorithm/LinearSolver.hpp>
53 
54 #include <lifev/core/array/MatrixEpetra.hpp>
55 
56 #include <lifev/core/filter/ExporterEnsight.hpp>
57 
58 #include <lifev/core/fem/FESpace.hpp>
59 #include <lifev/core/fem/BCManage.hpp>
60 
61 #include <lifev/core/mesh/MeshPartitioner.hpp>
62 #include <lifev/core/mesh/RegionMesh3DStructured.hpp>
63 #include <lifev/core/mesh/RegionMesh.hpp>
64 
65 #include <lifev/core/solver/ADRAssembler.hpp>
66 #include <lifev/core/mesh/MeshData.hpp>
67 
68 #include <Teuchos_ParameterList.hpp>
69 #include <Teuchos_XMLParameterListHelpers.hpp>
70 #include <Teuchos_RCP.hpp>
71 
72 using namespace LifeV;
73 
74 namespace
75 {
76 static bool regIF = (PRECFactory::instance().registerProduct ( "Ifpack", &createIfpack ) );
77 static bool regML = (PRECFactory::instance().registerProduct ( "ML", &createML ) );
78 }
79 
80 //#define TEST_MASS
81 //#define TEST_ADVECTION
82 #define TEST_RHS
83 
84 
85 #ifdef TEST_MASS
86 Real epsilon (1);
87 
88 Real exactSolution ( const Real& /* t */, const Real& x, const Real& /* y */, const Real& /* z */ , const ID& /* i */ )
89 {
90  Real seps (std::sqrt (epsilon) );
91  return std::exp (seps * x) / (std::exp (seps) - std::exp (-seps) );
92 }
93 #endif
94 
95 #ifdef TEST_ADVECTION
96 Real epsilon (1);
97 
98 Real exactSolution ( const Real& /* t */, const Real& x, const Real& /* y */, const Real& /* z */, const ID& /* i */ )
99 {
100  return (std::exp (x / epsilon) - 1 ) / ( std::exp (1 / epsilon) - 1);
101 }
102 
103 Real betaFct ( const Real& /* t */, const Real& /* x */, const Real& /* y */, const Real& /* z */, const ID& i )
104 {
105  return Real (i == 0);
106 }
107 #endif
108 
109 #ifdef TEST_RHS
110 Real epsilon (1);
111 
112 Real exactSolution ( const Real& /* t */, const Real& x, const Real& y, const Real& z , const ID& /* i */ )
113 {
114  return std::sin (x + y) + z * z / 2;
115 }
116 
117 
118 Real fRhs ( const Real& /* t */, const Real& x, const Real& y, const Real& /* z */ , const ID& /* i */ )
119 {
120  return 2 * std::sin (x + y) - 1;
121 }
122 #endif
123 
124 
129 typedef FESpace<mesh_Type, MapEpetra> feSpace_Type;
130 
135 
137 
138 
139 int
140 main ( int argc, char** argv )
141 {
142 
143 #ifdef HAVE_MPI
144  MPI_Init (&argc, &argv);
145  std::shared_ptr<Epetra_Comm> Comm (new Epetra_MpiComm (MPI_COMM_WORLD) );
146 #else
147  std::shared_ptr<Epetra_Comm> Comm (new Epetra_SerialComm);
148 #endif
149 
150  const bool verbose (Comm->MyPID() == 0);
151 
152  // Read first the data needed
153 
154  if (verbose)
155  {
156  std::cout << " -- Reading the data ... " << std::flush;
157  }
158  GetPot dataFile ( "data" );
159  if (verbose)
160  {
161  std::cout << " done ! " << std::endl;
162  }
163 
164  const UInt Nelements (dataFile ("mesh/nelements", 10) );
165  if (verbose)
166  {
167  std::cout << " ---> Number of elements : " << Nelements << std::endl;
168  }
169 
170  // Build and partition the mesh
171 
172  if (verbose)
173  {
174  std::cout << " -- Building the mesh ... " << std::flush;
175  }
176  std::shared_ptr< mesh_Type > fullMeshPtr ( new RegionMesh<LinearTetra> ( Comm ) );
177  regularMesh3D ( *fullMeshPtr, 1, Nelements, Nelements, Nelements, false,
178  2.0, 2.0, 2.0,
179  -1.0, -1.0, -1.0);
180  if (verbose)
181  {
182  std::cout << " done ! " << std::endl;
183  }
184 
185  if (verbose)
186  {
187  std::cout << " -- Partitioning the mesh ... " << std::flush;
188  }
189  std::shared_ptr< mesh_Type > meshPtr;
190  {
191  MeshPartitioner< mesh_Type > meshPart (fullMeshPtr, Comm);
192  meshPtr = meshPart.meshPartition();
193  }
194  if (verbose)
195  {
196  std::cout << " done ! " << std::endl;
197  }
198 
199  if (verbose)
200  {
201  std::cout << " -- Freeing the global mesh ... " << std::flush;
202  }
203  fullMeshPtr.reset();
204  if (verbose)
205  {
206  std::cout << " done ! " << std::endl;
207  }
208 
209  // Build the FESpaces
210 
211  if (verbose)
212  {
213  std::cout << " -- Building FESpaces ... " << std::flush;
214  }
215  std::string uOrder ("P1");
216  std::string bOrder ("P1");
217  std::shared_ptr<FESpace< mesh_Type, MapEpetra > > uFESpace ( new FESpace< mesh_Type, MapEpetra > (meshPtr, uOrder, 1, Comm) );
218  std::shared_ptr<FESpace< mesh_Type, MapEpetra > > betaFESpace ( new FESpace< mesh_Type, MapEpetra > (meshPtr, bOrder, 3, Comm) );
219  if (verbose)
220  {
221  std::cout << " done ! " << std::endl;
222  }
223  if (verbose)
224  {
225  std::cout << " ---> Dofs: " << uFESpace->dof().numTotalDof() << std::endl;
226  }
227 
228  // Build the assembler and the matrices
229 
230  if (verbose)
231  {
232  std::cout << " -- Building assembler ... " << std::flush;
233  }
234  ADRAssembler<mesh_Type, matrix_Type, vector_Type> adrAssembler;
235  if (verbose)
236  {
237  std::cout << " done! " << std::endl;
238  }
239 
240  if (verbose)
241  {
242  std::cout << " -- Setting up assembler ... " << std::flush;
243  }
244  adrAssembler.setup (uFESpace, betaFESpace);
245  if (verbose)
246  {
247  std::cout << " done! " << std::endl;
248  }
249 
250  if (verbose)
251  {
252  std::cout << " -- Defining the matrix ... " << std::flush;
253  }
254  std::shared_ptr<matrix_Type> systemMatrix (new matrix_Type ( uFESpace->map() ) );
255  *systemMatrix *= 0.0;
256  if (verbose)
257  {
258  std::cout << " done! " << std::endl;
259  }
260 
261  // Perform the assembly of the matrix
262 
263  if (verbose)
264  {
265  std::cout << " -- Adding the diffusion ... " << std::flush;
266  }
267  adrAssembler.addDiffusion (systemMatrix, epsilon);
268  if (verbose)
269  {
270  std::cout << " done! " << std::endl;
271  }
272  if (verbose)
273  {
274  std::cout << " Time needed : " << adrAssembler.diffusionAssemblyChrono().diffCumul() << std::endl;
275  }
276 
277 #ifdef TEST_ADVECTION
278  if (verbose)
279  {
280  std::cout << " -- Adding the advection ... " << std::flush;
281  }
282  vector_Type beta (betaFESpace->map(), Repeated);
283  betaFESpace->interpolate (betaFct, beta, 0.0);
284  adrAssembler.addAdvection (systemMatrix, beta);
285  if (verbose)
286  {
287  std::cout << " done! " << std::endl;
288  }
289 #endif
290 #ifdef TEST_MASS
291  if (verbose)
292  {
293  std::cout << " -- Adding the mass ... " << std::flush;
294  }
295  adrAssembler.addMass (systemMatrix, 1.0);
296  if (verbose)
297  {
298  std::cout << " done! " << std::endl;
299  }
300 #endif
301 
302  if (verbose)
303  {
304  std::cout << " -- Closing the matrix ... " << std::flush;
305  }
306  systemMatrix->globalAssemble();
307  if (verbose)
308  {
309  std::cout << " done ! " << std::endl;
310  }
311 
312 #ifdef TEST_RHS
313  Real matrixNorm (systemMatrix->norm1() );
314  if (verbose)
315  {
316  std::cout << " ---> Norm 1 : " << matrixNorm << std::endl;
317  }
318  if ( std::fabs (matrixNorm - 1.68421 ) > 1e-3)
319  {
320  std::cout << " <!> Matrix has changed !!! <!> " << std::endl;
321  return EXIT_FAILURE;
322  }
323 #endif
324 
325  // Definition and assembly of the RHS
326 
327  if (verbose)
328  {
329  std::cout << " -- Building the RHS ... " << std::flush;
330  }
331  //vector_Type rhs(uFESpace->map(),Unique);
332  vector_Type rhs (uFESpace->map(), Repeated);
333  rhs *= 0.0;
334 
335 #ifdef TEST_RHS
336  vector_Type fInterpolated (uFESpace->map(), Repeated);
337  fInterpolated *= 0.0;
338  uFESpace->interpolate ( static_cast<feSpace_Type::function_Type> ( fRhs ), fInterpolated, 0.0 );
339  adrAssembler.addMassRhs (rhs, fInterpolated);
340  rhs.globalAssemble();
341 #endif
342 
343  if (verbose)
344  {
345  std::cout << " done ! " << std::endl;
346  }
347 
348  // Definition and application of the BCs
349 
350  if (verbose)
351  {
352  std::cout << " -- Building the BCHandler ... " << std::flush;
353  }
354  BCHandler bchandler;
355  BCFunctionBase BCu ( exactSolution );
356  bchandler.addBC ("Dirichlet", 1, Essential, Full, BCu, 1);
357  for (UInt i (2); i <= 6; ++i)
358  {
359  bchandler.addBC ("Dirichlet", i, Essential, Full, BCu, 1);
360  }
361  if (verbose)
362  {
363  std::cout << " done ! " << std::endl;
364  }
365 
366  if (verbose)
367  {
368  std::cout << " -- Updating the BCs ... " << std::flush;
369  }
370  bchandler.bcUpdate (*uFESpace->mesh(), uFESpace->feBd(), uFESpace->dof() );
371  if (verbose)
372  {
373  std::cout << " done ! " << std::endl;
374  }
375 
376  if (verbose)
377  {
378  std::cout << " -- Applying the BCs ... " << std::flush;
379  }
380  vectorPtr_Type rhsBC ( new vector_Type (rhs, Unique) );
381  bcManage (*systemMatrix, *rhsBC, *uFESpace->mesh(), uFESpace->dof(), bchandler, uFESpace->feBd(), 1.0, 0.0);
382  rhs = *rhsBC;
383  if (verbose)
384  {
385  std::cout << " done ! " << std::endl;
386  }
387 
388  //************* SPY ***********
389  //systemMatrix->spy("matrix");
390  //rhs.spy("vector");
391  //*****************************
392 
393  // Definition of the solver
394 
395  if (verbose)
396  {
397  std::cout << " -- Building the solver ... " << std::flush;
398  }
399  LinearSolver linearSolver;
400 
401  Teuchos::RCP< Teuchos::ParameterList > belosList = Teuchos::rcp ( new Teuchos::ParameterList );
402  belosList = Teuchos::getParametersFromXmlFile ( "SolverParamList.xml" );
403 
404  linearSolver.setCommunicator ( Comm );
405  linearSolver.setParameters ( *belosList );
406 
407  prec_Type* precRawPtr;
408  basePrecPtr_Type precPtr;
409  precRawPtr = new prec_Type;
410  precRawPtr->setDataFromGetPot ( dataFile, "prec" );
411  precPtr.reset ( precRawPtr );
412  linearSolver.setPreconditioner ( precPtr );
413  if (verbose)
414  {
415  std::cout << " done ! " << std::endl;
416  }
417 
418  if (verbose)
419  {
420  std::cout << " -- Setting up the solver ... " << std::flush;
421  }
422 
423  if (verbose)
424  {
425  std::cout << " done ! " << std::endl;
426  }
427 
428  if (verbose)
429  {
430  std::cout << " -- Setting matrix in the solver ... " << std::flush;
431  }
432  linearSolver.setOperator ( systemMatrix );
433  if (verbose)
434  {
435  std::cout << " done ! " << std::endl;
436  }
437 
438  // Definition of the solution
439 
440  if (verbose)
441  {
442  std::cout << " -- Defining the solution ... " << std::flush;
443  }
444  vectorPtr_Type solution (new vector_Type (uFESpace->map(), Unique) );
445  solution->zero();
446  if (verbose)
447  {
448  std::cout << " done ! " << std::endl;
449  }
450 
451  // Solve the solution
452 
453  if (verbose)
454  {
455  std::cout << " -- Solving the system ... " << std::flush;
456  }
457  linearSolver.setRightHandSide ( rhsBC );
458  linearSolver.solve ( solution );
459  if (verbose)
460  {
461  std::cout << " done ! " << std::endl;
462  }
463 
464  //************* SPY ***********
465  //solution.spy("solution");
466  //*****************************
467 
468  // Error computation
469 
470  if (verbose)
471  {
472  std::cout << " -- Computing the error ... " << std::flush;
473  }
474  vector_Type solutionErr (*solution);
475  solutionErr *= 0.0;
476  uFESpace->interpolate ( static_cast<feSpace_Type::function_Type> ( exactSolution ), solutionErr, 0.0 );
477  solutionErr -= *solution;
478  solutionErr.abs();
479  Real l2error (uFESpace->l2Error (exactSolution, vector_Type (*solution, Repeated), 0.0) );
480  if (verbose)
481  {
482  std::cout << " -- done ! " << std::endl;
483  }
484  if (verbose)
485  {
486  std::cout << " ---> Norm L2 : " << l2error << std::endl;
487  }
488  Real linferror ( solutionErr.normInf() );
489  if (verbose)
490  {
491  std::cout << " ---> Norm Inf : " << linferror << std::endl;
492  }
493 
494 
495  if (l2error > 0.0055)
496  {
497  std::cout << " <!> Solution has changed !!! <!> " << std::endl;
498  return EXIT_FAILURE;
499  }
500  if (linferror > 0.0046)
501  {
502  std::cout << " <!> Solution has changed !!! <!> " << std::endl;
503  return EXIT_FAILURE;
504  }
505 
506  // Exporter definition and use
507 
508  if (verbose)
509  {
510  std::cout << " -- Defining the exporter ... " << std::flush;
511  }
512  ExporterEnsight<mesh_Type> exporter ( dataFile, meshPtr, "solution", Comm->MyPID() ) ;
513  if (verbose)
514  {
515  std::cout << " done ! " << std::endl;
516  }
517 
518  if (verbose)
519  {
520  std::cout << " -- Defining the exported quantities ... " << std::flush;
521  }
522 
523  std::shared_ptr<vector_Type> solutionPtr (new vector_Type (*solution, Repeated) );
524  std::shared_ptr<vector_Type> solutionErrPtr (new vector_Type (solutionErr, Repeated) );
525 
526  if (verbose)
527  {
528  std::cout << " done ! " << std::endl;
529  }
530 
531  if (verbose)
532  {
533  std::cout << " -- Updating the exporter ... " << std::flush;
534  }
535  exporter.addVariable ( ExporterData<mesh_Type>::ScalarField, "solution", uFESpace, solutionPtr, UInt (0) );
536  exporter.addVariable ( ExporterData<mesh_Type>::ScalarField, "error", uFESpace, solutionErrPtr, UInt (0) );
537  if (verbose)
538  {
539  std::cout << " done ! " << std::endl;
540  }
541 
542  if (verbose)
543  {
544  std::cout << " -- Exporting ... " << std::flush;
545  }
546  exporter.postProcess (0);
547  if (verbose)
548  {
549  std::cout << " done ! " << std::endl;
550  }
551 
552  if (verbose)
553  {
554  std::cout << "End Result: TEST PASSED" << std::endl;
555  }
556 
557 #ifdef HAVE_MPI
558  MPI_Finalize();
559 #endif
560 
561  return ( EXIT_SUCCESS );
562 }
VectorEpetra - The Epetra Vector format Wrapper.
LifeV::Preconditioner basePrec_Type
Real exactSolution(const Real &t, const Real &x, const Real &y, const Real &z, const ID &)
void importFromHDF5(std::string const &fileName, std::string const &matrixName="matrix")
Read a matrix from a HDF5 (.h5) file.
MatrixEpetra< Real > matrix_Type
Real epsilon(1)
LifeV::PreconditionerIfpack prec_Type
FESpace< mesh_Type, MapEpetra > feSpace_Type
Epetra_Import const & importer()
Getter for the Epetra_Import.
Definition: MapEpetra.cpp:394
uint32_type ID
IDs.
Definition: LifeV.hpp:194
double Real
Generic real data.
Definition: LifeV.hpp:175
std::shared_ptr< prec_Type > precPtr_Type
std::shared_ptr< basePrec_Type > basePrecPtr_Type
std::shared_ptr< feSpace_Type > feSpacePtr_Type
Real fRhs(const Real &, const Real &x, const Real &, const Real &, const ID &)
int main(int argc, char **argv)