// =================================================== // Methods // =================================================== Int SolverAztecOO::solve ( vector_type& solution, const vector_type& rhs ) { M_solver.SetLHS ( &solution.epetraVector() ); // The Solver from Aztecoo takes a non const (because of rescaling?) // We should be careful if you use scaling Epetra_FEVector* rhsVectorPtr ( const_cast<Epetra_FEVector*> (&rhs.epetraVector() ) ); M_solver.SetRHS ( rhsVectorPtr ); Int maxiter (M_maxIter); Real mytol (M_tolerance); Int status; if ( isPreconditionerSet() && M_preconditioner->preconditionerType().compare ("AztecOO") ) { M_solver.SetPrecOperator (M_preconditioner->preconditioner() ); } status = M_solver.Iterate (maxiter, mytol); #ifdef HAVE_LIFEV_DEBUG M_displayer->comm()->Barrier(); M_displayer->leaderPrint ( " o- Number of iterations = ", M_solver.NumIters() ); M_displayer->leaderPrint ( " o- Norm of the true residual = ", M_solver.TrueResidual() ); M_displayer->leaderPrint ( " o- Norm of the true ratio = ", M_solver.ScaledResidual() ); #endif /* try to solve again (reason may be: -2 "Aztec status AZ_breakdown: numerical breakdown" -3 "Aztec status AZ_loss: loss of precision" -4 "Aztec status AZ_ill_cond: GMRES hessenberg ill-conditioned" */ if ( status <= -2 ) { maxiter = M_maxIter; mytol = M_tolerance; Int oldIter = M_solver.NumIters(); status = M_solver.Iterate (maxiter, mytol); #ifdef HAVE_LIFEV_DEBUG M_displayer->comm()->Barrier(); M_displayer->leaderPrint ( " o- Second run: number of iterations = ", M_solver.NumIters() ); M_displayer->leaderPrint ( " o- Norm of the true residual = ", M_solver.TrueResidual() ); M_displayer->leaderPrint ( " o- Norm of the true ratio = ", M_solver.ScaledResidual() ); #endif return ( M_solver.NumIters() + oldIter ); } return ( M_solver.NumIters() ); }
Real SolverAztecOO::computeResidual ( vector_type& solution, vector_type& rhs ) { vector_type Ax ( solution.map() ); vector_type res ( rhs ); M_solver.GetUserMatrix()->Apply ( solution.epetraVector(), Ax.epetraVector() ); res.epetraVector().Update ( 1, Ax.epetraVector(), -1 ); Real residual; res.norm2 ( &residual ); return residual; }