Exemplo n.º 1
0
 virtual void setupInternal(NumericVector<Number> &X) {
   PetscVector<Number> *pX = cast_ptr<PetscVector<Number> *>(&X);
   PetscErrorCode ierr;
   ierr = TSSetIFunction(this->_ts,PETSC_NULL,this->_computeIFunction,this);
   CHKERRABORT(libMesh::COMM_WORLD,ierr);
   PetscMatrix<Number> *mat = cast_ptr<PetscMatrix<Number> *>(this->_fe_problem.getNonlinearSystem().sys().matrix);
   Mat pmat = mat->mat();
   ierr = TSSetIJacobian(this->_ts,pmat,pmat,this->_computeIJacobian,this);
   CHKERRABORT(libMesh::COMM_WORLD,ierr);
   ierr = TSSetFromOptions(this->_ts);
   CHKERRABORT(libMesh::COMM_WORLD,ierr);
   ierr = TSSetSolution(_ts,pX->vec());
   CHKERRABORT(libMesh::COMM_WORLD,ierr);
 }
Exemplo n.º 2
0
// =================================================
  void PetscPreconditioner::init() {
    if(!this->_matrix) {
      std::cerr << "ERROR: No matrix set for PetscPreconditioner, but init() called" << std::endl;
      abort();
    }
    //Clear the preconditioner in case it has been created in the past
    if(!this->_is_initialized)  {
      //Create the preconditioning object
      PCCreate(MPI_COMM_WORLD, &_pc);
      //Set the PCType
      set_petsc_preconditioner_type(this->_preconditioner_type, _pc);
// #ifdef LIBMESH_HAVE_PETSC_HYPRE
//     if(this->_preconditioner_type == AMG_PRECOND)
//       PCHYPRESetType(this->_pc, "boomerang");
// #endif
      PetscMatrix * pmatrix = libmeshM_cast_ptr<PetscMatrix*, SparseMatrix >(this->_matrix);
      _mat = pmatrix->mat();
    }
    //PCSetOperators(_pc,_mat,_mat,SAME_NONZERO_PATTERN);
    PCSetOperators(_pc, _mat, _mat); //PETSC3p5
    this->_is_initialized = true;
  }
Exemplo n.º 3
0
void PetscMatrix<T>::add (const T a_in, SparseMatrix<T> &X_in)
{
  libmesh_assert (this->initialized());

  // sanity check. but this cannot avoid
  // crash due to incompatible sparsity structure...
  libmesh_assert_equal_to (this->m(), X_in.m());
  libmesh_assert_equal_to (this->n(), X_in.n());

  PetscScalar     a = static_cast<PetscScalar>      (a_in);
  PetscMatrix<T>* X = libmesh_cast_ptr<PetscMatrix<T>*> (&X_in);

  libmesh_assert (X);

  PetscErrorCode ierr=0;

  // the matrix from which we copy the values has to be assembled/closed
  // X->close ();
  libmesh_assert(X->closed());

  semiparallel_only();

// 2.2.x & earlier style
#if PETSC_VERSION_LESS_THAN(2,3,0)

  ierr = MatAXPY(&a,  X->_mat, _mat, SAME_NONZERO_PATTERN);
         LIBMESH_CHKERRABORT(ierr);

// 2.3.x & newer
#else

  ierr = MatAXPY(_mat, a, X->_mat, DIFFERENT_NONZERO_PATTERN);
         LIBMESH_CHKERRABORT(ierr);

#endif
}
Exemplo n.º 4
0
std::pair<unsigned int, Real>
PetscNonlinearSolver<T>::solve (SparseMatrix<T>&  jac_in,  // System Jacobian Matrix
				NumericVector<T>& x_in,    // Solution vector
				NumericVector<T>& r_in,    // Residual vector
				const double,              // Stopping tolerance
				const unsigned int)
{
  START_LOG("solve()", "PetscNonlinearSolver");
  this->init ();

  // Make sure the data passed in are really of Petsc types
  PetscMatrix<T>* jac = libmesh_cast_ptr<PetscMatrix<T>*>(&jac_in);
  PetscVector<T>* x   = libmesh_cast_ptr<PetscVector<T>*>(&x_in);
  PetscVector<T>* r   = libmesh_cast_ptr<PetscVector<T>*>(&r_in);

  PetscErrorCode ierr=0;
  PetscInt n_iterations =0;
  // Should actually be a PetscReal, but I don't know which version of PETSc first introduced PetscReal
  Real final_residual_norm=0.;

  ierr = SNESSetFunction (_snes, r->vec(), __libmesh_petsc_snes_residual, this);
         LIBMESH_CHKERRABORT(ierr);

   // Only set the jacobian function if we've been provided with something to call.
   // This allows a user to set their own jacobian function if they want to
   if (this->jacobian || this->jacobian_object || this->residual_and_jacobian_object)
   {
     ierr = SNESSetJacobian (_snes, jac->mat(), jac->mat(), __libmesh_petsc_snes_jacobian, this);
     LIBMESH_CHKERRABORT(ierr);
   }
#if !PETSC_VERSION_LESS_THAN(3,3,0)
   // Only set the nullspace if we have a way of computing it and the result is non-empty.
   if (this->nullspace || this->nullspace_object)
   {
     MatNullSpace msp;
     this->build_mat_null_space(this->nullspace_object, this->nullspace, &msp);
     if (msp)
       {
         ierr = MatSetNullSpace(jac->mat(), msp);
         LIBMESH_CHKERRABORT(ierr);

         ierr = MatNullSpaceDestroy(&msp);
         LIBMESH_CHKERRABORT(ierr);
       }
   }

   // Only set the nearnullspace if we have a way of computing it and the result is non-empty.
   if (this->nearnullspace || this->nearnullspace_object)
   {
     MatNullSpace msp = PETSC_NULL;
     this->build_mat_null_space(this->nearnullspace_object, this->nearnullspace, &msp);

     if(msp) {
       ierr = MatSetNearNullSpace(jac->mat(), msp);
       LIBMESH_CHKERRABORT(ierr);

       ierr = MatNullSpaceDestroy(&msp);
       LIBMESH_CHKERRABORT(ierr);
     }
   }
#endif
   // Have the Krylov subspace method use our good initial guess rather than 0
   KSP ksp;
   ierr = SNESGetKSP (_snes, &ksp);
          LIBMESH_CHKERRABORT(ierr);

  // Set the tolerances for the iterative solver.  Use the user-supplied
  // tolerance for the relative residual & leave the others at default values
  ierr = KSPSetTolerances (ksp, this->initial_linear_tolerance, PETSC_DEFAULT,
                           PETSC_DEFAULT, this->max_linear_iterations);
         LIBMESH_CHKERRABORT(ierr);

  // Set the tolerances for the non-linear solver.
  ierr = SNESSetTolerances(_snes, this->absolute_residual_tolerance, this->relative_residual_tolerance,
                           this->relative_step_tolerance, this->max_nonlinear_iterations, this->max_function_evaluations);
         LIBMESH_CHKERRABORT(ierr);

  //Pull in command-line options
  KSPSetFromOptions(ksp);
  SNESSetFromOptions(_snes);

  if (this->user_presolve)
    this->user_presolve(this->system());

  //Set the preconditioning matrix
  if(this->_preconditioner)
  {
    this->_preconditioner->set_matrix(jac_in);
    this->_preconditioner->init();
  }

//    ierr = KSPSetInitialGuessNonzero (ksp, PETSC_TRUE);
//           LIBMESH_CHKERRABORT(ierr);

// Older versions (at least up to 2.1.5) of SNESSolve took 3 arguments,
// the last one being a pointer to an int to hold the number of iterations required.
# if PETSC_VERSION_LESS_THAN(2,2,0)

 ierr = SNESSolve (_snes, x->vec(), &n_iterations);
        LIBMESH_CHKERRABORT(ierr);

// 2.2.x style
#elif PETSC_VERSION_LESS_THAN(2,3,0)

 ierr = SNESSolve (_snes, x->vec());
        LIBMESH_CHKERRABORT(ierr);

// 2.3.x & newer style
#else

  ierr = SNESSolve (_snes, PETSC_NULL, x->vec());
         LIBMESH_CHKERRABORT(ierr);

  ierr = SNESGetIterationNumber(_snes,&n_iterations);
         LIBMESH_CHKERRABORT(ierr);

  ierr = SNESGetLinearSolveIterations(_snes, &_n_linear_iterations);
         LIBMESH_CHKERRABORT(ierr);

  ierr = SNESGetFunctionNorm(_snes,&final_residual_norm);
	 LIBMESH_CHKERRABORT(ierr);

#endif

  // Get and store the reason for convergence
  SNESGetConvergedReason(_snes, &_reason);

  //Based on Petsc 2.3.3 documentation all diverged reasons are negative
  this->converged = (_reason >= 0);

  this->clear();

  STOP_LOG("solve()", "PetscNonlinearSolver");

  // return the # of its. and the final residual norm.
  return std::make_pair(n_iterations, final_residual_norm);
}
Exemplo n.º 5
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;
}