#include "BSprivate.h"

/*@ BSpar_solve - General solver of a system of equations preconditioned 
                  by one of several preconditioners and using one of several
                  possible methods.  The rhs can be a block of vectors.

    Input Parameters:
.   A - a sparse matrix
.   fact_A - the incomplete factored version of A, if any
.   comm_A - the communication structure for A
.   rhs - the contiguous block of vectors forming the rhs
.   residual - the final computed residual

    Output Parameters:
.   x - the contiguous block of vectors containing the solution (can
	contain an initial guess if BSctx_set_guess() is set.

Now specified in procinfo context:
.   pre_option - the preconditioner to use:
$           PRE_ICC: incomplete Cholesky factorization
$           PRE_ILU: incomplete LU factorization
$           PRE_SSOR: Successive over relaxation
$           PRE_BJACOBI: Block Jacobi
.   err_tol - the tolerance to which to solve the problem
              stop if the estimated norm of the residual divided by
              the norm of the rhs is less than err_tol
.   max_iter - the maximum number of iterations to take
.   guess - if TRUE, then initialize out_x to 0, otherwise the program
            assumes that out_x contains an initial guess
.   procinfo - the usual processor stuff

    Returns:
    The number of iterations or a negative number indicating the number
    of iterations prior to finding that the matrix (or preconditioner) 
    is not positive definite.

    Notes:
    The preconditioners must be computed prior to calling BSpar_solve.
    For more information on the preconditioners, see the manual or
	BSctx_set_pre().

 @*/
int BSpar_solve(BSpar_mat *A, BSpar_mat *fact_A, BScomm *comm_A,
	FLOAT *rhs, FLOAT *x, FLOAT *residual, BSprocinfo *procinfo)
{
	int num_iter;

	/* Do some error checking */
	if((A->icc_storage)&&(!procinfo->single)) {
		if(comm_A->num_rhs!=procinfo->num_rhs) {
			MY_SETERRCN(PAR_SOLVE_ERROR,"num_rhs in context does not agree num_rhs in comm\n");
		}
	}
	if((procinfo->scaling)&&(A->scale_diag==NULL)) {
		MY_SETERRCN(SCALING_ERROR,"Scaling set in context however matrix not scaled\n");
	}

	if ((procinfo->print) && (PSISROOT(procinfo))) {
		BSctx_print(procinfo);
	}

	if(procinfo->method==GMRES) {
		num_iter = BSpar_gmres(procinfo->num_rhs,A,fact_A,comm_A,rhs,x,
			procinfo->preconditioner,procinfo->restart,
			procinfo->residual_tol,procinfo->max_iterations,
			residual,procinfo->guess,procinfo);
	} else {
		num_iter = BSpar_sym_solve(procinfo->num_rhs,A,fact_A,
			comm_A,rhs,x,procinfo->preconditioner,
			procinfo->residual_tol,procinfo->max_iterations,
			residual,procinfo->guess,procinfo);
	}
	return(num_iter);
}


syntax highlighted by Code2HTML, v. 0.9.1