Exemplo n.º 1
0
// ===================================================
// 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() );
}
Exemplo n.º 2
0
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;
}