bool CommonSolverUmfpack::solve(Matrix *mat, double *res) { printf("UMFPACK solver\n"); CSCMatrix *Acsc = NULL; if (CooMatrix *mcoo = dynamic_cast<CooMatrix*>(mat)) Acsc = new CSCMatrix(mcoo); 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(); // solve umfpack_di_defaults(control_array); /* symbolic analysis */ void *symbolic, *numeric; int status_symbolic = umfpack_di_symbolic(size, size, Acsc->get_Ap(), Acsc->get_Ai(), NULL, &symbolic, control_array, info_array); print_status(status_symbolic); /* LU factorization */ int status_numeric = umfpack_di_numeric(Acsc->get_Ap(), Acsc->get_Ai(), Acsc->get_Ax(), symbolic, &numeric, control_array, info_array); print_status(status_numeric); umfpack_di_free_symbolic(&symbolic); double *x = new double[size]; /* solve system */ int status_solve = umfpack_di_solve(UMFPACK_A, Acsc->get_Ap(), Acsc->get_Ai(), Acsc->get_Ax(), x, res, numeric, control_array, info_array); print_status(status_solve); umfpack_di_free_numeric(&numeric); if (symbolic) umfpack_di_free_symbolic(&symbolic); if (numeric) umfpack_di_free_numeric(&numeric); memcpy(res, x, size*sizeof(double)); delete[] x; if (!dynamic_cast<CSCMatrix*>(mat)) delete Acsc; }
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; }