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; }
int main(int argc, char *argv[]) { int ret = 0; int n; int nnz; std::map<unsigned int, MatrixEntry> ar_mat; std::map<unsigned int, double > ar_rhs; double* sln = nullptr; switch(atoi(argv[2])) { case 1: if(read_matrix_and_rhs((char*)"in/linsys-1", n, nnz, ar_mat, ar_rhs) != 0) throw Hermes::Exceptions::Exception("Failed to read the matrix and rhs."); break; case 2: if(read_matrix_and_rhs((char*)"in/linsys-2", n, nnz, ar_mat, ar_rhs) != 0) throw Hermes::Exceptions::Exception("Failed to read the matrix and rhs."); break; case 3: if(read_matrix_and_rhs((char*)"in/linsys-3", n, nnz, ar_mat, ar_rhs) != 0) throw Hermes::Exceptions::Exception("Failed to read the matrix and rhs."); break; } if(strcasecmp(argv[1], "petsc") == 0) { #ifdef WITH_PETSC PetscMatrix<double> mat; PetscVector<double> rhs; build_matrix(n, ar_mat, ar_rhs, &mat, &rhs); PetscLinearMatrixSolver<double> solver(&mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "petsc-block") == 0) { #ifdef WITH_PETSC PetscMatrix<double> mat; PetscVector<double> rhs; build_matrix_block(n, ar_mat, ar_rhs, &mat, &rhs); PetscLinearMatrixSolver<double> solver(&mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "umfpack") == 0) { #ifdef WITH_UMFPACK CSCMatrix<double> mat; SimpleVector<double> rhs; build_matrix(n, ar_mat, ar_rhs, &mat, &rhs); UMFPackLinearMatrixSolver<double> solver(&mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "umfpack-block") == 0) { #ifdef WITH_UMFPACK CSCMatrix<double> mat; SimpleVector<double> rhs; build_matrix_block(n, ar_mat, ar_rhs, &mat, &rhs); UMFPackLinearMatrixSolver<double> solver(&mat, &rhs); mat.export_to_file("matrix", "A", MatrixExportFormat::EXPORT_FORMAT_PLAIN_ASCII); rhs.export_to_file("vector", "b", MatrixExportFormat::EXPORT_FORMAT_PLAIN_ASCII); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "paralution") == 0) { #ifdef WITH_PARALUTION ParalutionMatrix<double> mat; ParalutionVector<double> rhs; build_matrix(n, ar_mat, ar_rhs, &mat, &rhs); Hermes::Solvers::IterativeParalutionLinearMatrixSolver<double> solver(&mat, &rhs); if(atoi(argv[2]) != 1) solver.set_solver_type(BiCGStab); solver.set_precond(new ParalutionPrecond<double>(ILU)); // Tested as of 13th August 2013. solver.set_max_iters(atoi(argv[2]) == 1 ? 1 : atoi(argv[2]) == 2 ? 2 : 5); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "paralution-block") == 0) { #ifdef WITH_PARALUTION ParalutionMatrix<double> mat; ParalutionVector<double> rhs; build_matrix_block(n, ar_mat, ar_rhs, &mat, &rhs); Hermes::Solvers::IterativeParalutionLinearMatrixSolver<double> solver(&mat, &rhs); solver.set_precond(new ParalutionPrecond<double>(ILU)); solver.set_max_iters(10000); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "superlu") == 0) { #ifdef WITH_SUPERLU CSCMatrix<double> mat; SimpleVector<double> rhs; build_matrix(n, ar_mat, ar_rhs, &mat, &rhs); Hermes::Solvers::SuperLUSolver<double> solver(&mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "superlu-block") == 0) { #ifdef WITH_SUPERLU CSCMatrix<double> mat; SimpleVector<double> rhs; build_matrix_block(n, ar_mat, ar_rhs, &mat, &rhs); Hermes::Solvers::SuperLUSolver<double> solver(&mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "aztecoo") == 0) { #ifdef WITH_TRILINOS EpetraMatrix<double> mat; EpetraVector<double> rhs; build_matrix(n, ar_mat, ar_rhs, &mat, &rhs); AztecOOSolver<double> solver(&mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "aztecoo-block") == 0) { #ifdef WITH_TRILINOS EpetraMatrix<double> mat; EpetraVector<double> rhs; build_matrix_block(n, ar_mat, ar_rhs, &mat, &rhs); AztecOOSolver<double> solver(&mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "amesos") == 0) { #ifdef WITH_TRILINOS EpetraMatrix<double> mat; EpetraVector<double> rhs; build_matrix(n, ar_mat, ar_rhs, &mat, &rhs); if(AmesosSolver<double>::is_available("Klu")) { AmesosSolver<double> solver("Klu", &mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); } #endif } else if(strcasecmp(argv[1], "amesos-block") == 0) { #ifdef WITH_TRILINOS EpetraMatrix<double> mat; EpetraVector<double> rhs; build_matrix_block(n, ar_mat, ar_rhs, &mat, &rhs); if(AmesosSolver<double>::is_available("Klu")) { AmesosSolver<double> solver("Klu", &mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); } #endif } else if(strcasecmp(argv[1], "mumps") == 0) { #ifdef WITH_MUMPS MumpsMatrix<double> mat; SimpleVector<double> rhs; build_matrix(n, ar_mat, ar_rhs, &mat, &rhs); MumpsSolver<double> solver(&mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "mumps-block") == 0) { #ifdef WITH_MUMPS MumpsMatrix<double> mat; SimpleVector<double> rhs; build_matrix_block(n, ar_mat, ar_rhs, &mat, &rhs); MumpsSolver<double> solver(&mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } bool success = true; if(sln) { switch(atoi(argv[2])) { case 1: success = Testing::test_value(sln[0], 4, "sln[0]", 1E-6) && success; success = Testing::test_value(sln[1], 2, "sln[1]", 1E-6) && success; success = Testing::test_value(sln[2], 3, "sln[2]", 1E-6) && success; break; case 2: success = Testing::test_value(sln[0], 2, "sln[0]", 1E-6) && success; success = Testing::test_value(sln[1], 3, "sln[1]", 1E-6) && success; success = Testing::test_value(sln[2], 1, "sln[2]", 1E-6) && success; success = Testing::test_value(sln[3], -3, "sln[3]", 1E-6) && success; success = Testing::test_value(sln[4], -1, "sln[4]", 1E-6) && success; break; case 3: success = Testing::test_value(sln[0], 1, "sln[0]", 1E-6) && success; success = Testing::test_value(sln[1], 2, "sln[1]", 1E-6) && success; success = Testing::test_value(sln[2], 3, "sln[2]", 1E-6) && success; success = Testing::test_value(sln[3], 4, "sln[3]", 1E-6) && success; success = Testing::test_value(sln[4], 5, "sln[4]", 1E-6) && success; break; } delete[] sln; if(success) { printf("Success!\n"); return 0; } else { printf("Failure!\n"); return -1; } } else return 0; }
bool CommonSolverUmfpack::solve(Matrix *mat, cplx *res) { printf("UMFPACK solver - cplx\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(); // complex components double *Axr = new double[nnz]; double *Axi = new double[nnz]; cplx *Ax = Acsc->get_Ax_cplx(); for (int i = 0; i < nnz; i++) { Axr[i] = Ax[i].real(); Axi[i] = Ax[i].imag(); } umfpack_zi_defaults(control_array); /* symbolic analysis */ void *symbolic, *numeric; int status_symbolic = umfpack_zi_symbolic(size, size, Acsc->get_Ap(), Acsc->get_Ai(), NULL, NULL, &symbolic, control_array, info_array); print_status(status_symbolic); /* LU factorization */ int status_numeric = umfpack_zi_numeric(Acsc->get_Ap(), Acsc->get_Ai(), Axr, Axi, symbolic, &numeric, control_array, info_array); print_status(status_numeric); umfpack_zi_free_symbolic(&symbolic); double *xr = new double[size]; double *xi = new double[size]; double *resr = new double[size]; double *resi = new double[size]; for (int i = 0; i < size; i++) { resr[i] = res[i].real(); resi[i] = res[i].imag(); } /* solve system */ int status_solve = umfpack_zi_solve(UMFPACK_A, Acsc->get_Ap(), Acsc->get_Ai(), Axr, Axi, xr, xi, resr, resi, numeric, control_array, info_array); print_status(status_solve); umfpack_zi_free_numeric(&numeric); delete[] resr; delete[] resi; delete[] Axr; delete[] Axi; if (symbolic) umfpack_di_free_symbolic(&symbolic); if (numeric) umfpack_di_free_numeric(&numeric); for (int i = 0; i < Acsc->get_size(); i++) res[i] = cplx(xr[i], xi[i]); delete[] xr; delete[] xi; if (!dynamic_cast<CSCMatrix*>(mat)) delete Acsc; }