Example #1
0
void PetscPreconditioner<T>::init ()
{
  if(!this->_matrix)
  {
    libMesh::err << "ERROR: No matrix set for PetscPreconditioner, but init() called" << std::endl;
    libmesh_error();
  }

  // Clear the preconditioner in case it has been created in the past
  if (!this->_is_initialized)
  {
    // Should probably use PCReset(), but it's not working at the moment so we'll destroy instead
    if (_pc)
    {
      int ierr = LibMeshPCDestroy(&_pc);
      LIBMESH_CHKERRABORT(ierr);
    }

    int ierr = PCCreate(this->comm().get(),&_pc);
    LIBMESH_CHKERRABORT(ierr);

    PetscMatrix<T> * pmatrix = libmesh_cast_ptr<PetscMatrix<T>*, SparseMatrix<T> >(this->_matrix);

    _mat = pmatrix->mat();
  }

  int ierr = PCSetOperators(_pc,_mat,_mat,SAME_NONZERO_PATTERN);
  LIBMESH_CHKERRABORT(ierr);

  // Set the PCType.  Note: this used to be done *before* the call to
  // PCSetOperators(), and only when !_is_initialized, but
  // 1.) Some preconditioners (those employing sub-preconditioners,
  // for example) have to call PCSetUp(), and can only do this after
  // the operators have been set.
  // 2.) It should be safe to call set_petsc_preconditioner_type()
  // multiple times.
  set_petsc_preconditioner_type(this->_preconditioner_type, _pc);

  this->_is_initialized = true;
}
Example #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;
  }
Example #3
0
// =====================================================
  void PetscPreconditioner::set_petsc_preconditioner_type
  (const PreconditionerType & preconditioner_type, PC & pc,  const int &parallelOverlapping) {
    int ierr = 0;
    switch(preconditioner_type)  {

      case IDENTITY_PRECOND:
        ierr = PCSetType(pc, (char*) PCNONE);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case CHOLESKY_PRECOND:
        ierr = PCSetType(pc, (char*) PCCHOLESKY);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case ICC_PRECOND:
        ierr = PCSetType(pc, (char*) PCICC);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;


      case ILU_PRECOND:
      {
        int nprocs;
        MPI_Comm_size(MPI_COMM_WORLD, &nprocs); //TODO
        // In serial, just set the ILU preconditioner type
        if(nprocs == 1)
        {
          ierr = PCSetType(pc, (char*) PCILU);
          CHKERRABORT(MPI_COMM_WORLD, ierr);
        }
        else
        {
//        But PETSc has no truly parallel ILU, instead you have to set
//        an actual parallel preconditioner (e.g. block Jacobi (parlleloverlapping 0) or ASM (parlleloverlapping >0))
//	  and then assign ILU sub-preconditioners.

          set_petsc_preconditioner_type(ASM_PRECOND, pc);
          PCASMSetOverlap(pc, parallelOverlapping);
          PCSetUp(pc);

          // Set ILU as the sub preconditioner type
          set_petsc_subpreconditioner_type(PCILU, pc);
        }
        break;
      }
      case LU_PRECOND: {
        int nprocs;
        MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
        if(nprocs == 1) {
          ierr = PCSetType(pc, (char*) PCLU);
          CHKERRABORT(MPI_COMM_WORLD, ierr);
        }
        else {
          ierr = PCSetType(pc, (char*) PCLU);
          CHKERRABORT(MPI_COMM_WORLD, ierr);

          ierr = PCFactorSetMatSolverPackage(pc, MATSOLVERMUMPS);
          CHKERRABORT(MPI_COMM_WORLD, ierr);
          ierr = PCFactorSetUpMatSolverPackage(pc);
          CHKERRABORT(MPI_COMM_WORLD, ierr);
          Mat       F;
          ierr = PCFactorGetMatrix(pc, &F);
          CHKERRABORT(MPI_COMM_WORLD, ierr);
          ierr = MatMumpsSetIcntl(F, 14, 30);
          CHKERRABORT(MPI_COMM_WORLD, ierr);
        }
        break;
      }

      case SLU_PRECOND:
        ierr = PCSetType(pc, (char*) PCLU);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        ierr = PCFactorSetMatSolverPackage(pc, MATSOLVERSUPERLU_DIST);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;    //here we set the SuperLU_dist solver package

      case MLU_PRECOND: //here we set the MUMPS parallel direct solver package
        ierr = PCSetType(pc, (char*) PCLU);
        CHKERRABORT(MPI_COMM_WORLD, ierr);

        ierr = PCFactorSetMatSolverPackage(pc, MATSOLVERMUMPS);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        ierr = PCFactorSetUpMatSolverPackage(pc);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        Mat       F;
        ierr = PCFactorGetMatrix(pc, &F);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        ierr = MatMumpsSetIcntl(F, 14, 30);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case ULU_PRECOND: //here we set the Umfpack serial direct solver package
        ierr = PCSetType(pc, (char*) PCLU);
        CHKERRABORT(MPI_COMM_WORLD, ierr);

        ierr = PCFactorSetMatSolverPackage(pc, MATSOLVERUMFPACK);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        ierr = PCFactorSetUpMatSolverPackage(pc);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case MCC_PRECOND:
        ierr = PCSetType(pc, (char*) PCCHOLESKY);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        ierr = PCFactorSetMatSolverPackage(pc, MATSOLVERMUMPS);
        CHKERRABORT(MPI_COMM_WORLD, ierr);                   //here we set the MUMPS parallel direct solver package
        break;

      case ASM_PRECOND:
        ierr = PCSetType(pc, (char*) PCASM);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case FIELDSPLIT_PRECOND:
        ierr = PCSetType(pc, (char*) PCFIELDSPLIT);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case JACOBI_PRECOND:
        ierr = PCSetType(pc, (char*) PCJACOBI);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case BLOCK_JACOBI_PRECOND:
        ierr = PCSetType(pc, (char*) PCBJACOBI);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case SOR_PRECOND:
        ierr = PCSetType(pc, (char*) PCSOR);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case EISENSTAT_PRECOND:
        ierr = PCSetType(pc, (char*) PCEISENSTAT);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case AMG_PRECOND:
        ierr = PCSetType(pc, (char*) PCHYPRE);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case MG_PRECOND:
        ierr = PCSetType(pc, (char*) PCMG);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case LSC_PRECOND:
        ierr = PCSetType(pc, (char*) PCLSC);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

#if !(PETSC_VERSION_LESS_THAN(2,1,2))
        // Only available for PETSC >= 2.1.2
      case USER_PRECOND:
        ierr = PCSetType(pc, (char*) PCMAT);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;
#endif

      case SHELL_PRECOND:
        ierr = PCSetType(pc, (char*) PCSHELL);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      default:
        std::cerr << "ERROR:  Unsupported PETSC Preconditioner: "
                  << preconditioner_type << std::endl
                  << "Continuing with PETSC defaults" << std::endl;
    }

    //Let the commandline override stuff
    if(preconditioner_type != AMG_PRECOND && preconditioner_type != MG_PRECOND)   PCSetFromOptions(pc);   //!!!!!!
  }