LifeV
lifev/navier_stokes/examples/oseen_assembler/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 Gwenol Grandperrin <gwenol.grandperrin@epfl.ch>
32  @author Samuel Quinodoz <samuel.quinodoz@epfl.ch>
33  @date 25-03-2011
34  */
35 
36 
37 #include <Epetra_ConfigDefs.h>
38 #ifdef EPETRA_MPI
39 #include <mpi.h>
40 #include <Epetra_MpiComm.h>
41 #else
42 #include <Epetra_SerialComm.h>
43 #endif
44 
45 
46 #include <lifev/core/LifeV.hpp>
47 #include <lifev/core/array/VectorEpetra.hpp>
48 #include <lifev/core/mesh/RegionMesh3DStructured.hpp>
49 #include <lifev/core/mesh/MeshData.hpp>
50 #include <lifev/core/mesh/RegionMesh.hpp>
51 #include <lifev/core/mesh/MeshPartitioner.hpp>
52 #include <lifev/core/fem/FESpace.hpp>
53 #include <lifev/core/fem/BCManage.hpp>
54 #include <lifev/core/array/MatrixEpetra.hpp>
55 #include <lifev/core/algorithm/PreconditionerIfpack.hpp>
56 #include <lifev/core/algorithm/PreconditionerML.hpp>
57 #include <lifev/core/algorithm/SolverAztecOO.hpp>
58 #include <lifev/core/filter/ExporterHDF5.hpp>
59 #include <lifev/core/fem/TimeAdvanceBDF.hpp>
60 #include <lifev/navier_stokes/solver/OseenAssembler.hpp>
61 #include <lifev/navier_stokes/function/RossEthierSteinmanDec.hpp>
62 
63 using namespace LifeV;
64 
65 namespace
66 {
67 
71 enum ConvectionType {Explicit, SemiImplicit, KIO91};
72 
73 /*
74  * Some references for the KIO91 scheme:
75  *
76  * Karniadakis, G.E., Israeli, M. and Orszag, S.A. (1991)
77  * High-OrderSplitting Methods for the Incompressible Navier-Stokes Equations,
78  * Journal of Computational Physics, 97, 414-443.
79  *
80  * Canuto, C., Hussaini, M.Y., Quarteroni, A., Zang, T.A. (2007),
81  * Spectral Methods Evolution to Complex Geometries and Applications to Fluid Dynamics
82  */
83 
85 typedef MatrixEpetra<Real> matrix_Type;
90 typedef LifeV::RossEthierSteinmanUnsteadyDec problem_Type;
91 }
92 
93 Real fluxFunction (const Real& /*t*/, const Real& /*x*/, const Real& /*y*/, const Real& /*z*/, const ID& /*i*/)
94 {
95  return 1;
96 }
97 
98 
99 void printErrors (const vector_Type& solution, const Real& currentTime, fespacePtr_Type uFESpace, fespacePtr_Type pFESpace, bool verbose)
100 {
101  vector_Type velocity (uFESpace->map(), Repeated);
102  vector_Type pressure (pFESpace->map(), Repeated);
103  if (verbose)
104  {
105  std::cout << std::endl << "[Computed errors]" << std::endl;
106  }
107  velocity.subset (solution);
108  pressure.subset (solution, 3 * uFESpace->dof().numTotalDof() );
109  Real uRelativeError, pRelativeError, uL2Error, pL2Error;
110  uL2Error = uFESpace->l2Error (problem_Type::uexact, velocity, currentTime, &uRelativeError );
111  pL2Error = pFESpace->l20Error (problem_Type::pexact, pressure, currentTime, &pRelativeError );
112  if (verbose)
113  {
114  std::cout << "Velocity" << std::endl;
115  }
116  if (verbose)
117  {
118  std::cout << " L2 error : " << uL2Error << std::endl;
119  }
120  if (verbose)
121  {
122  std::cout << " Relative error: " << uRelativeError << std::endl;
123  }
124  if (verbose)
125  {
126  std::cout << "Pressure" << std::endl;
127  }
128  if (verbose)
129  {
130  std::cout << " L2 error : " << pL2Error << std::endl;
131  }
132  if (verbose)
133  {
134  std::cout << " Relative error: " << pRelativeError << std::endl;
135  }
136 }
137 
138 
139 int
140 main ( int argc, char** argv )
141 {
142  // +-----------------------------------------------+
143  // | Initialization of MPI |
144  // +-----------------------------------------------+
145 #ifdef HAVE_MPI
146  MPI_Init (&argc, &argv);
147  std::shared_ptr<Epetra_Comm> Comm (new Epetra_MpiComm (MPI_COMM_WORLD) );
148  int nproc;
149  MPI_Comm_size (MPI_COMM_WORLD, &nproc);
150 #else
151  std::shared_ptr<Epetra_Comm> Comm (new Epetra_SerialComm);
152 #endif
153 
154  const bool verbose (Comm->MyPID() == 0);
155  if (verbose)
156  {
157  std::cout
158  << " +-----------------------------------------------+" << std::endl
159  << " | OseenAssembler example |" << std::endl
160  << " +-----------------------------------------------+" << std::endl
161  << std::endl
162  << " +-----------------------------------------------+" << std::endl
163  << " | Author: Gwenol Grandperrin |" << std::endl
164  << " | Date: 2010-03-25 |" << std::endl
165  << " +-----------------------------------------------+" << std::endl
166  << std::endl;
167 
168  std::cout << "[Initilization of MPI]" << std::endl;
169 #ifdef HAVE_MPI
170  std::cout << "Using MPI (" << nproc << " proc.)" << std::endl;
171 #else
172  std::cout << "Using serial version" << std::endl;
173 #endif
174  }
175 
176  // +-----------------------------------------------+
177  // | Loading the data |
178  // +-----------------------------------------------+
179  if (verbose)
180  {
181  std::cout << std::endl << "[Loading the data]" << std::endl;
182  }
183  LifeChrono globalChrono;
184  LifeChrono initChrono;
185  LifeChrono iterChrono;
186 
187  globalChrono.start();
188  initChrono.start();
189 
190  // **** Stupid GetPot stuff ****
191  GetPot command_line (argc, argv);
192  const std::string dataFileName = command_line.follow ("data", 2, "-f", "--file");
193  GetPot dataFile (dataFileName);
194  // *****************************
195 
196  // Physical quantity
197  const Real viscosity = 0.01;
198  const Real density = 1.0;
199 
200  // Time discretization
201  const Real initialTime = 0.0;
202  const Real endTime = 1e-2;
203  const Real timestep = 1e-3;
204 
205  // Space discretization
206  const UInt numDimensions = 3;
207  const MeshType meshSource = RegularMesh;
208  const UInt numMeshElem = 3;
209 
210  // Numerical scheme
211  const DiffusionType diffusionType = ViscousStress;
212  UInt BDFOrder = 3;
213  const InitType initializationMethod = Interpolation;
214  const ConvectionType convectionTerm = KIO91;
215 
216  // Reading settings from file
217  //dataFile;
218 
219 
220  // EthierSteinman data
221  problem_Type::setA (1.0);
222  problem_Type::setD (1.0);
223  problem_Type::setViscosity (viscosity);
224  problem_Type::setDensity (density);
225 
226  if (diffusionType == StiffStrain)
227  {
228  problem_Type::setFlagStrain (1);
229  }
230  else
231  {
232  problem_Type::setFlagStrain (0);
233  }
234 
235  // +-----------------------------------------------+
236  // | Loading the mesh |
237  // +-----------------------------------------------+
238  if (verbose)
239  {
240  std::cout << std::endl << "[Loading the mesh]" << std::endl;
241  }
242 
243  std::shared_ptr<RegionMesh<LinearTetra> > fullMeshPtr ( new RegionMesh<LinearTetra> ( Comm ) );
244 
245  // Building the mesh from the source
246  if (meshSource == RegularMesh)
247  {
248  regularMesh3D ( *fullMeshPtr,
249  1,
250  numMeshElem, numMeshElem, numMeshElem,
251  false,
252  2.0, 2.0, 2.0,
253  -1.0, -1.0, -1.0);
254 
255  if (verbose) std::cout << "Mesh source: regular mesh("
256  << numMeshElem << "x" << numMeshElem << "x" << numMeshElem << ")" << std::endl;
257  }
258  else if (meshSource == File)
259  {
260  MeshData meshData;
261  meshData.setup (dataFile, "fluid/space_discretization");
262  readMesh (*fullMeshPtr, meshData);
263 
264  if (verbose) std::cout << "Mesh source: file("
265  << meshData.meshDir() << meshData.meshFile() << ")" << std::endl;
266  }
267  else
268  {
269  if (verbose)
270  {
271  std::cout << std::endl << "Error: Unknown source type for the mesh" << std::endl;
272  }
273  exit (1);
274  }
275 
276  if (verbose)
277  {
278  std::cout << "Mesh size : " <<
279  MeshUtility::MeshStatistics::computeSize (*fullMeshPtr).maxH << std::endl;
280  }
281  if (verbose)
282  {
283  std::cout << "Partitioning the mesh ... " << std::endl;
284  }
285  std::shared_ptr<RegionMesh<LinearTetra> > meshPtr;
286  {
287  MeshPartitioner< RegionMesh<LinearTetra> > meshPart (fullMeshPtr, Comm);
288  meshPtr = meshPart.meshPartition();
289  }
290  fullMeshPtr.reset(); //Freeing the global mesh to save memory
291 
292  // +-----------------------------------------------+
293  // | Creating the FE spaces |
294  // +-----------------------------------------------+
295  if (verbose)
296  {
297  std::cout << std::endl << "[Creating the FE spaces]" << std::endl;
298  }
299  std::string uOrder ("P2");
300  std::string pOrder ("P1");
301 
302  if (verbose) std::cout << "FE for the velocity: " << uOrder << std::endl
303  << "FE for the pressure: " << pOrder << std::endl;
304 
305  if (verbose)
306  {
307  std::cout << "Building the velocity FE space ... " << std::flush;
308  }
309  fespacePtr_Type uFESpace ( new fespace_Type ( meshPtr, uOrder, numDimensions, Comm ) );
310  if (verbose)
311  {
312  std::cout << "ok." << std::endl;
313  }
314 
315  if (verbose)
316  {
317  std::cout << "Building the pressure FE space ... " << std::flush;
318  }
319  fespacePtr_Type pFESpace ( new fespace_Type ( meshPtr, pOrder, 1, Comm ) );
320  if (verbose)
321  {
322  std::cout << "ok." << std::endl;
323  }
324 
325  // Creation of the total map
326  MapEpetra solutionMap (uFESpace->map() + pFESpace->map() );
327 
328  // Pressure offset in the vector
329  UInt pressureOffset = numDimensions * uFESpace->dof().numTotalDof();
330 
331  if (verbose)
332  {
333  std::cout << "Total Velocity Dof: " << pressureOffset << std::endl;
334  }
335  if (verbose)
336  {
337  std::cout << "Total Pressure Dof: " << pFESpace->dof().numTotalDof() << std::endl;
338  }
339 
340  // +-----------------------------------------------+
341  // | Boundary conditions |
342  // +-----------------------------------------------+
343  if (verbose)
344  {
345  std::cout << std::endl << "[Boundary conditions]" << std::endl;
346  }
347  BCHandler bcHandler;
348  BCFunctionBase uDirichlet ( problem_Type::uexact );
349  BCFunctionBase uNeumann ( problem_Type::fNeumann );
350 
351  if (verbose)
352  {
353  std::cout << "Setting Neumann BC... " << std::flush;
354  }
355  bcHandler.addBC ( "Flux", 1, Natural, Full, uNeumann, 3 );
356  if (verbose)
357  {
358  std::cout << "ok." << std::endl;
359  }
360 
361  if (verbose)
362  {
363  std::cout << "Setting Dirichlet BC... " << std::flush;
364  }
365  for (UInt iDirichlet (2); iDirichlet <= 26; ++iDirichlet)
366  {
367  bcHandler.addBC ( "Wall", iDirichlet, Essential, Full, uDirichlet, 3 );
368  }
369  if (verbose)
370  {
371  std::cout << "ok." << std::endl;
372  }
373 
374  // Update the BCHandler (internal data related to FE)
375  bcHandler.bcUpdate ( *meshPtr, uFESpace->feBd(), uFESpace->dof() );
376 
377  // +-----------------------------------------------+
378  // | Matrices Assembly |
379  // +-----------------------------------------------+
380  if (verbose)
381  {
382  std::cout << std::endl << "[Matrices Assembly]" << std::endl;
383  }
384 
385  if (verbose)
386  {
387  std::cout << "Setting up assembler... " << std::flush;
388  }
389  OseenAssembler<mesh_Type, matrix_Type, vector_Type> oseenAssembler;
390  oseenAssembler.setup (uFESpace, pFESpace);
391  if (verbose)
392  {
393  std::cout << "done" << std::endl;
394  }
395 
396  if (verbose)
397  {
398  std::cout << "Defining the matrices... " << std::flush;
399  }
400  std::shared_ptr<matrix_Type> systemMatrix (new matrix_Type ( solutionMap ) );
401  *systemMatrix *= 0.0;
402  std::shared_ptr<matrix_Type> baseMatrix (new matrix_Type ( solutionMap ) );
403  *baseMatrix *= 0.0;
404  std::shared_ptr<matrix_Type> massMatrix (new matrix_Type ( solutionMap ) );
405  *massMatrix *= 0.0;
406  if (verbose)
407  {
408  std::cout << "done" << std::endl;
409  }
410 
411  // Perform the assembly of the matrix
412  switch (diffusionType)
413  {
414  case ViscousStress:
415  if (verbose)
416  {
417  std::cout << "Adding the viscous stress... " << std::flush;
418  }
419  oseenAssembler.addViscousStress (*baseMatrix, viscosity / density);
420  if (verbose)
421  {
422  std::cout << "done" << std::endl;
423  }
424  break;
425  case StiffStrain:
426  if (verbose)
427  {
428  std::cout << "Adding the stiff strain... " << std::flush;
429  }
430  oseenAssembler.addStiffStrain (*baseMatrix, viscosity / density);
431  if (verbose)
432  {
433  std::cout << "done" << std::endl;
434  }
435  break;
436  default:
437  std::cerr << "[Error] Diffusion type unknown" << std::endl;
438  return ( EXIT_FAILURE );
439  break;
440  }
441 
442  if (verbose)
443  {
444  std::cout << "Adding the gradient of the pressure... " << std::flush;
445  }
446  oseenAssembler.addGradPressure (*baseMatrix);
447  if (verbose)
448  {
449  std::cout << "done" << std::endl;
450  }
451 
452  if (verbose)
453  {
454  std::cout << "Adding the divergence free constraint... " << std::flush;
455  }
456  oseenAssembler.addDivergence (*baseMatrix, -1.0);
457  if (verbose)
458  {
459  std::cout << "done" << std::endl;
460  }
461 
462  if (verbose)
463  {
464  std::cout << "Adding the mass... " << std::flush;
465  }
466  oseenAssembler.addMass (*massMatrix, 1.0);
467  if (verbose)
468  {
469  std::cout << "done" << std::endl;
470  }
471 
472  if (verbose)
473  {
474  std::cout << "Closing the matrices... " << std::flush;
475  }
476  baseMatrix->globalAssemble();
477  massMatrix->globalAssemble();
478  if (verbose)
479  {
480  std::cout << "done" << std::endl;
481  }
482 
483  // +-----------------------------------------------+
484  // | Flux computation: vector initialization |
485  // +-----------------------------------------------+
486  BCFunctionBase flow (fluxFunction);
487 
488  BCHandler fluxHandler;
489  fluxHandler.addBC ("Flux" , 1, Flux, Normal, flow);
490 
491  // Update the BCHandler (internal data related to FE)
492  fluxHandler.bcUpdate ( *meshPtr, uFESpace->feBd(), uFESpace->dof() );
493 
494  vector_Type fluxVector (solutionMap);
495  oseenAssembler.addFluxTerms (fluxVector, fluxHandler);
496 
497 
498  // +-----------------------------------------------+
499  // | Solver initialization |
500  // +-----------------------------------------------+
501  if (verbose)
502  {
503  std::cout << std::endl << "[Solver initialization]" << std::endl;
504  }
505  SolverAztecOO linearSolver;
506 
507  if (verbose)
508  {
509  std::cout << "Setting up the solver... " << std::flush;
510  }
511  linearSolver.setDataFromGetPot (dataFile, "solver");
512  linearSolver.setupPreconditioner (dataFile, "prec");
513  if (verbose)
514  {
515  std::cout << "done" << std::endl;
516  }
517 
518  linearSolver.setCommunicator (Comm);
519 
520  // +-----------------------------------------------+
521  // | Initialization of the simulation |
522  // +-----------------------------------------------+
523  if (verbose)
524  {
525  std::cout << std::endl << "[Initialization of the simulation]" << std::endl;
526  }
527  if (verbose)
528  {
529  std::cout << "Creation of vectors... " << std::flush;
530  }
531  vectorPtr_Type rhs;
532  rhs.reset (new vector_Type (solutionMap, Unique) );
533 
534  vectorPtr_Type beta;
535  beta.reset (new vector_Type (solutionMap, Repeated) );
536 
537  vector_Type convect (rhs->map() );
538 
539  vectorPtr_Type velocity;
540  velocity.reset (new vector_Type (uFESpace->map(), Unique) );
541 
542  vectorPtr_Type pressure;
543  pressure.reset (new vector_Type (pFESpace->map(), Unique) );
544 
545  vectorPtr_Type solution;
546  solution.reset (new vector_Type (solutionMap, Unique) );
547  if (verbose)
548  {
549  std::cout << "done" << std::endl;
550  }
551 
552  if (verbose)
553  {
554  std::cout << "Computing the initial solution ... " << std::endl;
555  }
556  if (convectionTerm == KIO91)
557  {
558  BDFOrder = 3;
559  }
560 
561  // bdf object to store the previous solutions
562  TimeAdvanceBDF<vector_Type> bdf;
563  bdf.setup (BDFOrder);
564  TimeAdvanceBDF<vector_Type> bdfConvection;
565  bdfConvection.setup (BDFOrder);
566  TimeAdvanceBDF<vector_Type> bdfConvectionInit; // Just for KIO91
567  bdfConvectionInit.setup (BDFOrder);
568  Real currentTime = initialTime - timestep * BDFOrder;
569 
570  if (convectionTerm == KIO91)
571  {
572  uFESpace->interpolate ( static_cast<FESpace< mesh_Type, MapEpetra >::function_Type> ( problem_Type::uexact ), *velocity, currentTime );
573  *solution *= 0;
574  *solution = *velocity;
575  *beta *= 0;
576  oseenAssembler.addConvectionRhs (*beta, 1., *solution);
577  bdfConvection.setInitialCondition ( *beta );
578  bdfConvectionInit.setInitialCondition ( *beta );
579 
580  if (initializationMethod == Projection)
581  {
582  for (UInt i (0); i < BDFOrder; ++i)
583  {
584  uFESpace->interpolate ( static_cast<FESpace< mesh_Type, MapEpetra >::function_Type> ( problem_Type::uexact ), *velocity, currentTime - (3 - i) *timestep );
585  *solution = *velocity;
586  *beta *= 0;
587  oseenAssembler.addConvectionRhs (*beta, 1., *solution);
588  bdfConvectionInit.shiftRight ( *beta );
589  }
590  }
591  }
592 
593  uFESpace->interpolate ( static_cast<FESpace< mesh_Type, MapEpetra >::function_Type> ( problem_Type::uexact ), *velocity, currentTime );
594  pFESpace->interpolate ( static_cast<FESpace< mesh_Type, MapEpetra >::function_Type> ( problem_Type::pexact ), *pressure, currentTime );
595  *solution *= 0;
596  *solution = *velocity;
597  solution->add (*pressure, pressureOffset);
598  bdf.setInitialCondition ( *solution );
599 
600  // Compute initial flux trough face 1
601  Real fluxThrou1 = fluxVector.dot (*solution);
602  if (verbose) std::cout << "Flux through face 1 = "
603  << fluxThrou1 << std::endl;
604 
605  // Initial solution (interpolation or projection)
606  currentTime += timestep;
607  for ( ; currentTime <= initialTime + timestep / 2.; currentTime += timestep)
608  {
609  *rhs *= 0.;
610  *beta *= 0.;
611  *solution *= 0;
612 
613  uFESpace->interpolate ( static_cast<FESpace< mesh_Type, MapEpetra >::function_Type> ( problem_Type::uexact ), *velocity, currentTime );
614  pFESpace->interpolate ( static_cast<FESpace< mesh_Type, MapEpetra >::function_Type> ( problem_Type::pexact ), *pressure, currentTime );
615  *solution = *velocity;
616  solution->add (*pressure, pressureOffset);
617 
618  if (initializationMethod == Projection)
619  {
620  oseenAssembler.addMassRhs (*rhs, problem_Type::uderexact , currentTime);
621  *rhs *= -1.;
622 
623 
624  if (verbose)
625  {
626  std::cout << "Updating the system... " << std::flush;
627  }
628  systemMatrix.reset (new matrix_Type ( solutionMap ) );
629  *systemMatrix += *baseMatrix;
630  if (convectionTerm == SemiImplicit)
631  {
632  oseenAssembler.addConvection (*systemMatrix, 1.0, *solution);
633  }
634  else if (convectionTerm == Explicit)
635  {
636  oseenAssembler.addConvectionRhs (*rhs, 1., *solution);
637  }
638  else if (convectionTerm == KIO91)
639  {
640  bdfConvectionInit.extrapolation (convect);
641  *rhs -= convect;
642  *beta *= 0;
643  oseenAssembler.addConvectionRhs (*beta, 1., *solution);
644  bdfConvectionInit.shiftRight (*beta);
645  }
646 
647  if (verbose)
648  {
649  std::cout << "done" << std::endl;
650  }
651 
652  if (verbose)
653  {
654  std::cout << "Applying BC... " << std::flush;
655  }
656  bcManage (*systemMatrix, *rhs, *uFESpace->mesh(), uFESpace->dof(), bcHandler, uFESpace->feBd(), 1.0, currentTime);
657  systemMatrix->globalAssemble();
658  if (verbose)
659  {
660  std::cout << "done" << std::endl;
661  }
662 
663  if (verbose)
664  {
665  std::cout << "Solving the system... " << std::endl;
666  }
667  *solution *= 0;
668  linearSolver.setMatrix (*systemMatrix);
669  linearSolver.solveSystem (*rhs, *solution, systemMatrix);
670  }
671 
672  // Updating bdf
673  bdf.shiftRight ( *solution );
674 
675  if (convectionTerm == KIO91)
676  {
677  *beta *= 0;
678  oseenAssembler.addConvectionRhs (*beta, 1., *solution);
679  bdfConvection.shiftRight (*beta);
680  }
681 
682  }
683 
684  linearSolver.resetPreconditioner();
685 
686  // +-----------------------------------------------+
687  // | Setting the exporter |
688  // +-----------------------------------------------+
689  if (verbose)
690  {
691  std::cout << "Defining the exporter... " << std::flush;
692  }
693  ExporterHDF5<mesh_Type> exporter ( dataFile, "OseenAssembler");
694  exporter.setPostDir ( "./" ); // This is a test to see if M_post_dir is working
695  exporter.setMeshProcId ( meshPtr, Comm->MyPID() );
696  if (verbose)
697  {
698  std::cout << "done" << std::endl;
699  }
700 
701  if (verbose)
702  {
703  std::cout << "Updating the exporter... " << std::flush;
704  }
705  exporter.addVariable ( ExporterData<mesh_Type>::VectorField, "velocity", uFESpace,
706  solution, UInt (0) );
707  exporter.addVariable ( ExporterData<mesh_Type>::ScalarField, "pressure", pFESpace,
708  solution, pressureOffset );
709  if (verbose)
710  {
711  std::cout << "done" << std::endl;
712  }
713 
714  if (verbose)
715  {
716  std::cout << "Exporting solution at time t=" << initialTime << "... " << std::endl;
717  }
718  exporter.postProcess (initialTime);
719 
720  initChrono.stop();
721  if (verbose)
722  {
723  std::cout << "Initialization time: " << initChrono.diff() << " s." << std::endl;
724  }
725 
726  // +-----------------------------------------------+
727  // | Computing the error |
728  // +-----------------------------------------------+
729  printErrors (*solution, currentTime, uFESpace, pFESpace, verbose);
730 
731  // +-----------------------------------------------+
732  // | Solving the problem |
733  // +-----------------------------------------------+
734  if (verbose)
735  {
736  std::cout << std::endl << "[Solving the problem]" << std::endl;
737  }
738  int iter = 1;
739 
740  for ( ; currentTime <= endTime + timestep / 2.; currentTime += timestep, iter++)
741  {
742  iterChrono.reset();
743  iterChrono.start();
744 
745  if (verbose)
746  {
747  std::cout << std::endl << "[t = " << currentTime << " s.]" << std::endl;
748  }
749 
750  if (verbose)
751  {
752  std::cout << "Updating the system... " << std::flush;
753  }
754  bdf.updateRHSContribution ( timestep );
755  *rhs = *massMatrix * bdf.rhsContributionFirstDerivative();
756 
757  systemMatrix.reset (new matrix_Type ( solutionMap ) );
758  double alpha = bdf.coefficientFirstDerivative ( 0 ) / timestep;
759  *systemMatrix += *massMatrix * alpha;
760  *systemMatrix += *baseMatrix;
761 
762  if (convectionTerm == SemiImplicit)
763  {
764  // *beta = bdf.extrapolation(); // Extrapolation for the convective term
765  bdf.extrapolation ( *beta ); // Extrapolation for the convective term
766  oseenAssembler.addConvection (*systemMatrix, 1.0, *beta);
767  }
768  else if (convectionTerm == Explicit)
769  {
770  oseenAssembler.addConvectionRhs (*rhs, 1., *solution);
771  }
772  else if (convectionTerm == KIO91)
773  {
774  // *rhs -= bdfConvection.extrapolation();
775  convect *= 0.;
776  bdfConvection.extrapolation (convect);
777  *rhs -= convect;
778  }
779  if (verbose)
780  {
781  std::cout << "done" << std::endl;
782  }
783 
784  if (verbose)
785  {
786  std::cout << "Applying BC... " << std::flush;
787  }
788  bcManage (*systemMatrix, *rhs, *uFESpace->mesh(), uFESpace->dof(), bcHandler, uFESpace->feBd(), 1.0, currentTime);
789  systemMatrix->globalAssemble();
790  if (verbose)
791  {
792  std::cout << "done" << std::endl;
793  }
794 
795  if (verbose)
796  {
797  std::cout << "Solving the system... " << std::endl;
798  }
799  *solution *= 0;
800  linearSolver.setMatrix (*systemMatrix);
801  linearSolver.solveSystem (*rhs, *solution, systemMatrix);
802 
803  // Updating the BDF scheme
804  bdf.shiftRight ( *solution );
805 
806  if (convectionTerm == KIO91)
807  {
808  *beta *= 0;
809  oseenAssembler.addConvectionRhs (*beta, 1., *solution);
810  bdfConvection.shiftRight (*beta);
811  }
812 
813  // Exporting the solution
814  exporter.postProcess ( currentTime );
815 
816  iterChrono.stop();
817  if (verbose)
818  {
819  std::cout << "Iteration time: " << iterChrono.diff() << " s." << std::endl;
820  }
821 
822  // +-----------------------------------------------+
823  // | Computing the error |
824  // +-----------------------------------------------+
825  printErrors (*solution, currentTime, uFESpace, pFESpace, verbose);
826 
827  MPI_Barrier (MPI_COMM_WORLD);
828  }
829 
830  // +-----------------------------------------------+
831  // | Ending the simulation |
832  // +-----------------------------------------------+
833  exporter.closeFile();
834 
835  globalChrono.stop();
836  if (verbose)
837  {
838  std::cout << std::endl << "Total simulation time: " << globalChrono.diff() << " s." << std::endl;
839  }
840  if (verbose)
841  {
842  std::cout << std::endl << "[[END_SIMULATION]]" << std::endl;
843  }
844 
845 #ifdef HAVE_MPI
846  MPI_Finalize();
847 #endif
848  return ( EXIT_SUCCESS );
849 }
VectorEpetra - The Epetra Vector format Wrapper.
VectorEpetra & subset(const VectorEpetra &vector, const UInt offset=0)
Set the current vector to a subset of the given vector with an offset.
Real fluxFunction(const Real &, const Real &, const Real &, const Real &, const ID &)
FESpace - Short description here please!
Definition: FESpace.hpp:78
Epetra_Import const & importer()
Getter for the Epetra_Import.
Definition: MapEpetra.cpp:394
uint32_type ID
IDs.
Definition: LifeV.hpp:194
double Real
Generic real data.
Definition: LifeV.hpp:175
void printErrors(const vector_Type &solution, const Real &currentTime, fespacePtr_Type uFESpace, fespacePtr_Type pFESpace, bool verbose)
int main(int argc, char **argv)