static void
ICSolve(const VECTOR_int &pntr, const VECTOR_int &indx, 
    const VECTOR_double &val, VECTOR_double &dest)
{
  int M = dest.size();
  VECTOR_double work(M);

  int descra[9];

  descra[0] = 0;

  // lower diag
  descra[1] = 1;
  descra[2] = 0;

  F77NAME(dcscsm) (0, M, 1, 1, NULL, 1.0,
           descra, &val(0), &indx(0), &pntr(0),
           &dest(0), M, 0.0, &dest(1), M,
           &work(0), M);

  // lower diag transpose
  F77NAME(dcscsm) (1, M, 1, 1, NULL, 1.0,
           descra, &val(0), &indx(0), &pntr(0),
           &dest(0), M, 0.0, &dest(1), M,
           &work(0), M);
}
Beispiel #2
0
bool CommonSolverSparseLib::_solve(Matrix *mat, double *res)
{
    printf("SparseLib++ solver\n");

    CSCMatrix *Acsc = NULL;

    if (CooMatrix *mcoo = dynamic_cast<CooMatrix*>(mat))
        Acsc = new CSCMatrix(mcoo);
    else if (DenseMatrix *mden = dynamic_cast<DenseMatrix *>(mat))
        Acsc = new CSCMatrix(mden);
    else if (CSCMatrix *mcsc = dynamic_cast<CSCMatrix*>(mat))
        Acsc = mcsc;
    else if (CSRMatrix *mcsr = dynamic_cast<CSRMatrix*>(mat))
        Acsc = new CSCMatrix(mcsr);
    else
        _error("Matrix type not supported.");

    int nnz = Acsc->get_nnz();
    int size = Acsc->get_size();

    CompCol_Mat_double Acc = CompCol_Mat_double(size, size, nnz,
                                                Acsc->get_Ax(), Acsc->get_Ai(), Acsc->get_Ap());

    // rhs
    VECTOR_double rhs(res, size);

    // preconditioner
    CompCol_ILUPreconditioner_double ILU(Acc);
    VECTOR_double xv = ILU.solve(rhs);

    // method
    int result = -1;
    switch (method)
    {
    case HERMES_CommonSolverSparseLibSolver_ConjugateGradientSquared:
        result = CGS(Acc, xv, rhs, ILU, maxiter, tolerance);
        break;
    case CommonSolverSparseLibSolver_RichardsonIterativeRefinement:
        result = IR(Acc, xv, rhs, ILU, maxiter, tolerance);
        break;
    default:
        _error("SparseLib++ error. Method is not defined.");
    }

    if (result == 0)
        printf("SparseLib++ solver: maxiter: %i, tol: %e\n", maxiter, tolerance);
    else
        _error("SparseLib++ error.");

    double *x;
    x = (double*) malloc(size * sizeof(double));

    for (int i = 0 ; i < xv.size() ; i++)
        x[i] = xv(i);

    memcpy(res, x, size*sizeof(double));
    delete[] x;

    if (!dynamic_cast<CSCMatrix*>(mat))
        delete Acsc;
}