LifeV
cavity.cpp
Go to the documentation of this file.
1 /* -*- Mode : c++; c-tab-always-indent: t; indent-tabs-mode: nil; -*-
2 
3  <short description here>
4 
5  Gilles Fourestey gilles.fourestey@epfl.ch
6 
7 */
8 /** \file cavity.cpp
9 
10 */
11 
12 
13 #include <Epetra_ConfigDefs.h>
14 #ifdef EPETRA_MPI
15 #include <Epetra_MpiComm.h>
16 #else
17 #include <Epetra_SerialComm.h>
18 #endif
19 
20 #include <boost/program_options.hpp>
21 
22 #include <life/lifecore/LifeV.hpp>
23 #include <life/lifecore/application.hpp>
24 
25 #include "mpi.h"
26 
27 #include <life/lifearray/EpetraMatrix.hpp>
28 #include <life/lifearray/MapEpetra.hpp>
29 #include <life/lifemesh/MeshPartitioner.hpp>
30 #include <life/lifesolver/OseenData.hpp>
31 #include <life/lifefem/FESpace.hpp>
32 #include <life/lifefem/TimeAdvanceBDFNavierStokes.hpp>
33 #include <life/lifefilters/ExporterEnsight.hpp>
34 
35 #include <life/lifesolver/OseenSolver.hpp>
36 
37 #include <iostream>
38 
39 const int UPWALL = 2;
40 const int WALL = 1;
41 const int SLIPWALL = 20;
42 
43 
44 using namespace LifeV;
45 
46 typedef std::function<Real ( Real const&, Real const&, Real const&, Real const&, ID const& ) > fct_type;
47 
48 typedef OseenSolver< RegionMesh<LinearTetra> >::vector_type vector_type;
50 
51 Real zero_scalar ( const Real& /* t */,
52  const Real& /* x */,
53  const Real& /* y */,
54  const Real& /* z */,
55  const ID& /* i */ )
56 {
57  return 0.;
58 }
59 
60 Real uLid (const Real& t, const Real& /*x*/, const Real& /*y*/, const Real& /*z*/, const ID& i)
61 {
62  switch (i)
63  {
64  case 1:
65  return 1.0;
66  break;
67  case 3:
68  return 0.0;
69  break;
70  case 2:
71  return 0.0;
72  break;
73  }
74  return 0;
75 }
76 
77 
80 {
81  LifeV::AboutData about ( "life_cavity" ,
82  "life_cavity" ,
83  "0.1",
84  "3D cavity test case",
85  LifeV::AboutData::License_GPL,
86  "Copyright (c) 2008 EPFL");
87 
88  about.addAuthor ("Gilles Fourestey", "developer", "gilles.fourestey@epfl.ch", "");
89  return about;
90 
91 }
92 
93 
94 
95 int
96 main ( int argc, char** argv )
97 {
98 
99  //
100  // Mpi Communicator definition ( see http://www.mpi-forum.org/docs/docs.html for documentation ).
101  // The communicator (paralell or sequential) is then given to Epetra.
102  // This is standard and can be "copy/pasted"
103  //
104 
105  // a flag to see who's the leader for output purposes
106 
107  MPI_Init (&argc, &argv);
108  Epetra_MpiComm comm (MPI_COMM_WORLD);
109 
110  bool verbose = comm.MyPID() == 0;
111 
112  if ( verbose )
113  {
114  cout << "% using MPI" << endl;
115  int ntasks;
116  int err = MPI_Comm_size (MPI_COMM_WORLD, &ntasks);
117  std::cout << "My PID = " << comm.MyPID() << " out of " << ntasks << " running." << std::endl;
118  }
119 
120 
121  // We now proceed to the data file. Its name can be given using the
122  // -f or --file argument after the name of launch program.
123  // By default, it's data.
124 
125  GetPot command_line (argc, argv);
126  const std::string data_file_name = command_line.follow ("data-cavity", 2, "-f", "--file");
127  GetPot dataFile ( data_file_name );
128 
129  // everything ( mesh included ) will be stored in a class
130  OseenData<RegionMesh<LinearTetra> > oseenData (dataFile, false, "fluid/discretization", "fluid/discretization");
131  oseenData.setup ( dataFile );
132 
133  // Now for the boundary conditions :
134  // BCHandler is the class that stores the boundary conditions. Here we will
135  // set 3 boundary conditions :
136  // top : (ux, uy, uz) = (1., 0., 0.) essential BC
137  // left, right, down : (ux, uy, uz) = (0., 0., 0.) essential BC
138  // front and rear : uz = 0 essential BC
139 
140  BCHandler bcH (3);
141 
142  std::vector<ID> zComp (1);
143  zComp[0] = 3;
144 
145  BCFunctionBase uIn ( boost::bind (&uLid, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5) );
146  BCFunctionBase uZero ( zero_scalar );
147 
148  // boundary conditions definition.
149  // the first two are classical essential or dirichlet conditions
150  bcH.addBC ( "Upwall", UPWALL, Essential, Full, uIn, 3 );
151  bcH.addBC ( "Wall", WALL, Essential, Full, uZero, 3 );
152  // this bc is imposed only on some compenants, that is the ones given in zComp
153  // Here it's the thirs, ie z, in order to have u.n = 0
154  bcH.addBC ( "Slipwall", SLIPWALL, Essential, Component, uZero, zComp );
155 
156  // partitioning the mesh
157  partitionMesh< RegionMesh<LinearTetra> > meshPart (*oseenData.mesh(), comm);
158 
159  // Now we proceed with the FESpace definition
160  // here we decided to use P2/P1 elements
161 
162  const RefFE* refFE_vel;
163  const QuadRule* qR_vel;
164  const QuadRule* bdQr_vel;
165 
166  refFE_vel = &feTetraP2;
167  qR_vel = &quadRuleTetra15pt; // DoE 5
168  // refFE_vel = &feTetraP1bubble;
169  // qR_vel = &quadRuleTetra64pt; // DoE 2
170  bdQr_vel = &quadRuleTria3pt; // DoE 2
171 
172  const RefFE* refFE_press;
173  const QuadRule* qR_press;
174  const QuadRule* bdQr_press;
175 
176  refFE_press = &feTetraP1;
177  qR_press = &quadRuleTetra4pt; // DoE 2
178  bdQr_press = &quadRuleTria3pt; // DoE 2
179 
180  // Everything is ready to build the FE space
181 
182  // first the velocity FE space
183 
184  if (verbose)
185  {
186  std::cout << "Building the velocity FE space ... " << std::flush;
187  }
188 
189  FESpace< RegionMesh<LinearTetra>, MapEpetra > uFESpace (meshPart,
190  *refFE_vel,
191  *qR_vel,
192  *bdQr_vel,
193  3,
194  comm);
195 
196  if (verbose)
197  {
198  std::cout << "ok " << std::flush;
199  }
200 
201  // then the pressure FE space
202 
203  if (verbose)
204  {
205  std::cout << "Building the pressure FE space ... " << std::flush;
206  }
207 
208  FESpace< RegionMesh<LinearTetra>, MapEpetra > pFESpace (meshPart,
209  *refFE_press,
210  *qR_press,
211  *bdQr_press,
212  1,
213  comm);
214 
215 
216  if (verbose)
217  {
218  std::cout << "ok." << std::endl;
219  }
220 
221  UInt totalVelDof = uFESpace.map().getMap (Unique)->NumGlobalElements();
222  UInt totalPressDof = pFESpace.map().getMap (Unique)->NumGlobalElements();
223 
224 
225  if (verbose)
226  {
227  std::cout << "Total Velocity Dof ... " << totalVelDof << std::endl;
228  }
229  if (verbose)
230  {
231  std::cout << "Total Pressure Dof ... " << totalPressDof << std::endl;
232  }
233 
234 
235  // now that the FE spaces are built, we proceed to the NS solver constrution
236  // we will use oseen here
237 
238  if (verbose)
239  {
240  std::cout << "Calling the fluid constructor ... ";
241  }
242 
243  OseenSolver< RegionMesh<LinearTetra> > fluid (oseenData,
244  uFESpace,
245  pFESpace,
246  comm);
247 
248 
249  // this is the total map ( velocity + pressure ). it will be used to create
250  // vectors to strore the solutions
251 
252  MapEpetra fullMap (fluid.getMap() );
253 
254  if (verbose)
255  {
256  std::cout << "ok." << std::endl;
257  }
258 
259  // Now, the fluid solver is set up using the data file
260  fluid.setUp (dataFile);
261  // the we build the constant matrices
262  fluid.buildSystem();
263 
264 
265  // finally, let's create an exporter in order to view the results
266  // here, we use the ensight exporter
267 
268  Ensight<RegionMesh<LinearTetra> > ensight ( dataFile, meshPart.mesh(), "cavity", comm.MyPID() );
269 
270  // we have to define a variable that will store the solution
271  vector_ptrtype velAndPressure ( new vector_type (fluid.solution(), Repeated ) );
272 
273  // and we add the variables to be saved
274  // the velocity
275  ensight.addVariable ( ExporterData::Vector, "velocity", velAndPressure,
276  UInt (0), uFESpace.dof().numTotalDof() );
277 
278  // and the pressure
279  ensight.addVariable ( ExporterData::Scalar, "pressure", velAndPressure,
280  UInt (3 * uFESpace.dof().numTotalDof() ),
281  UInt ( pFESpace.dof().numTotalDof() ) );
282 
283  // everything is ready now
284  // a little barrier to synchronize the processes
285  MPI_Barrier (MPI_COMM_WORLD);
286 
287 
288  // Initialization
289 
290  Real dt = oseenData.timeStep();
291  Real t0 = oseenData.initialTime();
292  Real tFinal = oseenData.endTime();
293 
294  // bdf object to store the previous solutions
295 
296  TimeAdvanceBDFNavierStokes<vector_type> bdf (oseenData.orderBDF() );
297 
298  if (verbose)
299  {
300  std::cout << std::endl;
301  }
302  if (verbose)
303  {
304  std::cout << "Computing the stokes solution ... " << std::endl << std::endl;
305  }
306 
307  oseenData.setTime (t0);
308 
309  // advection speed (beta) and rhs definition using the full map
310  // (velocity + pressure)
311  vector_type beta ( fullMap );
312  vector_type rhs ( fullMap );
313 
314  MPI_Barrier (MPI_COMM_WORLD);
315 
316  beta *= 0.;
317  rhs *= 0.;
318 
319  // updating the system with no mass matrix, advection and rhs set to zero,
320  // that is the stokes problem
321  fluid.updateSystem (0, beta, rhs );
322 
323  // iterating the solver in order to produce the solution
324  fluid.iterate ( bcH );
325 
326  // a little postprocessing to see if everything goes according to plan
327  *velAndPressure = fluid.solution();
328  ensight.postProcess ( 0 );
329 }
LifeV::AboutData makeAbout()
Definition: cavity.cpp:79
Real zero_scalar(const Real &, const Real &, const Real &, const Real &, const ID &)
Definition: cavity.cpp:51
const int SLIPWALL
Definition: cavity.cpp:41
const int UPWALL
Definition: cavity.cpp:39
Real uLid(const Real &t, const Real &, const Real &, const Real &, const ID &i)
Definition: cavity.cpp:60
std::function< Real(Real const &, Real const &, Real const &, Real const &, ID const &) > fct_type
Definition: cavity.cpp:46
std::shared_ptr< vector_type > vector_ptrtype
Definition: cavity.cpp:49
int main(int argc, char **argv)
Definition: dummy.cpp:5
const int WALL
Definition: cavity.cpp:40