LifeV
lifev/navier_stokes/examples/TestCases/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 main.cpp
29  @brief Application to solve different Navier-Stokes problem
30 
31  @author Gwenol Grandperrin <gwenol.grandperrin@epfl.ch>
32  @date 03-12-2013
33  */
34 
35 #include <Epetra_ConfigDefs.h>
36 #ifdef EPETRA_MPI
37 #include <mpi.h>
38 #include <Epetra_MpiComm.h>
39 #else
40 #include <Epetra_SerialComm.h>
41 #endif
42 
43 #include <Teuchos_ParameterList.hpp>
44 #include <Teuchos_XMLParameterListHelpers.hpp>
45 #include <Teuchos_RCP.hpp>
46 
47 #include <lifev/core/LifeV.hpp>
48 #include <lifev/core/mesh/RegionMesh.hpp>
49 #include <lifev/core/util/Displayer.hpp>
50 #include <lifev/core/algorithm/Preconditioner.hpp>
51 #include <lifev/core/algorithm/PreconditionerIfpack.hpp>
52 #include <lifev/core/algorithm/PreconditionerML.hpp>
53 #include <lifev/core/algorithm/PreconditionerLinearSolver.hpp>
54 
55 // Includes the policies that I need to use
56 // (Here the list is quite exhaustive)
57 #include <lifev/navier_stokes/solver/NavierStokesSolver/NavierStokesProblem.hpp>
58 #include <lifev/navier_stokes/solver/NavierStokesSolver/NavierStokesSolver.hpp>
59 #include <lifev/navier_stokes/solver/NavierStokesSolver/AssemblyPolicyStokes.hpp>
60 #include <lifev/navier_stokes/solver/NavierStokesSolver/AssemblyPolicyGeneralizedStokes.hpp>
61 #include <lifev/navier_stokes/solver/NavierStokesSolver/AssemblyPolicyNavierStokesSemiImplicit.hpp>
62 #include <lifev/navier_stokes/solver/NavierStokesSolver/AssemblyPolicyNavierStokesNewton.hpp>
63 #include <lifev/navier_stokes/solver/NavierStokesSolver/AssemblyPolicyNavierStokesPicard.hpp>
64 #include <lifev/navier_stokes/solver/NavierStokesSolver/TimeIterationPolicyLinear.hpp>
65 #include <lifev/navier_stokes/solver/NavierStokesSolver/TimeIterationPolicyNonlinear.hpp>
66 #include <lifev/navier_stokes/solver/NavierStokesSolver/TimeIterationPolicyNonlinearIncremental.hpp>
67 #include <lifev/navier_stokes/solver/NavierStokesSolver/InitPolicyInterpolation.hpp>
68 #include <lifev/navier_stokes/solver/NavierStokesSolver/InitPolicyProjection.hpp>
69 #include <lifev/navier_stokes/solver/NavierStokesSolver/InitPolicySolver.hpp>
70 #include <lifev/navier_stokes/solver/NavierStokesSolver/ExporterPolicyHDF5.hpp>
71 
72 // Includes different test cases
73 #include <lifev/navier_stokes/examples/TestCases/NavierStokesCavity.hpp>
74 #include <lifev/navier_stokes/examples/TestCases/NavierStokesEthierSteinman.hpp>
75 
76 // Preconditioners for the Navier-Stokes equations
77 #include <lifev/navier_stokes/algorithm/PreconditionerLSC.hpp>
78 #include <lifev/navier_stokes/algorithm/PreconditionerPCD.hpp>
79 #include <lifev/navier_stokes/algorithm/PreconditionerSIMPLE.hpp>
80 #include <lifev/navier_stokes/algorithm/PreconditionerYosida.hpp>
81 
82 using namespace LifeV;
83 
84 namespace
85 {
86 
90 
104 
105 // This function is just there to create a preconditioner for the problem
106 // Note that for now some arguments are commented.
107 // This is because they will be used for more advanced preconditioners
108 // that should be merged soon.
110  const std::string& preconditionerName,
111  const std::string& precSection,
112  std::shared_ptr<NavierStokesProblem<mesh_Type> > nsProblem,
113  const nsSolver_Type& nsSolver,
114  const GetPot& dataFile,
115  std::shared_ptr<Epetra_Comm> Comm,
116  const bool useMinusDiv )
117 {
118  if ( preconditionerName == "FromFile" )
119  {
120  std::string precName = dataFile ( "prec/prectype", "Ifpack" );
121  precPtr.reset ( PRECFactory::instance().createObject ( precName ) );
122  ASSERT ( precPtr.get() != 0, " Preconditioner not set" );
123  precPtr->setDataFromGetPot ( dataFile, precSection );
124  }
125 #ifdef LIFEV_HAVE_TEKO
126  else if ( preconditionerName == "LSC" )
127  {
128  PreconditionerLSC* precLSCRawPtr ( 0 );
129  precLSCRawPtr = new PreconditionerLSC;
130  precLSCRawPtr->setFESpace ( nsSolver.uFESpace(), nsSolver.pFESpace() );
131  precLSCRawPtr->setDataFromGetPot ( dataFile, precSection );
132  precPtr.reset ( precLSCRawPtr );
133  }
134 #endif // LIFEV_HAVE_TEKO
135  else if ( preconditionerName == "PCD" )
136  {
137  PreconditionerPCD* precPCDRawPtr ( 0 );
138  precPCDRawPtr = new PreconditionerPCD;
139  precPCDRawPtr->setFESpace ( nsSolver.uFESpace(), nsSolver.pFESpace() );
140  precPCDRawPtr->setBCHandler ( nsSolver.bcHandler() );
141  precPCDRawPtr->setTimestep ( nsSolver.timestep() );
142  precPCDRawPtr->setViscosity ( nsProblem->viscosity() );
143  precPCDRawPtr->setDensity ( nsProblem->density() );
144  precPCDRawPtr->setComm ( Comm );
145  precPCDRawPtr->setDataFromGetPot ( dataFile, precSection );
146  precPCDRawPtr->setUseMinusDivergence ( useMinusDiv );
147  precPtr.reset ( precPCDRawPtr );
148  }
149  else if ( preconditionerName == "SIMPLE" )
150  {
151  PreconditionerSIMPLE* precSIMPLERawPtr ( 0 );
152  precSIMPLERawPtr = new PreconditionerSIMPLE;
153  precSIMPLERawPtr->setFESpace ( nsSolver.uFESpace(), nsSolver.pFESpace() );
154  precSIMPLERawPtr->setDampingFactor ( 1.0 );
155  precSIMPLERawPtr->setComm ( Comm );
156  precSIMPLERawPtr->setDataFromGetPot ( dataFile, precSection );
157  precPtr.reset ( precSIMPLERawPtr );
158  }
159  else if ( preconditionerName == "Yosida" )
160  {
161  PreconditionerYosida* precYosidaRawPtr ( 0 );
162  precYosidaRawPtr = new PreconditionerYosida;
163  precYosidaRawPtr->setFESpace ( nsSolver.uFESpace(), nsSolver.pFESpace() );
164  precYosidaRawPtr->setTimestep ( nsSolver.timestep() );
165  precYosidaRawPtr->setComm ( Comm );
166  precYosidaRawPtr->setDataFromGetPot ( dataFile, precSection );
167  precPtr.reset ( precYosidaRawPtr );
168  }
169  else
170  {
171  ASSERT ( false, "The preconditioner is unknown." );
172  }
173 }
174 
175 }
176 
177 
178 int
179 main ( int argc, char** argv )
180 {
181  // +-----------------------------------------------+
182  // | Initialization of MPI |
183  // +-----------------------------------------------+
184 #ifdef HAVE_MPI
185  MPI_Init ( &argc, &argv );
186  {
187  std::shared_ptr<Epetra_Comm> Comm ( new Epetra_MpiComm ( MPI_COMM_WORLD ) );
188 #else
189  std::shared_ptr<Epetra_Comm> Comm ( new Epetra_SerialComm );
190 #endif
191 
192  Displayer displayer ( Comm );
193 
194  displayer.leaderPrint ( " +-----------------------------------------------+\n" );
195  displayer.leaderPrint ( " | Navier-Stokes Framework |\n" );
196  displayer.leaderPrint ( " +-----------------------------------------------+\n\n" );
197  displayer.leaderPrint ( " +-----------------------------------------------+\n" );
198  displayer.leaderPrint ( " | Author: Gwenol Grandperrin |\n" );
199  displayer.leaderPrint ( " | Date: 2013-12-03 |\n" );
200  displayer.leaderPrint ( " +-----------------------------------------------+\n" );
201 
202  displayer.leaderPrint ( "\n[Initilization of MPI]\n" );
203 #ifdef HAVE_MPI
204  displayer.leaderPrint ( "Using MPI (", Comm->NumProc(), " proc.)\n" );
205 #else
206  displayer.leaderPrint ( "Using serial version\n" );
207 #endif
208 
209  LifeChrono globalChrono;
210  globalChrono.start();
211 
212  // +-----------------------------------------------+
213  // | Loading the data |
214  // +-----------------------------------------------+
215  displayer.leaderPrint ( "\n[Loading the data]\n" );
216 
217  // **** Stupid GetPot stuff ****
218  // In principle it would be better to rely only on
219  // teuchos lists but for now the preconditioners
220  // still read data from GetPot.
221  GetPot command_line ( argc, argv );
222  const std::string datafileName = command_line.follow ( "data", 2, "-f", "--data" );
223  GetPot dataFile ( datafileName );
224  // *****************************
225  Teuchos::ParameterList mainList = * ( Teuchos::getParametersFromXmlFile ( datafileName + ".xml" ) );
226 
227  std::string initPreconditionerName = mainList.get ( "Preconditioner for init", "none" );
228  std::string preconditionerName = mainList.get ( "Preconditioner", "none" );
229 
230  // +-----------------------------------------------+
231  // | Setup the test case |
232  // +-----------------------------------------------+
233  displayer.leaderPrint ( "\n[Setup the test case]\n" );
234 
235  // Problem parameters list
236  Teuchos::ParameterList problemList = mainList.sublist ( "Navier-Stokes problem: Parameter list" );
237  const std::string benchmark = problemList.get ( "Test case name", "none" );
238  const Real viscosity = problemList.get ( "Viscosity", 0.035 );
239  const Real density = problemList.get ( "Density", 1.0 );
240  const UInt meshRefinement = problemList.get ( "Mesh refinement", 2 );
241  std::string meshPath = problemList.get ( "Resources path", "./Resources" );
242  meshPath.append ("/");
243 
244  // Here we create a Navier-Stokes problem object
245  std::shared_ptr< NavierStokesProblem< mesh_Type > > nsProblem;
246  if ( benchmark == "Cavity" )
247  {
248  nsProblem.reset ( new NavierStokesCavity );
249  }
250  else if ( benchmark == "Ethier-Steinman" )
251  {
252  nsProblem.reset ( new NavierStokesEthierSteinman );
253  }
254  else
255  {
256  displayer.leaderPrint ( "[Error] This benchmark does not exist\n" );
257  exit ( 1 );
258  }
259  nsProblem->setMesh ( meshRefinement, meshPath );
260  nsProblem->setViscosity ( viscosity );
261  nsProblem->setDensity ( density );
262 
263  displayer.leaderPrint ( "Test case : ", nsProblem->name(), "\n" );
264 
265  // Mesh discretization
266  displayer.leaderPrint ( "Mesh refinement : ", meshRefinement, "\n" );
267  displayer.leaderPrint ( "Mesh path : ", meshPath, "\n" );
268 
269  // Physical quantity
270  displayer.leaderPrint ( "Viscosity : ", viscosity, "\n" );
271  displayer.leaderPrint ( "Density : ", density, "\n" );
272 
273  // +-----------------------------------------------+
274  // | Initialization |
275  // +-----------------------------------------------+
276  Teuchos::ParameterList nsSolverList = mainList.sublist ( "Navier-Stokes solver: Parameter list" );
277  bool useMinusDiv = nsSolverList.sublist ( "Time iteration: Parameter list" )
278  .sublist ( "Assembly: Parameter list" )
279  .get ( "Use minus divergence" , true );
280 
281  // We create the solver, set the problem, set the preconditioner
282  // and set the parameters.
283  nsSolver_Type nsSolver;
284  nsSolver.setProblem ( nsProblem );
285  nsSolver.setup ( nsSolverList );
286  basePrecPtr_Type precPtr;
287  setPreconditioner ( precPtr, initPreconditionerName,
288  "initprec", nsProblem, nsSolver, dataFile,
289  Comm, useMinusDiv );
290  nsSolver.setPreconditioner ( precPtr );
291 
292  // We compute the initial condition
293  nsSolver.init();
294 
295  // +-----------------------------------------------+
296  // | Solving the problem |
297  // +-----------------------------------------------+
298  // We set the preconditioner
299  setPreconditioner ( precPtr, preconditionerName,
300  "prec", nsProblem, nsSolver, dataFile,
301  Comm, useMinusDiv );
302  nsSolver.setPreconditioner ( precPtr );
303 
304  // We solve the Navier-Stokes equations timestep after timestep
305  nsSolver.solve();
306 
307  globalChrono.stop();
308  displayer.leaderPrintMax ( "\nTotal simulation time: ", globalChrono.diff(), " s.\n" );
309  displayer.leaderPrint ( "\n[[END_SIMULATION]]\n" );
310 
311 #ifdef HAVE_MPI
312  }
313  MPI_Finalize();
314 #endif
315  return ( EXIT_SUCCESS );
316 }
TimeIterationPolicyNonlinearIncremental< mesh_Type, AssemblyPolicyNavierStokesNewton< mesh_Type > > Newton
InitPolicyProjection< SolverPolicyLinearSolver > InitProj
TimeIterationPolicyNonlinear< mesh_Type, AssemblyPolicyNavierStokesPicard< mesh_Type > > PicardOseen
PreconditionerPCD(std::shared_ptr< Epetra_Comm > comm=std::shared_ptr< Epetra_Comm >(new Epetra_MpiComm(MPI_COMM_WORLD)))
default constructor
TimeIterationPolicyLinear< mesh_Type, AssemblyPolicyNavierStokesSemiImplicit< mesh_Type > > SemiImplicit
PreconditionerSIMPLE(std::shared_ptr< Epetra_Comm > comm=std::shared_ptr< Epetra_Comm >(new Epetra_MpiComm(MPI_COMM_WORLD)))
default constructor
void updateInverseJacobian(const UInt &iQuadPt)
void setDataFromGetPot(const GetPot &dataFile, const std::string &section)
Setter using GetPot.
void setUseMinusDivergence(const bool &useMinusDivergence)
Setter to know if we used B or -B in the discretization of the Navier-Stokes equations.
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
void setDataFromGetPot(const GetPot &dataFile, const std::string &section)
Setter using GetPot.
NavierStokesSolver(commPtr_Type comm=commPtr_Type(new Epetra_MpiComm(MPI_COMM_WORLD)))
int main(int argc, char **argv)
Definition: dummy.cpp:5
TimeIterationPolicyNonlinearIncremental< mesh_Type, AssemblyPolicyNavierStokesPicard< mesh_Type > > Picard
TimeIterationPolicyLinear< mesh_Type, AssemblyPolicyStokes< mesh_Type > > Stokes
Preconditioner - Abstract preconditioner class.
void setPreconditioner(basePrecPtr_Type &precPtr, const std::string &preconditionerName, const std::string &precSection, std::shared_ptr< NavierStokesProblem< mesh_Type > > nsProblem, const nsSolver_Type &nsSolver, const GetPot &dataFile, std::shared_ptr< Epetra_Comm > Comm, const bool useMinusDiv)
const std::string operator()(const char *VarName, const char *Default) const
Definition: GetPot.hpp:2045
TimeIterationPolicyLinear< mesh_Type, AssemblyPolicyGeneralizedStokes< mesh_Type > > GStokes
InitPolicySolver< mesh_Type, GStokes > InitGStokes
void setDampingFactor(const Real &dampingFactor)
Setter for the damping factor.
NavierStokesSolver< mesh_Type, InitStokes, SemiImplicit, HDF5Exporter > nsSolver_Type