Exemple #1
0
Real
darcy_nonlinear::run()
{
    using namespace dataProblem;

    // Life chonos
    LifeChrono chronoTotal;
    LifeChrono chronoReadAndPartitionMesh;
    LifeChrono chronoBoundaryCondition;
    LifeChrono chronoFiniteElementSpace;
    LifeChrono chronoProblem;
    LifeChrono chronoProcess;
    LifeChrono chronoError;

    // Displayer to print on screen
    boost::shared_ptr < Displayer > displayer ( new Displayer ( Members->comm ) );

    // Start chronoTotal for measure the total time for the computation
    chronoTotal.start();

    // Reading from data file
    GetPot dataFile ( Members->data_file_name.c_str() );

    //
    // The Darcy Solver
    //

    displayer->leaderPrint ( "The Darcy solver\n" );

    // Start chronoReadAndPartitionMesh for measure the total time for the creation of the local meshes
    chronoReadAndPartitionMesh.start();

    // Create the data file
    darcyDataPtr_Type darcyData ( new darcyData_Type );

    // Set up the data
    darcyData->setup ( dataFile );

    // Create a Teuchos parameter list for the linear algebra.
    darcyData_Type::paramListPtr_Type linearAlgebraList = Teuchos::rcp ( new darcyData_Type::paramList_Type );
    linearAlgebraList = Teuchos::getParametersFromXmlFile ( Members->xml_file_name );

    // Set the parameter list into the data darcy.
    darcyData->setLinearAlgebraList ( linearAlgebraList );

    // Create the mesh file handler
    MeshData meshData;

    // Set up the mesh file
    meshData.setup ( dataFile,  Members->discretization_section + "/space_discretization");

    // Create the the mesh
    regionMeshPtr_Type fullMeshPtr ( new regionMesh_Type ( Members->comm ) );

    // Select if the mesh is structured or not
    if ( meshData.meshType() != "structured" )
    {
        // Set up the mesh
        readMesh ( *fullMeshPtr, meshData );
    }
    else
    {
        // Section of the structured mesh
        const std::string structuredSection = Members->discretization_section + "/space_discretization/";

        // Set up the structured mesh
        regularMesh2D ( *fullMeshPtr, 0,
                        dataFile ( ( structuredSection + "nx" ).data(), 4 ),
                        dataFile ( ( structuredSection + "ny" ).data(), 4 ),
                        dataFile ( ( structuredSection + "verbose" ).data(), false ),
                        dataFile ( ( structuredSection + "lx" ).data(), 1. ),
                        dataFile ( ( structuredSection + "ly" ).data(), 1. ) );
    }

    // Create the local mesh ( local scope used to delete the meshPart object )
    regionMeshPtr_Type meshPtr;
    {
        // Create the partitioner
        MeshPartitioner< regionMesh_Type >  meshPart;

        // Partition the mesh using ParMetis
        meshPart.doPartition ( fullMeshPtr, Members->comm );

        // Get the local mesh
        meshPtr = meshPart.meshPartition();
    }

    // Stop chronoReadAndPartitionMesh
    chronoReadAndPartitionMesh.stop();

    // The leader process print chronoReadAndPartitionMesh
    displayer->leaderPrint ( "Time for read and partition the mesh ",
                             chronoReadAndPartitionMesh.diff(), "\n" );

    // Create the boundary conditions

    // Start chronoBoundaryCondition for measure the total time for create the boundary conditions
    chronoBoundaryCondition.start();

    bcHandlerPtr_Type bcDarcy ( new bcHandler_Type );

    setBoundaryConditions ( bcDarcy );

    // Stop chronoBoundaryCondition
    chronoBoundaryCondition.stop();

    // The leader process print chronoBoundaryCondition
    displayer->leaderPrint ( "Time for create the boundary conditions handler ",
                             chronoBoundaryCondition.diff(), "\n" );

    // Create the solution spaces

    // Start chronoFiniteElementSpace for measure the total time for create the finite element spaces
    chronoFiniteElementSpace.start();

    // Primal solution parameters
    const ReferenceFE* refFE_primal ( static_cast<ReferenceFE*> (NULL) );
    const QuadratureRule* qR_primal ( static_cast<QuadratureRule*> (NULL) );
    const QuadratureRule* bdQr_primal ( static_cast<QuadratureRule*> (NULL) );

    refFE_primal = &feTriaP0;
    qR_primal = &quadRuleTria4pt;
    bdQr_primal = &quadRuleSeg1pt;

    // Dual solution parameters
    const ReferenceFE* refFE_dual ( static_cast<ReferenceFE*> (NULL) );
    const QuadratureRule* qR_dual ( static_cast<QuadratureRule*> (NULL) );
    const QuadratureRule* bdQr_dual ( static_cast<QuadratureRule*> (NULL) );

    refFE_dual = &feTriaRT0;
    qR_dual = &quadRuleTria4pt;
    bdQr_dual = &quadRuleSeg1pt;

    // Interpolate of dual solution parameters
    const ReferenceFE* refFE_dualInterpolate ( static_cast<ReferenceFE*> (NULL) );
    const QuadratureRule* qR_dualInterpolate ( static_cast<QuadratureRule*> (NULL) );
    const QuadratureRule* bdQr_dualInterpolate ( static_cast<QuadratureRule*> (NULL) );

    refFE_dualInterpolate = &feTriaP0;
    qR_dualInterpolate = &quadRuleTria4pt;
    bdQr_dualInterpolate = &quadRuleSeg1pt;

    // Hybrid solution parameters
    // hybrid
    const ReferenceFE* refFE_hybrid ( static_cast<ReferenceFE*> (NULL) );
    const QuadratureRule* qR_hybrid ( static_cast<QuadratureRule*> (NULL) );
    const QuadratureRule* bdQr_hybrid ( static_cast<QuadratureRule*> (NULL) );

    refFE_hybrid = &feTriaRT0Hyb;
    qR_hybrid = &quadRuleTria4pt;
    bdQr_hybrid = &quadRuleSeg1pt;

    // Finite element space of the primal variable
    fESpacePtr_Type p_FESpacePtr ( new fESpace_Type ( meshPtr, *refFE_primal, *qR_primal,
                                                      *bdQr_primal, 1, Members->comm ) );

    // Finite element space of the dual variable
    fESpacePtr_Type u_FESpacePtr ( new fESpace_Type ( meshPtr, *refFE_dual, *qR_dual,
                                                      *bdQr_dual, 1, Members->comm ) );

    // Finite element space of the hybrid variable
    fESpacePtr_Type hybrid_FESpacePtr ( new fESpace_Type ( meshPtr, *refFE_hybrid, *qR_hybrid,
                                                           *bdQr_hybrid, 1, Members->comm ) );

    // Finite element space of the interpolation of dual variable
    fESpacePtr_Type uInterpolate_FESpacePtr ( new fESpace_Type ( meshPtr, *refFE_dualInterpolate, *qR_dualInterpolate,
                                                                 *bdQr_dualInterpolate, 2, Members->comm ) );

    // Stop chronoFiniteElementSpace
    chronoFiniteElementSpace.stop();

    // The leader process print chronoFiniteElementSpace
    displayer->leaderPrint ( "Time for create the finite element spaces ",
                             chronoFiniteElementSpace.diff(), "\n" );

    // Start chronoProblem for measure the total time for create the problem
    chronoProblem.start();

    // Instantiation of the DarcySolver class
    darcySolver_Type darcySolver;

    // Stop chronoProblem
    chronoProblem.stop();

    // The leader process print chronoProblem
    displayer->leaderPrint ( "Time for create the problem ", chronoProblem.diff(), "\n" );

    // Process the problem

    // Start chronoProcess for measure the total time for the simulation
    chronoProcess.start ();

    // Set the data for the solver.
    darcySolver.setData ( darcyData );

    // Set the displayer.
    darcySolver.setDisplayer ( displayer );

    // Setup phase for the linear solver
    darcySolver.setup ();

    // Create the fields for the solver

    // Scalar field for primal variable
    scalarFieldPtr_Type primalField ( new scalarField_Type ( p_FESpacePtr ) );

    // Scalar field for dual variable
    scalarFieldPtr_Type dualField ( new scalarField_Type ( u_FESpacePtr ) );

    // Scalar field for hybrid variable
    scalarFieldPtr_Type hybridField ( new scalarField_Type ( hybrid_FESpacePtr ) );

    // Vector for the interpolated dual solution
    vectorFieldPtr_Type dualInterpolated ( new vectorField_Type ( uInterpolate_FESpacePtr, Repeated ) );

    // Set the field for the solver

    // Set the h
    darcySolver.setHybridField ( hybridField );

    // Set the primal field
    darcySolver.setPrimalField ( primalField );

    // Set the dual field
    darcySolver.setDualField ( dualField );

    // Set the source term
    scalarFctPtr_Type scalarSourceFct ( new scalarSource );
    darcySolver.setScalarSource ( scalarSourceFct );

    // Set the vector source term
    vectorFctPtr_Type vectorSourceFct ( new vectorSource );
    darcySolver.setVectorSource ( vectorSourceFct );

    // Set the reaction term
    scalarFctPtr_Type reactionTermFct ( new reactionTerm );
    darcySolver.setReactionTerm ( reactionTermFct );

    // Set the inverse of the permeability
    matrixFctPtr_Type inversePermeabilityFct ( new inversePermeability );
    darcySolver.setInversePermeability ( inversePermeabilityFct );

    // Set the initial primal variable
    scalarFctPtr_Type initialPrimalFct ( new initialCondition );
    darcySolver.setInitialPrimal ( initialPrimalFct );

    // Set the mass function
    scalarFctPtr_Type massFct ( new massFunction );
    darcySolver.setMass ( massFct );

    // Set the boudary conditions
    darcySolver.setBoundaryConditions ( bcDarcy );

    // Set the exporter for the solution
    boost::shared_ptr< Exporter< regionMesh_Type > > exporter;

    // Shared pointer used in the exporter for the primal solution
    vectorPtr_Type primalExporter;

    // Shared pointer used in the exporter for the dual solution
    vectorPtr_Type dualExporter;

    // Type of the exporter
    std::string const exporterType = dataFile ( "exporter/type", "none" );

    // The name of the file
    const std::string exporterFileName = dataFile ( "exporter/file_name", "PressureVelocity" );

    // Choose the exporter
#ifdef HAVE_HDF5
    if ( exporterType.compare ("hdf5") == 0 )
    {
        exporter.reset ( new ExporterHDF5 < regionMesh_Type > ( dataFile, exporterFileName ) );
    }
    else
#endif
    {
        exporter.reset ( new ExporterEmpty < regionMesh_Type > ( dataFile, exporterFileName ) );
    }

    // Set directory where to save the solution
    exporter->setPostDir ( dataFile ( "exporter/folder", "./" ) );

    exporter->setMeshProcId ( meshPtr, Members->comm->MyPID() );

    // Set the exporter primal pointer
    primalExporter.reset ( new vector_Type ( primalField->getVector(), exporter->mapType() ) );

    // Add the primal variable to the exporter
    exporter->addVariable ( ExporterData < regionMesh_Type >::ScalarField,
                            dataFile ( "exporter/name_primal", "Pressure" ),
                            p_FESpacePtr,
                            primalExporter,
                            static_cast<UInt> ( 0 ),
                            ExporterData < regionMesh_Type >::UnsteadyRegime,
                            ExporterData < regionMesh_Type >::Cell );

    // Set the exporter dual pointer
    dualExporter.reset ( new vector_Type ( dualInterpolated->getVector(), exporter->mapType() ) );

    // Add the variable to the exporter
    exporter->addVariable ( ExporterData < regionMesh_Type >::VectorField,
                            dataFile ( "exporter/name_dual", "Velocity" ),
                            uInterpolate_FESpacePtr,
                            dualExporter,
                            static_cast<UInt> ( 0 ),
                            ExporterData < regionMesh_Type >::UnsteadyRegime,
                            ExporterData < regionMesh_Type >::Cell );

    // Display the total number of unknowns
    displayer->leaderPrint ( "Number of unknowns : ",
                             hybrid_FESpacePtr->map().map ( Unique )->NumGlobalElements(), "\n" );

    // Export the partitioning
    exporter->exportPID ( meshPtr, Members->comm );

    // Copy the initial primal to the exporter
    *primalExporter = primalField->getVector ();

    // Save the initial primal solution into the exporter
    exporter->postProcess ( darcyData->dataTimePtr()->initialTime() );

    // Define if the current time is the last time step.
    bool isLastTimeStep ( false );

    // Define the end time
    const Real endTime = darcyData->dataTimePtr()->endTime();

    // Define the tolerance for the elapsed time
    const Real tolTime = 1e-10;

    // Take the current time.
    Real currentTime = darcyData->dataTimePtr()->time();

    // A loop for the simulation
    while ( darcyData->dataTimePtr()->time() < endTime && !isLastTimeStep )
    {
        // Take the left time.
        const Real leftTime = endTime - currentTime;

        // Check if the time step is consistent
        if ( darcyData->dataTimePtr()->timeStep() > leftTime + tolTime )
        {
            // Compute the last time step.
            darcyData->dataTimePtr()->setTimeStep ( leftTime );

            // This is the last time step in the simulation
            isLastTimeStep = true;
        }

        // Advance the current time of \Delta t.
        darcyData->dataTimePtr()->updateTime();

        // Take the current time.
        currentTime = darcyData->dataTimePtr()->time();

        // The leader process prints the temporal data.
        if ( displayer->isLeader() )
        {
            darcyData->dataTimePtr()->showMe();
        }

        // Solve the problem.
        darcySolver.solve ();

        // Save the solutions.

        // Copy the primal solution to the exporter.
        *primalExporter = primalField->getVector ();

        // Interpolate the dual vector field spammed as Raviart-Thomas into a P0 vector field.
        dualInterpolated->getVector() = uInterpolate_FESpacePtr->feToFEInterpolate (
                                            *u_FESpacePtr, dualField->getVector() );

        // Copy the dual interpolated solution to the exporter.
        *dualExporter = dualInterpolated->getVector();

        // Save the solution into the exporter.
        exporter->postProcess ( currentTime );

    }

    // Stop chronoProcess
    chronoProcess.stop();

    // The leader process print chronoProcess
    displayer->leaderPrint ( "Time for process ", chronoProcess.diff(), "\n" );

    // Compute the errors
    // For non time dependences problem the time where the errors are computed is useless,
    // but thanks to common interface we handle both cases.

    // Start chronoError for measure the total time for computing the errors.
    chronoError.start();

    // Compute the error L2 norms
    Real primalL2Norm (0), exactPrimalL2Norm (0), primalL2Error (0), primalL2RelativeError (0);
    Real dualL2Norm (0), exactDualL2Norm (0), dualL2Error (0), dualL2RelativeError (0);

    // Norms and errors for the pressure
    displayer->leaderPrint ( "\nPRESSURE ERROR\n" );

    // Compute the L2 norm for the primal solution
    primalL2Norm = p_FESpacePtr->l2Norm ( primalField->getVector () );

    // Display the L2 norm for the primal solution
    displayer->leaderPrint ( " L2 norm of primal unknown:            ", primalL2Norm, "\n" );

    // Compute the L2 norm for the analytical primal
    exactPrimalL2Norm = p_FESpacePtr->l2NormFunction ( Members->getAnalyticalSolution(),
                                                       darcyData->dataTimePtr()->endTime() );

    // Display the L2 norm for the analytical primal
    displayer->leaderPrint ( " L2 norm of primal exact:              ", exactPrimalL2Norm, "\n" );

    // Compute the L2 error for the primal solution
    primalL2Error = p_FESpacePtr->l2ErrorWeighted ( Members->getAnalyticalSolution(),
                                                    primalField->getVector(),
                                                    Members->getUOne(),
                                                    darcyData->dataTimePtr()->endTime() );

    // Display the L2 error for the primal solution
    displayer->leaderPrint ( " L2 error of primal unknown:           ", primalL2Error, "\n" );

    // Compute the L2 realative error for the primal solution
    primalL2RelativeError = primalL2Error / exactPrimalL2Norm;

    // Display the L2 relative error for the primal solution
    displayer->leaderPrint ( " L2 relative error of primal unknown:  ", primalL2RelativeError, "\n" );

    // Norms and errors for the interpolated dual
    displayer->leaderPrint ( "\nINTERPOLATED DARCY VELOCITY ERROR\n" );

    // Compute the L2 norm for the interpolated dual solution
    dualL2Norm = uInterpolate_FESpacePtr->l2Norm ( dualInterpolated->getVector() );

    // Display the L2 norm for the interpolated dual solution
    displayer->leaderPrint ( " L2 norm of dual unknown:              ", dualL2Norm, "\n" );

    // Compute the L2 norm for the analytical dual
    exactDualL2Norm = uInterpolate_FESpacePtr->l2NormFunction ( Members->getAnalyticalFlux(),
                                                                darcyData->dataTimePtr()->endTime() );

    // Display the L2 norm for the analytical dual
    displayer->leaderPrint ( " L2 norm of dual exact:                ", exactDualL2Norm, "\n" );

    // Compute the L2 error for the dual solution
    dualL2Error = uInterpolate_FESpacePtr->l2Error ( Members->getAnalyticalFlux(),
                                                     dualInterpolated->getVector(),
                                                     darcyData->dataTimePtr()->endTime(),
                                                     NULL );

    // Display the L2 error for the dual solution
    displayer->leaderPrint ( " L2 error of dual unknown:             ", dualL2Error, "\n" );

    // Compute the L2 relative error for the dual solution
    dualL2RelativeError = dualL2Error / exactDualL2Norm;

    // Display the L2 relative error for the dual solution
    displayer->leaderPrint ( " L2 relative error of Dual unknown:    ", dualL2RelativeError, "\n" );

    // Stop chronoError
    chronoError.stop();

    // The leader process print chronoError
    displayer->leaderPrint ( "Time for compute errors ", chronoError.diff(), "\n" );

    // Stop chronoTotal
    chronoTotal.stop();

    // The leader process print chronoTotal
    displayer->leaderPrint ( "Total time for the computation ", chronoTotal.diff(), "\n" );

    // Return the error, needed for the succes/failure of the test
    return primalL2Error;

} // run
Exemple #2
0
void
Heart::run()
{
    typedef FESpace< mesh_Type, MapEpetra > feSpace_Type;
    typedef boost::shared_ptr<feSpace_Type> feSpacePtr_Type;

    LifeChrono chronoinitialsettings;
    LifeChrono chronototaliterations;
    chronoinitialsettings.start();
    Real normu;
    Real meanu;
    Real minu;

    //! Construction of data classes

#ifdef MONODOMAIN
    HeartMonodomainData _data (M_heart_fct);
#else
    HeartBidomainData _data (M_heart_fct);
#endif
    HeartIonicData _dataIonic (M_heart_fct->M_dataFile);

    MeshData meshData;
    meshData.setup (M_heart_fct->M_dataFile, "electric/space_discretization");
    boost::shared_ptr<mesh_Type > fullMeshPtr ( new mesh_Type ( M_heart_fct->M_comm ) );
    readMesh (*fullMeshPtr, meshData);
    bool verbose = (M_heart_fct->M_comm->MyPID() == 0);

    //! Boundary conditions handler and function
    BCFunctionBase uZero ( zero_scalar );
    BCHandler bcH;
    bcH.addBC ( "Endo",      ENDOCARDIUM,    Natural,    Full,   uZero,  1 );
    bcH.addBC ( "Epi",       EPICARDIUM,     Natural,    Full,   uZero,  1 );
    bcH.addBC ( "Trunc",     TRUNC_SEC,      Natural,    Full,   uZero,  1 );

    const ReferenceFE*    refFE_w;
    const QuadratureRule* qR_w;
    const QuadratureRule* bdQr_w;

    const ReferenceFE*    refFE_u;
    const QuadratureRule* qR_u;
    const QuadratureRule* bdQr_u;


    //! Construction of the partitioned mesh
    boost::shared_ptr<mesh_Type> localMeshPtr;
    {
        MeshPartitioner< mesh_Type >   meshPart (fullMeshPtr, M_heart_fct->M_comm);
        localMeshPtr = meshPart.meshPartition();
    }
    std::string uOrder =  M_heart_fct->M_dataFile ( "electric/space_discretization/u_order", "P1");

    //! Initialization of the FE type and quadrature rules for both the variables
    if ( uOrder.compare ("P1") == 0 )
    {
        if (verbose)
        {
            std::cout << "P1 potential " << std::flush;
        }
        refFE_u = &feTetraP1;
        qR_u    = &quadRuleTetra15pt;
        bdQr_u  = &quadRuleTria3pt;
    }
    else
    {
        cout << "\n " << uOrder << " finite element not implemented yet \n";
        exit (1);
    }

    std::string wOrder =  M_heart_fct->M_dataFile ( "electric/space_discretization/w_order", "P1");
    if ( wOrder.compare ("P1") == 0 )
    {
        if (verbose)
        {
            std::cout << "P1 recovery variable " << std::flush;
        }
        refFE_w = &feTetraP1;
        qR_w    = &quadRuleTetra4pt;
        bdQr_w  = &quadRuleTria3pt;
    }
    else
    {
        cout << "\n " << wOrder << " finite element not implemented yet \n";
        exit (1);
    }

    //! Construction of the FE spaces
    if (verbose)
    {
        std::cout << "Building the potential FE space ... " << std::flush;
    }

    feSpacePtr_Type uFESpacePtr ( new feSpace_Type ( localMeshPtr,
                                                     *refFE_u,
                                                     *qR_u,
                                                     *bdQr_u,
                                                     1,
                                                     M_heart_fct->M_comm) );

#ifdef BIDOMAIN
    feSpacePtr_Type _FESpacePtr ( new feSpace_Type (localMeshPtr,
                                                    *refFE_u,
                                                    *qR_u,
                                                    *bdQr_u,
                                                    2,
                                                    M_heart_fct->M_comm) );
#endif
    if (verbose)
    {
        std::cout << "ok." << std::endl;
    }
    if (verbose)
    {
        std::cout << "Building the recovery variable FE space ... " << std::flush;
    }
    if (verbose)
    {
        std::cout << "ok." << std::endl;
    }

    UInt totalUDof  = uFESpacePtr->map().map (Unique)->NumGlobalElements();
    if (verbose)
    {
        std::cout << "Total Potential DOF = " << totalUDof << std::endl;
    }
    if (verbose)
    {
        std::cout << "Calling the electric model constructor ... ";
    }

#ifdef MONODOMAIN
    HeartMonodomainSolver< mesh_Type > electricModel (_data, *uFESpacePtr, bcH, M_heart_fct->M_comm);
#else
    HeartBidomainSolver< mesh_Type > electricModel (_data, *_FESpacePtr, *uFESpacePtr, bcH, M_heart_fct->M_comm);
#endif

    if (verbose)
    {
        std::cout << "ok." << std::endl;
    }
    MapEpetra fullMap (electricModel.getMap() );
    vector_Type rhs ( fullMap);
    electricModel.setup ( M_heart_fct->M_dataFile );
    std::cout << "setup ok" << std::endl;

    if (verbose)
    {
        std::cout << "Calling the ionic model constructor ... ";
    }
    boost::shared_ptr< HeartIonicSolver< mesh_Type > > ionicModel;
    if (ion_model == 1)
    {
        if (verbose)
        {
            std::cout << "Ion Model = Rogers-McCulloch" << std::endl << std::flush;
        }
        ionicModel.reset (new RogersMcCulloch< mesh_Type > (_dataIonic,
                                                            *localMeshPtr,
                                                            *uFESpacePtr,
                                                            *M_heart_fct->M_comm) );
    }
    else if (ion_model == 2)
    {
        if (verbose)
        {
            std::cout << "Ion Model = Luo-Rudy" << std::endl << std::flush;
        }
        ionicModel.reset (new LuoRudy< mesh_Type > (_dataIonic,
                                                    *localMeshPtr,
                                                    *uFESpacePtr,
                                                    *M_heart_fct->M_comm) );
    }
    else if (ion_model == 3)
    {
        if (verbose)
        {
            std::cout << "Ion Model = Mitchell-Schaeffer" << std::endl << std::flush;
        }
        ionicModel.reset (new MitchellSchaeffer< mesh_Type > (_dataIonic,
                                                              *localMeshPtr,
                                                              *uFESpacePtr,
                                                              *M_heart_fct->M_comm) );
    }

#ifdef MONODOMAIN
    electricModel.initialize ( M_heart_fct->initialScalar() );
#else
    electricModel.initialize ( M_heart_fct->initialScalar(),
                               M_heart_fct->zeroScalar() );
#endif

    if (verbose)
    {
        std::cout << "ok." << std::endl;
    }

    ionicModel->initialize( );

    //! Building time-independent part of the system
    electricModel.buildSystem( );
    std::cout << "buildsystem ok" << std::endl;
    //! Initialization
    Real dt     = _data.timeStep();
    Real t0     = 0;
    Real tFinal = _data.endTime();
    MPI_Barrier (MPI_COMM_WORLD);

    if (verbose)
    {
        std::cout << "Setting the initial solution ... " << std::endl << std::endl;
    }
    _data.setTime (t0);
    electricModel.resetPreconditioner();
    if (verbose)
    {
        std::cout << " ok " << std::endl;
    }

    //! Setting generic Exporter postprocessing
    boost::shared_ptr< Exporter<mesh_Type > > exporter;
    std::string const exporterType =  M_heart_fct->M_dataFile ( "exporter/type", "ensight");
#ifdef HAVE_HDF5
    if (exporterType.compare ("hdf5") == 0)
    {
        exporter.reset ( new ExporterHDF5<mesh_Type > ( M_heart_fct->M_dataFile,
                                                        "heart" ) );
        exporter->setPostDir ( "./" ); // This is a test to see if M_post_dir is working
        exporter->setMeshProcId ( localMeshPtr, M_heart_fct->M_comm->MyPID() );
    }
    else
#endif
    {
        if (exporterType.compare ("none") == 0)
        {
            exporter.reset ( new ExporterEmpty<mesh_Type > ( M_heart_fct->M_dataFile,
                                                             localMeshPtr,
                                                             "heart",
                                                             M_heart_fct->M_comm->MyPID() ) );
        }
        else
        {
            exporter.reset ( new ExporterEnsight<mesh_Type > ( M_heart_fct->M_dataFile,
                                                               localMeshPtr,
                                                               "heart",
                                                               M_heart_fct->M_comm->MyPID() ) );
        }
    }


    vectorPtr_Type Uptr ( new vector_Type (electricModel.solutionTransmembranePotential(), Repeated ) );

    exporter->addVariable ( ExporterData<mesh_Type>::ScalarField,  "potential", uFESpacePtr,
                            Uptr, UInt (0) );

#ifdef BIDOMAIN
    vectorPtr_Type Ueptr ( new vector_Type (electricModel.solutionExtraPotential(), Repeated ) );
    exporter->addVariable ( ExporterData<mesh_Type>::ScalarField,  "potential_e", _FESpacePtr,
                            Ueptr, UInt (0) );
#endif

    vectorPtr_Type Fptr ( new vector_Type (electricModel.fiberVector(), Repeated ) );

    if (_data.hasFibers() )
        exporter->addVariable ( ExporterData<mesh_Type>::VectorField,
                                "fibers",
                                uFESpacePtr,
                                Fptr,
                                UInt (0) );
    exporter->postProcess ( 0 );

    MPI_Barrier (MPI_COMM_WORLD);
    chronoinitialsettings.stop();

    //! Temporal loop
    LifeChrono chrono;
    Int iter = 1;
    chronototaliterations.start();
    for ( Real time = t0 + dt ; time <= tFinal + dt / 2.; time += dt, iter++)
    {
        _data.setTime (time);
        if (verbose)
        {
            std::cout << std::endl;
            std::cout << "We are now at time " << _data.time() << " s. " << std::endl;
            std::cout << std::endl;
        }
        chrono.start();
        MPI_Barrier (MPI_COMM_WORLD);
        ionicModel->solveIonicModel ( electricModel.solutionTransmembranePotential(), _data.timeStep() );
        rhs *= 0;
        computeRhs ( rhs, electricModel, ionicModel, _data );
        electricModel.updatePDESystem ( rhs );
        electricModel.PDEiterate ( bcH );
        normu = electricModel.solutionTransmembranePotential().norm2();
        electricModel.solutionTransmembranePotential().epetraVector().MeanValue (&meanu);
        electricModel.solutionTransmembranePotential().epetraVector().MaxValue (&minu);
        if (verbose)
        {
            std::cout << "norm u " << normu << std::endl;
            std::cout << "mean u " << meanu << std::endl;
            std::cout << "max u " << minu << std::endl << std::flush;
        }

        *Uptr = electricModel.solutionTransmembranePotential();
#ifdef BIDOMAIN
        *Ueptr = electricModel.solutionExtraPotential();
#endif

        exporter->postProcess ( time );
        MPI_Barrier (MPI_COMM_WORLD);
        chrono.stop();
        if (verbose)
        {
            std::cout << "Total iteration time " << chrono.diff() << " s." << std::endl;
        }
        chronototaliterations.stop();
    }

    if (verbose)
    {
        std::cout << "Total iterations time " << chronototaliterations.diff() << " s." << std::endl;
    }
    if (verbose)
    {
        std::cout << "Total initial settings time " << chronoinitialsettings.diff() << " s." << std::endl;
    }
    if (verbose)
    {
        std::cout << "Total execution time " << chronoinitialsettings.diff() + chronototaliterations.diff() << " s." << std::endl;
    }
}
Exemple #3
0
int main(int argc, char *argv[])
{
  #ifdef HAVE_MPI
    MPI_Init(&argc,&argv);
    {
    boost::shared_ptr<Epetra_Comm> Comm (new Epetra_MpiComm (MPI_COMM_WORLD));
  #else
    std::shared_ptr<Epetra_Comm> Comm (new Epetra_SerialComm) ;
  #endif

    typedef RegionMesh<LinearTetra>             mesh_Type;

    if (Comm->MyPID()==0)
        std::cout << "Testing solver class..." << std::endl;


    bool verbose = true;

    // Load data
    GetPot command_line(argc,argv);
    const std::string dataFileName = command_line.follow("data",2,"-f","--file");
    GetPot dataFile(dataFileName);


    // Build mesh

    if(verbose && Comm->MyPID() == 0 )
        std::cout << "[Loading mesh]" << std::endl;

    meshPtr_Type fullMeshPtr(new mesh_Type(Comm));

    regularMesh3D( *fullMeshPtr , 0 ,
                   dataFile("mesh/nx",15) , dataFile("mesh/ny",15) , dataFile("mesh/nz",15) ,
                   dataFile("mesh/verbose",false) ,
                   2.0 , 2.0 , 2.0 , -1.0 , -1.0 , -1.0 ) ;

    const UInt overlap(dataFile("mesh/overlap",0));
  
    meshPtr_Type localMeshPtr;
    {
        MeshPartitioner<mesh_Type> meshPart;
        if (overlap)
            meshPart.setPartitionOverlap(overlap);
        meshPart.doPartition(fullMeshPtr , Comm);
        localMeshPtr = meshPart.meshPartition();
    }

    fullMeshPtr.reset();

    // manage bc
    const int BACK = 1;
    const int FRONT = 2;
    const int LEFT = 3;
    const int RIGHT = 4;
    const int TOP = 5;
    const int BOTTOM = 6;

    BCHandler bcHandler;

    BCFunctionBase ZeroBC (zeroFunction) ;

    bcHandler.addBC("Back", BACK , Essential , Scalar , ZeroBC , 1) ;
    bcHandler.addBC("Left" , LEFT , Essential , Scalar , ZeroBC , 1);
    bcHandler.addBC("Top" , TOP , Essential , Scalar , ZeroBC , 1);
    bcHandler.addBC("Front" , FRONT , Essential , Scalar , ZeroBC , 1);
    bcHandler.addBC("Right" , RIGHT , Essential , Scalar , ZeroBC , 1);
    bcHandler.addBC("Bottom" , BOTTOM , Essential , Scalar , ZeroBC , 1);


    // Set exporter
    ExporterHDF5 <mesh_Type > exporter (dataFile , "fwd");
    exporter.setMeshProcId (localMeshPtr , Comm->MyPID());
    exporter.setPrefix("test_fwd");
    exporter.setPostDir("./");


    // Instantiate class
    InverseETAEllipticSolver<mesh_Type> solver( dataFile ,
                                                localMeshPtr ,
                                                "SolverParamList2.xml" ,
                                                bcHandler ,
                                                &torsoLocation
                                                );

    solver.solveFwd(exporter);

    // Exporter post-processing

    exporter.postProcess(0);
    exporter.closeFile();




//  // Assemble matrix and rhs

//  if(verbose)
//    std::cout << "[Building graph and matrix]" << std::endl;
  
//  graphPtr_Type systemGraph;
//  matrixPtr_Type systemMatrix;

//  if (overlap)
//  {
//    systemGraph.reset( new graph_Type( Copy , * (uFESpace->map().map(Unique)),
//                                        50,true ) );
//  }
//  else
//  {
//    systemGraph.reset( new graph_Type( Copy , * (uFESpace->map().map(Unique)),
//                                        50 ) );
//  }

//  {
//    using namespace ExpressionAssembly ;

//    buildGraph (
//              elements(localMeshPtr) ,
//              uFESpace->qr() ,
//              ETuFESpace,
//              ETuFESpace,
//              dot(grad(phi_i) , grad(phi_j) )
//              )
//              >> systemGraph ;
//  }

//  systemGraph->GlobalAssemble();


//  if(overlap)
//  {
//    systemMatrix.reset( new matrix_Type ( ETuFESpace->map() , *systemGraph , true));
//  }
//  else
//  {
//    systemMatrix.reset( new matrix_Type ( ETuFESpace->map() , *systemGraph ));
//  }

//  systemMatrix->zero();

//  {
//    using namespace ExpressionAssembly;

//    integrate (
//      elements(localMeshPtr) ,
//      uFESpace->qr() ,
//      ETuFESpace,
//      ETuFESpace,
//      dot (grad ( phi_i) , grad(phi_j) )
//    )
//    >> systemMatrix ;
//  }

  #ifdef HAVE_MPI
    }
    MPI_Finalize();
  #endif
  return EXIT_SUCCESS;
}
Exemple #4
0
int main (int argc, char** argv)
{
#ifdef LIFEV_HAS_HDF5
#ifdef HAVE_MPI

    typedef RegionMesh<LinearTetra> mesh_Type;

    MPI_Init (&argc, &argv);
    boost::shared_ptr<Epetra_Comm> comm (new Epetra_MpiComm (MPI_COMM_WORLD) );

    if (comm->NumProc() != 1)
    {
        std::cout << "This test needs to be run "
                  << "with a single process. Aborting."
                  << std::endl;
        return (EXIT_FAILURE);
    }

    GetPot commandLine (argc, argv);
    string dataFileName = commandLine.follow ("data", 2, "-f", "--file");
    GetPot dataFile (dataFileName);

    const UInt numElements (dataFile ("mesh/nelements", 10) );
    const UInt numParts (dataFile ("test/num_parts", 4) );
    const std::string partsFileName (dataFile ("test/hdf5_file_name", "cube.h5") );
    const std::string ioClass (dataFile ("test/io_class", "new") );

    std::cout << "Number of elements in mesh: " << numElements << std::endl;
    std::cout << "Number of parts: " << numParts << std::endl;
    std::cout << "Name of HDF5 container: " << partsFileName << std::endl;

    boost::shared_ptr<mesh_Type> fullMeshPtr (new mesh_Type ( comm ) );
    regularMesh3D (*fullMeshPtr, 1, numElements, numElements, numElements,
                   false, 2.0, 2.0, 2.0, -1.0, -1.0, -1.0);

    MeshPartitioner<mesh_Type> meshPart;
    meshPart.setup (numParts, comm);

    meshPart.attachUnpartitionedMesh (fullMeshPtr);
    meshPart.doPartitionGraph();
    meshPart.doPartitionMesh();

    // Release the original mesh from the MeshPartitioner object and
    // delete the RegionMesh object
    meshPart.releaseUnpartitionedMesh();
    fullMeshPtr.reset();

    // Write mesh parts to HDF5 container
    if (! ioClass.compare ("old") )
    {
        ExporterHDF5Mesh3D<mesh_Type> HDF5Output (dataFile,
                                                  meshPart.meshPartition(),
                                                  partsFileName,
                                                  comm->MyPID() );
        HDF5Output.addPartitionGraph (meshPart.elementDomains(), comm);
        HDF5Output.addMeshPartitionAll (meshPart.meshPartitions(), comm);
        HDF5Output.postProcess (0);
        HDF5Output.closeFile();
    }
    else
    {
        boost::shared_ptr<Epetra_MpiComm> mpiComm =
            boost::dynamic_pointer_cast<Epetra_MpiComm> (comm);
        PartitionIO<mesh_Type> partitionIO (partsFileName, mpiComm);
        partitionIO.write (meshPart.meshPartitions() );
    }

    MPI_Finalize();

#else
    std::cout << "This test needs MPI to run. Aborting." << std::endl;
    return (EXIT_FAILURE);
#endif /* HAVE_MPI */
#else
    std::cout << "This test needs HDF5 to run. Aborting." << std::endl;
    return (EXIT_FAILURE);
#endif /* LIFEV_HAS_HDF5 */

    return (EXIT_SUCCESS);
}
int
main ( int argc, char** argv )
{
	bool verbose (false);
#ifdef HAVE_MPI
	MPI_Init (&argc, &argv);
	boost::shared_ptr<Epetra_Comm> Comm ( new Epetra_MpiComm (MPI_COMM_WORLD) );
	if ( Comm->MyPID() == 0 )
	{
		verbose = true;
	}
#else
	boost::shared_ptr<Epetra_Comm> Comm( new Epetra_SerialComm () );
	verbose = true;
#endif

	typedef RegionMesh< LinearTetra > mesh_Type;
	typedef FESpace< mesh_Type, MapEpetra > uSpaceStd_Type;
	typedef boost::shared_ptr< uSpaceStd_Type > uSpaceStdPtr_Type;
	typedef ETFESpace< mesh_Type, MapEpetra, 3, 3 > uSpaceETA_Type;
	typedef ETFESpace< mesh_Type, MapEpetra, 3, 3 > uSpaceETAVectorial_Type;
	typedef boost::shared_ptr< uSpaceETA_Type > uSpaceETAPtr_Type;
	typedef boost::shared_ptr< uSpaceETAVectorial_Type > uSpaceETAVectorialPtr_Type;
	typedef FESpace<mesh_Type, MapEpetra>::function_Type function_Type;
	typedef MatrixEpetra< Real > matrix_Type;
	typedef boost::shared_ptr< MatrixEpetra< Real > > matrixPtr_Type;
	typedef VectorEpetra vector_Type;
	typedef boost::shared_ptr<VectorEpetra> vectorPtr_Type;

	// DATAFILE
	GetPot command_line ( argc, argv );
	const std::string dataFileName = command_line.follow ( "data", 2, "-f", "--file" );
	GetPot dataFile ( dataFileName );

	// GENERAZIONE MESH
	boost::shared_ptr< mesh_Type > fullMeshPtr ( new mesh_Type ( Comm ) );
	MeshData meshData;
	meshData.setup (dataFile, "space_discretization");
	readMesh (*fullMeshPtr, meshData);

	// CREAZIONE CONNETTIVITA MESH
	uSpaceStdPtr_Type uFESpace_serial ( new uSpaceStd_Type ( fullMeshPtr, dataFile ("finite_element/degree", "P1"), 3, Comm ) );
	BuildReducedMesh RedMeshGenerator(uFESpace_serial);

	uFESpace_serial.reset();

	// PARTIZIONAMENTO MESH
	boost::shared_ptr< mesh_Type > localMeshPtr;
	MeshPartitioner< mesh_Type > meshPart;
	meshPart.doPartition ( fullMeshPtr, Comm );
	localMeshPtr = meshPart.meshPartition();
	//fullMeshPtr.reset();

	// SPAZI ELEMENTI FINITI
	uSpaceStdPtr_Type uFESpace ( new uSpaceStd_Type ( localMeshPtr, dataFile ("finite_element/degree", "P1"), 3, Comm ) );
	uSpaceETAPtr_Type ETuFESpace ( new uSpaceETA_Type ( localMeshPtr, & ( uFESpace->refFE() ), & ( uFESpace->fe().geoMap() ), Comm ) );

	// OGGETTI PER VISUALIZZAZIONE MESH RIDOTTA
	uSpaceStdPtr_Type FESpace_reducedMesh ( new uSpaceStd_Type ( fullMeshPtr, dataFile ("finite_element/degree", "P1"), 1, Comm ) );
	vectorPtr_Type reduced_mesh ( new vector_Type ( FESpace_reducedMesh->map(), Unique ) );
	reduced_mesh->zero();

	ExporterHDF5< mesh_Type > exporter_reduced_mesh ( dataFile, "exporter" );
	exporter_reduced_mesh.setMeshProcId( localMeshPtr, Comm->MyPID() );
	exporter_reduced_mesh.setPrefix( dataFile ("exporter/name_output_reduced_mesh", "ReducedMesh") );
	exporter_reduced_mesh.setPostDir( "./" );
	exporter_reduced_mesh.addVariable ( ExporterData< mesh_Type >::ScalarField, "reduced mesh", FESpace_reducedMesh, reduced_mesh, UInt ( 0 ) );

    // Offset componenti
    int offsetComponent = uFESpace->dof().numTotalDof();
    
    int numSolSnapshots;
	EpetraExt::HDF5 HDF5_importer(*Comm);

	HDF5_importer.Open( dataFile ("name_output_file_system/name_input_file_solution", "SolSnapshots")+".h5" );
	std::string h5_sol_prefix     = dataFile("solution/prefix", "sol");
	HDF5_importer.Read("info", "num_"+h5_sol_prefix+"Snapshots", numSolSnapshots);
	HDF5_importer.Close();

	// ---------------------------
	// HDF5 file managers
	// ---------------------------
	EpetraExt::HDF5 HDF5_exporter( *Comm );
	HDF5_exporter.Create( dataFile("rom_exporter/name_output_file", "ROM")+".h5" );

	DenseHDF5 HDF5dense_exporter;
	if ( Comm->MyPID() == 0 )
	{
		HDF5dense_exporter.Create( dataFile("rom_exporter/hyper_output_file", "Hyper_ROM")+".h5" );
	}

	std::string JacobianApproximation = dataFile ("hyperreduction/jacobian_approximation", "DEIM");
	bool SplitInternalForces   = dataFile ("hyperreduction/split_internal_force", false);

	// ---------------------------
	// Build FE Matrix Map rows in the internal dofs
	// ---------------------------

	boost::shared_ptr<BCHandler> bc_markingDOFs = BCh_marking ();
	bc_markingDOFs->bcUpdate( *uFESpace->mesh(), uFESpace->feBd(), uFESpace->dof() );

	boost::shared_ptr<DOF_Extractor> dofExtractor;
	dofExtractor.reset ( new DOF_Extractor ( uFESpace ) );
	dofExtractor->setup( bc_markingDOFs );

	mapPtr_Type map_rows;
	map_rows.reset ( new MapEpetra ( *dofExtractor->getMapUnmarked() ) );

	// ---------------------------
	// Build Reduced Basis for the solution
	// ---------------------------
    ReductionVector RBsol(dataFile, "solution", Comm, map_rows);
	RBsol.perform();
	RBsol.write(HDF5_exporter, HDF5dense_exporter);

	boost::shared_ptr<Epetra_FECrsMatrix> V;
	RBsol.getPODbasis(V);
	int numSolBases = RBsol.getNumBases();


	// ---------------------------
	// Hyper Reduce RHS Internal ISO Forces
	// ---------------------------

	HyperReductionVector HyperFIiso( dataFile, "residual_internal_force_iso", Comm, map_rows);

	HyperFIiso.perform();
	HyperFIiso.write(HDF5dense_exporter);
	HyperFIiso.project(V, numSolBases, HDF5_exporter);

	std::vector<int> deim_FIiso_GID = HyperFIiso.getDeimGID();

	if (JacobianApproximation=="DEIM")
	{
		HyperFIiso.DEIMjacobianLeftProjection(V, HDF5_exporter, "DEIMjacobianLeftProjection_iso");
	}

	// ---------------------------
	// Hyper Reduce RHS Internal VOL Forces
	// ---------------------------
	HyperReductionVector HyperFIvol( dataFile, "residual_internal_force_vol", Comm, map_rows);

	HyperFIvol.perform();
	HyperFIvol.write(HDF5dense_exporter);
	HyperFIvol.project(V, numSolBases, HDF5_exporter);

	std::vector<int> deim_FIvol_GID = HyperFIvol.getDeimGID();

	if (JacobianApproximation=="DEIM")
	{
		HyperFIvol.DEIMjacobianLeftProjection(V, HDF5_exporter, "DEIMjacobianLeftProjection_vol");
	}

	// ---------------------------
	// Hyper Reduce RHS External Forces
	// ---------------------------
	HyperReductionVector HyperFE( dataFile, "residual_external_force", Comm, map_rows);

	HyperFE.perform();
	HyperFE.write(HDF5dense_exporter);
	HyperFE.project(V, numSolBases, HDF5_exporter);

	std::vector<int> deim_FE_GID = HyperFE.getDeimGID();

	// ---------------------------
	// Hyper Reduce MATRIX
	// ---------------------------
	if (JacobianApproximation=="MDEIM")
	{
		HyperReductionMatrix HyperA( dataFile, "jacobian_matrix", Comm, map_rows);

		HyperA.perform();
		HyperA.write(HDF5dense_exporter);
		HyperA.project(V, numSolBases, HDF5_exporter);

		std::vector<int> deim_A_GID = HyperA.getDeimDofs();
		RedMeshGenerator.appendSelectedDofs(deim_A_GID);
	}

	// ---------------------------
	// Build Reduced Mesh
	// ---------------------------
	RedMeshGenerator.appendSelectedDofs(deim_FIiso_GID);
	RedMeshGenerator.appendSelectedDofs(deim_FIvol_GID);
	RedMeshGenerator.appendSelectedDofs(deim_FE_GID);
	RedMeshGenerator.DofsToNodes_CSM();
	RedMeshGenerator.build(FESpace_reducedMesh, reduced_mesh, HDF5dense_exporter);

	exporter_reduced_mesh.postProcess(0.0);
	exporter_reduced_mesh.closeFile();
     
	// close HDF5 file manager
	HDF5_exporter.Close();
	if ( Comm->MyPID() == 0 )
	{
		HDF5dense_exporter.Close();
	}


#ifdef HAVE_MPI
	if (verbose)
	{
		std::cout << "\nMPI Finalization\n" << std::endl;
	}
	MPI_Finalize();
#endif
	return ( EXIT_SUCCESS );
}
Exemple #6
0
void
EnsightToHdf5::run()
{

    // Reading from data file
    GetPot dataFile ( d->data_file_name.c_str() );

    bool verbose = (d->comm->MyPID() == 0);

    // Fluid solver
    boost::shared_ptr<OseenData> oseenData (new OseenData() );
    oseenData->setup ( dataFile );

    MeshData meshData;
    meshData.setup (dataFile, "fluid/space_discretization");

    boost::shared_ptr<mesh_Type > fullMeshPtr (new mesh_Type ( d->comm ) );
    readMesh (*fullMeshPtr, meshData);

    // writeMesh("test.mesh", *fullMeshPtr);
    // Scale, Rotate, Translate (if necessary)
    boost::array< Real, NDIM >    geometryScale;
    boost::array< Real, NDIM >    geometryRotate;
    boost::array< Real, NDIM >    geometryTranslate;

    geometryScale[0] = dataFile ( "fluid/space_discretization/transform", 1., 0);
    geometryScale[1] = dataFile ( "fluid/space_discretization/transform", 1., 1);
    geometryScale[2] = dataFile ( "fluid/space_discretization/transform", 1., 2);

    geometryRotate[0] = dataFile ( "fluid/space_discretization/transform", 0., 3) * M_PI / 180;
    geometryRotate[1] = dataFile ( "fluid/space_discretization/transform", 0., 4) * M_PI / 180;
    geometryRotate[2] = dataFile ( "fluid/space_discretization/transform", 0., 5) * M_PI / 180;

    geometryTranslate[0] = dataFile ( "fluid/space_discretization/transform", 0., 6);
    geometryTranslate[1] = dataFile ( "fluid/space_discretization/transform", 0., 7);
    geometryTranslate[2] = dataFile ( "fluid/space_discretization/transform", 0., 8);

    MeshUtility::MeshTransformer<mesh_Type, mesh_Type::markerCommon_Type > _transformMesh (*fullMeshPtr);
    _transformMesh.transformMesh ( geometryScale, geometryRotate, geometryTranslate );

    boost::shared_ptr<mesh_Type > meshPtr;
    {
        MeshPartitioner< mesh_Type >   meshPart (fullMeshPtr, d->comm);
        meshPtr = meshPart.meshPartition();
    }

    std::string uOrder =  dataFile ( "fluid/space_discretization/vel_order", "P1");
    std::string pOrder =  dataFile ( "fluid/space_discretization/press_order", "P1");

    //oseenData->meshData()->setMesh(meshPtr);

    if (verbose)
    {
        std::cout << "Building the velocity FE space ... " << std::flush;
    }

    feSpacePtr_Type uFESpacePtr ( new feSpace_Type (meshPtr, uOrder, 3, d->comm) );

    if (verbose)
    {
        std::cout << "ok." << std::endl;
    }

    if (verbose)
    {
        std::cout << "Building the pressure FE space ... " << std::flush;
    }

    feSpacePtr_Type pFESpacePtr ( new feSpace_Type ( meshPtr, pOrder, 1, d->comm ) );

    if (verbose)
    {
        std::cout << "ok." << std::endl;
    }

    if (verbose)
    {
        std::cout << "Building the P0 pressure FE space ... " << std::flush;
    }

    feSpacePtr_Type p0FESpacePtr ( new feSpace_Type ( meshPtr, feTetraP0, quadRuleTetra1pt,
                                                      quadRuleTria1pt, 1, d->comm ) );

    if (verbose)
    {
        std::cout << "ok." << std::endl;
    }



    UInt totalVelDof   = uFESpacePtr->map().map (Unique)->NumGlobalElements();
    UInt totalPressDof = pFESpacePtr->map().map (Unique)->NumGlobalElements();
    UInt totalP0PresDof = p0FESpacePtr->map().map (Unique)->NumGlobalElements();

    if (verbose)
    {
        std::cout << "Total Velocity DOF = " << totalVelDof << std::endl;
    }
    if (verbose)
    {
        std::cout << "Total Pressure DOF = " << totalPressDof << std::endl;
    }
    if (verbose)
    {
        std::cout << "Total P0Press  DOF = " << totalP0PresDof << std::endl;
    }

    if (verbose)
    {
        std::cout << "Calling the fluid constructor ... ";
    }

    OseenSolver< mesh_Type > fluid (oseenData,
                                    *uFESpacePtr,
                                    *pFESpacePtr,
                                    d->comm);
    MapEpetra fullMap (fluid.getMap() );

    if (verbose)
    {
        std::cout << "ok." << std::endl;
    }

    fluid.setUp (dataFile);

    // Initialization
    Real dt     = oseenData->dataTime()->timeStep();
    Real t0     = oseenData->dataTime()->initialTime();
    Real tFinal = oseenData->dataTime()->endTime();

    boost::shared_ptr< Exporter<mesh_Type > > exporter;
    boost::shared_ptr< Exporter<mesh_Type > > importer;

    std::string const exporterType =  dataFile ( "exporter/type", "hdf5");
    std::string const exporterName =  dataFile ( "exporter/filename", "ethiersteinman");
    std::string const exportDir    =  dataFile ( "exporter/exportDir", "./");

    std::string const importerType =  dataFile ( "importer/type", "ensight");
    std::string const importerName =  dataFile ( "importer/filename", "ethiersteinman");
    std::string const importDir    =  dataFile ( "importer/importDir", "importDir/");

#ifdef HAVE_HDF5
    if (exporterType.compare ("hdf5") == 0)
    {
        exporter.reset ( new ExporterHDF5<mesh_Type > ( dataFile, exporterName ) );
    }
    else
#endif
        exporter.reset ( new ExporterEnsight<mesh_Type > ( dataFile, exporterName ) );

    exporter->setPostDir ( exportDir ); // This is a test to see if M_post_dir is working
    exporter->setMeshProcId ( meshPtr, d->comm->MyPID() );

#ifdef HAVE_HDF5
    if (importerType.compare ("hdf5") == 0)
    {
        importer.reset ( new ExporterHDF5<mesh_Type > ( dataFile, importerName ) );
    }
    else
#endif
        importer.reset ( new ExporterEnsight<mesh_Type > ( dataFile, importerName ) );

    // todo this will not work with the ExporterEnsight filter (it uses M_importDir, a private variable)
    importer->setPostDir ( importDir ); // This is a test to see if M_post_dir is working
    importer->setMeshProcId ( meshPtr, d->comm->MyPID() );

    vectorPtr_Type velAndPressureExport ( new vector_Type (*fluid.solution(), exporter->mapType() ) );
    vectorPtr_Type velAndPressureImport ( new vector_Type (*fluid.solution(), importer->mapType() ) );

    if ( exporter->mapType() == Unique )
    {
        velAndPressureExport->setCombineMode (Zero);
    }

    importer->addVariable ( ExporterData<mesh_Type>::VectorField, "velocity", uFESpacePtr,
                            velAndPressureImport, UInt (0) );
    importer->addVariable ( ExporterData<mesh_Type>::ScalarField, "pressure", pFESpacePtr,
                            velAndPressureImport, UInt (3 * uFESpacePtr->dof().numTotalDof() ) );
    importer->import ( t0 );

    *velAndPressureExport = *velAndPressureImport;


    vectorPtr_Type P0pres ( new vector_Type (p0FESpacePtr->map() ) );
    MPI_Barrier (MPI_COMM_WORLD);
    computeP0pressure (pFESpacePtr, p0FESpacePtr, uFESpacePtr, *velAndPressureImport, *P0pres, t0);

    exporter->addVariable ( ExporterData<mesh_Type>::VectorField, "velocity", uFESpacePtr,
                            velAndPressureExport, UInt (0) );

    exporter->addVariable ( ExporterData<mesh_Type>::ScalarField, "pressure", pFESpacePtr,
                            velAndPressureExport, UInt (3 * uFESpacePtr->dof().numTotalDof() ) );

    exporter->addVariable (ExporterData<mesh_Type>::ScalarField, "P0pressure", p0FESpacePtr,
                           P0pres, UInt (0),
                           ExporterData<mesh_Type>::SteadyRegime, ExporterData<mesh_Type>::Cell );
    exporter->postProcess ( t0 );

    // Temporal loop
    LifeChrono chrono;
    int iter = 1;

    for ( Real time = t0 + dt ; time <= tFinal + dt / 2.; time += dt, iter++)
    {
        chrono.stop();
        importer->import ( time );

        *velAndPressureExport = *velAndPressureImport;
        MPI_Barrier (MPI_COMM_WORLD);
        computeP0pressure (pFESpacePtr, p0FESpacePtr, uFESpacePtr, *velAndPressureImport, *P0pres, time);

        exporter->postProcess ( time );

        chrono.stop();
        if (verbose)
        {
            std::cout << "Total iteration time " << chrono.diff() << " s." << std::endl;
        }
    }
}
Exemple #7
0
int main (int argc, char** argv )
{
    typedef FESpace < RegionMesh<LinearTetra>, MapEpetra > FESpaceTetra_Type;
    typedef boost::shared_ptr < FESpaceTetra_Type > FESpaceTetraPtr_Type;

    typedef FESpace < RegionMesh<LinearHexa>, MapEpetra > FESpaceHexa_Type;
    typedef boost::shared_ptr < FESpaceHexa_Type > FESpaceHexaPtr_Type;


#ifdef HAVE_MPI
    MPI_Init (&argc, &argv);
    boost::shared_ptr<Epetra_Comm> Comm (new Epetra_MpiComm (MPI_COMM_WORLD) );
#else
    boost::shared_ptr<Epetra_Comm> Comm (new Epetra_SerialComm);
#endif

    UInt verbose = (Comm->MyPID() == 0);

    bool check (true);


    //definition of Array of Errors which will be used to check the correctness of the interpolate test.

    const Real errArrayBilinear[2] = { 0.0312819802, 0. };

    const Real errArrayQuadratic[12] = {    0.0136247667, 0.0005088372, 0.0005577494, 0.0005088372,
                                            0.0136172446, 0.0005088372, 0.0004270717, 0.0005088372,
                                            0.0136172446, 0.0005088372, 0.0004270717,           0.
                                       };

    const Real errArrayBubble[12] = {   0.0094702745, 3.584186e-10, 3.67611e-10,  3.584186e-10,
                                        0.0094702745, 3.584186e-10,           0., 3.584186e-10,
                                        0.0094702745, 3.584186e-10, 3.67611e-10,  3.584186e-10
                                    };

    const Real errArrayLinear[12] = {   0.010437463587, 0., 0., 0.,
                                        0.010437463587, 0., 0., 0.,
                                        0.010437463587, 0., 0., 0.
                                    };


    const std::string stringArrayP[12] = {  "P1  -> P0 ",  "P1  -> P1 ",  "P1  -> P1b", "P1  -> P2 ",
                                            "P1b -> P0 ",  "P1b -> P1 ",  "P1b -> P1b", "P1b -> P2 ",
                                            "P2  -> P0 ",  "P2  -> P1 ",  "P2  -> P1b", "P2  -> P2 "
                                         };

    const std::string stringArrayQ[2] = {"Q1  -> Q0 ", "Q1  -> Q1 "};


    // Import/Generate an hexahedral and  a Tetrahedral mesh.

    boost::shared_ptr<RegionMesh<LinearTetra> > fullMeshTetraPtr ( new RegionMesh<LinearTetra> ( Comm ) );
    boost::shared_ptr<RegionMesh<LinearHexa> > fullMeshHexaPtr ( new RegionMesh<LinearHexa> ( Comm ) );
    UInt nEl (10);
    GetPot dataFile ("./data");
    MeshData meshData (dataFile, "interpolate/space_discretization");
    readMesh (*fullMeshHexaPtr, meshData);
    regularMesh3D ( *fullMeshTetraPtr, 1, nEl, nEl, nEl);


    // Partition the meshes using ParMetis
    boost::shared_ptr<RegionMesh<LinearHexa> > localMeshHexaPtr;
    {
        // Create the partitioner
        MeshPartitioner< RegionMesh<LinearHexa> >  meshPartHexa;

        // Partition the mesh using ParMetis
        meshPartHexa.doPartition ( fullMeshHexaPtr, Comm );

        // Get the local mesh
        localMeshHexaPtr = meshPartHexa.meshPartition();
    }
    boost::shared_ptr<RegionMesh<LinearTetra> > localMeshTetraPtr;
    {
        // Create the partitioner
        MeshPartitioner< RegionMesh<LinearTetra> >  meshPartTetra;

        // Partition the mesh using ParMetis
        meshPartTetra.doPartition ( fullMeshTetraPtr, Comm );

        // Get the local mesh
        localMeshTetraPtr = meshPartTetra.meshPartition();
    }

    //Building finite element spaces

    //Finite element space of the first scalar field - P0
    FESpaceTetraPtr_Type feSpaceP0 ( new FESpaceTetra_Type ( localMeshTetraPtr, feTetraP0, quadRuleTetra4pt,
                                     quadRuleTria4pt, 3, Comm ) );

    //Finite element space of the second scalar field - P1
    FESpaceTetraPtr_Type feSpaceP1 ( new FESpaceTetra_Type ( localMeshTetraPtr, feTetraP1, quadRuleTetra4pt,
                                     quadRuleTria4pt, 3, Comm ) );

    // Finite element space of the second scalar field - P1bubble
    FESpaceTetraPtr_Type feSpaceP1Bubble ( new FESpaceTetra_Type ( localMeshTetraPtr, feTetraP1bubble, quadRuleTetra15pt,
                                           quadRuleTria4pt, 3, Comm ) );

    // Finite element space of the second scalar field - P2
    FESpaceTetraPtr_Type feSpaceP2 ( new FESpaceTetra_Type ( localMeshTetraPtr, feTetraP2, quadRuleTetra4pt,
                                     quadRuleTria4pt, 3, Comm ) );

    // Finite element space of the first scalar field - Q0
    FESpaceHexaPtr_Type feSpaceQ0 ( new FESpaceHexa_Type ( localMeshHexaPtr, feHexaQ0, quadRuleHexa8pt,
                                    quadRuleQuad4pt, 2, Comm ) );

    // Finite element space of the second scalar field - Q1
    FESpaceHexaPtr_Type feSpaceQ1 ( new FESpaceHexa_Type ( localMeshHexaPtr, feHexaQ1, quadRuleHexa8pt,
                                    quadRuleQuad4pt, 2, Comm ) );

    //vectors containing the original and final  FE spaces
    //(FE vectors will be interpolated from original FE spaces into final FE Spaces)
    std::vector<FESpaceHexaPtr_Type > originalFeSpaceHexaVec (1),  finalFeSpaceHexaVec (2);
    std::vector<FESpaceTetraPtr_Type> originalFeSpaceTetraVec (3), finalFeSpaceTetraVec (4);

    originalFeSpaceHexaVec[0] = feSpaceQ1;
    finalFeSpaceHexaVec[0] = feSpaceQ0;
    finalFeSpaceHexaVec[1] = feSpaceQ1;

    originalFeSpaceTetraVec[0] = feSpaceP1;
    originalFeSpaceTetraVec[1] = feSpaceP1Bubble;
    originalFeSpaceTetraVec[2] = feSpaceP2;

    finalFeSpaceTetraVec[0] = feSpaceP0;
    finalFeSpaceTetraVec[1] = feSpaceP1;
    finalFeSpaceTetraVec[2] = feSpaceP1Bubble;
    finalFeSpaceTetraVec[3] = feSpaceP2;

    Real time = 0.5;

    if (verbose)
    {
        std::cout << "\nA bilinear function is interpolated into Q1 vector. \nThen this FE vector is interpolated into Q0 and Q1 vectors. \nThese are the errors with respect to the analytical solution.\n";
    }
    check = check_interpolate (originalFeSpaceHexaVec, finalFeSpaceHexaVec, Unique, bilinearFunction, errArrayBilinear, stringArrayQ, 1e-10, time, verbose);


    if (verbose)
        std::cout << "\nA linear function is interpolated into P1, P1b, P2 vectors. "
                  "\nThen these FE vectors are interpolated into the following finite elements \nand error with respect to the analytic solution are reported.\n";

    check &= check_interpolate (originalFeSpaceTetraVec, finalFeSpaceTetraVec, Repeated, linearFunction, errArrayLinear, stringArrayP, 1e-10, time, verbose);


    if (verbose)
        std::cout << "\nA quadratic function is interpolated into P1, P1b, P2 vectors. "
                  "\nThen these FE vectors are interpolated into the following finite elements \nand error with respect to the analytic solution are reported.\n";

    check &= check_interpolate (originalFeSpaceTetraVec, finalFeSpaceTetraVec, Unique, quadraticFunction, errArrayQuadratic, stringArrayP, 1e-10, time, verbose);


    if (verbose)
        std::cout << "\nA linear bubble function is interpolated into P1, P1b, P2 vectors. "
                  "\nThen these FE vectors are interpolated into the following finite elements \nand error with respect to the analytic solution are reported.\n";

    check &= check_interpolate (originalFeSpaceTetraVec, finalFeSpaceTetraVec, Repeated, linearBubbleFunction,  errArrayBubble, stringArrayP, 1e-10, time, verbose);


#ifdef HAVE_MPI
    std::cout << "MPI Finalization" << std::endl;
    MPI_Finalize();
#endif

    if (verbose)
    {
        if (check)
        {
            std::cout << "\nTEST INTERPOLATE WAS SUCCESSFUL.\n\n";
        }
        else
        {
            std::cout << "\nTEST INTERPOLATE FAILED.\n\n";
        }
    }

    if (check)
    {
        return EXIT_SUCCESS;
    }
    else
    {
        return EXIT_FAILURE;
    }
}//end main