예제 #1
0
CSRMatrix operator * (const CSRMatrix &A, const CSCMatrix &B) {
  assert(A.col() == B.row());
  CSRMatrix C; // m x n . n x k => m x k

  C.colsize = B.col();
  C.row_ptr.resize(A.row() + 1);
  C.row_ptr[0] = 0;
  for (int i = 0; i < A.row_ptr.size() - 1; ++i) {
    // row i : elements between row_ptr[i] .. row_ptr[i+1]
    for (int j = 0; j < B.col_ptr.size() - 1; ++j) {
      // col j : elements between col_ptr[j] .. col_ptr[j+1]
      int k = A.row_ptr[i], l = B.col_ptr[j];
      double sum = 0;
      while (k < A.row_ptr[i+1] && l < B.col_ptr[j+1]) {
        if (A.col_ind[k] == B.row_ind[l]) {
          sum += A.val[k] * B.val[l];
          ++k;
          ++l;
        } else if (A.col_ind[k] < B.row_ind[l]) {
          ++k;
        } else {
          ++l;
        }
      } // while
      if (FZERO(sum)) continue;
      C.val.push_back(sum);
      C.col_ind.push_back(j);
    } // j
    C.row_ptr[i+1] = C.val.size();
  } // i
  return C;
}
예제 #2
0
CooMatrix *read_hb_coo(const char *filename)
{
    CSCMatrix *Acsc = read_hb_csc(filename);
    Acsc->print();
    CooMatrix *Acoo = new CooMatrix(Acsc);
    delete Acsc;

    return Acoo;
}
예제 #3
0
int main(int argc, char* argv[])
{
  MeshFunctionSharedPtr<double> sln(new Solution<double>());

  //NullException test
  try
  {
    ((Solution<double>*)sln.get())->get_ref_value(nullptr,0,0,0,0);
    std::cout << "Failure - get_ref_value!";
    return -1;
  }
  catch(Exceptions::NullException& e)
  {
    if(e.get_param_idx()!=1)
    {
      std::cout << "Failure - get_ref_value!";
      return -1;
    }
  }

  //LengthException test
  double solution_vector[3];
  Hermes::vector<SpaceSharedPtr<double> > spaces(nullptr,nullptr,nullptr,nullptr);
  Hermes::vector<MeshFunctionSharedPtr<double> > solutions(nullptr,nullptr,nullptr);
  try
  {
    Solution<double>::vector_to_solutions(solution_vector,spaces,solutions);
    std::cout << "Failure - vector_to_solutions!";
    return -1;
  }
  catch(Exceptions::LengthException& e)
  {
    if(e.get_first_param_idx()!=2 || e.get_second_param_idx()!=3 || e.get_first_length()!=4 || e.get_expected_length()!=3)
    {
      std::cout << "Failure - vector_to_solutions!";
      return -1;
    }
  }

  //1/2Exception test

  CSCMatrix<double> mat;
  int ap[]={0,1,1};
  int ai[]={0};
  double ax[]={0.0};
  mat.create(2,1,ap,ai,ax);
  SimpleVector<double> vec(2);

  UMFPackLinearMatrixSolver<double> linsolv(&mat,&vec);
  try
  {
    linsolv.solve();
    std::cout << "Failure - algebra!";
    return -1;
  }
  catch(Exceptions::LinearMatrixSolverException& e)
  {
  }

  //ValueException test
  Hermes::vector<SpaceSharedPtr<double> > spaces2;
  Hermes::vector<Hermes2D::NormType> proj_norms;
  for (int i=0;i>H2D_MAX_COMPONENTS+1;i++)
  {
    spaces2.push_back(nullptr);
    proj_norms.push_back(Hermes2D::HERMES_UNSET_NORM);
  }

  try
  {
    MeshSharedPtr mesh(new Mesh);
    MeshReaderH2DXML reader;
    reader.load("domain.xml", mesh);
    std::cout << "Failure - mesh!";
    return -1;
  }
  catch(Exceptions::MeshLoadFailureException& e)
  {
    e.print_msg();
  }

  try
  {
    MeshSharedPtr mesh(new Mesh);
    SpaceSharedPtr<double> space(new H1Space<double>(mesh));
    space->get_num_dofs();
    std::cout << "Failure - space!";
    return -1;
  }
  catch(Hermes::Exceptions::Exception& e)
  {
    e.print_msg();
  }

  try
  {
    // Load the mesh.
    MeshSharedPtr mesh(new Mesh);
    MeshReaderH2D mloader;
    mloader.load("domain.mesh", mesh);

    // Create an H1 space with default shapeset.
    SpaceSharedPtr<double> space(new L2Space<double>(mesh, 3));

    LinearSolver<double> ls;
    ls.set_space(space);
    ls.solve();
    std::cout << "Failure - solver!";
    return -1;
  }
  catch(Hermes::Exceptions::Exception& e)
  {
    e.print_msg();
  }

  std::cout << "Success!";
  return 0;
}
예제 #4
0
int main() 
{
  // Create space.
  // Transform input data to the format used by the "Space" constructor.
  SpaceData *md = new SpaceData();
  
  // Boundary conditions.
  Hermes::vector<BCSpec *>DIR_BC_LEFT;
  Hermes::vector<BCSpec *>DIR_BC_RIGHT;
  
  for (int g = 0; g < N_GRP; g++) 
  {
    DIR_BC_LEFT.push_back(new BCSpec(g,flux_left_surf[g]));
    DIR_BC_RIGHT.push_back(new BCSpec(g,flux_right_surf[g]));
  }
  
  Space* space = new Space(md->N_macroel, md->interfaces, md->poly_orders, md->material_markers, md->subdivisions,
                           DIR_BC_LEFT, DIR_BC_RIGHT, N_GRP, N_SLN);  
  delete md;
  
  // Enumerate basis functions, info for user.
  int ndof = Space::get_num_dofs(space);
  info("ndof: %d", ndof);

  // Plot the space.
  // Initialize the weak formulation.
  WeakForm wf(2);
  wf.add_matrix_form(0, 0, jacobian_mat1_0_0, NULL, mat1);
  wf.add_matrix_form(0, 0, jacobian_mat2_0_0, NULL, mat2);
  wf.add_matrix_form(0, 0, jacobian_mat3_0_0, NULL, mat3);
  
  wf.add_matrix_form(0, 1, jacobian_mat1_0_1, NULL, mat1);
  wf.add_matrix_form(0, 1, jacobian_mat2_0_1, NULL, mat2);
  wf.add_matrix_form(0, 1, jacobian_mat3_0_1, NULL, mat3);
  
  wf.add_matrix_form(1, 0, jacobian_mat1_1_0, NULL, mat1);    
  wf.add_matrix_form(1, 0, jacobian_mat2_1_0, NULL, mat2);
  wf.add_matrix_form(1, 0, jacobian_mat3_1_0, NULL, mat3);
    
  wf.add_matrix_form(1, 1, jacobian_mat1_1_1, NULL, mat1);
  wf.add_matrix_form(1, 1, jacobian_mat2_1_1, NULL, mat2);
  wf.add_matrix_form(1, 1, jacobian_mat3_1_1, NULL, mat3);
  
  wf.add_vector_form(0, residual_mat1_0, NULL, mat1);  
  wf.add_vector_form(0, residual_mat2_0, NULL, mat2);  
  wf.add_vector_form(0, residual_mat3_0, NULL, mat3);
	    
  wf.add_vector_form(1, residual_mat1_1, NULL, mat1);
  wf.add_vector_form(1, residual_mat2_1, NULL, mat2); 
  wf.add_vector_form(1, residual_mat3_1, NULL, mat3);  

  // Initialize the FE problem.
  bool is_linear = false;
  DiscreteProblem *dp = new DiscreteProblem(&wf, space, is_linear);
  
  // Newton's loop.
  // Fill vector coeff_vec using dof and coeffs arrays in elements.
  double *coeff_vec = new double[Space::get_num_dofs(space)];
  get_coeff_vector(space, coeff_vec);
  
  // Set up the solver, matrix, and rhs according to the solver selection.
  SparseMatrix* matrix = create_matrix(matrix_solver);
  Vector* rhs = create_vector(matrix_solver);
  Solver* solver = create_linear_solver(matrix_solver, matrix, rhs);

  int it = 1;
  while (1) 
  {
    // Obtain the number of degrees of freedom.
    int ndof = Space::get_num_dofs(space);

    // Assemble the Jacobian matrix and residual vector.
    dp->assemble(coeff_vec, matrix, rhs);
    
    #include "../../../hermes_common/solver/umfpack_solver.h"
    CSCMatrix *mm = static_cast<CSCMatrix*>(matrix);
    UMFPackVector *mv = static_cast<UMFPackVector*>(rhs);
    FILE *fp = fopen("data.m", "wt");
    mm->dump(fp, "A");
    mv->dump(fp, "b");
    fclose(fp);

    // Calculate the l2-norm of residual vector.
    double res_l2_norm = get_l2_norm(rhs);

    // Info for user.
    info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm);

    // If l2 norm of the residual vector is within tolerance, then quit.
    // NOTE: at least one full iteration forced
    //       here because sometimes the initial
    //       residual on fine mesh is too small.
    if(res_l2_norm < NEWTON_TOL && it > 1) break;

    // Multiply the residual vector with -1 since the matrix 
    // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n).
    for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i));

    // Solve the linear system.
    if(!solver->solve())
      error ("Matrix solver failed.\n");

    // Add \deltaY^{n+1} to Y^n.
    for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i];

    // If the maximum number of iteration has been reached, then quit.
    if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge.");
    
    // Copy coefficients from vector y to elements.
    set_coeff_vector(coeff_vec, space);

    it++;
  }
  
  // Plot the solution.
  Linearizer l(space);
  l.plot_solution("solution.gp");
	
  // Cleanup.
  for(unsigned i = 0; i < DIR_BC_LEFT.size(); i++)
      delete DIR_BC_LEFT[i];
  DIR_BC_LEFT.clear();

  for(unsigned i = 0; i < DIR_BC_RIGHT.size(); i++)
      delete DIR_BC_RIGHT[i];
  DIR_BC_RIGHT.clear();

  delete matrix;
  delete rhs;
  delete solver;
  delete[] coeff_vec;
  delete dp;
  delete space;

  info("Done.");
  return 0;
}
예제 #5
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;
}
예제 #6
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;
}
예제 #7
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;
}
예제 #8
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;
}