예제 #1
0
 inline int applyInverse (const VectorEpetra& X, VectorEpetra& Y)
 {
     return ApplyInverse (X.epetraVector(), Y.epetraVector() );
 }
예제 #2
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() );
}
예제 #3
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() );
    }