37 #include <Epetra_ConfigDefs.h> 40 #include <Epetra_MpiComm.h> 42 #include <Epetra_SerialComm.h> 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> 63 using namespace LifeV;
105 std::cout << std::endl <<
"[Computed errors]" << std::endl;
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 );
114 std::cout <<
"Velocity" << std::endl;
118 std::cout <<
" L2 error : " << uL2Error << std::endl;
122 std::cout <<
" Relative error: " << uRelativeError << std::endl;
126 std::cout <<
"Pressure" << std::endl;
130 std::cout <<
" L2 error : " << pL2Error << std::endl;
134 std::cout <<
" Relative error: " << pRelativeError << std::endl;
146 MPI_Init (&argc, &argv);
147 std::shared_ptr<Epetra_Comm> Comm (
new Epetra_MpiComm (MPI_COMM_WORLD) );
149 MPI_Comm_size (MPI_COMM_WORLD, &nproc);
151 std::shared_ptr<Epetra_Comm> Comm (
new Epetra_SerialComm);
154 const bool verbose (Comm->MyPID() == 0);
158 <<
" +-----------------------------------------------+" << std::endl
159 <<
" | OseenAssembler example |" << std::endl
160 <<
" +-----------------------------------------------+" << std::endl
162 <<
" +-----------------------------------------------+" << std::endl
163 <<
" | Author: Gwenol Grandperrin |" << std::endl
164 <<
" | Date: 2010-03-25 |" << std::endl
165 <<
" +-----------------------------------------------+" << std::endl
168 std::cout <<
"[Initilization of MPI]" << std::endl;
170 std::cout <<
"Using MPI (" << nproc <<
" proc.)" << std::endl;
172 std::cout <<
"Using serial version" << std::endl;
181 std::cout << std::endl <<
"[Loading the data]" << std::endl;
183 LifeChrono globalChrono;
184 LifeChrono initChrono;
185 LifeChrono iterChrono;
187 globalChrono.start();
191 GetPot command_line (argc, argv);
192 const std::string dataFileName = command_line.follow (
"data", 2,
"-f",
"--file");
193 GetPot dataFile (dataFileName);
197 const Real viscosity = 0.01;
198 const Real density = 1.0;
201 const Real initialTime = 0.0;
202 const Real endTime = 1e-2;
203 const Real timestep = 1e-3;
206 const UInt numDimensions = 3;
207 const MeshType meshSource = RegularMesh;
208 const UInt numMeshElem = 3;
211 const DiffusionType diffusionType = ViscousStress;
213 const InitType initializationMethod = Interpolation;
214 const ConvectionType convectionTerm = KIO91;
221 problem_Type::setA (1.0);
222 problem_Type::setD (1.0);
223 problem_Type::setViscosity (viscosity);
224 problem_Type::setDensity (density);
226 if (diffusionType == StiffStrain)
228 problem_Type::setFlagStrain (1);
232 problem_Type::setFlagStrain (0);
240 std::cout << std::endl <<
"[Loading the mesh]" << std::endl;
243 std::shared_ptr<RegionMesh<LinearTetra> > fullMeshPtr (
new RegionMesh<LinearTetra> ( Comm ) );
246 if (meshSource == RegularMesh)
248 regularMesh3D ( *fullMeshPtr,
250 numMeshElem, numMeshElem, numMeshElem,
255 if (verbose) std::cout <<
"Mesh source: regular mesh(" 256 << numMeshElem <<
"x" << numMeshElem <<
"x" << numMeshElem <<
")" << std::endl;
258 else if (meshSource == File)
261 meshData.setup (dataFile,
"fluid/space_discretization");
262 readMesh (*fullMeshPtr, meshData);
264 if (verbose) std::cout <<
"Mesh source: file(" 265 << meshData.meshDir() << meshData.meshFile() <<
")" << std::endl;
271 std::cout << std::endl <<
"Error: Unknown source type for the mesh" << std::endl;
278 std::cout <<
"Mesh size : " <<
279 MeshUtility::MeshStatistics::computeSize (*fullMeshPtr).maxH << std::endl;
283 std::cout <<
"Partitioning the mesh ... " << std::endl;
285 std::shared_ptr<RegionMesh<LinearTetra> > meshPtr;
287 MeshPartitioner< RegionMesh<LinearTetra> > meshPart (fullMeshPtr, Comm);
288 meshPtr = meshPart.meshPartition();
297 std::cout << std::endl <<
"[Creating the FE spaces]" << std::endl;
299 std::string uOrder (
"P2");
300 std::string pOrder (
"P1");
302 if (verbose) std::cout <<
"FE for the velocity: " << uOrder << std::endl
303 <<
"FE for the pressure: " << pOrder << std::endl;
307 std::cout <<
"Building the velocity FE space ... " << std::flush;
309 fespacePtr_Type uFESpace (
new fespace_Type ( meshPtr, uOrder, numDimensions, Comm ) );
312 std::cout <<
"ok." << std::endl;
317 std::cout <<
"Building the pressure FE space ... " << std::flush;
319 fespacePtr_Type pFESpace (
new fespace_Type ( meshPtr, pOrder, 1, Comm ) );
322 std::cout <<
"ok." << std::endl;
326 MapEpetra solutionMap (uFESpace->map() + pFESpace->map() );
329 UInt pressureOffset = numDimensions * uFESpace->dof().numTotalDof();
333 std::cout <<
"Total Velocity Dof: " << pressureOffset << std::endl;
337 std::cout <<
"Total Pressure Dof: " << pFESpace->dof().numTotalDof() << std::endl;
345 std::cout << std::endl <<
"[Boundary conditions]" << std::endl;
348 BCFunctionBase uDirichlet ( problem_Type::uexact );
349 BCFunctionBase uNeumann ( problem_Type::fNeumann );
353 std::cout <<
"Setting Neumann BC... " << std::flush;
355 bcHandler.addBC (
"Flux", 1, Natural, Full, uNeumann, 3 );
358 std::cout <<
"ok." << std::endl;
363 std::cout <<
"Setting Dirichlet BC... " << std::flush;
365 for (UInt iDirichlet (2); iDirichlet <= 26; ++iDirichlet)
367 bcHandler.addBC (
"Wall", iDirichlet, Essential, Full, uDirichlet, 3 );
371 std::cout <<
"ok." << std::endl;
375 bcHandler.bcUpdate ( *meshPtr, uFESpace->feBd(), uFESpace->dof() );
382 std::cout << std::endl <<
"[Matrices Assembly]" << std::endl;
387 std::cout <<
"Setting up assembler... " << std::flush;
389 OseenAssembler<mesh_Type, matrix_Type, vector_Type> oseenAssembler;
390 oseenAssembler.setup (uFESpace, pFESpace);
393 std::cout <<
"done" << std::endl;
398 std::cout <<
"Defining the matrices... " << std::flush;
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 ) );
404 std::shared_ptr<matrix_Type> massMatrix (
new matrix_Type ( solutionMap ) );
408 std::cout <<
"done" << std::endl;
412 switch (diffusionType)
417 std::cout <<
"Adding the viscous stress... " << std::flush;
419 oseenAssembler.addViscousStress (*baseMatrix, viscosity / density);
422 std::cout <<
"done" << std::endl;
428 std::cout <<
"Adding the stiff strain... " << std::flush;
430 oseenAssembler.addStiffStrain (*baseMatrix, viscosity / density);
433 std::cout <<
"done" << std::endl;
437 std::cerr <<
"[Error] Diffusion type unknown" << std::endl;
438 return ( EXIT_FAILURE );
444 std::cout <<
"Adding the gradient of the pressure... " << std::flush;
446 oseenAssembler.addGradPressure (*baseMatrix);
449 std::cout <<
"done" << std::endl;
454 std::cout <<
"Adding the divergence free constraint... " << std::flush;
456 oseenAssembler.addDivergence (*baseMatrix, -1.0);
459 std::cout <<
"done" << std::endl;
464 std::cout <<
"Adding the mass... " << std::flush;
466 oseenAssembler.addMass (*massMatrix, 1.0);
469 std::cout <<
"done" << std::endl;
474 std::cout <<
"Closing the matrices... " << std::flush;
476 baseMatrix->globalAssemble();
477 massMatrix->globalAssemble();
480 std::cout <<
"done" << std::endl;
486 BCFunctionBase flow (fluxFunction);
488 BCHandler fluxHandler;
489 fluxHandler.addBC (
"Flux" , 1, Flux, Normal, flow);
492 fluxHandler.bcUpdate ( *meshPtr, uFESpace->feBd(), uFESpace->dof() );
494 vector_Type fluxVector (solutionMap);
495 oseenAssembler.addFluxTerms (fluxVector, fluxHandler);
503 std::cout << std::endl <<
"[Solver initialization]" << std::endl;
505 SolverAztecOO linearSolver;
509 std::cout <<
"Setting up the solver... " << std::flush;
511 linearSolver.setDataFromGetPot (dataFile,
"solver");
512 linearSolver.setupPreconditioner (dataFile,
"prec");
515 std::cout <<
"done" << std::endl;
518 linearSolver.setCommunicator (Comm);
525 std::cout << std::endl <<
"[Initialization of the simulation]" << std::endl;
529 std::cout <<
"Creation of vectors... " << std::flush;
532 rhs.reset (
new vector_Type (solutionMap, Unique) );
535 beta.reset (
new vector_Type (solutionMap, Repeated) );
537 vector_Type convect (rhs->map() );
539 vectorPtr_Type velocity;
540 velocity.reset (
new vector_Type (uFESpace->map(), Unique) );
542 vectorPtr_Type pressure;
543 pressure.reset (
new vector_Type (pFESpace->map(), Unique) );
545 vectorPtr_Type solution;
546 solution.reset (
new vector_Type (solutionMap, Unique) );
549 std::cout <<
"done" << std::endl;
554 std::cout <<
"Computing the initial solution ... " << std::endl;
556 if (convectionTerm == KIO91)
562 TimeAdvanceBDF<vector_Type> bdf;
563 bdf.setup (BDFOrder);
564 TimeAdvanceBDF<vector_Type> bdfConvection;
565 bdfConvection.setup (BDFOrder);
566 TimeAdvanceBDF<vector_Type> bdfConvectionInit;
567 bdfConvectionInit.setup (BDFOrder);
568 Real currentTime = initialTime - timestep * BDFOrder;
570 if (convectionTerm == KIO91)
572 uFESpace->interpolate (
static_cast<FESpace< mesh_Type, MapEpetra >::function_Type> ( problem_Type::uexact ), *velocity, currentTime );
574 *solution = *velocity;
576 oseenAssembler.addConvectionRhs (*beta, 1., *solution);
577 bdfConvection.setInitialCondition ( *beta );
578 bdfConvectionInit.setInitialCondition ( *beta );
580 if (initializationMethod == Projection)
582 for (UInt i (0); i < BDFOrder; ++i)
584 uFESpace->interpolate (
static_cast<FESpace< mesh_Type, MapEpetra >::function_Type> ( problem_Type::uexact ), *velocity, currentTime - (3 - i) *timestep );
585 *solution = *velocity;
587 oseenAssembler.addConvectionRhs (*beta, 1., *solution);
588 bdfConvectionInit.shiftRight ( *beta );
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 );
596 *solution = *velocity;
597 solution->add (*pressure, pressureOffset);
598 bdf.setInitialCondition ( *solution );
601 Real fluxThrou1 = fluxVector.dot (*solution);
602 if (verbose) std::cout <<
"Flux through face 1 = " 603 << fluxThrou1 << std::endl;
606 currentTime += timestep;
607 for ( ; currentTime <= initialTime + timestep / 2.; currentTime += timestep)
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);
618 if (initializationMethod == Projection)
620 oseenAssembler.addMassRhs (*rhs, problem_Type::uderexact , currentTime);
626 std::cout <<
"Updating the system... " << std::flush;
628 systemMatrix.reset (
new matrix_Type ( solutionMap ) );
629 *systemMatrix += *baseMatrix;
630 if (convectionTerm == SemiImplicit)
632 oseenAssembler.addConvection (*systemMatrix, 1.0, *solution);
634 else if (convectionTerm == Explicit)
636 oseenAssembler.addConvectionRhs (*rhs, 1., *solution);
638 else if (convectionTerm == KIO91)
640 bdfConvectionInit.extrapolation (convect);
643 oseenAssembler.addConvectionRhs (*beta, 1., *solution);
644 bdfConvectionInit.shiftRight (*beta);
649 std::cout <<
"done" << std::endl;
654 std::cout <<
"Applying BC... " << std::flush;
656 bcManage (*systemMatrix, *rhs, *uFESpace->mesh(), uFESpace->dof(), bcHandler, uFESpace->feBd(), 1.0, currentTime);
657 systemMatrix->globalAssemble();
660 std::cout <<
"done" << std::endl;
665 std::cout <<
"Solving the system... " << std::endl;
668 linearSolver.setMatrix (*systemMatrix);
669 linearSolver.solveSystem (*rhs, *solution, systemMatrix);
673 bdf.shiftRight ( *solution );
675 if (convectionTerm == KIO91)
678 oseenAssembler.addConvectionRhs (*beta, 1., *solution);
679 bdfConvection.shiftRight (*beta);
684 linearSolver.resetPreconditioner();
691 std::cout <<
"Defining the exporter... " << std::flush;
693 ExporterHDF5<mesh_Type> exporter ( dataFile,
"OseenAssembler");
694 exporter.setPostDir (
"./" );
695 exporter.setMeshProcId ( meshPtr, Comm->MyPID() );
698 std::cout <<
"done" << std::endl;
703 std::cout <<
"Updating the exporter... " << std::flush;
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 );
711 std::cout <<
"done" << std::endl;
716 std::cout <<
"Exporting solution at time t=" << initialTime <<
"... " << std::endl;
718 exporter.postProcess (initialTime);
723 std::cout <<
"Initialization time: " << initChrono.diff() <<
" s." << std::endl;
729 printErrors (*solution, currentTime, uFESpace, pFESpace, verbose);
736 std::cout << std::endl <<
"[Solving the problem]" << std::endl;
740 for ( ; currentTime <= endTime + timestep / 2.; currentTime += timestep, iter++)
747 std::cout << std::endl <<
"[t = " << currentTime <<
" s.]" << std::endl;
752 std::cout <<
"Updating the system... " << std::flush;
754 bdf.updateRHSContribution ( timestep );
755 *rhs = *massMatrix * bdf.rhsContributionFirstDerivative();
757 systemMatrix.reset (
new matrix_Type ( solutionMap ) );
758 double alpha = bdf.coefficientFirstDerivative ( 0 ) / timestep;
759 *systemMatrix += *massMatrix * alpha;
760 *systemMatrix += *baseMatrix;
762 if (convectionTerm == SemiImplicit)
765 bdf.extrapolation ( *beta );
766 oseenAssembler.addConvection (*systemMatrix, 1.0, *beta);
768 else if (convectionTerm == Explicit)
770 oseenAssembler.addConvectionRhs (*rhs, 1., *solution);
772 else if (convectionTerm == KIO91)
776 bdfConvection.extrapolation (convect);
781 std::cout <<
"done" << std::endl;
786 std::cout <<
"Applying BC... " << std::flush;
788 bcManage (*systemMatrix, *rhs, *uFESpace->mesh(), uFESpace->dof(), bcHandler, uFESpace->feBd(), 1.0, currentTime);
789 systemMatrix->globalAssemble();
792 std::cout <<
"done" << std::endl;
797 std::cout <<
"Solving the system... " << std::endl;
800 linearSolver.setMatrix (*systemMatrix);
801 linearSolver.solveSystem (*rhs, *solution, systemMatrix);
804 bdf.shiftRight ( *solution );
806 if (convectionTerm == KIO91)
809 oseenAssembler.addConvectionRhs (*beta, 1., *solution);
810 bdfConvection.shiftRight (*beta);
814 exporter.postProcess ( currentTime );
819 std::cout <<
"Iteration time: " << iterChrono.diff() <<
" s." << std::endl;
825 printErrors (*solution, currentTime, uFESpace, pFESpace, verbose);
827 MPI_Barrier (MPI_COMM_WORLD);
833 exporter.closeFile();
838 std::cout << std::endl <<
"Total simulation time: " << globalChrono.diff() <<
" s." << std::endl;
842 std::cout << std::endl <<
"[[END_SIMULATION]]" << std::endl;
848 return ( EXIT_SUCCESS );
VectorEpetra - The Epetra Vector format Wrapper.
LifeV::RossEthierSteinmanUnsteadyDec problem_Type
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!
Epetra_Import const & importer()
Getter for the Epetra_Import.
FESpace< mesh_Type, MapEpetra > fespace_Type
RegionMesh< LinearTetra > mesh_Type
double Real
Generic real data.
void printErrors(const vector_Type &solution, const Real ¤tTime, fespacePtr_Type uFESpace, fespacePtr_Type pFESpace, bool verbose)
std::shared_ptr< fespace_Type > fespacePtr_Type
MatrixEpetra< Real > matrix_Type
std::shared_ptr< VectorEpetra > vectorPtr_Type
int main(int argc, char **argv)