示例#1
0
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;
}
示例#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;
}
示例#3
0
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;
}
示例#4
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;
}