37 #pragma GCC diagnostic ignored "-Wunused-variable" 38 #pragma GCC diagnostic ignored "-Wunused-parameter" 40 #include <Epetra_ConfigDefs.h> 43 #include <Epetra_MpiComm.h> 45 #include <Epetra_SerialComm.h> 49 #pragma GCC diagnostic warning "-Wunused-variable" 50 #pragma GCC diagnostic warning "-Wunused-parameter" 52 #include <lifev/core/LifeV.hpp> 53 #include <lifev/core/mesh/RegionMesh3DStructured.hpp> 54 #include <lifev/core/mesh/MeshData.hpp> 55 #include <lifev/core/mesh/RegionMesh.hpp> 56 #include <lifev/core/mesh/MeshPartitioner.hpp> 58 #include <lifev/eta/expression/Integrate.hpp> 59 #include <lifev/core/fem/FESpace.hpp> 60 #include <lifev/eta/fem/ETFESpace.hpp> 62 #include <lifev/core/fem/BCManage.hpp> 64 #include <lifev/core/array/MatrixEpetra.hpp> 65 #include <lifev/core/array/VectorEpetra.hpp> 66 #include <lifev/core/array/MatrixEpetraStructured.hpp> 67 #include <lifev/core/array/VectorBlockMonolithicEpetra.hpp> 70 #include <lifev/core/algorithm/PreconditionerIfpack.hpp> 71 #include <lifev/core/algorithm/PreconditionerML.hpp> 72 #include <lifev/core/algorithm/SolverAztecOO.hpp> 73 #include <lifev/core/filter/ExporterHDF5.hpp> 74 #include <lifev/core/fem/TimeAdvanceBDF.hpp> 76 #include <lifev/navier_stokes/solver/StabilizationIP.hpp> 77 #include <lifev/core/fem/Assembly.hpp> 78 #include <lifev/core/fem/AssemblyElemental.hpp> 80 using namespace LifeV;
116 return (1 * t / 0.5 * (t < 0.5) + 1 * (t > 0.5) );
129 return (1 * ux * t / 0.5 * (t < 0.5) + 1 * ux * (t > 0.5) );
146 Real norm (sqrt ( value
[0
]*value
[0
] + value
[1
]*value
[1
] + value
[2
]*value
[2
]) );
150 return value
* (1.0 / norm);
169 Real norm (sqrt ( value
[0
]*value
[0
] + value
[1
]*value
[1
] + value
[2
]*value
[2
]) );
187 MPI_Init (&argc, &argv);
188 std::shared_ptr<Epetra_Comm> Comm (
new Epetra_MpiComm (MPI_COMM_WORLD) );
190 MPI_Comm_size (MPI_COMM_WORLD, &nproc);
192 std::shared_ptr<Epetra_Comm> Comm (
new Epetra_SerialComm);
195 const bool verbose (Comm->MyPID() == 0);
199 <<
" +-----------------------------------------------+" << std::endl
200 <<
" | Vortex shedding example w/ETA assembly |" << std::endl
201 <<
" +-----------------------------------------------+" << std::endl
203 <<
" +-----------------------------------------------+" << std::endl
204 <<
" | Author: Toni Lassila |" << std::endl
205 <<
" | Date: 2012-11-13 |" << std::endl
206 <<
" +-----------------------------------------------+" << std::endl
209 std::cout <<
"[Initilization of MPI]" << std::endl;
211 std::cout <<
"Using MPI (" << nproc <<
" proc.)" << std::endl;
213 std::cout <<
"Using serial version" << std::endl;
222 std::cout << std::endl <<
"[Loading the data]" << std::endl;
224 LifeChrono globalChrono;
225 LifeChrono initChrono;
226 LifeChrono iterChrono;
228 globalChrono.start();
232 GetPot command_line (argc, argv);
233 const std::string dataFileName = command_line.follow (
"data", 2,
"-f",
"--file");
234 GetPot dataFile (dataFileName);
238 const Real viscosity = 0.01 / 5;
239 const Real density = 1.0;
242 const Real initialTime = 0.0;
243 const Real endTime = 100.0;
244 const Real timestep = 1e-1;
247 const UInt numDimensions = 3;
253 const StabilizationType stabilizationMethod = VMS;
256 const InitType initializationMethod = Interpolation;
257 const ConvectionType convectionTerm = SemiImplicit;
264 std::cout << std::endl <<
"[Loading the mesh]" << std::endl;
267 std::shared_ptr<RegionMesh<LinearTetra> > fullMeshPtr (
new RegionMesh<LinearTetra>);
271 meshData.setup (dataFile,
"fluid/space_discretization");
272 readMesh (*fullMeshPtr, meshData);
274 if (verbose) std::cout <<
"Mesh source: file(" 275 << meshData.meshDir() << meshData.meshFile() <<
")" << std::endl;
279 std::cout <<
"Mesh size : " <<
280 MeshUtility::MeshStatistics::computeSize (*fullMeshPtr).maxH << std::endl;
284 std::cout <<
"Partitioning the mesh ... " << std::endl;
286 MeshPartitioner< RegionMesh<LinearTetra> > meshPart (fullMeshPtr, Comm);
294 std::cout << std::endl <<
"[Creating the FE spaces]" << std::endl;
296 std::string uOrder (
"P1");
297 std::string pOrder (
"P1");
299 if (verbose) std::cout <<
"FE for the velocity: " << uOrder << std::endl
300 <<
"FE for the pressure: " << pOrder << std::endl;
304 std::cout <<
"Building the velocity FE space ... " << std::flush;
306 fespacePtr_Type uFESpace (
new FESpace< mesh_Type, MapEpetra > (meshPart, uOrder, numDimensions, Comm) );
309 std::cout <<
"ok." << std::endl;
314 std::cout <<
"Building the pressure FE space ... " << std::flush;
316 fespacePtr_Type pFESpace (
new FESpace< mesh_Type, MapEpetra > (meshPart, pOrder, 1, Comm) );
319 std::cout <<
"ok." << std::endl;
323 etaUspacePtr_Type ETuFESpace (
new etaUspace_Type (meshPart, & (uFESpace->refFE() ), Comm) );
324 etaPspacePtr_Type ETpFESpace (
new etaPspace_Type (meshPart, & (pFESpace->refFE() ), Comm) );
327 MapEpetra solutionMap (uFESpace->map() + pFESpace->map() );
330 UInt pressureOffset = numDimensions * uFESpace->dof().numTotalDof();
334 std::cout <<
"Total Velocity Dof: " << pressureOffset << std::endl;
338 std::cout <<
"Total Pressure Dof: " << pFESpace->dof().numTotalDof() << std::endl;
346 std::cout << std::endl <<
"[Boundary conditions]" << std::endl;
349 BCFunctionBase uZero ( zeroFunction );
350 BCFunctionBase uInflow ( inflowFunction );
353 std::vector<LifeV::ID> zComp (1);
358 std::cout <<
"Setting Neumann BC... " << std::flush;
360 bcHandler.addBC (
"Outflow", 3, Natural, Full, uZero, 3 );
363 std::cout <<
"ok." << std::endl;
368 std::cout <<
"Setting Dirichlet BC... " << std::flush;
370 bcHandler.addBC (
"Inflow", 1, Essential, Full, uInflow, 3 );
371 bcHandler.addBC (
"Wall", 2, Essential, Full, uInflow, 3 );
372 bcHandler.addBC (
"Cube", 4, Essential, Full, uZero, 3 );
373 bcHandler.addBC (
"Symmetry", 5, Essential, Component, uZero, zComp );
377 std::cout <<
"ok." << std::endl;
381 bcHandler.bcUpdate ( *meshPart.meshPartition(), uFESpace->feBd(), uFESpace->dof() );
388 std::cout << std::endl <<
"[Matrices Assembly]" << std::endl;
393 std::cout <<
"Defining the matrices... " << std::flush;
397 std::shared_ptr<matrix_block_type> systemMatrix (
new matrix_block_type ( ETuFESpace->map() | ETpFESpace->map() ) );
398 std::shared_ptr<matrix_block_type> baseMatrix (
new matrix_block_type ( ETuFESpace->map() | ETpFESpace->map() ) );
399 std::shared_ptr<matrix_block_type> convMatrix (
new matrix_block_type ( ETuFESpace->map() | ETpFESpace->map() ) );
400 std::shared_ptr<matrix_block_type> massMatrix (
new matrix_block_type ( ETuFESpace->map() | ETpFESpace->map() ) );
402 *systemMatrix *= 0.0;
409 std::cout <<
"done" << std::endl;
415 std::shared_ptr<NormalizeFct> normalize (
new NormalizeFct);
417 using namespace ExpressionAssembly;
421 elements (ETuFESpace->mesh() ),
425 0.5 * viscosity * dot (grad (phi_i) + transpose (grad (phi_i) ), grad (phi_j) + transpose (grad (phi_j) ) )
427 >> baseMatrix->block (0, 0);
430 elements (ETuFESpace->mesh() ),
434 value (-1.0) * phi_j * div (phi_i)
436 >> baseMatrix->block (0, 1);
440 elements (ETuFESpace->mesh() ),
446 >> baseMatrix->block (1, 0);
449 elements (ETuFESpace->mesh() ),
456 >> massMatrix->block (0, 0);
461 std::cout <<
"done" << std::endl;
466 std::cout <<
"Closing the matrices... " << std::flush;
468 baseMatrix->globalAssemble();
469 massMatrix->globalAssemble();
470 convMatrix->globalAssemble();
474 std::cout <<
"done" << std::endl;
482 std::cout << std::endl <<
"[Solver initialization]" << std::endl;
484 SolverAztecOO linearSolver;
488 std::cout <<
"Setting up the solver... " << std::flush;
490 linearSolver.setDataFromGetPot (dataFile,
"solver");
491 linearSolver.setupPreconditioner (dataFile,
"prec");
494 std::cout <<
"done" << std::endl;
497 linearSolver.setCommunicator (Comm);
504 std::cout << std::endl <<
"[Initialization of the simulation]" << std::endl;
508 std::cout <<
"Creation of vectors... " << std::flush;
511 vectorPtr_Type prevRhs;
513 rhs.reset (
new vector_Type (solutionMap, Unique) );
514 prevRhs.reset (
new vector_Type (solutionMap, Unique) );
516 vectorPtr_Type velocityExtrapolated;
517 velocityExtrapolated.reset (
new vector_Type (solutionMap, Repeated) );
519 vector_Type convect (rhs->map() );
521 vectorPtr_Type velocity;
522 velocity.reset (
new vector_Type (uFESpace->map(), Unique) );
524 vectorPtr_Type pressure;
525 vectorPtr_Type prevPressure;
526 pressure.reset (
new vector_Type (pFESpace->map(), Unique) );
527 prevPressure.reset (
new vector_Type (pFESpace->map(), Unique) );
529 vectorPtr_Type solution;
530 vectorPtr_Type prevSolution;
531 vectorPtr_Type prevSolutionTimeDerivative;
533 solution.reset (
new vector_Type (solutionMap, Unique) );
534 prevSolution.reset (
new vector_Type (solutionMap, Unique) );
535 prevSolutionTimeDerivative.reset (
new vector_Type (solutionMap, Unique) );
538 std::cout <<
"done" << std::endl;
543 std::cout <<
"Computing the initial solution ... " << std::endl;
547 TimeAdvanceBDF<vector_Type> bdf;
548 bdf.setup (BDFOrder);
550 TimeAdvanceBDF<vector_Type> bdfConvection;
551 bdfConvection.setup (BDFOrder);
553 Real currentTime = initialTime - timestep * BDFOrder;
561 *prevSolutionTimeDerivative *= 0.;
564 bdf.setInitialCondition ( *solution );
567 currentTime += timestep;
568 for ( ; currentTime <= initialTime + timestep / 2.; currentTime += timestep)
571 *velocityExtrapolated *= 0.;
574 if (initializationMethod == Projection)
580 std::cout <<
"Updating the system... " << std::flush;
582 systemMatrix.reset (
new matrix_block_type ( solutionMap ) );
583 *systemMatrix += *baseMatrix;
587 if (convectionTerm == SemiImplicit)
589 convMatrix.reset (
new matrix_block_type ( solutionMap ) );
594 using namespace ExpressionAssembly;
597 elements (ETuFESpace->mesh() ),
601 dot (grad (phi_j) * value (ETuFESpace, *velocityExtrapolated), phi_i)
603 >> convMatrix->block (0, 0);
605 *systemMatrix += *convMatrix;
607 else if (convectionTerm == Explicit)
624 std::shared_ptr<matrix_block_type> stabMatrix (
new matrix_block_type ( ETuFESpace->map() | ETpFESpace->map() ) );
626 stabMatrix->globalAssemble();
627 *systemMatrix += *stabMatrix;
631 std::cout <<
"done" << std::endl;
636 std::cout <<
"Applying BC... " << std::flush;
638 bcManage (*systemMatrix, *rhs, *uFESpace->mesh(), uFESpace->dof(), bcHandler, uFESpace->feBd(), 1.0, currentTime);
639 systemMatrix->globalAssemble();
642 std::cout <<
"done" << std::endl;
647 std::cout <<
"Solving the system... " << std::endl;
652 std::shared_ptr<matrix_Type> systemMatrixNoBlock (
new matrix_Type ( systemMatrix->matrixPtr() ) );
653 linearSolver.setMatrix (*systemMatrix);
654 linearSolver.solveSystem (*rhs, *solution, systemMatrixNoBlock);
658 bdf.shiftRight ( *solution );
662 linearSolver.resetPreconditioner();
669 std::cout <<
"Defining the exporter... " << std::flush;
671 ExporterHDF5<mesh_Type> exporter ( dataFile,
"OseenAssembler");
672 exporter.setPostDir (
"./" );
673 exporter.setMeshProcId ( meshPart.meshPartition(), Comm->MyPID() );
676 std::cout <<
"done" << std::endl;
681 std::cout <<
"Updating the exporter... " << std::flush;
683 exporter.addVariable ( ExporterData<mesh_Type>::VectorField,
"velocity", uFESpace, solution, UInt (0) );
684 exporter.addVariable ( ExporterData<mesh_Type>::ScalarField,
"pressure", pFESpace, solution, pressureOffset );
687 std::cout <<
"done" << std::endl;
692 std::cout <<
"Exporting solution at time t=" << initialTime <<
"... " << std::endl;
694 exporter.postProcess (initialTime);
699 std::cout <<
"Initialization time: " << initChrono.diff() <<
" s." << std::endl;
707 std::cout << std::endl <<
"[Solving the problem]" << std::endl;
711 for ( ; currentTime <= endTime + timestep / 2.; currentTime += timestep, iter++)
718 std::cout << std::endl <<
"[t = " << currentTime <<
" s.]" << std::endl;
723 std::cout <<
"Updating the system... " << std::flush;
725 bdf.updateRHSContribution ( timestep );
726 *rhs = *massMatrix * bdf.rhsContributionFirstDerivative();
728 systemMatrix.reset (
new matrix_block_type ( solutionMap ) );
729 double alpha = bdf.coefficientFirstDerivative ( 0 ) / timestep;
730 *systemMatrix += *massMatrix * alpha;
731 *systemMatrix += *baseMatrix;
733 if (convectionTerm == SemiImplicit)
735 bdf.extrapolation ( *velocityExtrapolated );
737 convMatrix.reset (
new matrix_block_type ( solutionMap ) );
742 using namespace ExpressionAssembly;
745 elements (ETuFESpace->mesh() ),
749 dot (grad (phi_j) * value (ETuFESpace, *velocityExtrapolated), phi_i)
751 >> convMatrix->block (0, 0);
753 convMatrix->globalAssemble();
754 *systemMatrix += *convMatrix;
756 else if (convectionTerm == Explicit)
781 #define SUPG_TEST value(TauM) * h_K * (grad(phi_i) * value(ETuFESpace, *velocityExtrapolated)) 782 #define VMS_TEST value(TauM) * h_K * (transpose(grad(phi_i)) * value(ETuFESpace, *velocityExtrapolated)) 783 #define PSPG_TEST value(TauM) * h_K * grad(phi_i) 784 #define DIVDIV_TEST value(TauC) * h_K * div(phi_i) 786 #define RES_MOMENTUM grad(phi_j) * value(ETuFESpace, *velocityExtrapolated) * density + value(alpha) * density * phi_j 787 #define RES_MASS div(phi_j) 788 #define RES_PRESSURE grad(phi_j) 790 #define RESIDUAL_EXPLICIT value(TauM) * h_K * value(ETuFESpace, *residualVector) 792 std::shared_ptr<matrix_block_type> stabMatrix (
new matrix_block_type ( ETuFESpace->map() | ETpFESpace->map() ) );
793 std::shared_ptr<matrix_block_type> residualMatrix (
new matrix_block_type ( ETuFESpace->map() | ETpFESpace->map() ) );
794 vector_block_type NSRhs ( ETuFESpace->map() | ETpFESpace->map(), Repeated );
795 vectorPtr_Type residualVector;
796 residualVector.reset (
new vector_Type (solutionMap, Unique) );
799 *residualMatrix *= 0;
800 *residualVector *= 0;
803 if (stabilizationMethod == VMS)
806 std::shared_ptr<NormalizeFct> normalize (
new NormalizeFct);
808 using namespace ExpressionAssembly;
812 elements (ETuFESpace->mesh() ),
818 >> residualMatrix->block (0, 0);
821 elements (ETuFESpace->mesh() ),
827 >> residualMatrix->block (0, 1);
830 residualMatrix->globalAssemble();
831 bcManage (*residualMatrix, *prevRhs, *uFESpace->mesh(), uFESpace->dof(), bcHandler, uFESpace->feBd(), 1.0, currentTime);
834 *residualVector = *prevRhs - (*residualMatrix * (*prevSolution) );
838 elements (ETuFESpace->mesh() ),
846 >> stabMatrix->block (0, 0);
850 elements (ETuFESpace->mesh() ),
857 >> stabMatrix->block (0, 1);
862 elements (ETuFESpace->mesh() ),
868 >> stabMatrix->block (1, 0);
872 elements (ETuFESpace->mesh() ),
878 >> stabMatrix->block (1, 1);
881 stabMatrix->globalAssemble();
882 *systemMatrix += *stabMatrix;
884 else if (stabilizationMethod == IP)
886 details::StabilizationIP<mesh_Type, DOF> M_ipStabilization;
887 M_ipStabilization.setFeSpaceVelocity ( *uFESpace );
888 M_ipStabilization.setViscosity ( viscosity );
891 M_ipStabilization.setGammaBeta ( 0.1 );
892 M_ipStabilization.setGammaDiv ( 0.1 );
893 M_ipStabilization.setGammaPress ( 0.1 );
895 M_ipStabilization.apply ( *stabMatrix, *velocityExtrapolated,
false );
896 stabMatrix->globalAssemble();
897 *systemMatrix += *stabMatrix;
904 std::cout <<
"done" << std::endl;
907 if (stabilizationMethod == VMS)
909 std::shared_ptr<NormalizeFct> normalize (
new NormalizeFct);
911 using namespace ExpressionAssembly;
914 elements (ETuFESpace->mesh() ),
917 dot (value (ETuFESpace, *rhs),
SUPG_TEST)
918 + dot (value (ETuFESpace, *rhs),
VMS_TEST)
925 elements (ETuFESpace->mesh() ),
928 dot (value (ETuFESpace, *rhs),
PSPG_TEST)
933 vector_block_type NSRhsUnique ( NSRhs, Unique );
938 std::cout <<
"done" << std::endl;
945 std::cout <<
"Applying BC... " << std::flush;
947 bcManage (*systemMatrix, *rhs, *uFESpace->mesh(), uFESpace->dof(), bcHandler, uFESpace->feBd(), 1.0, currentTime);
952 std::cout <<
"Solving the system... " << std::endl;
957 std::shared_ptr<matrix_Type> systemMatrixNoBlock (
new matrix_Type ( systemMatrix->matrixPtr() ) );
958 linearSolver.setMatrix (*systemMatrix);
959 linearSolver.solveSystem (*rhs, *solution, systemMatrixNoBlock);
962 bdf.shiftRight ( *solution );
965 exporter.postProcess ( currentTime );
968 *prevSolution = *solution;
974 std::cout <<
"Iteration time: " << iterChrono.diff() <<
" s." << std::endl;
977 MPI_Barrier (MPI_COMM_WORLD);
983 exporter.closeFile();
988 std::cout << std::endl <<
"Total simulation time: " << globalChrono.diff() <<
" s." << std::endl;
992 std::cout << std::endl <<
"[[END_SIMULATION]]" << std::endl;
998 return ( EXIT_SUCCESS );
ETFESpace< mesh_Type, MapEpetra, 3, 1 > etaPspace_Type
Real fluxFunction(const Real &, const Real &, const Real &, const Real &, const ID &)
FESpace - Short description here please!
VectorSmall< 3 > return_Type
Real const & operator[](UInt const &i) const
Operator [].
std::shared_ptr< ETFESpace< mesh_Type, MapEpetra, 3, 1 > > etaPspacePtr_Type
return_Type operator()(const VectorSmall< 3 > &value)
#define RESIDUAL_EXPLICIT
VectorBlockMonolithicEpetra vector_block_type
Real inflowFunction(const Real &t, const Real &, const Real &, const Real &, const ID &i)
VectorSmall< 3 > operator*(Real const &factor) const
Operator * (multiplication by scalar on the right)
FESpace< mesh_Type, MapEpetra > fespace_Type
RegionMesh< LinearTetra > mesh_Type
std::shared_ptr< VectorBlockMonolithicEpetra > vector_blockPtr_type
Real zeroFunction(const Real &, const Real &, const Real &, const Real &, const ID &)
ETFESpace< mesh_Type, MapEpetra, 3, 3 > etaUspace_Type
NormalizeFct(const NormalizeFct &)
double Real
Generic real data.
std::shared_ptr< fespace_Type > fespacePtr_Type
MatrixEpetra< Real > matrix_Type
std::shared_ptr< ETFESpace< mesh_Type, MapEpetra, 3, 3 > > etaUspacePtr_Type
std::shared_ptr< VectorEpetra > vectorPtr_Type
return_Type operator()(const VectorSmall< 3 > value)
class ETFESpace A light, templated version of the FESpace
int main(int argc, char **argv)
MatrixEpetraStructured< Real > matrix_block_type