LifeV
lifev/core/testsuite/adr_assembler/1d/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
32  @date
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 #include <lifev/core/algorithm/PreconditionerIfpack.hpp>
48 #include <lifev/core/algorithm/PreconditionerML.hpp>
49 
50 #include <lifev/core/algorithm/SolverAztecOO.hpp>
51 #include <lifev/core/algorithm/LinearSolver.hpp>
52 
53 #include <lifev/core/array/MatrixEpetra.hpp>
54 
55 #ifdef HAVE_HDF5
56 #include <lifev/core/filter/ExporterHDF5.hpp>
57 #else
58 #include <lifev/core/filter/ExporterVTK.hpp>
59 #endif
60 
61 #include <lifev/core/fem/FESpace.hpp>
62 #include <lifev/core/fem/BCManage.hpp>
63 
64 #include <lifev/core/mesh/RegionMesh1DStructured.hpp>
65 #include <lifev/core/mesh/MeshData.hpp>
66 
67 #include <lifev/core/solver/ADRAssembler.hpp>
68 
69 #include <Teuchos_ParameterList.hpp>
70 #include <Teuchos_XMLParameterListHelpers.hpp>
71 #include <Teuchos_RCP.hpp>
72 
73 using namespace LifeV;
74 
75 namespace
76 {
77 static bool regIF = (PRECFactory::instance().registerProduct ( "Ifpack", &createIfpack ) );
78 static bool regML = (PRECFactory::instance().registerProduct ( "ML", &createML ) );
79 }
80 
81 Real exactSolution ( const Real& /* t */, const Real& x, const Real& /*y*/, const Real& /* z */, const ID& /* i */ )
82 {
83  return std::sin ( M_PI * 0.5 * x );
84 }
85 
86 
87 Real fRhs ( const Real& /* t */, const Real& x, const Real& /* y */, const Real& /* z */ , const ID& /* i */ )
88 {
89  return 1.25 * M_PI * M_PI * std::sin ( M_PI * 0.5 * x );
90 }
91 
92 
93 int
94 main ( int argc, char* argv[] )
95 {
96 
97 #ifdef HAVE_MPI
98  MPI_Init (&argc, &argv);
99 #endif
100 
101  {
102  // needed to properly destroy all objects inside before mpi finalize
103 
104 #ifdef HAVE_MPI
105  std::shared_ptr<Epetra_Comm> Comm (new Epetra_MpiComm (MPI_COMM_WORLD) );
106  ASSERT ( Comm->NumProc() < 2, "The test does not run in parallel." );
107 #else
108  std::shared_ptr<Epetra_Comm> Comm (new Epetra_SerialComm);
109 #endif
110 
111  typedef RegionMesh<LinearLine> mesh_Type;
112  typedef MatrixEpetra<Real> matrix_Type;
113  typedef VectorEpetra vector_Type;
114  typedef std::shared_ptr<vector_Type> vectorPtr_Type;
115  typedef FESpace<mesh_Type, MapEpetra> feSpace_Type;
116 
117  typedef LifeV::Preconditioner basePrec_Type;
118  typedef std::shared_ptr<basePrec_Type> basePrecPtr_Type;
119  typedef LifeV::PreconditionerIfpack prec_Type;
120  typedef std::shared_ptr<prec_Type> precPtr_Type;
121 
122  typedef std::shared_ptr<feSpace_Type> feSpacePtr_Type;
123 
124 
125  const bool verbose (Comm->MyPID() == 0);
126 
127  // Read first the data needed
128 
129  if (verbose)
130  {
131  std::cout << " -- Reading the data ... " << std::flush;
132  }
133  GetPot dataFile ( "data" );
134  if (verbose)
135  {
136  std::cout << " done ! " << std::endl;
137  }
138 
139  // Build the mesh
140 
141  if (verbose)
142  {
143  std::cout << " -- Reading the mesh ... " << std::flush;
144  }
145  // MeshData meshData(dataFile, "mesh");
146  std::shared_ptr< mesh_Type > meshPtr ( new mesh_Type ( Comm ) );
147 
148  // Set up the structured mesh
149  regularMesh1D ( *meshPtr, 0,
150  dataFile ( "mesh/n", 20 ),
151  dataFile ( "mesh/verbose", false ),
152  dataFile ( "mesh/length", 1. ),
153  dataFile ( "mesh/origin", 0. ) );
154 
155  if (verbose)
156  {
157  std::cout << " done ! " << std::endl;
158  }
159 
160  // Build the FESpaces
161  if (verbose)
162  {
163  std::cout << " -- Building FESpaces ... " << std::flush;
164  }
165  feSpacePtr_Type uFESpace ( new feSpace_Type ( meshPtr, feSegP1, quadRuleSeg1pt, quadRuleNode1pt, 1, Comm ) );
166  if (verbose)
167  {
168  std::cout << " done ! " << std::endl;
169  }
170  if (verbose)
171  {
172  std::cout << " ---> Dofs: " << uFESpace->dof().numTotalDof() << std::endl;
173  }
174 
175  // Build the assembler and the matrices
176 
177  if (verbose)
178  {
179  std::cout << " -- Building assembler ... " << std::flush;
180  }
181  ADRAssembler<mesh_Type, matrix_Type, vector_Type> adrAssembler;
182  if (verbose)
183  {
184  std::cout << " done! " << std::endl;
185  }
186 
187  if (verbose)
188  {
189  std::cout << " -- Setting up assembler ... " << std::flush;
190  }
191  adrAssembler.setFespace (uFESpace);
192  if (verbose)
193  {
194  std::cout << " done! " << std::endl;
195  }
196 
197  if (verbose)
198  {
199  std::cout << " -- Defining the matrix ... " << std::flush;
200  }
201  std::shared_ptr<matrix_Type> systemMatrix (new matrix_Type ( uFESpace->map() ) );
202  if (verbose)
203  {
204  std::cout << " done! " << std::endl;
205  }
206 
207  // Perform the assembly of the matrix
208 
209  if (verbose)
210  {
211  std::cout << " -- Adding the diffusion ... " << std::flush;
212  }
213  adrAssembler.addDiffusion (systemMatrix, 1.);
214  if (verbose)
215  {
216  std::cout << " done! " << std::endl;
217  }
218  if (verbose)
219  {
220  std::cout << " Time needed : " << adrAssembler.diffusionAssemblyChrono().diffCumul() << std::endl;
221  }
222 
223  if (verbose)
224  {
225  std::cout << " -- Adding the mass ... " << std::flush;
226  }
227  adrAssembler.addMass (systemMatrix, M_PI * M_PI );
228  if (verbose)
229  {
230  std::cout << " done! " << std::endl;
231  }
232 
233  if (verbose)
234  {
235  std::cout << " -- Closing the matrix ... " << std::flush;
236  }
237  systemMatrix->globalAssemble();
238  if (verbose)
239  {
240  std::cout << " done ! " << std::endl;
241  }
242 
243  // Definition and assembly of the RHS
244  if (verbose)
245  {
246  std::cout << " -- Building the RHS ... " << std::flush;
247  }
248  vector_Type rhs (uFESpace->map(), Repeated);
249 
250  vector_Type fInterpolated (uFESpace->map(), Repeated);
251  uFESpace->interpolate ( static_cast<feSpace_Type::function_Type> ( fRhs ), fInterpolated, 0.0 );
252  adrAssembler.addMassRhs (rhs, fInterpolated);
253  rhs.globalAssemble();
254 
255  if (verbose)
256  {
257  std::cout << " done ! " << std::endl;
258  }
259 
260  // Definition and application of the BCs
261  if (verbose)
262  {
263  std::cout << " -- Building the BCHandler ... " << std::flush;
264  }
265  BCHandler bchandler;
266 
267  BCFunctionBase BCu ( static_cast<feSpace_Type::function_Type> ( exactSolution ) );
268 
269  bchandler.addBC ("Dirichlet", Structured1DLabel::LEFT, Essential, Full, BCu, 1);
270  bchandler.addBC ("Dirichlet", Structured1DLabel::RIGHT, Essential, Full, BCu, 1);
271 
272  if (verbose)
273  {
274  std::cout << " done ! " << std::endl;
275  }
276 
277  if (verbose)
278  {
279  std::cout << " -- Updating the BCs ... " << std::flush;
280  }
281  bchandler.bcUpdate (*uFESpace->mesh(), uFESpace->feBd(), uFESpace->dof() );
282  if (verbose)
283  {
284  std::cout << " done ! " << std::endl;
285  }
286 
287  if (verbose)
288  {
289  std::cout << " -- Applying the BCs ... " << std::flush;
290  }
291  vectorPtr_Type rhsBC ( new vector_Type (rhs, Unique) );
292  bcManage (*systemMatrix, *rhsBC, *uFESpace->mesh(), uFESpace->dof(), bchandler, uFESpace->feBd(), 1.0, 0.0);
293  rhs = *rhsBC;
294  if (verbose)
295  {
296  std::cout << " done ! " << std::endl;
297  }
298 
299  // Definition of the solver
300  if (verbose)
301  {
302  std::cout << " -- Building the solver ... " << std::flush;
303  }
304  LinearSolver linearSolver;
305 
306  if (verbose)
307  {
308  std::cout << " done ! " << std::endl;
309  }
310 
311  if (verbose)
312  {
313  std::cout << " -- Setting up the solver ... " << std::flush;
314  }
315  Teuchos::RCP< Teuchos::ParameterList > belosList = Teuchos::rcp ( new Teuchos::ParameterList );
316  belosList = Teuchos::getParametersFromXmlFile ( "SolverParamList.xml" );
317 
318  linearSolver.setCommunicator ( Comm );
319  linearSolver.setParameters ( *belosList );
320 
321  prec_Type* precRawPtr;
322  basePrecPtr_Type precPtr;
323  precRawPtr = new prec_Type;
324  precRawPtr->setDataFromGetPot ( dataFile, "prec" );
325  precPtr.reset ( precRawPtr );
326  linearSolver.setPreconditioner ( precPtr );
327  if (verbose)
328  {
329  std::cout << " done ! " << std::endl;
330  }
331 
332  if (verbose)
333  {
334  std::cout << " -- Setting matrix in the solver ... " << std::flush;
335  }
336  linearSolver.setOperator ( systemMatrix );
337  if (verbose)
338  {
339  std::cout << " done ! " << std::endl;
340  }
341 
342  // Definition of the solution
343  if (verbose)
344  {
345  std::cout << " -- Defining the solution ... " << std::flush;
346  }
347  vectorPtr_Type solution (new vector_Type (uFESpace->map(), Unique) );
348  if (verbose)
349  {
350  std::cout << " done ! " << std::endl;
351  }
352 
353  // Solve the solution
354  if (verbose)
355  {
356  std::cout << " -- Solving the system ... " << std::flush;
357  }
358  linearSolver.setRightHandSide ( rhsBC );
359  linearSolver.solve ( solution );
360  if (verbose)
361  {
362  std::cout << " done ! " << std::endl;
363  }
364 
365  // Error computation
366  if (verbose)
367  {
368  std::cout << " -- Computing the error ... " << std::flush;
369  }
370  vector_Type solutionErr (*solution);
371  uFESpace->interpolate ( static_cast<feSpace_Type::function_Type> ( exactSolution ), solutionErr, 0.0 );
372  solutionErr -= *solution;
373  solutionErr.abs();
374  Real l2error (uFESpace->l2Error (exactSolution, vector_Type (*solution, Repeated), 0.0) );
375  if (verbose)
376  {
377  std::cout << " -- done ! " << std::endl;
378  }
379  if (verbose)
380  {
381  std::cout << " ---> Norm L2 : " << l2error << std::endl;
382  }
383  Real linferror ( solutionErr.normInf() );
384  if (verbose)
385  {
386  std::cout << " ---> Norm Inf : " << linferror << std::endl;
387  }
388 
389  // Exporter definition and use
390  if (verbose)
391  {
392  std::cout << " -- Defining the exporter ... " << std::flush;
393  }
394 
395 #ifdef HAVE_HDF5
396  ExporterHDF5<mesh_Type> exporter ( dataFile, "solution" );
397 #else
398  ExporterVTK<mesh_Type> exporter ( dataFile, "solution" );
399 #endif
400  exporter.setMeshProcId ( meshPtr, Comm->MyPID() ) ;
401  if (verbose)
402  {
403  std::cout << " done ! " << std::endl;
404  }
405 
406  if (verbose)
407  {
408  std::cout << " -- Defining the exported quantities ... " << std::flush;
409  }
410 
411  std::shared_ptr<vector_Type> solutionPtr (new vector_Type (*solution, Repeated) );
412  std::shared_ptr<vector_Type> solutionErrPtr (new vector_Type (solutionErr, Repeated) );
413 
414  if (verbose)
415  {
416  std::cout << " done ! " << std::endl;
417  }
418 
419  if (verbose)
420  {
421  std::cout << " -- Updating the exporter ... " << std::flush;
422  }
423  exporter.addVariable ( ExporterData<mesh_Type>::ScalarField, "solution", uFESpace, solutionPtr, UInt (0) );
424  exporter.addVariable ( ExporterData<mesh_Type>::ScalarField, "error", uFESpace, solutionErrPtr, UInt (0) );
425  if (verbose)
426  {
427  std::cout << " done ! " << std::endl;
428  }
429 
430  if (verbose)
431  {
432  std::cout << " -- Exporting ... " << std::flush;
433  }
434  exporter.postProcess (0);
435  if (verbose)
436  {
437  std::cout << " done ! " << std::endl;
438  }
439 
440  if ( std::fabs ( l2error - 0.0006169843149652788l ) > 1e-10 )
441  {
442  std::cout << " <!> Solution has changed !!! <!> " << std::endl;
443  return EXIT_FAILURE;
444  }
445  if ( std::fabs ( linferror - 0.0001092814405985187l ) > 1e-10 )
446  {
447  std::cout << " <!> Solution has changed !!! <!> " << std::endl;
448  return EXIT_FAILURE;
449  }
450 
451  if (verbose)
452  {
453  std::cout << "End Result: TEST PASSED" << std::endl;
454  }
455 
456  } // needed to properly destroy all objects inside before mpi finalize
457 
458 #ifdef HAVE_MPI
459  MPI_Finalize();
460 #endif
461 
462  return ( EXIT_SUCCESS );
463 }
Real exactSolution(const Real &t, const Real &x, const Real &y, const Real &z, const ID &)
#define M_PI
Definition: winmath.h:20
uint32_type ID
IDs.
Definition: LifeV.hpp:194
double Real
Generic real data.
Definition: LifeV.hpp:175
Real fRhs(const Real &, const Real &x, const Real &, const Real &, const ID &)
int main(int argc, char **argv)