예제 #1
0
void ExporterEnsight<MeshType>::import (const Real& time)
{
    this->M_timeSteps.push_back (time);
    ++this->M_steps;

    // typedef std::list< exporterData_Type >::iterator Iterator;

    this->computePostfix();

    assert ( this->M_postfix.find ( "*" ) == std::string::npos );

    if (!this->M_procId)
    {
        std::cout << "  X-  ExporterEnsight importing ..." << std::endl;
    }

    LifeChrono chrono;
    chrono.start();
    for (typename super::dataVectorIterator_Type i = this->M_dataVector.begin(); i != this->M_dataVector.end(); ++i)
    {
        this->readVariable (*i);
    }
    chrono.stop();
    if (!this->M_procId)
    {
        std::cout << "      done in " << chrono.diff() << " s." << std::endl;
    }

}
예제 #2
0
Int SolverAztecOO::solveSystem ( const vector_type& rhsFull,
                                 vector_type&       solution,
                                 matrix_ptrtype&    baseMatrixForPreconditioner )

{

    bool retry ( true );

    LifeChrono chrono;

    M_displayer->leaderPrint ( "SLV-  Setting up the solver ...                \n" );

    if ( baseMatrixForPreconditioner.get() == 0 )
    {
        M_displayer->leaderPrint ( "SLV-  Warning: baseMatrixForPreconditioner is empty     \n" );
    }

    if ( !isPreconditionerSet() || !M_reusePreconditioner  )
    {
        buildPreconditioner ( baseMatrixForPreconditioner );
        // do not retry if I am recomputing the preconditioner
        retry = false;
    }
    else
    {
        M_displayer->leaderPrint ( "SLV-  Reusing precond ...                 \n" );
    }

    Int numIter = solveSystem ( rhsFull, solution, M_preconditioner );

    // If we do not want to retry, return now.
    // otherwise rebuild the preconditioner and solve again:
    if ( numIter < 0  && retry )
    {
        chrono.start();

        M_displayer->leaderPrint ( "SLV-  Iterative solver failed, numiter = " , - numIter );
        M_displayer->leaderPrint ( "SLV-  maxIterSolver = " , M_maxIter );
        M_displayer->leaderPrint ( "SLV-  retrying:          " );

        buildPreconditioner ( baseMatrixForPreconditioner );

        chrono.stop();
        M_displayer->leaderPrintMax ( "done in " , chrono.diff() );
        // Solving again, but only once (retry = false)
        numIter = solveSystem ( rhsFull, solution, M_preconditioner );

        if ( numIter < 0 )
        {
            M_displayer->leaderPrint ( " ERROR: Iterative solver failed again.\n" );
        }
    }

    if ( std::abs (numIter) > M_maxIterForReuse )
    {
        resetPreconditioner();
    }

    return numIter;
}
예제 #3
0
void
LinearSolver::buildPreconditioner()
{
    LifeChrono chrono;
    Real condest( -1 );

    if( M_preconditioner )
    {
        if( M_matrix.get() == 0 )
        {
            M_displayer->leaderPrint( "SLV-  ERROR: LinearSolver requires a matrix to build the preconditioner!\n" );
            exit( 1 );
        }
        else
        {
            chrono.start();
            if( !M_silent ) M_displayer->leaderPrint( "SLV-  Computing the preconditioner...\n" );
            if ( M_baseMatrixForPreconditioner.get() == 0 )
            {
                if( !M_silent ) M_displayer->leaderPrint( "SLV-  Build the preconditioner using the problem matrix\n" );
                M_preconditioner->buildPreconditioner( M_matrix );
            }
            else
            {
                if( !M_silent ) M_displayer->leaderPrint( "SLV-  Build the preconditioner using the base matrix provided\n" );
                M_preconditioner->buildPreconditioner( M_baseMatrixForPreconditioner );
            }
            condest = M_preconditioner->condest();
            chrono.stop();
            if( !M_silent ) M_displayer->leaderPrintMax( "SLV-  Preconditioner computed in " , chrono.diff(), " s." );
            if( !M_silent ) M_displayer->leaderPrint( "SLV-  Estimated condition number               " , condest, "\n" );
        }
    }
}
예제 #4
0
int
PreconditionerComposed::push_back (operatorPtr_Type& oper,
                                   const bool useInverse,
                                   const bool useTranspose
                                  )
{
    if (!M_prec.get() )
    {
        M_prec.reset (new prec_Type (M_displayer.comm() ) );
    }
    M_operVector.push_back (oper);
    LifeChrono chrono;
    epetraPrecPtr_Type prec;

    this->M_displayer.leaderPrint ( std::string ("ICP-  Preconditioner type:                     ") + M_prec->Operator() [M_operVector.size() - 1]->preconditionerType() + std::string ("\n") );
    this->M_displayer.leaderPrint ( "ICP-  Computing preconditioner ...             " );
    chrono.start();
    createPrec (oper, M_prec->OperatorView() [M_operVector.size() - 1]);
    chrono.stop();
    this->M_displayer.leaderPrintMax ("done in ", chrono.diff() );
    M_prec->replace (prec, useInverse, useTranspose); // \TODO to reset as push_back
    if ( M_prec->Operator().size() == M_operVector.size() )
    {
        this->M_preconditionerCreated = true;
    }
    return EXIT_SUCCESS;
}
void
WallTensionEstimatorCylindricalCoordinates<Mesh >::analyzeTensionsRecoveryCauchyStressesCylindrical ( void )
{

    LifeChrono chrono;

    chrono.start();
    UInt dim = this->M_FESpace->dim();

    constructGlobalStressVector();


    for ( UInt iDOF = 0; iDOF < ( UInt ) this->M_FESpace->dof().numTotalDof(); iDOF++ )
    {

        if ( this->M_displacement->blockMap().LID ( static_cast<EpetraInt_Type> (iDOF) ) != -1 ) // The Global ID is on the calling processors
        {

            (* (this->M_sigma) ).Scale (0.0);

            //Extracting the gradient of U on the current DOF
            for ( UInt iComp = 0; iComp < this->M_FESpace->fieldDim(); ++iComp )
            {
                Int LIDid = this->M_displacement->blockMap().LID ( static_cast<EpetraInt_Type> (iDOF + iComp * dim + this->M_offset ) );
                Int GIDid = this->M_displacement->blockMap().GID (static_cast<EpetraInt_Type> (LIDid) );
                (* (this->M_sigma) ) (iComp, 0) = (*this->M_sigmaX) (GIDid); // (d_xX,d_yX,d_zX)
                (* (this->M_sigma) ) (iComp, 1) = (*this->M_sigmaY) (GIDid); // (d_xY,d_yY,d_zY)
                (* (this->M_sigma) ) (iComp, 2) = (*this->M_sigmaZ) (GIDid); // (d_xZ,d_yZ,d_zZ)
            }

            //Compute the eigenvalue
            AssemblyElementalStructure::computeEigenvalues (* (this->M_sigma), this->M_eigenvaluesR, this->M_eigenvaluesI);

            //The Cauchy tensor is symmetric and therefore, the eigenvalues are real
            //Check on the imaginary part of eigen values given by the Lapack method
            Real sum (0);
            for ( int i = 0; i < this->M_eigenvaluesI.size(); i++ )
            {
                sum += std::abs (this->M_eigenvaluesI[i]);
            }
            ASSERT_PRE ( sum < 1e-6 , "The eigenvalues of the Cauchy stress tensors have to be real!" );

            std::sort ( this->M_eigenvaluesR.begin(), this->M_eigenvaluesR.end() );

            //Save the eigenvalues in the global vector
            for ( UInt icoor = 0; icoor < this->M_FESpace->fieldDim(); ++icoor )
            {
                Int LIDid = this->M_displacement->blockMap().LID ( static_cast<EpetraInt_Type> (iDOF + icoor * dim + this->M_offset) );
                Int GIDid = this->M_displacement->blockMap().GID (static_cast<EpetraInt_Type> (LIDid) );
                (* (this->M_globalEigenvalues) ) (GIDid) = this->M_eigenvaluesR[icoor];
            }

        }
    }

    chrono.stop();
    this->M_displayer->leaderPrint ("Analysis done in: ", chrono.diff() );

}
예제 #6
0
void ExporterEnsight<MeshType>::postProcess (const Real& time)
{
    // writing the geo file and the list of global IDs, but only upon the first instance
    if ( M_firstTimeStep )
    {
        if (!this->M_multimesh)
        {
            writeAsciiGeometry ( this->M_postDir + this->M_prefix + this->M_me + ".geo" );
        }

        writeGlobalIDs ( this->M_postDir + super::M_prefix + "_globalIDs" +
                         this->M_me + ".scl" );

        M_firstTimeStep = false;
    }
    // prepare the file postfix
    this->computePostfix();

    // the postfix will be full of stars, if this time step is not going to generate a snapshot
    std::size_t found ( this->M_postfix.find ( "*" ) );
    if ( found == std::string::npos )
    {
        if (!this->M_procId)
        {
            std::cout << "  X-  ExporterEnsight post-processing ...        " << std::flush;
        }
        LifeChrono chrono;
        chrono.start();
        for (typename super::dataVectorIterator_Type i = this->M_dataVector.begin();
                i != this->M_dataVector.end(); ++i)
        {
            // the "regime" attribute needs to be valid
            if ( i->regime() != exporterData_Type::NullRegime )
            {
                writeAscii (*i);
            }
            // if the solution is steady, we do not need to export it at each time step
            if (i->regime() == exporterData_Type::SteadyRegime)
            {
                i->setRegime ( exporterData_Type::NullRegime );
            }
        }
        // write an updated case file
        writeCase (time);

        // write an updated geo file, if needed
        if (this->M_multimesh)
        {
            writeAsciiGeometry ( this->M_postDir + this->M_prefix + this->M_postfix + this->M_me + ".geo" );
        }
        chrono.stop();
        if (!this->M_procId)
        {
            std::cout << "      done in " << chrono.diff() << " s." << std::endl;
        }
    }

}
예제 #7
0
void SolverAztecOO::buildPreconditioner ( matrix_ptrtype& preconditioner )
{
    LifeChrono chrono;
    Real condest (-1);

    chrono.start();

    M_displayer->leaderPrint ( "SLV-  Computing the precond ...                " );

    M_preconditioner->buildPreconditioner ( preconditioner );

    condest = M_preconditioner->condest();
    chrono.stop();

    M_displayer->leaderPrintMax ( "done in " , chrono.diff() );
    M_displayer->leaderPrint ( "SLV-  Estimated condition number               " , condest, "\n" );
}
예제 #8
0
void ExporterVTK<MeshType>::import(const Real& /*time*/)
{
    this->computePostfix();

    assert( this->M_postfix != "*****" );

    if (!this->M_procId) std::cout << "  X-  ExporterVTK importing ..."<< std::endl;

    LifeChrono chrono;
    chrono.start();
    for (typename super::dataVectorIterator_Type iData=this->M_dataVector.begin();
                    iData != this->M_dataVector.end(); ++iData)
    {
        this->readVTUFiles(*iData);
    }
    chrono.stop();
    if (!this->M_procId) std::cout << "      done in " << chrono.diff() << " s." << std::endl;

}
예제 #9
0
int
PreconditionerComposed::replace(operatorPtr_Type& oper,
                            const UInt index,
                            const bool useInverse,
                            const bool useTranspose)
{
    ASSERT(index <= M_operVector.size(), "PreconditionerComposed::replace: index too large");

    M_operVector[index] = oper;
    LifeChrono chrono;
    //ifpack_prec_type prec;
    this->M_displayer.leaderPrint( std::string("ICP-  Preconditioner type:                     ") + M_prec->Operator()[index]->preconditionerType() + std::string("\n") );
    this->M_displayer.leaderPrint( "ICP-  Computing preconditioner ...             " );
    chrono.start();
    createPrec(oper, M_prec->OperatorView()[index]);
    chrono.stop();
    this->M_displayer.leaderPrintMax("done in ", chrono.diff());

    M_prec->replace(M_prec->Operator()[index], index, useInverse, useTranspose);

    return EXIT_SUCCESS;
}
예제 #10
0
파일: timeAdvance.cpp 프로젝트: xyuan/lifev
// ===================================================
//! Methods
// ===================================================
void
problem::run()
{
    typedef RegionMesh<LinearTetra>                                   mesh_Type;
    typedef VenantKirchhoffViscoelasticSolver< mesh_Type >::vector_type vector_Type;
    typedef boost::shared_ptr<vector_Type>                              vectorPtr_Type;

    typedef boost::shared_ptr< TimeAdvance< vector_Type > >             TimeAdvance_type;

    typedef FESpace< mesh_Type, MapEpetra >                             FESpace_type;
    typedef  boost::shared_ptr<FESpace_type>                            FESpace_ptrtype;

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

    //
    // VenantKirchhoffViscoelasticData
    //

    GetPot dataFile( members->data_file_name.c_str() );
    boost::shared_ptr<VenantKirchhoffViscoelasticData> dataProblem(new VenantKirchhoffViscoelasticData( ));
    dataProblem->setup(dataFile, "problem");


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

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

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

    //
    // The Problem Solver
    //

    if (verbose) std::cout << "The Problem Solver" << std::flush;

    // Scalar Solution Space:

    std::string Order =  dataFile( "problem/space_discretization/order", "P1");

    if ( Order.compare("P1") == 0 )
    {
        if (verbose) std::cout << "  Space order : P1" << std::flush;

    }
    else if ( Order.compare("P2") == 0 )
    {
        if (verbose) std::cout << " Space order : P2";

    }
    if (verbose) std::cout << std::endl;


    // finite element space of the solution
    // finite element space of the solution
    std::string dOrder =  dataFile( "problem/space_discretization/order", "P1");

    FESpace_ptrtype feSpace( new FESpace_type(localMeshPtr,dOrder,1,members->comm) );

    // instantiation of the VenantKirchhoffViscoelasticSolver class

    VenantKirchhoffViscoelasticSolver< mesh_Type > problem;

    problem.setup(dataProblem,  feSpace,
                  members->comm);

    problem.setDataFromGetPot(dataFile);
// the boundary conditions

    BCFunctionBase uZero ( members->getUZero()  );
    BCFunctionBase uEx(uexact);

    BCHandler bcH;

    bcH.addBC( "Top",     TOP,    Essential, Full,      uEx, 1 );
    bcH.addBC( "Bottom",  BOTTOM, Essential, Full,      uEx, 1 );
    bcH.addBC( "Left",    LEFT,   Essential, Full,      uEx, 1 );
    bcH.addBC( "Right",   RIGHT,  Essential, Full,      uEx, 1 );
    bcH.addBC( "Front",   FRONT,  Essential, Full,      uEx, 1 );
    bcH.addBC( "Back",    BACK,   Essential, Full,      uEx, 1 );

    std::ofstream out_norm;
    if (verbose)
    {
        out_norm.open("norm.txt");
        out_norm << "  time   "
        <<"  L2_Error    "
        <<"  H1_Error    "
        <<"  L2_RelError "
        <<"  H1_RelError \n";
        out_norm.close();
    }

    LifeChrono chrono;

    std::string TimeAdvanceMethod =  dataFile( "problem/time_discretization/method", "Newmark");

    TimeAdvance_type  timeAdvance( TimeAdvanceFactory::instance().createObject( TimeAdvanceMethod ) );

    UInt OrderDev = 1;

    //! initialization of parameters of time Advance method:

    if (TimeAdvanceMethod =="Newmark")
        timeAdvance->setup( dataProblem->dataTimeAdvance()->coefficientsNewmark() , OrderDev);

    if (TimeAdvanceMethod =="BDF")
        timeAdvance->setup(dataProblem->dataTimeAdvance()->orderBDF() , OrderDev);

    Real dt = dataProblem->dataTime()->timeStep();
    Real T  = dataProblem->dataTime()->endTime();

    chrono.start();

    dataProblem->setup(dataFile, "problem");

    double alpha = timeAdvance->coefficientFirstDerivative( 0 ) / ( dataProblem->dataTime()->timeStep());

    problem.buildSystem(alpha);

    MPI_Barrier(MPI_COMM_WORLD);

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

    // building some vectors:
    MapEpetra uMap = problem.solution()->map();

    // computing the rhs
    vector_Type rhs ( uMap, Unique );
    vector_Type rhsV( uMap, Unique );

    // postProcess
    boost::shared_ptr< Exporter<mesh_Type > > exporter;

    std::string const exporterType =  dataFile( "exporter/type", "ensight");

#ifdef HAVE_HDF5
    if (exporterType.compare("hdf5") == 0)
        exporter.reset( new ExporterHDF5<mesh_Type > ( dataFile, "problem" ) );
    else
#endif
    {
        if (exporterType.compare("none") == 0)
            exporter.reset( new ExporterEmpty<mesh_Type > ( dataFile, localMeshPtr, "problem", members ->comm->MyPID()) );
        else
            exporter.reset( new ExporterEnsight<mesh_Type > ( dataFile, localMeshPtr, "problem",   members->comm->MyPID()) );
    }

    exporter->setPostDir( "./" ); // This is a test to see if M_post_dir is working
    exporter->setMeshProcId( localMeshPtr,  members->comm->MyPID() );

    vectorPtr_Type U ( new vector_Type(*problem.solution(), exporter->mapType() ) );
    vectorPtr_Type V  ( new vector_Type(*problem.solution(),  exporter->mapType() ) );
    vectorPtr_Type Exact ( new vector_Type(*problem.solution(), exporter->mapType() ) );
    vectorPtr_Type vExact  ( new vector_Type(*problem.solution(),  exporter->mapType() ) );
    vectorPtr_Type RHS ( new vector_Type(*problem.solution(), exporter->mapType() ) );
    exporter->addVariable( ExporterData<mesh_Type>::ScalarField, "displacement",
                           feSpace, U, UInt(0) );

    exporter->addVariable( ExporterData<mesh_Type>::ScalarField, "velocity",
                           feSpace, V, UInt(0) );

    exporter->addVariable( ExporterData<mesh_Type>::ScalarField, "uexact",
                           feSpace, Exact, UInt(0) );

    exporter->addVariable( ExporterData<mesh_Type>::ScalarField, "vexact",
                           feSpace, vExact, UInt(0) );

    exporter->postProcess( 0 );

    //initialization of unk

    //evaluate disp and vel as interpolate the bcFunction d0 and v0
    feSpace->interpolate( static_cast<FESpace_type::function_Type>( d0 ), *U, 0.0 );
    feSpace->interpolate( static_cast<FESpace_type::function_Type>( v0 ), *V, 0.0 );

    //evaluate disp and vel as interpolate the bcFunction d0 and v0

    std::vector<vectorPtr_Type> uv0;

    if (TimeAdvanceMethod =="Newmark")
    {
      uv0.push_back(U);
      uv0.push_back(V);
    }
    if (TimeAdvanceMethod =="BDF")
    {
        for ( UInt previousPass=0; previousPass < dataProblem->dataTimeAdvance()->orderBDF() ; previousPass++)
        {
            Real previousTimeStep = -previousPass*dt;
// <<<<<<< HEAD
            feSpace->interpolate(uexact, *U, previousTimeStep );
            uv0.push_back(U);
// =======
            // feSpace->interpolate( static_cast<FESpace_type::function_Type>( uexact ), *U, previousTimeStep );
            // uv0.push_back(*U);
        //>>>>>>> master
        }
    }

    //the uv0[0] should be the displacement
    //the uv0[1] should be the velocity

    //timeAdvance->setInitialCondition(uv0[0],uv0[1]);
    timeAdvance->setInitialCondition(uv0);

    timeAdvance-> setTimeStep(dataProblem->dataTime()->timeStep());

    timeAdvance->showMe();

    feSpace->interpolate( static_cast<FESpace_type::function_Type>( uexact ), *Exact , 0);
    feSpace->interpolate( static_cast<FESpace_type::function_Type>( v0 ), *vExact , 0);

    *U = timeAdvance->solution();
    *V = timeAdvance->firstDerivative();

    for (Real time = dt; time <= T; time += dt)
    {
        dataProblem->dataTime()->setTime(time);

        if (verbose)
        {
            std::cout << std::endl;
            std::cout << " P - Now we are at time " << dataProblem->dataTime()->time() << " s." << std::endl;
        }

        //evaluate rhs
        rhs *=0;
        timeAdvance->updateRHSContribution(dt);
        rhsV = timeAdvance->rhsContributionFirstDerivative();
        feSpace->l2ScalarProduct(source_in, rhs, time);
        rhs += problem.matrMass() *rhsV;

        //updateRHS
        problem.updateRHS(rhs);

        //solver system
        problem.iterate( bcH );    // Computes the matrices and solves the system

        //update unknowns of timeAdvance
        timeAdvance->shiftRight(*problem.solution());

        //evaluate uexact solution
        feSpace->interpolate( static_cast<FESpace_type::function_Type>( uexact ), *Exact , time);
        feSpace->interpolate( static_cast<FESpace_type::function_Type>( v0 ), *vExact , time);
        *U =  timeAdvance->solution();
        *V  =timeAdvance->firstDerivative();

        //postProcess
        exporter->postProcess(time);

        // Error L2 and H1 Norms
        AnalyticalSol uExact;
        vector_Type u (*problem.solution(), Repeated);

        Real H1_Error,  H1_RelError,  L2_Error, L2_RelError;

        L2_Error = feSpace->l2Error(uexact, u, time ,&L2_RelError);
        H1_Error = feSpace->h1Error(uExact, u, time ,&H1_RelError);

        //save the norm
        if (verbose)
        {
            out_norm.open("norm.txt", std::ios::app);
            out_norm << time             << "   "
            << L2_Error       << "   "
            << H1_Error      << "   "
            << L2_RelError << "   "
            << H1_RelError << "\n";
            out_norm.close();
        }

        MPI_Barrier(MPI_COMM_WORLD);
    }
    chrono.stop();
    if (verbose) std::cout << "Total iteration time " << chrono.diff() << " s." << std::endl;
}
예제 #11
0
// ===================================================
// Methods
// ===================================================
Int
LinearSolver::solve ( vectorPtr_Type solutionPtr )
{
    // Build preconditioners if needed
    bool retry ( true );
    if ( !isPreconditionerSet() || !M_reusePreconditioner  )
    {
        buildPreconditioner();

        // There will be no retry if the preconditioner is recomputed
        retry = false;
    }
    else
    {
        if ( !M_silent )
        {
            M_displayer->leaderPrint ( "SLV-  Reusing precond ...\n" );
        }
    }

    if ( M_rhs.get() == 0 || M_operator == 0 )
    {
        M_displayer->leaderPrint ( "SLV-  ERROR: LinearSolver failed to set up correctly!\n" );
        return -1;
    }

    // Setup the Solver Operator
    setupSolverOperator();

    // Reset status informations
    bool failure = false;
    this->resetStatus();
    M_solverOperator->resetStatus();

    // Solve the linear system
    LifeChrono chrono;
    chrono.start();

    M_solverOperator->ApplyInverse ( M_rhs->epetraVector(), solutionPtr->epetraVector() );
    M_converged         = M_solverOperator->hasConverged();
    M_lossOfPrecision   = M_solverOperator->isLossOfAccuracyDetected();
    chrono.stop();
    if ( !M_silent )
    {
        M_displayer->leaderPrintMax ( "SLV-  Solution time: " , chrono.diff(), " s." );
    }

    // Getting informations post-solve
    Int numIters = M_solverOperator->numIterations();

    // Second run recomputing the preconditioner
    // This is done only if the preconditioner has not been
    // already recomputed and if it is a LifeV preconditioner.
    if ( M_converged != SolverOperator_Type::yes
            && retry
            && M_preconditioner )
    {
        M_displayer->leaderPrint ( "SLV-  Iterative solver failed, numiter = " , numIters, "\n" );
        M_displayer->leaderPrint ( "SLV-  retrying:\n" );

        buildPreconditioner();

        // Solving again, but only once (retry = false)
        chrono.start();
        M_solverOperator->ApplyInverse ( M_rhs->epetraVector(), solutionPtr->epetraVector() );
        M_converged         = M_solverOperator->hasConverged();
        M_lossOfPrecision   = M_solverOperator->isLossOfAccuracyDetected();
        chrono.stop();
        if ( !M_silent )
        {
            M_displayer->leaderPrintMax ( "SLV-  Solution time: " , chrono.diff(), " s." );
        }
    }

    if ( M_lossOfPrecision == SolverOperator_Type::yes )
    {
        M_displayer->leaderPrint ( "SLV-  WARNING: Loss of accuracy detected!\n" );
        failure = true;
    }

    if ( M_converged == SolverOperator_Type::yes )
    {
        if ( !M_silent )
        {
            M_displayer->leaderPrint ( "SLV-  Convergence in " , numIters, " iterations\n" );
        }
        M_maxNumItersReached = SolverOperator_Type::no;
    }
    else
    {
        M_displayer->leaderPrint ( "SLV-  WARNING: Solver failed to converged to the desired precision!\n" );
        M_maxNumItersReached = SolverOperator_Type::yes;
        failure = true;
    }

    // If quitOnFailure is enabled and if some problems occur
    // the simulation is stopped
    if ( M_quitOnFailure && failure )
    {
        exit ( -1 );
    }

    // Reset the solver to free the internal pointers
    M_solverOperator->resetSolver();

    // If the number of iterations reaches the threshold of maxIterForReuse
    // we reset the preconditioners to force to solver to recompute it next
    // time
    if ( numIters > M_maxItersForReuse )
    {
        resetPreconditioner();
    }

    return numIters;
}
예제 #12
0
파일: main.cpp 프로젝트: hamed20/lifev
Int main (Int argc, char** argv)
{
    //Setup main communicator
    boost::shared_ptr<Epetra_Comm>  comm;

#ifdef HAVE_MPI
    std::cout << "MPI Initialization" << std::endl;
    MPI_Init ( &argc, &argv );
#endif

    //MPI Preprocessing
#ifdef EPETRA_MPI
    Int nprocs;
    Int rank;

    MPI_Comm_size ( MPI_COMM_WORLD, &nprocs );
    MPI_Comm_rank ( MPI_COMM_WORLD, &rank );

    if ( rank == 0 )
    {
        std::cout << "MPI Processes: " << nprocs << std::endl;
        std::cout << "MPI Epetra Initialization ... " << std::endl;
    }
    comm.reset ( new Epetra_MpiComm ( MPI_COMM_WORLD ) );

    comm->Barrier();
#else
    std::cout << "MPI SERIAL Epetra Initialization ... " << std::endl;
    comm.reset ( new Epetra_SerialComm() );
#endif

    // *********************************
    // Useful typedefs
    // *********************************
    typedef MultiscaleModelFSI1D::physics_Type       physics_Type;
    typedef MultiscaleModelFSI1D::flux_Type          flux_Type;
    typedef MultiscaleModelFSI1D::source_Type        source_Type;

    typedef MultiscaleModelFSI1D::bc_Type            bc_Type;
    typedef bc_Type::bcFunction_Type                 bcFunction_Type;

    // *********************************
    // Reading from data file
    // *********************************
    GetPot command_line (argc, argv);

    // checking if we are checking for the nightly build
    const bool check = command_line.search (2, "-c", "--check");

    string fileName = command_line.follow ("data", 2, "-f", "--file");
    GetPot dataFile ( fileName );

    // *********************************
    // Build the 1D model
    // *********************************
    MultiscaleModelFSI1D oneDModel;
    oneDModel.setCommunicator ( comm );

    // Scale, Rotate, Translate 1D (if necessary)
    boost::array< Real, NDIM >    geometryScale;
    boost::array< Real, NDIM >    geometryRotate;
    boost::array< Real, NDIM >    geometryTranslate;

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

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

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

    oneDModel.setGeometry ( geometryScale, geometryRotate, geometryTranslate );

    oneDModel.setupData ( fileName );

    // *********************************
    // BC for the 1D model
    // *********************************

    // Set BC using BCInterface
    //oneDModel.GetBCInterface().FillHandler( fileName, "1D_Model" );

    // Set BC using standard approach
    Sin sinus ( 0, 10, .01, 0.);
    bcFunction_Type sinusoidalFunction ( boost::bind ( &Sin::operator(), &sinus, _1 ) );

    // Absorbing
    bc_Type::bcFunctionSolverDefinedPtr_Type absorbing ( new OneDFSIFunctionSolverDefinedAbsorbing ( OneDFSI::right, OneDFSI::W2 ) );
    bcFunction_Type absorbingFunction ( boost::bind ( &OneDFSIFunctionSolverDefinedAbsorbing::operator(),
                                                      dynamic_cast<OneDFSIFunctionSolverDefinedAbsorbing*> ( & ( *absorbing ) ), _1, _2 ) );

    // BC to test A_from_P conversion
    //Constant constantArea( 1.00 );
    //bcFunction_Type constantAreaFunction( boost::bind( &Constant::operator(), &constantArea, _1 ) );

    //Constant constantPressure( 24695.0765959599 );
    //bcFunction_Type constantPressureFunction( boost::bind( &Constant::operator(), &constantPressure, _1 ) );

    oneDModel.bc().setBC ( OneDFSI::left,  OneDFSI::first, OneDFSI::Q,  sinusoidalFunction  );
    oneDModel.bc().setBC ( OneDFSI::right, OneDFSI::first, OneDFSI::W2, absorbingFunction );

    //oneDModel.bc().setBC( OneDFSI::right, OneDFSI::first, OneDFSI::A, constantAreaFunction );
    //oneDModel.bc().setBC( OneDFSI::right, OneDFSI::first, OneDFSI::P,   constantPressureFunction );

    oneDModel.setupModel();

    absorbing->setSolution ( oneDModel.solution() );
    absorbing->setFluxSource ( oneDModel.flux(), oneDModel.source() );

    // *********************************
    // Tempolar loop
    // *********************************
    std::cout << "\nTemporal loop:" << std::endl;

    LifeChrono chronoTotal;
    LifeChrono chronoSystem;
    LifeChrono chronoIteration;

    Int count = 0;
    chronoTotal.start();
    for ( ; oneDModel.data().dataTime()->canAdvance() ; oneDModel.data().dataTime()->updateTime(), ++count )
    {
        std::cout << std::endl << "--------- Iteration " << count << " time = " << oneDModel.data().dataTime()->time() << std::endl;

        chronoIteration.start();

        if ( oneDModel.data().dataTime()->isFirstTimeStep() )
        {
            oneDModel.buildModel();
        }
        else
        {
            oneDModel.updateModel();
        }

        chronoSystem.start();

        oneDModel.solveModel();

        chronoSystem.stop();

        oneDModel.updateSolution();

        //Save solution
        if ( count % 50 == 0 || oneDModel.data().dataTime()->isLastTimeStep() )
        {
            oneDModel.saveSolution();
        }

        chronoIteration.stop();

        std::cout << " System solved in " << chronoSystem.diff() << " s, (total time " << chronoIteration.diff() << " s)." << std::endl;
    }

    chronoTotal.stop();
    std::cout << std::endl << " Simulation ended successfully in " << chronoTotal.diff()  << " s" << std::endl;

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

    if ( check )
    {
        bool ok = true;
        Int rightNodeID = oneDModel.solver()->boundaryDOF ( OneDFSI::right );

        ok = ok && checkValue ( 0.999998  , (*oneDModel.solution ("A") ) [rightNodeID]);
        ok = ok && checkValue (-0.00138076, (*oneDModel.solution ("Q") ) [rightNodeID]);
        ok = ok && checkValue (-0.00276153, (*oneDModel.solution ("W1") ) [rightNodeID]);
        ok = ok && checkValue ( 0.00000000, (*oneDModel.solution ("W2") ) [rightNodeID]);

        ok = ok && checkValue ( 0.999999  , (*oneDModel.solution ("A") ) [rightNodeID - 1]);
        ok = ok && checkValue (-0.00040393, (*oneDModel.solution ("Q") ) [rightNodeID - 1]);
        ok = ok && checkValue (-0.00080833, (*oneDModel.solution ("W1") ) [rightNodeID - 1]);
        ok = ok && checkValue ( 0.00000045, (*oneDModel.solution ("W2") ) [rightNodeID - 1]);

        if (ok)
        {
            std::cout << "Test successful" << std::endl;
            return 0;
        }
        else
        {
            std::cout << "Test unsuccessful" << std::endl;
            return -1;
        }
    }
    else
    {
        return 0;
    }
}
예제 #13
0
void Heart::computeRhs ( vector_Type& rhs,
                         HeartBidomainSolver< mesh_Type >& electricModel,
                         boost::shared_ptr< HeartIonicSolver< mesh_Type > > ionicModel,
                         HeartBidomainData& data )
{
    bool verbose = (M_heart_fct->M_comm->MyPID() == 0);
    if (verbose)
    {
        std::cout << "  f-  Computing Rhs ...        " << "\n" << std::flush;
    }
    LifeChrono chrono;
    chrono.start();

    //! u, w with repeated map
    vector_Type uVecRep (electricModel.solutionTransmembranePotential(), Repeated);
    ionicModel->updateRepeated();

    VectorElemental elvec_Iapp ( electricModel.potentialFESpace().fe().nbFEDof(), 2 ),
                    elvec_u ( electricModel.potentialFESpace().fe().nbFEDof(), 1 ),
                    elvec_Iion ( electricModel.potentialFESpace().fe().nbFEDof(), 1 );
    for (UInt iVol = 0; iVol < electricModel.potentialFESpace().mesh()->numVolumes(); ++iVol)
    {
        electricModel.potentialFESpace().fe().updateJacQuadPt ( electricModel.potentialFESpace().mesh()->volumeList ( iVol ) );
        elvec_u.zero();
        elvec_Iion.zero();
        elvec_Iapp.zero();

        UInt eleIDu = electricModel.potentialFESpace().fe().currentLocalId();
        UInt nbNode = ( UInt ) electricModel.potentialFESpace().fe().nbFEDof();
        for ( UInt iNode = 0 ; iNode < nbNode ; iNode++ )
        {
            Int ig = electricModel.potentialFESpace().dof().localToGlobalMap ( eleIDu, iNode );
            elvec_u.vec() [ iNode ] = uVecRep[ig];
        }

        UInt eleID = electricModel.potentialFESpace().fe().currentLocalId();
        ionicModel->updateElementSolution (eleID);
        ionicModel->computeIonicCurrent (data.membraneCapacitance(), elvec_Iion, elvec_u, electricModel.potentialFESpace() );

        //! Computing Iapp
        AssemblyElemental::source (M_heart_fct->stimulus(),
                                   elvec_Iapp,
                                   electricModel.potentialFESpace().fe(),
                                   data.time(), 0);
        AssemblyElemental::source (M_heart_fct->stimulus(),
                                   elvec_Iapp,
                                   electricModel.potentialFESpace().fe(),
                                   data.time(),
                                   1);
        UInt totalUDof  = electricModel.potentialFESpace().map().map (Unique)->NumGlobalElements();

        for ( UInt iNode = 0 ; iNode < nbNode ; iNode++ )
        {
            Int ig = electricModel.potentialFESpace().dof().localToGlobalMap ( eleIDu, iNode );
            rhs.sumIntoGlobalValues (ig, elvec_Iapp.vec() [iNode] +
                                     data.volumeSurfaceRatio() * elvec_Iion.vec() [iNode] );
            rhs.sumIntoGlobalValues (ig + totalUDof,
                                     -elvec_Iapp.vec() [iNode + nbNode] -
                                     data.volumeSurfaceRatio() * elvec_Iion.vec() [iNode] );
        }
    }
    rhs.globalAssemble();

    rhs += electricModel.matrMass() * data.volumeSurfaceRatio() *
           data.membraneCapacitance() * electricModel.BDFIntraExtraPotential().time_der (data.timeStep() );

    MPI_Barrier (MPI_COMM_WORLD);

    chrono.stop();
    if (verbose)
    {
        std::cout << "done in " << chrono.diff() << " s." << std::endl;
    }
}
예제 #14
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
void
WallTensionEstimatorCylindricalCoordinates<Mesh >::analyzeTensionsRecoveryEigenvaluesCylindrical ( void )
{

    LifeChrono chrono;

    this->M_displayer->leaderPrint (" \n*********************************\n  ");
    this->M_displayer->leaderPrint ("   Performing the analysis recovering the tensions..., ", this->M_dataMaterial->solidType() );
    this->M_displayer->leaderPrint (" \n*********************************\n  ");

    solutionVect_Type patchArea (* (this->M_displacement), Unique, Add);
    patchArea *= 0.0;

    super::constructPatchAreaVector ( patchArea );

    //Before assembling the reconstruction process is done
    solutionVect_Type patchAreaR (patchArea, Repeated);

    QuadratureRule fakeQuadratureRule;

    Real refElemArea (0); //area of reference element
    //compute the area of reference element
    for (UInt iq = 0; iq < this->M_FESpace->qr().nbQuadPt(); iq++)
    {
        refElemArea += this->M_FESpace->qr().weight (iq);
    }

    Real wQuad (refElemArea / this->M_FESpace->refFE().nbDof() );

    //Setting the quadrature Points = DOFs of the element and weight = 1
    std::vector<GeoVector> coords = this->M_FESpace->refFE().refCoor();
    std::vector<Real> weights (this->M_FESpace->fe().nbFEDof(), wQuad);
    fakeQuadratureRule.setDimensionShape ( shapeDimension (this->M_FESpace->refFE().shape() ), this->M_FESpace->refFE().shape() );
    fakeQuadratureRule.setPoints (coords, weights);

    //Set the new quadrature rule
    this->M_FESpace->setQuadRule (fakeQuadratureRule);

    UInt totalDof = this->M_FESpace->dof().numTotalDof();
    VectorElemental dk_loc (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() );

    //Vectors for the deformation tensor
    std::vector<matrix_Type> vectorDeformationF (this->M_FESpace->fe().nbFEDof(), * (this->M_deformationF) );
    //Copying the displacement field into a vector with repeated map for parallel computations
    solutionVect_Type dRep (* (this->M_displacement), Repeated);

    VectorElemental elVecTens (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() );

    chrono.start();

    //Loop on each volume
    for ( UInt i = 0; i < this->M_FESpace->mesh()->numVolumes(); ++i )
    {
        this->M_FESpace->fe().updateFirstDerivQuadPt ( this->M_FESpace->mesh()->volumeList ( i ) );
        elVecTens.zero();

        this->M_marker = this->M_FESpace->mesh()->volumeList ( i ).markerID();

        UInt eleID = this->M_FESpace->fe().currentLocalId();

        //Extracting the local displacement
        for ( UInt iNode = 0; iNode < ( UInt ) this->M_FESpace->fe().nbFEDof(); iNode++ )
        {
            UInt  iloc = this->M_FESpace->fe().patternFirst ( iNode );

            for ( UInt iComp = 0; iComp < this->M_FESpace->fieldDim(); ++iComp )
            {
                UInt ig = this->M_FESpace->dof().localToGlobalMap ( eleID, iloc ) + iComp * this->M_FESpace->dim() + this->M_offset;
                dk_loc[iloc + iComp * this->M_FESpace->fe().nbFEDof()] = dRep[ig];
            }
        }

        //Compute the element tensor F
        AssemblyElementalStructure::computeLocalDeformationGradientWithoutIdentity ( dk_loc, vectorDeformationF, this->M_FESpace->fe() );

        //Compute the local vector of the principal stresses
        for ( UInt nDOF = 0; nDOF < ( UInt ) this->M_FESpace->fe().nbFEDof(); nDOF++ )
        {
            UInt  iloc = this->M_FESpace->fe().patternFirst ( nDOF );
            vector_Type localDisplacement (this->M_FESpace->fieldDim(), 0.0);

            for ( UInt coor = 0; coor < this->M_FESpace->fieldDim(); coor++ )
            {
                localDisplacement[coor] = iloc + coor * this->M_FESpace->fe().nbFEDof();
            }

            this->M_sigma->Scale (0.0);
            this->M_firstPiola->Scale (0.0);
            this->M_cofactorF->Scale (0.0);
            M_deformationCylindricalF->Scale (0.0);

            moveToCylindricalCoordinates (vectorDeformationF[nDOF], iloc, *M_deformationCylindricalF);

            //Compute the rightCauchyC tensor
            AssemblyElementalStructure::computeInvariantsRightCauchyGreenTensor (this->M_invariants, *M_deformationCylindricalF, * (this->M_cofactorF) );

            //Compute the first Piola-Kirchhoff tensor
            this->M_material->computeLocalFirstPiolaKirchhoffTensor (* (this->M_firstPiola), *M_deformationCylindricalF, * (this->M_cofactorF), this->M_invariants, this->M_marker);

            //Compute the Cauchy tensor
            AssemblyElementalStructure::computeCauchyStressTensor (* (this->M_sigma), * (this->M_firstPiola), this->M_invariants[3], *M_deformationCylindricalF);

            //Compute the eigenvalue
            AssemblyElementalStructure::computeEigenvalues (* (this->M_sigma), this->M_eigenvaluesR, this->M_eigenvaluesI);

            //The Cauchy tensor is symmetric and therefore, the eigenvalues are real
            //Check on the imaginary part of eigen values given by the Lapack method
            Real sum (0);
            for ( int i = 0; i < this->M_eigenvaluesI.size(); i++ )
            {
                sum += std::abs (this->M_eigenvaluesI[i]);
            }
            ASSERT_PRE ( sum < 1e-6 , "The eigenvalues of the Cauchy stress tensors have to be real!" );

            std::sort ( this->M_eigenvaluesR.begin(), this->M_eigenvaluesR.end() );

            //Assembling the local vector
            for ( int coor = 0; coor < this->M_eigenvaluesR.size(); coor++ )
            {
                elVecTens[iloc + coor * this->M_FESpace->fe().nbFEDof()] = this->M_eigenvaluesR[coor];
            }
        }

        super::reconstructElementaryVector ( elVecTens, patchAreaR, *this->M_FESpace );

        //Assembling the local into global vector
        for ( UInt ic = 0; ic < this->M_FESpace->fieldDim(); ++ic )
        {
            assembleVector (* (this->M_globalEigenvalues), elVecTens, this->M_FESpace->fe(), this->M_FESpace->dof(), ic, this->M_offset +  ic * totalDof );
        }
    }

    this->M_globalEigenvalues->globalAssemble();

    chrono.stop();
    this->M_displayer->leaderPrint ("Analysis done in: ", chrono.diff() );
}
void
WallTensionEstimatorCylindricalCoordinates<Mesh >::analyzeTensionsRecoveryDisplacementCylindrical ( void )
{

    LifeChrono chrono;

    this->M_displayer->leaderPrint (" \n*********************************\n  ");
    this->M_displayer->leaderPrint ("   Performing the analysis recovering the displacement..., ", this->M_dataMaterial->solidType() );
    this->M_displayer->leaderPrint (" \n*********************************\n  ");

    solutionVectPtr_Type grDisplX ( new solutionVect_Type (* (this->M_FESpace->mapPtr() ) ) );
    solutionVectPtr_Type grDisplY ( new solutionVect_Type (* (this->M_FESpace->mapPtr() ) ) );
    solutionVectPtr_Type grDisplZ ( new solutionVect_Type (* (this->M_FESpace->mapPtr() ) ) );

    //Compute the deformation gradient tensor F of the displ field
    super::computeDisplacementGradient ( grDisplX, grDisplY, grDisplZ);

    solutionVect_Type grXRep (*grDisplX, Repeated);
    solutionVect_Type grYRep (*grDisplY, Repeated);
    solutionVect_Type grZRep (*grDisplZ, Repeated);
    solutionVect_Type dRep (* (this->M_displacement), Repeated);

    //For each of the DOF, the Cauchy tensor is computed.
    //Therefore the tensor C,P, \sigma are computed for each DOF

    chrono.start();

    for ( UInt i (0); i < this->M_FESpace->mesh()->numVolumes(); ++i )
    {

        //Setup quantities
        this->M_FESpace->fe().updateFirstDerivQuadPt ( this->M_FESpace->mesh()->volumeList ( i ) );
        UInt eleID = this->M_FESpace->fe().currentLocalId();
        this->M_marker = this->M_FESpace->mesh()->volumeList ( i ).markerID();

        //store the local \grad(u)
        matrix_Type gradientDispl ( this->M_FESpace->fieldDim(), this->M_FESpace->fieldDim() );
        gradientDispl.Scale ( 0.0 );

        //Extracting the local displacement
        for ( UInt iNode = 0; iNode < ( UInt ) this->M_FESpace->fe().nbFEDof(); iNode++ )
        {
            UInt  iloc = this->M_FESpace->fe().patternFirst ( iNode );

            for ( UInt iComp = 0; iComp < this->M_FESpace->fieldDim(); ++iComp )
            {
                UInt ig = this->M_FESpace->dof().localToGlobalMap ( eleID, iloc ) + iComp * this->M_FESpace->dim() + this->M_offset;

                gradientDispl (iComp, 0) = grXRep[ig];
                gradientDispl (iComp, 1) = grYRep[ig];
                gradientDispl (iComp, 2) = grZRep[ig];
            }

            //Reinitialization of matrices and arrays
            ( * (this->M_cofactorF) ).Scale (0.0);
            ( * (this->M_firstPiola) ).Scale (0.0);
            ( * (this->M_sigma) ).Scale (0.0);

            //Moving to cylindrical coordinates
            moveToCylindricalCoordinates ( gradientDispl, iloc, *M_deformationCylindricalF );

            //Compute the rightCauchyC tensor
            AssemblyElementalStructure::computeInvariantsRightCauchyGreenTensor (this->M_invariants, *M_deformationCylindricalF, * (this->M_cofactorF) );

            //Compute the first Piola-Kirchhoff tensor
            this->M_material->computeLocalFirstPiolaKirchhoffTensor (* (this->M_firstPiola), *M_deformationCylindricalF, * (this->M_cofactorF), this->M_invariants, this->M_marker);

            //Compute the Cauchy tensor
            AssemblyElementalStructure::computeCauchyStressTensor (* (this->M_sigma), * (this->M_firstPiola), this->M_invariants[3], *M_deformationCylindricalF);

            //Compute the eigenvalue
            AssemblyElementalStructure::computeEigenvalues (* (this->M_sigma), this->M_eigenvaluesR, this->M_eigenvaluesI);

            //The Cauchy tensor is symmetric and therefore, the eigenvalues are real
            //Check on the imaginary part of eigen values given by the Lapack method
            Real sum (0);
            for ( UInt j (0); j < this->M_eigenvaluesI.size(); ++j )
            {
                sum += std::abs ( this->M_eigenvaluesI[j] );
            }

            ASSERT ( sum < 1e-6 , "The eigenvalues of the Cauchy stress tensors have to be real!" );

            std::sort ( this->M_eigenvaluesR.begin(), this->M_eigenvaluesR.end() );

            std::cout << "Saving eigenvalues" << i << std::endl;

            //Save the eigenvalues in the global vector
            for ( UInt icoor = 0; icoor < this->M_FESpace->fieldDim(); ++icoor )
            {
                UInt ig = this->M_FESpace->dof().localToGlobalMap ( eleID, iloc ) + icoor * this->M_FESpace->dim() + this->M_offset;
                (* (this->M_globalEigenvalues) ) (ig) = this->M_eigenvaluesR[icoor];
                // Int LIDid = this->M_displacement->blockMap().LID(ig);
                // if( this->M_globalEigenvalues->blockMap().LID(ig) != -1  )
                // {
                //     Int GIDid = this->M_globalEigenvalues->blockMap().GID(LIDid);

                // }
            }
        }
    }

    chrono.stop();
    this->M_displayer->leaderPrint ("Analysis done in: ", chrono.diff() );

}
예제 #17
0
void ExporterVTK<MeshType>::postProcess (const Real& time)
{
    // typedef std::list< ExporterData >::iterator Iterator;

    this->computePostfix();

    std::size_t found ( this->M_postfix.find ( "*" ) );
    if ( found == string::npos )
    {
        if (this->M_procId == 0)
        {
            std::cout << "  X-  ExporterVTK post-processing" << std::flush;
        }

        LifeChrono chrono;
        chrono.start();

        this->M_timeSteps.push_back (time);

        for (typename super::dataVectorIterator_Type iData = this->M_dataVector.begin();
                iData != this->M_dataVector.end(); ++iData)
        {
            std::ofstream vtkFile;
            std::stringstream buffer ("");

            // a unique PVTU file + a time collection is produced by the leader process
            if (this->M_procId == 0)
            {
                composePVTUStream (*iData, buffer);

                std::string vtkPFileName ( this->M_prefix + "_" + iData->variableName() +
                                           this->M_postfix + ".pvtu" );
                std::string vtkPFileNameWithDir (this->M_postDir + vtkPFileName);

                std::ofstream vtkPFile;
                vtkPFile.open ( vtkPFileNameWithDir.c_str() );
                ASSERT (vtkPFile.is_open(), "There is an error while opening " + vtkPFileName );
                ASSERT (vtkPFile.good(), "There is an error while writing to " + vtkPFileName );
                vtkPFile << buffer.str();
                vtkPFile.close();

                buffer.str ("");

                this->M_pvtuFiles[iData->variableName()].push_back (vtkPFileName);

            }


            // redundant. should be done just the first time
            std::map<UInt, UInt> ltgPointsMap, gtlPointsMap;
            std::vector<Vector> pointsCoords;
            createPointsMaps ( iData->feSpacePtr(), gtlPointsMap, ltgPointsMap, pointsCoords );

            composeVTUHeaderStream ( gtlPointsMap.size(), buffer );
            composeVTUGeoStream ( iData->feSpacePtr(), gtlPointsMap, pointsCoords, buffer );

            composeTypeDataHeaderStream (iData->where(), buffer);
            composeDataArrayStream (*iData, ltgPointsMap, buffer);
            composeTypeDataFooterStream (iData->where(), buffer);

            composeVTUFooterStream ( buffer );

            // each process writes its own file
            std::string filename ( this->M_postDir + this->M_prefix + "_" + iData->variableName() +
                                   this->M_postfix + "." + this->M_procId + ".vtu" );
            vtkFile.open ( filename.c_str() );
            ASSERT (vtkFile.is_open(), "There is an error while opening " + filename );
            ASSERT (vtkFile.good(), "There is an error while writing to " + filename );
            vtkFile << buffer.str();
            vtkFile.close();

            buffer.str ("");

        }
        chrono.stop();
        if (!this->M_procId)
        {
            std::cout << "...done in " << chrono.diff() << " s." << std::endl;
        }
    }
}
예제 #18
0
파일: main.cpp 프로젝트: Danniel-UCAS/lifev
Int main ( Int argc, char** argv )
{
    //! Initializing Epetra communicator
    MPI_Init (&argc, &argv);
    boost::shared_ptr<Epetra_Comm>  Comm ( new Epetra_MpiComm (MPI_COMM_WORLD) );
    if ( Comm->MyPID() == 0 )
    {
        std::cout << "% using MPI" << std::endl;
    }

    //********************************************//
    // Import parameters from an xml list. Use    //
    // Teuchos to create a list from a given file //
    // in the execution directory.                //
    //********************************************//

    std::cout << "Importing parameters list...";
    Teuchos::ParameterList FHNParameterList = * ( Teuchos::getParametersFromXmlFile ( "FitzHughNagumoParameters.xml" ) );
    std::cout << " Done!" << std::endl;


    //********************************************//
    // Creates a new model object representing the//
    // model from Fitz-Hugh Nagumo. The           //
    // model input are the parameters. Pass  the  //
    // parameter list in the constructor          //
    //********************************************//
    std::cout << "Building Constructor for Fitz-Hugh Nagumo Model with parameters ... ";
    IonicFitzHughNagumo  model ( FHNParameterList );
    std::cout << " Done!" << std::endl;


    //********************************************//
    // Show the parameters of the model as well as//
    // other informations  about the object.      //
    //********************************************//
    model.showMe();

    //********************************************//
    // Simulation starts on t=0 and ends on t=TF. //
    // The timestep is given by dt                //
    //********************************************//

    Real TF ( FHNParameterList.get ("TF", 300.0) );
    Real dt ( FHNParameterList.get ("dt", 0.01) );

    std::cout << "Time parameters : " << std::endl;
    std::cout << "TF = " << TF << std::endl;
    std::cout << "dt = " << dt << std::endl;

    std::string filename = "test_expeuler.txt";


    std::ofstream output (filename.c_str() );

    //********************************************//
    // Time loop starts.                          //
    //********************************************//
    std::cout << "Time loop starts...\n\n\n";

    LifeChrono chrono;
    chrono.start();

    Real valueToTest;

    valueToTest = EulerExplicit (dt, TF, model, FHNParameterList.get ("Iapp", 2000.0), output);


    chrono.stop();
    std::cout << "\n...Time loop ends.\n";
    std::cout << "\nElapsed time : " << chrono.diff() << std::endl;
    std::cout << "Solution written on file: " << filename << "\n";
    //********************************************//
    // Close exported file.                       //
    //********************************************//
    output.close();

    //! Finalizing Epetra communicator
    MPI_Finalize();

    Real returnValue;
    Real err = std::abs (valueToTest - SolutionTestNorm) / std::abs (SolutionTestNorm);
    std::cout << std::setprecision (20) << "\nError: " << err << "\nSolution norm: " << valueToTest << "\n";
    if ( err > 1e-12 )
    {
        returnValue = EXIT_FAILURE; // Norm of solution did not match
    }
    else
    {
        returnValue = EXIT_SUCCESS;
    }
    return ( returnValue );
}
void
WallTensionEstimatorCylindricalCoordinates<Mesh >::constructGlobalStressVector()
{

    //Creating the local stress tensors
    VectorElemental elVecSigmaX (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() );
    VectorElemental elVecSigmaY (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() );
    VectorElemental elVecSigmaZ (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() );

    LifeChrono chrono;

    //Constructing the patch area vector for reconstruction purposes
    solutionVect_Type patchArea (* (this->M_displacement), Unique, Add);
    patchArea *= 0.0;

    super::constructPatchAreaVector ( patchArea );

    //Before assembling the reconstruction process is done
    solutionVect_Type patchAreaR (patchArea, Repeated);

    QuadratureRule fakeQuadratureRule;

    Real refElemArea (0); //area of reference element
    //compute the area of reference element
    for (UInt iq = 0; iq < this->M_FESpace->qr().nbQuadPt(); iq++)
    {
        refElemArea += this->M_FESpace->qr().weight (iq);
    }

    Real wQuad (refElemArea / this->M_FESpace->refFE().nbDof() );

    //Setting the quadrature Points = DOFs of the element and weight = 1
    std::vector<GeoVector> coords = this->M_FESpace->refFE().refCoor();
    std::vector<Real> weights (this->M_FESpace->fe().nbFEDof(), wQuad);
    fakeQuadratureRule.setDimensionShape ( shapeDimension (this->M_FESpace->refFE().shape() ), this->M_FESpace->refFE().shape() );
    fakeQuadratureRule.setPoints (coords, weights);

    //Set the new quadrature rule
    this->M_FESpace->setQuadRule (fakeQuadratureRule);

    this->M_displayer->leaderPrint (" \n*********************************\n  ");
    this->M_displayer->leaderPrint ("   Performing the analysis recovering the Cauchy stresses..., ", this->M_dataMaterial->solidType() );
    this->M_displayer->leaderPrint (" \n*********************************\n  ");

    UInt totalDof = this->M_FESpace->dof().numTotalDof();
    VectorElemental dk_loc (this->M_FESpace->fe().nbFEDof(), this->M_FESpace->fieldDim() );

    //Vectors for the deformation tensor
    std::vector<matrix_Type> vectorDeformationF (this->M_FESpace->fe().nbFEDof(), * (this->M_deformationF) );
    //Copying the displacement field into a vector with repeated map for parallel computations
    solutionVect_Type dRep (* (this->M_displacement), Repeated);

    chrono.start();

    //Loop on each volume
    for ( UInt i = 0; i < this->M_FESpace->mesh()->numVolumes(); ++i )
    {
        this->M_FESpace->fe().updateFirstDerivQuadPt ( this->M_FESpace->mesh()->volumeList ( i ) );

        elVecSigmaX.zero();
        elVecSigmaY.zero();
        elVecSigmaZ.zero();

        this->M_marker = this->M_FESpace->mesh()->volumeList ( i ).markerID();

        UInt eleID = this->M_FESpace->fe().currentLocalId();

        //Extracting the local displacement
        for ( UInt iNode = 0; iNode < ( UInt ) this->M_FESpace->fe().nbFEDof(); iNode++ )
        {
            UInt  iloc = this->M_FESpace->fe().patternFirst ( iNode );

            for ( UInt iComp = 0; iComp < this->M_FESpace->fieldDim(); ++iComp )
            {
                UInt ig = this->M_FESpace->dof().localToGlobalMap ( eleID, iloc ) + iComp * this->M_FESpace->dim() + this->M_offset;
                dk_loc[iloc + iComp * this->M_FESpace->fe().nbFEDof()] = dRep[ig];
            }
        }

        //Compute the element tensor F
        AssemblyElementalStructure::computeLocalDeformationGradientWithoutIdentity ( dk_loc, vectorDeformationF, this->M_FESpace->fe() );

        //Compute the local vector of the principal stresses
        for ( UInt nDOF = 0; nDOF < ( UInt ) this->M_FESpace->fe().nbFEDof(); nDOF++ )
        {
            UInt  iloc = this->M_FESpace->fe().patternFirst ( nDOF );

            vector_Type localDisplacement (this->M_FESpace->fieldDim(), 0.0);

            for ( UInt coor = 0; coor < this->M_FESpace->fieldDim(); coor++ )
            {
                localDisplacement[coor] = iloc + coor * this->M_FESpace->fe().nbFEDof();
            }

            this->M_sigma->Scale (0.0);
            this->M_firstPiola->Scale (0.0);
            this->M_cofactorF->Scale (0.0);
            this->M_deformationCylindricalF->Scale (0.0);

            moveToCylindricalCoordinates (vectorDeformationF[nDOF], iloc, *M_deformationCylindricalF);

            //Compute the rightCauchyC tensor
            AssemblyElementalStructure::computeInvariantsRightCauchyGreenTensor (this->M_invariants, *M_deformationCylindricalF, * (this->M_cofactorF) );

            //Compute the first Piola-Kirchhoff tensor
            this->M_material->computeLocalFirstPiolaKirchhoffTensor (* (this->M_firstPiola), *M_deformationCylindricalF, * (this->M_cofactorF), this->M_invariants, this->M_marker);

            //Compute the Cauchy tensor
            AssemblyElementalStructure::computeCauchyStressTensor (* (this->M_sigma), * (this->M_firstPiola), this->M_invariants[3], *M_deformationCylindricalF);

            //Assembling the local vectors for local tensions Component X
            for ( int coor = 0; coor < this->M_FESpace->fieldDim(); coor++ )
            {
                (elVecSigmaX) [iloc + coor * this->M_FESpace->fe().nbFEDof()] = (* (this->M_sigma) ) (coor, 0);
            }

            //Assembling the local vectors for local tensions Component Y
            for ( int coor = 0; coor < this->M_FESpace->fieldDim(); coor++ )
            {
                (elVecSigmaY) [iloc + coor * this->M_FESpace->fe().nbFEDof()] = (* (this->M_sigma) ) (coor, 1);
            }

            //Assembling the local vectors for local tensions Component Z
            for ( int coor = 0; coor < this->M_FESpace->fieldDim(); coor++ )
            {
                (elVecSigmaZ) [iloc + coor * this->M_FESpace->fe().nbFEDof()] = (* (this->M_sigma) ) (coor, 2);
            }

        }

        super::reconstructElementaryVector ( elVecSigmaX, patchAreaR, *this->M_FESpace );
        super::reconstructElementaryVector ( elVecSigmaY, patchAreaR, *this->M_FESpace );
        super::reconstructElementaryVector ( elVecSigmaZ, patchAreaR, *this->M_FESpace );

        //Assembling the three elemental vector in the three global
        for ( UInt ic = 0; ic < this->M_FESpace->fieldDim(); ++ic )
        {
            assembleVector (*this->M_sigmaX, elVecSigmaX, this->M_FESpace->fe(), this->M_FESpace->dof(), ic, this->M_offset +  ic * totalDof );
            assembleVector (*this->M_sigmaY, elVecSigmaY, this->M_FESpace->fe(), this->M_FESpace->dof(), ic, this->M_offset +  ic * totalDof );
            assembleVector (*this->M_sigmaZ, elVecSigmaZ, this->M_FESpace->fe(), this->M_FESpace->dof(), ic, this->M_offset +  ic * totalDof );
        }
    }


    this->M_sigmaX->globalAssemble();
    this->M_sigmaY->globalAssemble();
    this->M_sigmaZ->globalAssemble();
}
예제 #20
0
파일: cylinder.cpp 프로젝트: nuraiman/lifev
void
Cylinder::run()

{
    typedef FESpace< mesh_Type, MapEpetra >       feSpace_Type;
    typedef boost::shared_ptr<feSpace_Type>       feSpacePtr_Type;
    typedef OseenSolver< mesh_Type >::vector_Type vector_Type;
    typedef boost::shared_ptr<vector_Type>        vectorPtr_Type;
    // Reading from data file
    //
    GetPot dataFile( d->data_file_name );

    //    int save = dataFile("fluid/miscellaneous/save", 1);

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

    // Boundary conditions
    BCHandler bcH;
    BCFunctionBase uZero( zero_scalar );
    std::vector<ID> zComp(1);
    zComp[0] = 3;

    BCFunctionBase uIn  (  d->getU_2d() );
    BCFunctionBase uOne (  d->getU_one() );
    BCFunctionBase uPois(  d->getU_pois() );


    //BCFunctionBase unormal(  d->get_normal() );

    //cylinder

    bcH.addBC( "Inlet",    INLET,    Essential,     Full,     uPois  , 3 );
    bcH.addBC( "Ringin",   RINGIN,   Essential,     Full,     uZero  , 3 );
    bcH.addBC( "Ringout",  RINGOUT,  Essential,     Full,     uZero  , 3 );
    bcH.addBC( "Outlet",   OUTLET,   Natural,     Full,     uZero, 3 );
    bcH.addBC( "Wall",     WALL,     Essential,   Full,     uZero, 3 );

    int numLM = 0;

    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);

    boost::shared_ptr<mesh_Type> meshPtr;
    {
        MeshPartitioner< mesh_Type >   meshPart(fullMeshPtr, d->comm);
        meshPtr = meshPart.meshPartition();
    }
    if (verbose) std::cout << std::endl;
    if (verbose) std::cout << "Time discretization order " << oseenData->dataTime()->orderBDF() << std::endl;

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

    std::string uOrder =  dataFile( "fluid/space_discretization/vel_order", "P1");
    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;


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

    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;

    UInt totalVelDof   = uFESpacePtr->map().map(Unique)->NumGlobalElements();
    UInt totalPressDof = pFESpacePtr->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 << "Calling the fluid constructor ... ";

    bcH.setOffset( "Inlet", totalVelDof + totalPressDof - 1 );

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

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

    fluid.setUp(dataFile);
    fluid.buildSystem();

    MPI_Barrier(MPI_COMM_WORLD);

    // Initialization

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


    // bdf object to store the previous solutions

    TimeAdvanceBDFNavierStokes<vector_Type> bdf;
    bdf.setup(oseenData->dataTime()->orderBDF());

    vector_Type beta( fullMap );
    vector_Type rhs ( fullMap );

#ifdef HAVE_HDF5
    ExporterHDF5<mesh_Type > ensight( dataFile, meshPtr, "cylinder", d->comm->MyPID());
#else
    ExporterEnsight<mesh_Type > ensight( dataFile, meshPtr, "cylinder", d->comm->MyPID());
#endif

    vectorPtr_Type velAndPressure ( new vector_Type(*fluid.solution(), ensight.mapType() ) );

    ensight.addVariable( ExporterData<mesh_Type>::VectorField, "velocity", uFESpacePtr,
                         velAndPressure, UInt(0) );

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

    // initialization with stokes solution

    if (d->initial_sol == "stokes")
    {
        if (verbose) std::cout << std::endl;
        if (verbose) std::cout << "Computing the stokes solution ... " << std::endl << std::endl;

        oseenData->dataTime()->setTime(t0);

        MPI_Barrier(MPI_COMM_WORLD);

        beta *= 0.;
        rhs  *= 0.;

        fluid.updateSystem(0, beta, rhs );
        fluid.iterate( bcH );

//    fluid.postProcess();

        *velAndPressure = *fluid.solution();
        ensight.postProcess( 0 );
        fluid.resetPreconditioner();
    }

    bdf.bdfVelocity().setInitialCondition( *fluid.solution() );

    // Temporal loop

    LifeChrono chrono;
    int iter = 1;

    for ( Real time = t0 + dt ; time <= tFinal + dt/2.; time += dt, iter++)
    {

        oseenData->dataTime()->setTime(time);

        if (verbose)
        {
            std::cout << std::endl;
            std::cout << "We are now at time "<< oseenData->dataTime()->time() << " s. " << std::endl;
            std::cout << std::endl;
        }

        chrono.start();

        double alpha = bdf.bdfVelocity().coefficientFirstDerivative( 0 ) / oseenData->dataTime()->timeStep();

        beta = bdf.bdfVelocity().extrapolation();
        bdf.bdfVelocity().updateRHSContribution( oseenData->dataTime()->timeStep());
        rhs  = fluid.matrixMass()*bdf.bdfVelocity().rhsContributionFirstDerivative();

        fluid.updateSystem( alpha, beta, rhs );
        fluid.iterate( bcH );

        bdf.bdfVelocity().shiftRight( *fluid.solution() );

//         if (((iter % save == 0) || (iter == 1 )))
//         {
        *velAndPressure = *fluid.solution();
        ensight.postProcess( time );
//         }
//         postProcessFluxesPressures(fluid, bcH, time, verbose);


        MPI_Barrier(MPI_COMM_WORLD);

        chrono.stop();
        if (verbose) std::cout << "Total iteration time " << chrono.diff() << " s." << std::endl;
    }

}
예제 #21
0
파일: test_bdf.cpp 프로젝트: nuraiman/lifev
// ===================================================
//! Methods
// ===================================================
void test_bdf::run()
{

    //Useful typedef
    typedef SolverAztecOO solver_type;
    typedef VectorEpetra vector_type;
    typedef boost::shared_ptr<vector_type> vector_ptrtype;

    // Reading from data file
    GetPot dataFile(Members->data_file_name.c_str());
    // Select Pid(0) to write on std output
    bool verbose = (Members->comm->MyPID() == 0);

    if (verbose)
        std::cout << "The BDF Solver" << std::flush;

    //the forcing term
    SourceFct sf;
    // the boundary conditions
    BCFunctionBase g_Ess(AnalyticalSol::u);

    BCHandler bc;

    bc.addBC("Top", TOP, Essential, Full, g_Ess, 1);
    bc.addBC("Bottom", BOTTOM, Essential, Full, g_Ess, 1);
    bc.addBC("Left", LEFT, Essential, Full, g_Ess, 1);
    bc.addBC("Right", RIGHT, Essential, Full, g_Ess, 1);
    bc.addBC("Front", FRONT, Essential, Full, g_Ess, 1);
    bc.addBC("Back", BACK, Essential, Full, g_Ess, 1);

    //=============================================================================
    //Mesh stuff
    Members->comm->Barrier();
    MeshData meshData(dataFile, ("bdf/" + discretization_section).c_str());
    boost::shared_ptr<regionMesh> fullMeshPtr( new regionMesh( Members->comm ) );
    readMesh(*fullMeshPtr,meshData);
    boost::shared_ptr<regionMesh> meshPtr;
    {
        MeshPartitioner<regionMesh> meshPart( fullMeshPtr, Members->comm );
        meshPtr = meshPart.meshPartition();
    }

    //=============================================================================
    //finite element space of the solution
    boost::shared_ptr<FESpace<regionMesh, MapEpetra> > feSpacePtr(
        new FESpace<regionMesh, MapEpetra> (
                        meshPtr, dataFile(("bdf/"+discretization_section + "/order").c_str(), "P2"), 1, Members->comm) );

    if (verbose)
        std::cout << "  Number of unknowns : "
                  << feSpacePtr->map().map(Unique)->NumGlobalElements()
                  << std::endl;

    bc.bcUpdate(*(feSpacePtr->mesh()), feSpacePtr->feBd(), feSpacePtr->dof());

    //=============================================================================
    //Fe Matrices and vectors
    MatrixElemental elmat(feSpacePtr->fe().nbFEDof(), 1, 1); //local matrix
    MatrixEpetra<double> matM(feSpacePtr->map()); //mass matrix
    boost::shared_ptr<MatrixEpetra<double> > matA_ptr(
        new MatrixEpetra<double> (feSpacePtr->map())); //stiff matrix
    VectorEpetra u(feSpacePtr->map(), Unique); // solution vector
    VectorEpetra f(feSpacePtr->map(), Unique); // forcing term vector

    LifeChrono chrono;
    //Assembling Matrix M
    Members->comm->Barrier();
    chrono.start();
    for (UInt iVol = 0; iVol < feSpacePtr->mesh()->numElements(); iVol++)
    {
        feSpacePtr->fe().updateJac(feSpacePtr->mesh()->element(iVol));
        elmat.zero();
        mass(1., elmat, feSpacePtr->fe(), 0, 0);
        assembleMatrix(matM, elmat, feSpacePtr->fe(), feSpacePtr->fe(), feSpacePtr->dof(),
                       feSpacePtr->dof(), 0, 0, 0, 0);
    }
    matM.globalAssemble();
    Members->comm->Barrier();
    chrono.stop();
    if (verbose)
        std::cout << "\n \n -- Mass matrix assembling time = " << chrono.diff() << std::endl
                  << std::endl;

    // ==========================================
    // Definition of the time integration stuff
    // ==========================================
    Real Tfin = dataFile("bdf/endtime", 10.0);
    Real delta_t = dataFile("bdf/timestep", 0.5);
    Real t0 = 1.;
    UInt ord_bdf = dataFile("bdf/order", 3);
    TimeAdvanceBDFVariableStep<VectorEpetra> bdf;
    bdf.setup(ord_bdf);

    //Initialization
    bdf.setInitialCondition<Real(*) (Real, Real, Real, Real, UInt), FESpace<regionMesh, MapEpetra> >(AnalyticalSol::u, u, *feSpacePtr, t0, delta_t);

    if (verbose) bdf.showMe();
    Members->comm->Barrier();

    //===================================================
    // post processing setup
    boost::shared_ptr<Exporter<regionMesh> > exporter;
    std::string const exporterType =  dataFile( "exporter/type", "hdf5");

#ifdef HAVE_HDF5
    if (exporterType.compare("hdf5") == 0)
    {
        exporter.reset( new ExporterHDF5<regionMesh > ( dataFile, "bdf_test" ) );
    }
    else
#endif
    {
        if (exporterType.compare("none") == 0)
        {
            exporter.reset( new ExporterEmpty<regionMesh > ( dataFile, meshPtr, "bdf_test", Members->comm->MyPID()) );
        }
        else
        {
            exporter.reset( new ExporterEnsight<regionMesh > ( dataFile, meshPtr, "bdf_test", Members->comm->MyPID()) );
        }
    }

    exporter->setPostDir( "./" );
    exporter->setMeshProcId( meshPtr, Members->comm->MyPID() );

    boost::shared_ptr<VectorEpetra> u_display_ptr(new VectorEpetra(
                                                      feSpacePtr->map(), exporter->mapType()));
    exporter->addVariable(ExporterData<regionMesh >::ScalarField, "u", feSpacePtr,
                          u_display_ptr, UInt(0));
    *u_display_ptr = u;
    exporter->postProcess(0);


    //===================================================
    //Definition of the linear solver
    SolverAztecOO az_A(Members->comm);
    az_A.setDataFromGetPot(dataFile, "bdf/solver");
    az_A.setupPreconditioner(dataFile, "bdf/prec");

    //===================================================
    // TIME LOOP
    //===================================================

    matA_ptr.reset(new MatrixEpetra<double> (feSpacePtr->map()));

    for (Real t = t0 + delta_t; t <= Tfin; t += delta_t)
    {
        Members->comm->Barrier();
        if (verbose)
            cout << "Now we are at time " << t << endl;

        chrono.start();
        //Assemble A
        Real coeff = bdf.coefficientDerivative(0) / delta_t;
        Real visc = nu(t);
        Real s = sigma(t);
        for (UInt i = 0; i < feSpacePtr->mesh()->numElements(); i++)
        {
            feSpacePtr->fe().updateFirstDerivQuadPt(feSpacePtr->mesh()->element(i));
            elmat.zero();
            mass(coeff + s, elmat, feSpacePtr->fe());
            stiff(visc, elmat, feSpacePtr->fe());
            assembleMatrix(*matA_ptr, elmat, feSpacePtr->fe(), feSpacePtr->fe(),
                           feSpacePtr->dof(), feSpacePtr->dof(), 0, 0, 0, 0);
        }

        chrono.stop();
        if (verbose)
            cout << "A has been constructed in "<< chrono.diff() << "s." << endl;

        // Handling of the right hand side
        f = (matM*bdf.rhsContribution());       //f = M*\sum_{i=1}^{orderBdf} \alpha_i u_{n-i}
        feSpacePtr->l2ScalarProduct(sf, f, t);  //f +=\int_\Omega{ volumeForces *v dV}
        Members->comm->Barrier();

        // Treatment of the Boundary conditions
        if (verbose) cout << "*** BC Management: " << endl;
        Real tgv = 1.;
        chrono.start();
        bcManage(*matA_ptr, f, *feSpacePtr->mesh(), feSpacePtr->dof(), bc, feSpacePtr->feBd(), tgv, t);
        matA_ptr->globalAssemble();
        chrono.stop();
        if (verbose) cout << chrono.diff() << "s." << endl;

        //Set Up the linear system
        Members->comm->Barrier();
        chrono.start();
        az_A.setMatrix(*matA_ptr);
        az_A.setReusePreconditioner(false);

        Members->comm->Barrier();
        az_A.solveSystem(f, u, matA_ptr);
        chrono.stop();

        bdf.shiftRight(u);

        if (verbose)
            cout << "*** Solution computed in " << chrono.diff() << "s."
                 << endl;

        Members->comm->Barrier();

        // Error in the L2
        vector_type uComputed(u, Repeated);

        Real L2_Error, L2_RelError;

        L2_Error = feSpacePtr->l2Error(AnalyticalSol::u, uComputed, t, &L2_RelError);

        if (verbose)
            std::cout << "Error Norm L2: " << L2_Error
                      << "\nRelative Error Norm L2: " << L2_RelError << std::endl;

        Members->errorNorm = L2_Error;

        //transfer the solution at time t.
        *u_display_ptr = u;
        
        matA_ptr->zero();
        
        exporter->postProcess(t);
    }



}
예제 #22
0
void Heart::computeRhs ( vector_Type& rhs,
                         HeartMonodomainSolver< mesh_Type >& electricModel,
                         boost::shared_ptr< HeartIonicSolver< mesh_Type > > ionicModel,
                         HeartMonodomainData& data )
{
    bool verbose = (M_heart_fct->M_comm->MyPID() == 0);
    if (verbose)
    {
        std::cout << "  f-  Computing Rhs ...        " << "\n" << std::flush;
    }
    LifeChrono chrono;
    chrono.start();

    //! u, w with repeated map
    vector_Type uVecRep (electricModel.solutionTransmembranePotential(), Repeated);
    ionicModel->updateRepeated();
    VectorElemental elvec_Iapp ( electricModel.potentialFESpace().fe().nbFEDof(), 2 ),
                    elvec_u ( electricModel.potentialFESpace().fe().nbFEDof(), 1 ),
                    elvec_Iion ( electricModel.potentialFESpace().fe().nbFEDof(), 1 );

    for (UInt iVol = 0; iVol < electricModel.potentialFESpace().mesh()->numVolumes(); ++iVol)
    {
        electricModel.potentialFESpace().fe().updateJacQuadPt ( electricModel.potentialFESpace().mesh()->volumeList ( iVol ) );
        elvec_Iapp.zero();
        elvec_u.zero();
        elvec_Iion.zero();

        UInt eleIDu = electricModel.potentialFESpace().fe().currentLocalId();
        UInt nbNode = ( UInt ) electricModel.potentialFESpace().fe().nbFEDof();

        //! Filling local elvec_u with potential values in the nodes
        for ( UInt iNode = 0 ; iNode < nbNode ; iNode++ )
        {
            Int  ig = electricModel.potentialFESpace().dof().localToGlobalMap ( eleIDu, iNode );
            elvec_u.vec() [ iNode ] = uVecRep[ig];
        }

        ionicModel->updateElementSolution (eleIDu);
        ionicModel->computeIonicCurrent (data.membraneCapacitance(), elvec_Iion, elvec_u, electricModel.potentialFESpace() );

        //! Computing the current source of the righthand side, repeated
        AssemblyElemental::source (M_heart_fct->stimulus(),
                                   elvec_Iapp,
                                   electricModel.potentialFESpace().fe(),
                                   data.time(),
                                   0);
        AssemblyElemental::source (M_heart_fct->stimulus(),
                                   elvec_Iapp,
                                   electricModel.potentialFESpace().fe(),
                                   data.time(),
                                   1);

        //! Assembling the righthand side
        for ( UInt i = 0 ; i < electricModel.potentialFESpace().fe().nbFEDof() ; i++ )
        {
            Int  ig = electricModel.potentialFESpace().dof().localToGlobalMap ( eleIDu, i );
            rhs.sumIntoGlobalValues (ig, (data.conductivityRatio() * elvec_Iapp.vec() [i] +
                                          elvec_Iapp.vec() [i + nbNode]) /
                                     (1 + data.conductivityRatio() ) + data.volumeSurfaceRatio() * elvec_Iion.vec() [i] );
        }
    }
    rhs.globalAssemble();
    Real coeff = data.volumeSurfaceRatio() * data.membraneCapacitance() / data.timeStep();
    vector_Type tmpvec (electricModel.solutionTransmembranePotential() );
    tmpvec *= coeff;
    rhs += electricModel.massMatrix() * tmpvec;
    MPI_Barrier (MPI_COMM_WORLD);
    chrono.stop();
    if (verbose)
    {
        std::cout << "done in " << chrono.diff() << " s." << std::endl;
    }
}
예제 #23
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;
        }
    }
}
예제 #24
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;
    }
}
예제 #25
0
파일: main.cpp 프로젝트: Danniel-UCAS/lifev
Int
main ( Int argc, char** argv )
{
    //Setup main communicator
    boost::shared_ptr< Epetra_Comm > comm;

    //Setup MPI variables
    Int numberOfProcesses (1);
    Int rank (0);

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

    MPI_Comm_size ( MPI_COMM_WORLD, &numberOfProcesses );
    MPI_Comm_rank ( MPI_COMM_WORLD, &rank );
#endif

    if ( rank == 0 )
    {
        std::cout << std::endl;
        std::cout << "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" << std::endl;
        std::cout << " THE ZERO DIMENSIONAL SOLVER IS AN ALPHA VERSION UNDER STRONG DEVELOPMENT" << std::endl;
        std::cout << "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" << std::endl << std::endl;

        std::cout << "MPI Processes: " << numberOfProcesses << std::endl;
    }

#ifdef HAVE_MPI
    if ( numberOfProcesses > 1 )
    {
        if ( rank == 0 )
        {
            std::cout << "test_ZeroDimensional not enabled in parallel, failing gracefully." << std::endl;
            std::cout << "MPI Finalization" << std::endl;
        }
        MPI_Finalize();
        return EXIT_FAILURE;
    }
#endif

#ifdef EPETRA_MPI
    if ( rank == 0 )
    {
        std::cout << "MPI Epetra Initialization ... " << std::endl;
    }
    comm.reset ( new Epetra_MpiComm ( MPI_COMM_WORLD ) );
#else
    std::cout << "SERIAL Epetra Initialization ... " << std::endl;
    comm.reset ( new Epetra_SerialComm() );
#endif

    bool exitFlag = EXIT_SUCCESS;

#if ( defined(HAVE_NOX_THYRA) && defined(HAVE_TRILINOS_RYTHMOS) )
    // Command line parameters
    GetPot commandLine ( argc, argv );
    const bool check = commandLine.search ( 2, "-c", "--check" );
    string fileName  = commandLine.follow ( "data", 2, "-f", "--file" );

    // SetupData
    GetPot dataFile ( fileName  + ".dat" );

    std::string circuitDataFile = dataFile ( "0D_Model/CircuitDataFile", "./inputFile.dat" );
    BCInterface0D< ZeroDimensionalBCHandler, ZeroDimensionalData >  zeroDimensionalBC;
    zeroDimensionalBC.createHandler();
    zeroDimensionalBC.fillHandler ( circuitDataFile, "Files" );

    boost::shared_ptr< ZeroDimensionalData > zeroDimensionalData ( new ZeroDimensionalData );
    zeroDimensionalData->setup ( dataFile, zeroDimensionalBC.handler() );

    boost::shared_ptr< ZeroDimensionalSolver > zeroDimensionalSolver ( new ZeroDimensionalSolver ( zeroDimensionalData->unknownCounter(), comm, zeroDimensionalData->circuitData() ) );
    zeroDimensionalSolver->setup ( zeroDimensionalData->solverData() );

    zeroDimensionalData->showMe();

    // SetupModel
    zeroDimensionalData->dataTime()->setInitialTime (0);
    zeroDimensionalData->initializeSolution();

    // Create output folder
    if ( comm->MyPID() == 0 )
    {
        mkdir ( "output", 0777 );
    }

    // Save initial solution
    zeroDimensionalData->saveSolution();

    zeroDimensionalData->dataTime()->updateTime();
    zeroDimensionalData->dataTime()->setInitialTime (zeroDimensionalData->dataTime()->time() );

    // Definitions for the time loop
    LifeChrono chronoTotal;
    LifeChrono chronoSystem;
    LifeChrono chronoIteration;

    Int count = 0;
    chronoTotal.start();

    for ( ; zeroDimensionalData->dataTime()->canAdvance() ; zeroDimensionalData->dataTime()->updateTime(), ++count )
    {
        std::cout << std::endl << "--------- Iteration " << count << " time = " << zeroDimensionalData->dataTime()->time() << std::endl;

        chronoIteration.start();
        chronoSystem.start();

        zeroDimensionalSolver->takeStep ( zeroDimensionalData->dataTime()->previousTime(), zeroDimensionalData->dataTime()->time() );

        chronoSystem.stop();

        //Save solution
        zeroDimensionalData->saveSolution();

        chronoIteration.stop();

        std::cout << " System solved in " << chronoSystem.diff() << " s, (total time " << chronoIteration.diff() << " s)." << std::endl;
    }

    chronoTotal.stop();
    std::cout << std::endl << " Simulation ended successfully in " << chronoTotal.diff()  << " s" << std::endl;

    // Final check
    if ( check )
    {
        bool ok = true;

        ok = ok && checkValue ( 0.001329039627, zeroDimensionalData->circuitData()->Nodes()->nodeListAt (1)->voltage() );
        ok = ok && checkValue ( 0.000787475119, zeroDimensionalData->circuitData()->Elements()->elementListAt (1)->current() );
        if (ok)
        {
            std::cout << " Test succesful" << std::endl;
            exitFlag = EXIT_SUCCESS;
        }
        else
        {
            std::cout << " Test unsuccesful" << std::endl;
            exitFlag = EXIT_FAILURE;
        }
    }
#else
    std::cout << "ZeroDimensional requires configuring Trilinos with Rythmos/NOX/Thyra. Skipping test." << std::endl;
    exitFlag = EXIT_SUCCESS;
#endif /* HAVE_NOX_THYRA && HAVE_TRILINOS_RYTHMOS */

    if (rank == 0)
    {
        std::cout << "End Result: TEST PASSED" << std::endl;
    }

#ifdef HAVE_MPI
    if ( rank == 0 )
    {
        std::cout << "MPI Finalization" << std::endl;
    }
    MPI_Finalize();
#endif

    return exitFlag;
}