VectorEpetra<T>::VectorEpetra ( VectorEpetra const& v ) : super( v ), M_emap( v.Map() ), M_vec( v.vec() ) { this->M_is_initialized = true; checkInvariants(); }
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 ) ); } }
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; }
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() ); }
inline int applyInverse (const VectorEpetra& X, VectorEpetra& Y) { return ApplyInverse (X.epetraVector(), Y.epetraVector() ); }
/*! \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() ); }