inline int applyInverse (const VectorEpetra& X, VectorEpetra& Y) { return ApplyInverse (X.epetraVector(), Y.epetraVector() ); }
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() ); }
/*! \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() ); }