示例#1
0
文件: main.cpp 项目: nuraiman/lifev
int
main( int argc, char* argv[] )
{

#ifdef HAVE_MPI
    MPI_Init(&argc, &argv);
#endif

    { // needed to properly destroy all objects inside before mpi finalize

#ifdef HAVE_MPI
    boost::shared_ptr<Epetra_Comm> Comm(new Epetra_MpiComm(MPI_COMM_WORLD));
    ASSERT ( Comm->NumProc() < 2, "The test does not run in parallel." );
#else
    boost::shared_ptr<Epetra_Comm> Comm(new Epetra_SerialComm);
#endif

    typedef RegionMesh<LinearLine> mesh_Type;
    typedef MatrixEpetra<Real> matrix_Type;
    typedef VectorEpetra vector_Type;
    typedef FESpace<mesh_Type, MapEpetra> feSpace_Type;
    typedef boost::shared_ptr<feSpace_Type> feSpacePtr_Type;

    const bool verbose(Comm->MyPID()==0);

    // Read first the data needed

    if (verbose) std::cout << " -- Reading the data ... " << std::flush;
    GetPot dataFile( "data" );
    if (verbose) std::cout << " done ! " << std::endl;

    // Build the mesh

    if (verbose) std::cout << " -- Reading the mesh ... " << std::flush;
    MeshData meshData(dataFile, "mesh");
    boost::shared_ptr< mesh_Type > meshPtr( new mesh_Type( Comm ) );

    // Set up the structured mesh
    regularMesh1D( *meshPtr, 0,
                   dataFile( "mesh/n", 20 ),
                   dataFile( "mesh/verbose", false ),
                   dataFile( "mesh/length", 1. ),
                   dataFile( "mesh/origin", 0. ) );

    if (verbose) std::cout << " done ! " << std::endl;

    // Build the FESpaces
    if (verbose) std::cout << " -- Building FESpaces ... " << std::flush;
    feSpacePtr_Type uFESpace( new feSpace_Type( meshPtr, feSegP1, quadRuleSeg1pt, quadRuleNode1pt, 1, Comm ) );
    if (verbose) std::cout << " done ! " << std::endl;
    if (verbose) std::cout << " ---> Dofs: " << uFESpace->dof().numTotalDof() << std::endl;

    // Build the assembler and the matrices

    if (verbose) std::cout << " -- Building assembler ... " << std::flush;
    ADRAssembler<mesh_Type,matrix_Type,vector_Type> adrAssembler;
    if (verbose) std::cout << " done! " << std::endl;

    if (verbose) std::cout << " -- Setting up assembler ... " << std::flush;
    adrAssembler.setFespace(uFESpace);
    if (verbose) std::cout << " done! " << std::endl;

    if (verbose) std::cout << " -- Defining the matrix ... " << std::flush;
    boost::shared_ptr<matrix_Type> systemMatrix(new matrix_Type( uFESpace->map() ));
    if (verbose) std::cout << " done! " << std::endl;

    // Perform the assembly of the matrix

    if (verbose) std::cout << " -- Adding the diffusion ... " << std::flush;
    adrAssembler.addDiffusion(systemMatrix, 1.);
    if (verbose) std::cout << " done! " << std::endl;
    if (verbose) std::cout << " Time needed : " << adrAssembler.diffusionAssemblyChrono().diffCumul() << std::endl;

    if (verbose) std::cout << " -- Adding the mass ... " << std::flush;
    adrAssembler.addMass(systemMatrix, M_PI * M_PI );
    if (verbose) std::cout << " done! " << std::endl;

    if (verbose) std::cout << " -- Closing the matrix ... " << std::flush;
    systemMatrix->globalAssemble();
    if (verbose) std::cout << " done ! " << std::endl;

    // Definition and assembly of the RHS
    if (verbose) std::cout << " -- Building the RHS ... " << std::flush;
    vector_Type rhs(uFESpace->map(),Repeated);

    vector_Type fInterpolated(uFESpace->map(),Repeated);
    uFESpace->interpolate( static_cast<feSpace_Type::function_Type>( fRhs ), fInterpolated, 0.0 );
    adrAssembler.addMassRhs(rhs,fInterpolated);
    rhs.globalAssemble();

    if (verbose) std::cout << " done ! " << std::endl;

    // Definition and application of the BCs
    if (verbose) std::cout << " -- Building the BCHandler ... " << std::flush;
    BCHandler bchandler;

    BCFunctionBase BCu( static_cast<feSpace_Type::function_Type>( exactSolution ) );

    bchandler.addBC("Dirichlet", Structured1DLabel::LEFT,Essential,Full,BCu,1);
    bchandler.addBC("Dirichlet", Structured1DLabel::RIGHT,Essential,Full,BCu,1);

    if (verbose) std::cout << " done ! " << std::endl;

    if (verbose) std::cout << " -- Updating the BCs ... " << std::flush;
    bchandler.bcUpdate(*uFESpace->mesh(),uFESpace->feBd(),uFESpace->dof());
    if (verbose) std::cout << " done ! " << std::endl;

    if (verbose) std::cout << " -- Applying the BCs ... " << std::flush;
    vector_Type rhsBC(rhs,Unique);
    bcManage(*systemMatrix,rhsBC,*uFESpace->mesh(),uFESpace->dof(),bchandler,uFESpace->feBd(),1.0,0.0);
    rhs = rhsBC;
    if (verbose) std::cout << " done ! " << std::endl;

    // Definition of the solver
    if (verbose) std::cout << " -- Building the solver ... " << std::flush;
    SolverAztecOO linearSolver;
    if (verbose) std::cout << " done ! " << std::endl;

    if (verbose) std::cout << " -- Setting up the solver ... " << std::flush;
    linearSolver.setDataFromGetPot(dataFile,"solver");
    linearSolver.setupPreconditioner(dataFile,"prec");
    if (verbose) std::cout << " done ! " << std::endl;

    if (verbose) std::cout << " -- Setting matrix in the solver ... " << std::flush;
    linearSolver.setMatrix(*systemMatrix);
    if (verbose) std::cout << " done ! " << std::endl;

    linearSolver.setCommunicator(Comm);

    // Definition of the solution
    if (verbose) std::cout << " -- Defining the solution ... " << std::flush;
    vector_Type solution(uFESpace->map(),Unique);
    if (verbose) std::cout << " done ! " << std::endl;

    // Solve the solution
    if (verbose) std::cout << " -- Solving the system ... " << std::flush;
    linearSolver.solveSystem(rhsBC,solution,systemMatrix);
    if (verbose) std::cout << " done ! " << std::endl;

    // Error computation
    if (verbose) std::cout << " -- Computing the error ... " << std::flush;
    vector_Type solutionErr(solution);
    uFESpace->interpolate( static_cast<feSpace_Type::function_Type>( exactSolution ), solutionErr, 0.0 );
    solutionErr-=solution;
    solutionErr.abs();
    Real l2error(uFESpace->l2Error(exactSolution,vector_Type(solution,Repeated),0.0));
    if (verbose) std::cout << " -- done ! " << std::endl;
    if (verbose) std::cout << " ---> Norm L2  : " << l2error << std::endl;
    Real linferror( solutionErr.normInf());
    if (verbose) std::cout << " ---> Norm Inf : " << linferror << std::endl;

    // Exporter definition and use
    if (verbose) std::cout << " -- Defining the exporter ... " << std::flush;

#ifdef HAVE_HDF5
    ExporterHDF5<mesh_Type> exporter ( dataFile, "solution" );
#else
    ExporterVTK<mesh_Type> exporter ( dataFile, "solution" );
#endif
    exporter.setMeshProcId( meshPtr, Comm->MyPID()) ;
    if (verbose) std::cout << " done ! " << std::endl;

    if (verbose) std::cout << " -- Defining the exported quantities ... " << std::flush;
    boost::shared_ptr<vector_Type> solutionPtr (new vector_Type(solution,Repeated));
    boost::shared_ptr<vector_Type> solutionErrPtr (new vector_Type(solutionErr,Repeated));
    if (verbose) std::cout << " done ! " << std::endl;

    if (verbose) std::cout << " -- Updating the exporter ... " << std::flush;
    exporter.addVariable( ExporterData<mesh_Type>::ScalarField, "solution", uFESpace, solutionPtr, UInt(0) );
    exporter.addVariable( ExporterData<mesh_Type>::ScalarField, "error", uFESpace, solutionErrPtr, UInt(0) );
    if (verbose) std::cout << " done ! " << std::endl;

    if (verbose) std::cout << " -- Exporting ... " << std::flush;
    exporter.postProcess(0);
    if (verbose) std::cout << " done ! " << std::endl;

    if ( std::fabs( l2error - 0.0006169843149652788l ) > 1e-10 )
    {
        std::cout << " <!> Solution has changed !!! <!> " << std::endl;
        return EXIT_FAILURE;
    }
    if ( std::fabs( linferror - 0.0001092814405985187l ) > 1e-10 )
    {
        std::cout << " <!> Solution has changed !!! <!> " << std::endl;
        return EXIT_FAILURE;
    }

    if (verbose) std::cout << "End Result: TEST PASSED" << std::endl;

    } // needed to properly destroy all objects inside before mpi finalize

#ifdef HAVE_MPI
    MPI_Finalize();
#endif

    return( EXIT_SUCCESS );
}