LifeV
cavity/cavity.cpp
Go to the documentation of this file.
1 /* -*- mode: c++ -*-
2  This program is part of the LifeV library
3  Copyright (C) 2001,2002,2003,2004 EPFL, INRIA, Politechnico di Milano
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU General Public License
7  as published by the Free Software Foundation; either version 2
8  of the License, or (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19 /**
20  \file cavity.cpp
21  \author Gwenol Grandperrin <gwenol.grandperrin@epfl.ch>
22  \date 2010-10-25
23  */
24 
25 // LifeV definition files
26 #include <life/lifecore/LifeV.hpp>
27 #include <life/lifecore/LifeChrono.hpp>
28 #include <life/lifesolver/OseenSolver.hpp>
29 #include <life/lifemesh/MeshData.hpp>
30 #include <life/lifesolver/OseenData.hpp>
31 #include <life/lifearray/MapEpetra.hpp>
32 #include <life/lifefem/FESpace.hpp>
33 #include <life/lifefem/TimeAdvanceBDFNavierStokes.hpp>
34 #include <life/lifemesh/MeshPartitioner.hpp>
35 #include <life/lifefilters/ExporterEnsight.hpp>
36 #include <life/lifefilters/ExporterHDF5.hpp>
37 #include <life/lifefilters/ExporterEmpty.hpp>
38 //#include <fstream> // To create an output for the flux
39 
40 // Trilinos-MPI communication definitions
41 #include <Epetra_ConfigDefs.h>
42 #ifdef HAVE_MPI
43 #include "Epetra_MpiComm.h"
44 #else
45 #include "Epetra_SerialComm.h"
46 #endif
47 
48 // Object type definitions
55 
56 // +-----------------------------------------------+
57 // | Data and functions for the boundary conditions|
58 // +-----------------------------------------------+
59 const int BACK = 1;
60 const int FRONT = 2;
61 const int LEFT = 3;
62 const int RIGHT = 4;
63 const int BOTTOM = 5;
64 const int TOP = 6;
65 
66 LifeV::Real lidBC (const LifeV::Real& /*t*/, const LifeV::Real& /*x*/, const LifeV::Real& /*y*/, const LifeV::Real& /*z*/, const LifeV::ID& i)
67 {
68  switch (i)
69  {
70  case 1:
71  return 1.0;
72  default:
73  return 0.0;
74  }
75 }
76 
77 LifeV::Real fZero ( const LifeV::Real& /* t */,
78  const LifeV::Real& /* x */,
79  const LifeV::Real& /* y */,
80  const LifeV::Real& /* z */,
81  const LifeV::ID& /* i */ )
82 {
83  return 0.0;
84 }
85 
86 int main (int argc, char** argv)
87 {
88 
89  // +-----------------------------------------------+
90  // | Initialization of MPI |
91  // +-----------------------------------------------+
92 #ifdef HAVE_MPI
93  MPI_Init (&argc, &argv);
94 #endif
95 
96  std::shared_ptr<Epetra_Comm> comm;
97 #ifdef EPETRA_MPI
98  comm.reset ( new Epetra_MpiComm ( MPI_COMM_WORLD ) );
99  int nproc;
100  MPI_Comm_size (MPI_COMM_WORLD, &nproc);
101 #else
102  comm.reset ( new Epetra_SerialComm() );
103 #endif
104 
105  bool verbose (false);
106  if (comm->MyPID() == 0)
107  {
108  verbose = true;
109  std::cout
110  << " +-----------------------------------------------+" << std::endl
111  << " | Cavity example for LifeV |" << std::endl
112  << " +-----------------------------------------------+" << std::endl
113  << std::endl
114  << " +-----------------------------------------------+" << std::endl
115  << " | Author: Gwenol Grandperrin |" << std::endl
116  << " | Date: October 25, 2010 |" << std::endl
117  << " +-----------------------------------------------+" << std::endl
118  << std::endl;
119 
120  std::cout << "[Initilization of MPI]" << std::endl;
121 #ifdef HAVE_MPI
122  std::cout << "Using MPI (" << nproc << " proc.)" << std::endl;
123 #else
124  std::cout << "Using serial version" << std::endl;
125 #endif
126  }
127 
128  // Chronometer
129  LifeV::LifeChrono globalChrono;
130  LifeV::LifeChrono initChrono;
131  LifeV::LifeChrono iterChrono;
132  globalChrono.start();
133  initChrono.start();
134 
135  // +-----------------------------------------------+
136  // | Loading the data |
137  // +-----------------------------------------------+
138  if (verbose)
139  {
140  std::cout << std::endl << "[Loading the data]" << std::endl;
141  }
142  GetPot command_line (argc, argv);
143  const std::string dataFileName = command_line.follow ("data", 2, "-f", "--file");
144  GetPot dataFile (dataFileName);
145 
146  // +-----------------------------------------------+
147  // | Loading the mesh |
148  // +-----------------------------------------------+
149  if (verbose)
150  {
151  std::cout << std::endl << "[Loading the mesh]" << std::endl;
152  }
153  LifeV::MeshData meshData;
154  meshData.setup (dataFile, "fluid/space_discretization");
155  if (verbose)
156  {
157  std::cout << "Mesh file: " << meshData.meshDir() << meshData.meshFile() << std::endl;
158  }
159  std::shared_ptr< mesh_Type > fullMeshPtr (new mesh_Type);
160  LifeV::readMesh (*fullMeshPtr, meshData);
161  // Split the mesh between processors
162  std::shared_ptr< mesh_Type > localMeshPtr;
163  {
164  LifeV::MeshPartitioner< mesh_Type > meshPart (fullMeshPtr, comm);
165  localMeshPtr = meshPart.meshPartition();
166  }
167 
168  // +-----------------------------------------------+
169  // | Creating the FE spaces |
170  // +-----------------------------------------------+
171  if (verbose)
172  {
173  std::cout << std::endl << "[Creating the FE spaces]" << std::endl;
174  }
175  std::string uOrder = dataFile ( "fluid/space_discretization/vel_order", "P2");
176  std::string pOrder = dataFile ( "fluid/space_discretization/press_order", "P1");
177  if (verbose) std::cout << "FE for the velocity: " << uOrder << std::endl
178  << "FE for the pressure: " << pOrder << std::endl;
179 
180  if (verbose)
181  {
182  std::cout << "Building the velocity FE space... " << std::flush;
183  }
184  feSpacePtr_Type uFESpacePtr ( new feSpace_Type (localMeshPtr, uOrder, 3, comm) );
185  if (verbose)
186  {
187  std::cout << "ok." << std::endl;
188  }
189 
190  if (verbose)
191  {
192  std::cout << "Building the pressure FE space... " << std::flush;
193  }
194  feSpacePtr_Type pFESpacePtr ( new feSpace_Type (localMeshPtr, pOrder, 1, comm) );
195  if (verbose)
196  {
197  std::cout << "ok." << std::endl;
198  }
199 
200  // Total degrees of freedom (elements of matrix)
201  LifeV::UInt totalVelDof = uFESpacePtr->map().map (LifeV::Unique)->NumGlobalElements();
202  LifeV::UInt totalPressDof = pFESpacePtr->map().map (LifeV::Unique)->NumGlobalElements();
203 
204  if (verbose)
205  {
206  std::cout << "Total Velocity Dof: " << totalVelDof << std::endl;
207  }
208  if (verbose)
209  {
210  std::cout << "Total Pressure Dof: " << totalPressDof << std::endl;
211  }
212 
213  // +-----------------------------------------------+
214  // | Boundary conditions |
215  // +-----------------------------------------------+
216  if (verbose)
217  {
218  std::cout << std::endl << "[Boundary conditions]" << std::endl;
219  }
220 
221  LifeV::BCFunctionBase uZero (fZero);
222  LifeV::BCFunctionBase uLid (lidBC);
223 
224  std::vector<LifeV::ID> xComp (1);
225  xComp[0] = 1;
226 
227  LifeV::BCHandler bcH;
228  // A boundary condition in every face
229  bcH.addBC ( "Top" , TOP , LifeV::Essential, LifeV::Full , uLid , 3 );
230  bcH.addBC ( "Left" , LEFT , LifeV::Essential, LifeV::Full , uZero, 3 );
231  bcH.addBC ( "Front" , FRONT , LifeV::Essential, LifeV::Component, uZero, xComp );
232  bcH.addBC ( "Right" , RIGHT , LifeV::Essential, LifeV::Full , uZero, 3 );
233  bcH.addBC ( "Back" , BACK , LifeV::Essential, LifeV::Component, uZero, xComp );
234  bcH.addBC ( "Bottom", BOTTOM, LifeV::Essential, LifeV::Full , uZero, 3 );
235 
236  // Get the number of Lagrange Multiplyers (LM) and set the offsets
237  std::vector<LifeV::bcName_Type> fluxVector = bcH.findAllBCWithType ( LifeV::Flux );
238  LifeV::UInt numLM = static_cast<LifeV::UInt> ( fluxVector.size() );
239 
240  LifeV::UInt offset = uFESpacePtr->map().map (LifeV::Unique)->NumGlobalElements()
241  + pFESpacePtr->map().map (LifeV::Unique)->NumGlobalElements();
242 
243  for ( LifeV::UInt i = 0; i < numLM; ++i )
244  {
245  bcH.setOffset ( fluxVector[i], offset + i );
246  }
247 
248  // +-----------------------------------------------+
249  // | Creating the problem |
250  // +-----------------------------------------------+
251  if (verbose)
252  {
253  std::cout << std::endl << "[Creating the problem]" << std::endl;
254  }
255  std::shared_ptr<LifeV::OseenData> oseenData (new LifeV::OseenData() );
256  oseenData->setup ( dataFile );
257 
258  if (verbose)
259  {
260  std::cout << "Time discretization order " << oseenData->dataTime()->orderBDF() << std::endl;
261  }
262 
263  // The problem (matrix and rhs) is packed in an object called fluid
264  LifeV::OseenSolver< mesh_Type > fluid (oseenData,
265  *uFESpacePtr,
266  *pFESpacePtr,
267  comm,
268  numLM);
269  // Gets inputs from the data file
270  fluid.setUp (dataFile);
271 
272  // Assemble the matrices
273  fluid.buildSystem();
274 
275  // Communication map
276  LifeV::MapEpetra fullMap (fluid.getMap() );
277 
278  // Synchronization
279  MPI_Barrier (MPI_COMM_WORLD);
280 
281  // +-----------------------------------------------+
282  // | Initialization of the simulation |
283  // +-----------------------------------------------+
284  if (verbose)
285  {
286  std::cout << std::endl << "[Initialization of the simulation]" << std::endl;
287  }
288  LifeV::Real dt = oseenData->dataTime()->timeStep();
289  LifeV::Real t0 = oseenData->dataTime()->initialTime();
290  LifeV::Real tFinal = oseenData->dataTime()->endTime ();
291 
292  // bdf object to store the previous solutions
293  LifeV::TimeAdvanceBDFNavierStokes<vector_Type> bdf;
294  bdf.setup (oseenData->dataTime()->orderBDF() );
295 
296  // Initialization with exact solution: either interpolation or "L2-NS"-projection
297  t0 -= dt * bdf.bdfVelocity().order();
298 
299  vector_Type beta ( fullMap );
300  vector_Type rhs ( fullMap );
301 
302  MPI_Barrier (MPI_COMM_WORLD);
303 
304  // We get the initial solution using a steady Stokes problem
305  oseenData->dataTime()->setTime (t0);
306 
307  beta *= 0.;
308  rhs *= 0.;
309  fluid.updateSystem (0.0, beta, rhs);
310  fluid.iterate (bcH);
311  bdf.bdfVelocity().setInitialCondition ( *fluid.solution() );
312 
313  LifeV::Real time = t0 + dt;
314  for ( ; time <= oseenData->dataTime()->initialTime() + dt / 2.; time += dt)
315  {
316  oseenData->dataTime()->setTime (time);
317 
318  fluid.updateSystem (0.0, beta, rhs);
319  fluid.iterate (bcH);
320  bdf.bdfVelocity().shiftRight ( *fluid.solution() );
321  }
322 
323  // We erase the preconditioner build for Stokes
324  // (A new one should be built for Navier-Stokes)
325  fluid.resetPreconditioner();
326 
327  std::shared_ptr< LifeV::ExporterHDF5<mesh_Type> > exporter;
328 
329  vectorPtr_Type velAndPressure;
330 
331  std::string const exporterType = dataFile ( "exporter/type", "ensight");
332 
333  exporter.reset ( new LifeV::ExporterHDF5<mesh_Type> ( dataFile, "cavity_example" ) );
334  exporter->setPostDir ( "./" ); // This is a test to see if M_post_dir is working
335  exporter->setMeshProcId ( localMeshPtr, comm->MyPID() );
336 
337  velAndPressure.reset ( new vector_Type (*fluid.solution(), exporter->mapType() ) );
338 
339  exporter->addVariable ( LifeV::ExporterData<mesh_Type>::VectorField, "velocity", uFESpacePtr,
340  velAndPressure, LifeV::UInt (0) );
341 
342  exporter->addVariable ( LifeV::ExporterData<mesh_Type>::ScalarField, "pressure", pFESpacePtr,
343  velAndPressure, LifeV::UInt (3 * uFESpacePtr->dof().numTotalDof() ) );
344  exporter->postProcess ( 0 );
345 
346  initChrono.stop();
347  if (verbose)
348  {
349  std::cout << "Initialization time: " << initChrono.diff() << " s." << std::endl;
350  }
351 
352  // +-----------------------------------------------+
353  // | Solving the problem |
354  // +-----------------------------------------------+
355  if (verbose)
356  {
357  std::cout << std::endl << "[Solving the problem]" << std::endl;
358  }
359  int iter = 1;
360 
361  for ( ; time <= tFinal + dt / 2.; time += dt, iter++)
362  {
363 
364  oseenData->dataTime()->setTime (time);
365 
366  if (verbose)
367  {
368  std::cout << "[t = " << oseenData->dataTime()->time() << " s.]" << std::endl;
369  }
370 
371  iterChrono.start();
372 
373  double alpha = bdf.bdfVelocity().coefficientFirstDerivative ( 0 ) / oseenData->dataTime()->timeStep();
374  //Matteo
375  // beta =bdf.bdfVelocity().extrapolation();
376  bdf.bdfVelocity().extrapolation ( beta ); // Extrapolation for the convective term
377  bdf.bdfVelocity().updateRHSContribution (oseenData->dataTime()->timeStep() );
378  rhs = fluid.matrixMass() * bdf.bdfVelocity().rhsContributionFirstDerivative();
379 
380  fluid.getDisplayer().leaderPrint ("alpha ", alpha);
381  fluid.getDisplayer().leaderPrint ("\n");
382  fluid.getDisplayer().leaderPrint ("norm beta ", beta.norm2() );
383  fluid.getDisplayer().leaderPrint ("\n");
384  fluid.getDisplayer().leaderPrint ("norm rhs ", rhs.norm2() );
385  fluid.getDisplayer().leaderPrint ("\n");
386 
387  fluid.updateSystem ( alpha, beta, rhs );
388  fluid.iterate ( bcH );
389 
390  bdf.bdfVelocity().shiftRight ( *fluid.solution() );
391 
392  // Computation of the error
393  vector_Type vel (uFESpacePtr->map(), LifeV::Repeated);
394  vector_Type press (pFESpacePtr->map(), LifeV::Repeated);
395  vector_Type velpressure ( *fluid.solution(), LifeV::Repeated );
396 
397  velpressure = *fluid.solution();
398  vel.subset (velpressure);
399  press.subset (velpressure, uFESpacePtr->dim() *uFESpacePtr->fieldDim() );
400 
401 
402  bool verbose = (comm->MyPID() == 0);
403 
404 
405  // Exporting the solution
406  *velAndPressure = *fluid.solution();
407  exporter->postProcess ( time );
408 
409 
410  MPI_Barrier (MPI_COMM_WORLD);
411 
412  iterChrono.stop();
413  if (verbose)
414  {
415  std::cout << "Iteration time: " << iterChrono.diff() << " s." << std::endl << std::endl;
416  }
417  }
418 
419  globalChrono.stop();
420  if (verbose)
421  {
422  std::cout << "Total simulation time: " << globalChrono.diff() << " s." << std::endl;
423  }
424 
425  exporter->closeFile();
426 
427 #ifdef HAVE_MPI
428  MPI_Finalize();
429 #endif
430 
431  return 0;
432 }
const int BOTTOM
LifeV::RegionMesh< LifeV::LinearTetra > mesh_Type
LifeV::Real fZero(const LifeV::Real &, const LifeV::Real &, const LifeV::Real &, const LifeV::Real &, const LifeV::ID &)
Definition: cavity.old.cpp:75
std::shared_ptr< feSpace_Type > feSpacePtr_Type
const int BACK
LifeV::OseenSolver< mesh_Type > fluid_Type
const int FRONT
const int TOP
int main(int argc, char **argv)
Definition: dummy.cpp:5
LifeV::Real lidBC(const LifeV::Real &t, const LifeV::Real &, const LifeV::Real &, const LifeV::Real &, const LifeV::ID &i)
Definition: cavity.old.cpp:64
LifeV::FESpace< mesh_Type, LifeV::MapEpetra > feSpace_Type
std::shared_ptr< vector_Type > vectorPtr_Type
fluid_Type::vector_Type vector_Type
const int LEFT
const int RIGHT