예제 #1
0
VectorEpetra<T>::VectorEpetra ( VectorEpetra const& v )
    :
    super( v ),
    M_emap( v.Map() ),
    M_vec( v.vec() )

{
    this->M_is_initialized = true;
    checkInvariants();
}
예제 #2
0
void
assembleVector ( VectorEpetra&    globalVector,
                 const UInt&      elementID,
                 VectorElemental&         localVector,
                 const UInt&      feNbDof,
                 const DofType&   dof,
                 Int              block,
                 Int              offset = 0)

{
    VectorElemental::vector_view localView = localVector.block ( block );

    UInt iGlobalID;

    for ( UInt i (0) ; i < feNbDof ; ++i )
    {
        iGlobalID = dof.localToGlobalMap ( elementID, i ) + offset;
        globalVector.sumIntoGlobalValues ( iGlobalID, localView ( i ) );
    }
}
예제 #3
0
Int NonLinearRichardson( VectorEpetra& sol,
                      Fct&        functional,
                      Real        abstol,
                      Real        reltol,
                      UInt&       maxit,
                      Real        eta_max,
                      Int         NonLinearLineSearch,
                      std::ofstream& out_res,
                      const Real& time,
                      UInt iter = UInt(0) )
{
    /*
        */

    /*
      max_increase_res: maximum number of successive increases in residual
      before failure is reported
    */

//    const Int max_increase_res = 5;

    /*
      Parameters for the linear solver, gamma: Default value = 0.9
    */

    const Real gamma   = 0.9;

    //----------------------------------------------------------------------

    bool const verbose(sol.comm().MyPID() == 0);

    //UInt iter = 0;

    VectorEpetra residual ( sol.map() );
    VectorEpetra step     ( sol.map() );

    step *= 0.;

    Real normResOld = 1;

    if (verbose)
    {
        //std::cout << "------------------------------------------------------------------" << std::endl;
        std::cout << std::endl;
        std::cout << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl;
        std::cout << "      Non-Linear Richardson: starting          " << std::endl;
        std::cout << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
        std::cout << std::endl;
        //std::cout << "------------------------------------------------------------------" << std::endl;
    }
    functional.evalResidual( residual, sol, iter );

    Real normRes      = residual.normInf();
    Real stop_tol     = abstol + reltol*normRes;
    Real linearRelTol = std::fabs(eta_max);
    Real eta_old;
    Real eta_new;
    Real ratio;
    Real slope;
    Real linres;
    Real lambda;

    //

    Real solNormInf(sol.normInf());
    Real stepNormInf;
    if (verbose)
    {
        out_res << std::scientific;
        out_res << "# time = ";
        out_res << time << "   " << "initial norm_res " <<  normRes
        << " stop tol = " << stop_tol
        << "initial norm_sol "
        << solNormInf << std::endl;
        out_res << "#iter      disp_norm       step_norm       residual_norm" << std::endl;
    }
    while ( normRes > stop_tol && iter < maxit )
    {
        if (verbose)
        {
            std::cout << std::endl;
            //std::cout << "------------------------------------------------------------------" << std::endl;
            std::cout << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl;
            std::cout << "      Non-Linear Richardson: iteration  =      " << iter << std::endl
                      << "                             residual   =      " << normRes << std::endl
                      << "                             tolerance  =      " << stop_tol << std::endl;
            std::cout << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
            std::cout << std::endl;
            //std::cout << "------------------------------------------------------------------" << std::endl;
            //std::cout << std::endl;
        }

        iter++;

        ratio      = normRes/normResOld;
        normResOld = normRes;
        normRes    = residual.normInf();

        residual *= -1;
        functional.solveJac(step, residual, linearRelTol); // J*step = -R

        solNormInf = sol.normInf();
        stepNormInf = step.normInf();
        if (verbose)
        {
            out_res   << std::setw(5) << iter
            << std::setw(15) << solNormInf
            << std::setw(15) << stepNormInf;
        }
        linres = linearRelTol;

        lambda = 1.;
        slope  = normRes * normRes * ( linres * linres - 1 );

        Int status(EXIT_SUCCESS);
        switch ( NonLinearLineSearch )
        {
        case 0: // no NonLinearLineSearch
            sol += step;
            functional.evalResidual( residual, sol, iter);
//                normRes = residual.NormInf();
            break;
        case 1:
            status = NonLinearLineSearchParabolic( functional, residual, sol, step, normRes, lambda, iter, verbose );
            break;
        case 2:  // recommended
            status = NonLinearLineSearchCubic( functional, residual, sol, step, normRes, lambda, slope, iter, verbose );
            break;
        default:
            std::cout << "Unknown NonLinearLineSearch \n";
            status = EXIT_FAILURE;
        }

        if (status == EXIT_FAILURE)
            return status;



        normRes = residual.normInf();

        if (verbose)
            out_res << std::setw(15) << normRes << std::endl;

        if ( eta_max > 0 )
        {
            eta_old = linearRelTol;
            eta_new = gamma * ratio * ratio;
            if ( gamma * eta_old * eta_old > .1 )
            {
                eta_new = std::max<Real>( eta_new, gamma * eta_old * eta_old );
            }
            linearRelTol = std::min<Real>( eta_new, eta_max );
            linearRelTol = std::min<Real>( eta_max,
                                           std::max<Real>( linearRelTol,
                                                           .5 * stop_tol / normRes ) );
            //if (verbose)
            //    std::cout << "    Newton: forcing term eta = " << linearRelTol << std::endl;
        }

    }

    if ( normRes > stop_tol )
    {
        if (verbose)
            std::cout << "!!! NonLinRichardson: convergence fails" << std::endl;
        maxit = iter;
        return EXIT_FAILURE;
    }

    if (verbose)
    {
        std::cout << std::endl;
        //std::cout << "------------------------------------------------------------------" << std::endl;
        std::cout << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl;
        std::cout << "      Non-Linear Richardson: convergence =     " << normRes << std::endl
                  << "                             iterations  =     " << iter << std::endl;
        std::cout << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
        std::cout << std::endl;
        //std::cout << "------------------------------------------------------------------" << std::endl;
    }
    maxit = iter;

    return EXIT_SUCCESS;
}
예제 #4
0
std::pair<int, typename SolverNonLinearTrilinos<T>::real_type>
SolverNonLinearTrilinos<T>::solve ( sparse_matrix_ptrtype&  jac_in,  // System Jacobian Matrix
                                    vector_ptrtype& x_in,    // Solution vector
                                    vector_ptrtype& r_in,    // Residual vector
                                    const double,              // Stopping tolerance
                                    const unsigned int )
{
    //printf("Entering solve...\n");
    MatrixEpetra* jac = dynamic_cast<MatrixEpetra *>( jac_in.get() );
    VectorEpetra<T>* x  = dynamic_cast<VectorEpetra<T>*>( x_in.get() );

    // We cast to pointers so we can be sure that they succeeded
    // by comparing the result against NULL.
    //    assert(jac != NULL); assert(jac->mat() != NULL);
    //    assert(x   != NULL); assert(x->vec()   != NULL);
    //    assert(r   != NULL); assert(r->vec()   != NULL);

    // Create the top level parameter list
    Teuchos::RCP<Teuchos::ParameterList> nlParamsPtr =
        Teuchos::rcp( new Teuchos::ParameterList );
    Teuchos::ParameterList& nlParams = *( nlParamsPtr.get() );

    // Set the nonlinear solver method
    nlParams.set( "Nonlinear Solver", "Line Search Based" );

    // Set the printing parameters in the "Printing" sublist
    Teuchos::ParameterList& printParams = nlParams.sublist( "Printing" );
    printParams.set( "Output Precision", 10 );
    printParams.set( "Output Processor", 0 );
    printParams.set( "Output Information",
                     NOX::Utils::OuterIteration +
                     NOX::Utils::OuterIterationStatusTest +
                     NOX::Utils::InnerIteration +
                     NOX::Utils::Parameters +
                     NOX::Utils::Details +
                     NOX::Utils::Warning );

    // start definition of nonlinear solver parameters
    // Sublist for line search
    Teuchos::ParameterList& searchParams = nlParams.sublist( "Line Search" );
    searchParams.set( "Method", "Polynomial" );

    // Sublist for direction
    Teuchos::ParameterList& dirParams = nlParams.sublist( "Direction" );
    dirParams.set( "Method", "Newton" );

    Teuchos::ParameterList& newtonParams = dirParams.sublist( "Newton" );
    newtonParams.set( "Forcing Term Method", "Constant" );

    // Sublist for linear solver for the Newton method
    Teuchos::ParameterList& lsParams = newtonParams.sublist( "Linear Solver" );
    lsParams.set( "Aztec Solver", "GMRES" );
    lsParams.set( "Max Iterations", 800 );
    lsParams.set( "Tolerance", 1e-7 );
    lsParams.set( "Output Frequency", 50 );
    lsParams.set( "Aztec Preconditioner", "ilu" );

    // -> A : Jacobian for the first iteration
    // -> InitialGuess : first value x0
    //printf("convert vectors...\n");
    boost::shared_ptr<Epetra_Vector> InitialGuess = x->epetraVector();

    // has_ownership=false in order to let the matrix jac be destroyed by boost
    // and not by Teuchos::RCP
    Teuchos::RCP<Epetra_CrsMatrix> A =
        Teuchos::rcp( ( ( boost::shared_ptr<Epetra_CrsMatrix> )( jac->matrix() ) ).get(),false );

    //std::cout << "A.has_ownership()=" << A.has_ownership() << std::endl;

    Teuchos::RCP<NOX::Epetra::Interface::Required> iReq =
        Teuchos::rcp( new SolverNonLinearTrilinosInterface( this ) );
    Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac =
        Teuchos::rcp( new SolverNonLinearTrilinosInterface( this ) );
    Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> linSys =
        Teuchos::rcp( new NOX::Epetra::LinearSystemAztecOO( printParams,
                      lsParams,
                      iReq,
                      iJac,
                      A,
                      *InitialGuess ) );

    // Need a NOX::Epetra::Vector for constructor
    NOX::Epetra::Vector noxInitGuess( *InitialGuess, NOX::DeepCopy );
    Teuchos::RCP<NOX::Epetra::Group> grpPtr =
        Teuchos::rcp( new NOX::Epetra::Group( printParams,
                      iReq,
                      noxInitGuess,
                      linSys ) );

    // Set up the status tests
    Teuchos::RCP<NOX::StatusTest::NormF> testNormF =
        Teuchos::rcp( new NOX::StatusTest::NormF( 1.0e-7 ) );
    Teuchos::RCP<NOX::StatusTest::MaxIters> testMaxIters =
        Teuchos::rcp( new NOX::StatusTest::MaxIters( 20 ) );

    // this will be the convergence test to be used
    Teuchos::RCP<NOX::StatusTest::Combo> combo =
        Teuchos::rcp( new NOX::StatusTest::Combo( NOX::StatusTest::Combo::OR,
                      testNormF, testMaxIters ) );

    // Create the solver
    Teuchos::RCP<NOX::Solver::Generic> solver =
        NOX::Solver::buildSolver( grpPtr, combo, nlParamsPtr );

    // Solve the nonlinesar system
    NOX::StatusTest::StatusType status = solver->solve();

    if ( NOX::StatusTest::Converged  != status )
        std::cout << "\n" << "-- NOX solver did not converged --" << "\n";

    else
        std::cout << "\n" << "-- NOX solver converged --" << "\n";

    // Print the answer
    std::cout << "\n" << "-- Parameter List From Solver --" << "\n";
    solver->getList().print( cout );

    // Get the Epetra_Vector with the final solution from the solver
    const NOX::Epetra::Group & finalGroup =
        dynamic_cast<const NOX::Epetra::Group&>( solver->getSolutionGroup() );
    const Epetra_Vector & finalSolution =
        ( dynamic_cast<const NOX::Epetra::Vector&>( finalGroup.getX() ) ).getEpetraVector();

    //cout << "Computed solution : " << endl;
    //cout << finalSolution;
    x_in = boost::shared_ptr<VectorEpetra<T> > ( new VectorEpetra<T>( &finalSolution ) );

    //std::cout << "InitialGuess.use_count()=" << InitialGuess.use_count() << std::endl;
    //std::cout << "jac.use_count()=" << jac->matrix().use_count() << std::endl;
    //std::cout << "x_in.use_count()=" << x_in.use_count() << std::endl;

    return std::make_pair( 1,finalGroup.getNormF() );
}
예제 #5
0
 inline int applyInverse (const VectorEpetra& X, VectorEpetra& Y)
 {
     return ApplyInverse (X.epetraVector(), Y.epetraVector() );
 }
예제 #6
0
    /*!
    \param In
       X - A VectorEpetra to multiply with matrix.
    \param Out
       Y -A VectorEpetra containing result.

    \return Integer error code, set to 0 if successful.
    */
    inline int apply (const VectorEpetra& X, VectorEpetra& Y) const
    {
        return Apply (X.epetraVector(), Y.epetraVector() );
    }