LifeV
NavierStokesSolver.hpp
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 NavierStokesSolver class
29  @brief This class contains all the informations necessary to solve a Navier-Stokes problem
30 
31  @author Gwenol Grandperrin <gwenol.grandperrin@epfl.ch>
32  @date 30-09-2011
33  */
34 
35 #ifndef NAVIERSTOKESSOLVER_HPP
36 #define NAVIERSTOKESSOLVER_HPP
37 
38 #include <string>
39 #include <iostream>
40 #include <boost/shared_ptr.hpp>
41 
42 
43 #ifdef HAVE_MPI
44 #include <Epetra_MpiComm.h>
45 #else
46 #include <Epetra_SerialComm.h>
47 #endif
48 
49 #include <Teuchos_ParameterList.hpp>
50 #include <Teuchos_XMLParameterListHelpers.hpp>
51 #include <Teuchos_RCP.hpp>
52 
53 
54 #include <lifev/core/LifeV.hpp>
55 #include <lifev/core/array/MapEpetra.hpp>
56 #include <lifev/core/array/MatrixEpetra.hpp>
57 #include <lifev/core/array/VectorEpetra.hpp>
58 #include <lifev/core/mesh/RegionMesh.hpp>
59 #include <lifev/core/util/Displayer.hpp>
60 #include <lifev/core/util/LifeAssert.hpp>
61 #include <lifev/core/util/LifeChrono.hpp>
62 #include <lifev/core/fem/FESpace.hpp>
63 #include <lifev/core/fem/BCHandler.hpp>
64 #include <lifev/core/fem/BCManage.hpp>
65 #include <lifev/core/fem/TimeAdvanceBDF.hpp>
66 #include <lifev/navier_stokes/solver/OseenAssembler.hpp>
67 
68 #include <lifev/navier_stokes/solver/NavierStokesSolver/ExporterPolicyNoExporter.hpp>
69 #include <lifev/navier_stokes/solver/NavierStokesSolver/NavierStokesProblem.hpp>
70 
71 
72 namespace LifeV
73 {
74 
75 template< class Mesh, class InitPolicy, class TimeIterationPolicy, class ExporterPolicy = ExporterPolicyNoExporter >
76 class NavierStokesSolver : private InitPolicy, public virtual TimeIterationPolicy, private ExporterPolicy
77 {
78 
79 public:
80 
89  typedef FESpace< Mesh, map_Type > fespace_Type;
93  //typedef LifeV::Preconditioner basePrec_Type;
94  //typedef std::shared_ptr<basePrec_Type> basePrecPtr_Type;
97  typedef OseenAssembler< Mesh, matrix_Type, vector_Type > assembler_Type;
99  typedef TimeAdvanceBDF<vector_Type> bdf_Type;
101 
102  //! @name Constructors, destructor
103  //@{
104 #ifdef HAVE_MPI
106 #else
107  NavierStokesSolver ( commPtr_Type comm = commPtr_Type ( new Epetra_SerialComm ) );
108 #endif
109 
110 
112 
113  //@}
114 
115  //! @name Methods
116  //@{
117 
118  //! Prints the error of the finite element solution vector
119  void printErrors();
120 
121  //! Setup all the parameters
122  void setup ( Teuchos::ParameterList& list );
123 
124  //! Computes an initial solutions, or several solutions, if needed.
125  void init();
126 
127  //! Solves the Navier-Stokes equations
128  void solve();
129 
130  //@}
131 
132  //! @name Set Methods
133  //@{
134 
135  //! Setup the problem to be solved
136  void setProblem ( NSProblemPtr_Type nsProblem );
137 
138  //@}
139 
140  //! @name Get Methods
141  //@{
142 
143  //! Returns the type of problem (e.g. Navier-Stokes)
144  NSProblemPtr_Type problem() const;
145 
147 
148  //! Returns the FE space for the velocity
149  fespacePtr_Type uFESpace() const;
150 
151  //! Returns the FE space for the pressure
152  fespacePtr_Type pFESpace() const;
153 
154  //! Returns the initial time
155  Real initialTime() const;
156 
157  //! Returns the end time
158  Real endTime() const;
159 
160  //! Returns the timestep
161  Real timestep() const;
162 
163  //! Returns the current time
164  Real currentTime() const;
165 
166  //@}
167 
168 private:
169 
170  // Informations and communications
173 
174  // Problem data
178 
179  // Finite element discretization
182 
183  // Solution data
186 
187  // Keeping track of time
193 
194  // Parameters
196 
197  // Getters for the policies
199  {
200  return M_displayer;
201  }
203  {
204  return M_mesh;
205  }
207  {
208  return M_comm;
209  }
210  bdfPtr_Type bdf() const
211  {
212  return M_bdf;
213  }
214 };
215 
216 
217 template< class Mesh, class InitPolicy, class TimeIterationPolicy, class ExporterPolicy >
218 NavierStokesSolver<Mesh, InitPolicy, TimeIterationPolicy, ExporterPolicy>::NavierStokesSolver ( commPtr_Type comm ) :
219  M_comm ( comm ), M_displayer ( comm )
220 {
221 
222 }
223 
224 template< class Mesh, class InitPolicy, class TimeIterationPolicy, class ExporterPolicy >
225 NavierStokesSolver<Mesh, InitPolicy, TimeIterationPolicy, ExporterPolicy>::~NavierStokesSolver()
226 {
227 
228 }
229 
230 template< class Mesh, class InitPolicy, class TimeIterationPolicy, class ExporterPolicy >
231 void
232 NavierStokesSolver<Mesh, InitPolicy, TimeIterationPolicy, ExporterPolicy>::printErrors()
233 {
234  ASSERT ( M_nsProblem->hasExactSolution(), "The problem does not have an exact solution" );
235 
236  vector_Type velocity ( M_uFESpace->map(), Repeated );
237  vector_Type pressure ( M_pFESpace->map(), Repeated );
238  M_displayer.leaderPrint ( "[Computing errors]\n" );
239  velocity.subset ( *M_solution );
240  pressure.subset ( *M_solution, M_uFESpace->fieldDim() * M_uFESpace->dof().numTotalDof() );
241  Real uRelativeError, pRelativeError, uL2Error, pL2Error;
242  uL2Error = M_uFESpace->l2Error ( M_nsProblem->uexact(), velocity, M_currentTime, &uRelativeError );
243  pL2Error = M_pFESpace->l20Error ( M_nsProblem->pexact(), pressure, M_currentTime, &pRelativeError );
244  M_displayer.leaderPrint ( "Velocity\n" );
245  M_displayer.leaderPrint ( " L2 error : ", uL2Error, "\n" );
246  M_displayer.leaderPrint ( " Relative error: ", uRelativeError, "\n" );
247  M_displayer.leaderPrint ( "Pressure\n" );
248  M_displayer.leaderPrint ( " L2 error : ", pL2Error, "\n");
249  M_displayer.leaderPrint ( " Relative error: ", pRelativeError, "\n" );
250 }
251 
252 template< class Mesh, class InitPolicy, class TimeIterationPolicy, class ExporterPolicy >
253 void
254 NavierStokesSolver<Mesh, InitPolicy, TimeIterationPolicy, ExporterPolicy>::setProblem ( NSProblemPtr_Type nsProblem )
255 {
256  M_nsProblem = nsProblem;
257 }
258 
259 template< class Mesh, class InitPolicy, class TimeIterationPolicy, class ExporterPolicy >
260 void
261 NavierStokesSolver<Mesh, InitPolicy, TimeIterationPolicy, ExporterPolicy>::setup ( Teuchos::ParameterList& list )
262 {
263  ASSERT ( M_nsProblem.get() != 0, "NavierStokesSolver::init : Error: You must set a Navier-Stokes problem first." );
264 
265  // FE parameters
266  std::string uOrder = list.get ( "Velocity FE", "P2" );
267  std::string pOrder = list.get ( "Pressure FE", "P1" );
268 
269  // Time parameters list
270  Teuchos::ParameterList timeList = list.sublist ( "Time: Parameter list" );
271  M_initialTime = timeList.get ( "Initial time", 0.0 );
272  M_endTime = timeList.get ( "Final time", 1e-2 );
273  M_timestep = timeList.get ( "Timestep", 1e-3 );
274 
275  // Solver parameters list
276  Teuchos::ParameterList solverList = list.sublist ( "Solver: Parameter list" );
277  M_usePreviousSolutionAsGuess = solverList.get ( "Use previous solution as guess", false );
278 
279  // +-----------------------------------------------+
280  // | Loading the mesh |
281  // +-----------------------------------------------+
282  M_displayer.leaderPrint ( "\n[Loading the mesh]\n" );
283  M_nsProblem->mesh ( M_mesh );
284 
285  // +-----------------------------------------------+
286  // | Creating the FE spaces |
287  // +-----------------------------------------------+
288  M_displayer.leaderPrint ( "\n[Creating the FE spaces]\n" );
289  LifeChrono feSpaceChrono;
290  feSpaceChrono.start();
291 
292  M_displayer.leaderPrint ( "FE for the velocity: ", uOrder, "\n" );
293  M_displayer.leaderPrint ( "FE for the pressure: ", pOrder, "\n" );
294 
295  M_displayer.leaderPrint ( "Building the velocity FE space ... " );
296  M_uFESpace.reset ( new fespace_Type ( M_mesh, uOrder, 3, M_comm ) );
297  M_displayer.leaderPrint ( "ok.\n" );
298 
299  M_displayer.leaderPrint ( "Building the pressure FE space ... " );
300  M_pFESpace.reset ( new fespace_Type ( M_mesh, pOrder, 1, M_comm ) );
301  M_displayer.leaderPrint ( "ok.\n" );
302 
303  // Creation of the total map
304  M_solutionMap.reset ( new map_Type ( M_uFESpace->map() + M_pFESpace->map() ) );
305 
306  // Pressure offset in the vector
307  UInt pressureOffset = M_uFESpace->fieldDim() * M_uFESpace->dof().numTotalDof();
308 
309  M_displayer.leaderPrint ( "Total Velocity Dof: ", pressureOffset, "\n" );
310  M_displayer.leaderPrint ( "Total Pressure Dof: ", M_pFESpace->dof().numTotalDof(), "\n" );
311 
312  feSpaceChrono.stop();
313  M_displayer.leaderPrintMax ("FE spaces building time: ", feSpaceChrono.diff(), " s.\n");
314 
315  // +-----------------------------------------------+
316  // | Boundary conditions |
317  // +-----------------------------------------------+
318  M_displayer.leaderPrint ( "\n[Boundary conditions]\n" );
319 
320  LifeChrono bcSetupChrono;
321  bcSetupChrono.start();
322 
323  M_bcHandler.reset ( new bcContainer_Type );
324 
325  M_displayer.leaderPrint ( "Setting BC... " );
326  M_nsProblem->boundaryConditions ( M_bcHandler );
327  M_displayer.leaderPrint ( "ok.\n" );
328 
329  // Update the BCHandler (internal data related to FE)
330  M_bcHandler->bcUpdate ( *M_mesh, M_uFESpace->feBd(), M_uFESpace->dof() );
331 
332  bcSetupChrono.stop();
333  M_displayer.leaderPrintMax ("Time to setup the BC: ", bcSetupChrono.diff(), " s.\n");
334 
335  // +-----------------------------------------------+
336  // | Vectors |
337  // +-----------------------------------------------+
338  M_displayer.leaderPrint ( "Creation of vectors... " );
339  M_solution.reset ( new vector_Type ( *M_solutionMap, Unique ) );
340  M_displayer.leaderPrint ( "done\n" );
341 
342  M_bdf.reset ( new bdf_Type );
343  M_bdf->setup ( TimeIterationPolicy::BDFOrder );
344 
345  // Exporter parameters list
346  Teuchos::ParameterList exporterList = list.sublist ( "Exporter: Parameter list" );
347  ExporterPolicy::initExporter ( exporterList,
348  M_solution );
349 
350  // Time iteration parameters list
351  Teuchos::ParameterList timeIterationList = list.sublist ( "Time iteration: Parameter list" );
352  TimeIterationPolicy::initTimeIteration ( timeIterationList );
353  // Init parameters list
354  InitPolicy::setupInit ( timeIterationList ) ;
355 
356 }
357 
358 template< class Mesh, class InitPolicy, class TimeIterationPolicy, class ExporterPolicy >
359 void
360 NavierStokesSolver<Mesh, InitPolicy, TimeIterationPolicy, ExporterPolicy>::init()
361 {
362  // Find an initial solution
363  InitPolicy::initSimulation ( M_bcHandler,
364  M_solution );
365 
367 
368  if ( M_nsProblem->hasExactSolution() )
369  {
371  }
372 
373  // Export the initial solution
374  ExporterPolicy::exportSolution ();
375 }
376 
377 template< class Mesh, class InitPolicy, class TimeIterationPolicy, class ExporterPolicy >
378 void
379 NavierStokesSolver<Mesh, InitPolicy, TimeIterationPolicy, ExporterPolicy>::solve()
380 {
381  // Solving the problem
382  M_displayer.leaderPrint ( "\n[Solving the problem]\n" );
383 
384  LifeChrono nsTimeLoopChrono;
385  nsTimeLoopChrono.start();
386 
388 
389  while ( M_currentTime <= M_endTime + M_timestep / 2. )
390  {
391  LifeChrono iterChrono;
392  iterChrono.start();
393 
394  M_displayer.leaderPrint ( "\n[t = ", M_currentTime, " s.]\n" );
395 
397  {
398  *M_solution = 0;
399  }
400 
401  TimeIterationPolicy::iterate ( M_solution,
402  M_bcHandler,
403  M_currentTime );
404 
405  // Updating the BDF scheme
406  M_bdf->shiftRight ( *M_solution );
407 
408  ExporterPolicy::exportSolution ();
409 
410  iterChrono.stop();
411  M_displayer.leaderPrintMax ( "Iteration time: ", iterChrono.diff(), " s.\n" );
412 
413  if ( M_nsProblem->hasExactSolution() )
414  {
416  }
417 
419 
420 #ifdef HAVE_MPI
421  MPI_Barrier ( MPI_COMM_WORLD );
422 #endif
423  }
424 
425  nsTimeLoopChrono.stop();
426  M_displayer.leaderPrintMax ("Time of the temporal loop: ", nsTimeLoopChrono.diff(), " s.\n");
427 
428  // Ending the simulation
429  ExporterPolicy::finalizeExporter();
430 }
431 
432 template< class Mesh, class InitPolicy, class TimeIterationPolicy, class ExporterPolicy >
433 typename NavierStokesSolver< Mesh, InitPolicy, TimeIterationPolicy, ExporterPolicy>::NSProblemPtr_Type
434 NavierStokesSolver<Mesh, InitPolicy, TimeIterationPolicy, ExporterPolicy>::problem() const
435 {
436  return M_nsProblem;
437 }
438 
439 template< class Mesh, class InitPolicy, class TimeIterationPolicy, class ExporterPolicy >
440 typename NavierStokesSolver< Mesh, InitPolicy, TimeIterationPolicy, ExporterPolicy>::bcContainerPtr_Type
441 NavierStokesSolver<Mesh, InitPolicy, TimeIterationPolicy, ExporterPolicy>::bcHandler() const
442 {
443  return M_bcHandler;
444 }
445 
446 template< class Mesh, class InitPolicy, class TimeIterationPolicy, class ExporterPolicy >
447 typename NavierStokesSolver< Mesh, InitPolicy, TimeIterationPolicy, ExporterPolicy>::fespacePtr_Type
448 NavierStokesSolver<Mesh, InitPolicy, TimeIterationPolicy, ExporterPolicy>::uFESpace() const
449 {
450  return M_uFESpace;
451 }
452 
453 template< class Mesh, class InitPolicy, class TimeIterationPolicy, class ExporterPolicy >
454 typename NavierStokesSolver< Mesh, InitPolicy, TimeIterationPolicy, ExporterPolicy>::fespacePtr_Type
455 NavierStokesSolver<Mesh, InitPolicy, TimeIterationPolicy, ExporterPolicy>::pFESpace() const
456 {
457  return M_pFESpace;
458 }
459 
460 template< class Mesh, class InitPolicy, class TimeIterationPolicy, class ExporterPolicy >
461 Real
462 NavierStokesSolver<Mesh, InitPolicy, TimeIterationPolicy, ExporterPolicy>::initialTime() const
463 {
464  return M_initialTime;
465 }
466 
467 template< class Mesh, class InitPolicy, class TimeIterationPolicy, class ExporterPolicy >
468 Real
469 NavierStokesSolver<Mesh, InitPolicy, TimeIterationPolicy, ExporterPolicy>::endTime() const
470 {
471  return M_endTime;
472 }
473 
474 template< class Mesh, class InitPolicy, class TimeIterationPolicy, class ExporterPolicy >
475 Real
476 NavierStokesSolver<Mesh, InitPolicy, TimeIterationPolicy, ExporterPolicy>::timestep() const
477 {
478  return M_timestep;
479 }
480 
481 template< class Mesh, class InitPolicy, class TimeIterationPolicy, class ExporterPolicy >
482 Real
483 NavierStokesSolver<Mesh, InitPolicy, TimeIterationPolicy, ExporterPolicy>::currentTime() const
484 {
485  return M_currentTime;
486 }
487 
488 } // namespace LifeV
489 
490 #endif /* NAVIERSTOKESSOLVER_HPP */
VectorEpetra - The Epetra Vector format Wrapper.
MatrixEpetra< Real > matrix_Type
void start()
Start the timer.
Definition: LifeChrono.hpp:93
bcContainerPtr_Type bcHandler() const
void importFromHDF5(std::string const &fileName, std::string const &matrixName="matrix")
Read a matrix from a HDF5 (.h5) file.
Displayer(const commPtr_Type &comm)
Definition: Displayer.cpp:56
void printErrors()
Prints the error of the finite element solution vector.
BCHandler - class for handling boundary conditions.
Definition: BCHandler.hpp:100
std::shared_ptr< assembler_Type > assemblerPtr_Type
void setup(Teuchos::ParameterList &list)
Setup all the parameters.
std::shared_ptr< fespace_Type > fespacePtr_Type
Real endTime() const
Returns the end time.
std::shared_ptr< comm_Type > commPtr_Type
void updateInverseJacobian(const UInt &iQuadPt)
Real timestep() const
Returns the timestep.
std::shared_ptr< bdf_Type > bdfPtr_Type
Real initialTime() const
Returns the initial time.
void solve()
Solves the Navier-Stokes equations.
OseenAssembler< Mesh, matrix_Type, vector_Type > assembler_Type
Epetra_Import const & importer()
Getter for the Epetra_Import.
Definition: MapEpetra.cpp:394
fespacePtr_Type pFESpace() const
Returns the FE space for the pressure.
std::shared_ptr< map_Type > mapPtr_Type
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
std::shared_ptr< Mesh > meshPtr_Type
NavierStokesSolver(commPtr_Type comm=commPtr_Type(new Epetra_MpiComm(MPI_COMM_WORLD)))
Real diff()
Compute the difference in time between start and stop.
Definition: LifeChrono.hpp:111
FESpace< Mesh, map_Type > fespace_Type
void init()
Computes an initial solutions, or several solutions, if needed.
bcContainerPtr_Type M_bcHandler
Real currentTime() const
Returns the current time.
double Real
Generic real data.
Definition: LifeV.hpp:175
std::shared_ptr< NavierStokesProblem< Mesh > > NSProblemPtr_Type
TimeAdvanceBDF< vector_Type > bdf_Type
void stop()
Stop the timer.
Definition: LifeChrono.hpp:100
void setProblem(NSProblemPtr_Type nsProblem)
Setup the problem to be solved.
fespacePtr_Type uFESpace() const
Returns the FE space for the velocity.
std::shared_ptr< matrix_Type > matrixPtr_Type
std::shared_ptr< VectorEpetra > vectorPtr_Type
NSProblemPtr_Type problem() const
Returns the type of problem (e.g. Navier-Stokes)
Displayer - This class is used to display messages in parallel simulations.
Definition: Displayer.hpp:62
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
std::shared_ptr< bcContainer_Type > bcContainerPtr_Type