예제 #1
0
#if defined(PETSC_HAVE_FORTRAN_CAPS)
#define pchypresettype_            PCHYPRESETTYPE
#define pchypregettype_            PCHYPREGETTYPE
#elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
#define pchypresettype_            pchypresettype
#define pchypregettype_            pchypregettype
#endif


EXTERN_C_BEGIN

void PETSC_STDCALL  pchypresettype_(PC *pc, CHAR name PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len) )
{
  char *t;
  FIXCHAR(name,len,t);
  *ierr = PCHYPRESetType(*pc,t);
  FREECHAR(name,t);
}

void PETSC_STDCALL pchypregettype_(PC *pc,CHAR name PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len))
{
  const char *tname;

  *ierr = PCHYPREGetType(*pc,&tname);
  *ierr = PetscStrncpy(name,tname,len);if (*ierr) return;
  FIXRETURNCHAR(PETSC_TRUE,name,len);

}

EXTERN_C_END
	/*! \brief solve simple use a Krylov solver + Simple selected Parallel Pre-conditioner
	 *
	 */
	void solve_Krylov_simple(Mat & A_, const Vec & b_, Vec & x_)
	{
		PETSC_SAFE_CALL(KSPSetType(ksp,s_type));

		// We set the size of x according to the Matrix A
		PetscInt row;
		PetscInt col;
		PetscInt row_loc;
		PetscInt col_loc;

		PETSC_SAFE_CALL(MatGetSize(A_,&row,&col));
		PETSC_SAFE_CALL(MatGetLocalSize(A_,&row_loc,&col_loc));

		PC pc;

		// We set the Matrix operators
		PETSC_SAFE_CALL(KSPSetOperators(ksp,A_,A_));

		// We set the pre-conditioner
		PETSC_SAFE_CALL(KSPGetPC(ksp,&pc));

		// PETSC_SAFE_CALL(PCSetType(pc,PCJACOBI));

		PETSC_SAFE_CALL(PCSetType(pc,PCHYPRE));
//		PCGAMGSetNSmooths(pc,0);
	    PCFactorSetShiftType(pc, MAT_SHIFT_NONZERO);
	    PCFactorSetShiftAmount(pc, PETSC_DECIDE);
		PCHYPRESetType(pc, "boomeramg");
		MatSetBlockSize(A_,4);
		PetscOptionsSetValue("-pc_hypre_boomeramg_print_statistics","2");
		PetscOptionsSetValue("-pc_hypre_boomeramg_max_iter","1000");
		PetscOptionsSetValue("-pc_hypre_boomeramg_nodal_coarsen","true");
		PetscOptionsSetValue("-pc_hypre_boomeramg_relax_type_all","SOR/Jacobi");
		PetscOptionsSetValue("-pc_hypre_boomeramg_coarsen_type","Falgout");
		PetscOptionsSetValue("-pc_hypre_boomeramg_cycle_type","W");
		PetscOptionsSetValue("-pc_hypre_boomeramg_max_levels","10");
		KSPSetFromOptions(ksp);
		// if we are on on best solve set-up a monitor function

		if (try_solve == true)
		{
			// for bench-mark we are interested in non-preconditioned norm
			PETSC_SAFE_CALL(KSPMonitorSet(ksp,monitor,&vres,NULL));

			// Disable convergence check
			PETSC_SAFE_CALL(KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL));
		}

		// Solve the system
		PETSC_SAFE_CALL(KSPSolve(ksp,b_,x_));

		auto & v_cl = create_vcluster();
//		if (try_solve == true)
//		{
			// calculate error statistic about the solution
			solError err = statSolutionError(A_,b_,x_);

			if (v_cl.getProcessUnitID() == 0)
			{
				std::cout << "Method: " << s_type << " " << " pre-conditoner: " << PCJACOBI << "  iterations: " << err.its << std::endl;
				std::cout << "Norm of error: " << err.err_norm << "   Norm infinity: " << err.err_inf << std::endl;
			}
//		}
	}
예제 #3
0
void PetscPreconditioner<T>::set_petsc_preconditioner_type (const PreconditionerType & preconditioner_type, PC & pc)
{
  int ierr = 0;

  // get the communicator from the PETSc object
  Parallel::communicator comm;
  PetscObjectGetComm((PetscObject)pc, &comm);
  Parallel::Communicator communicator(comm);

  switch (preconditioner_type)
  {
  case IDENTITY_PRECOND:
    ierr = PCSetType (pc, (char*) PCNONE);      CHKERRABORT(comm,ierr); break;

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

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

  case ILU_PRECOND:
    {
      // In serial, just set the ILU preconditioner type
      if (communicator.size())
	{
	  ierr = PCSetType (pc, (char*) PCILU);
	  CHKERRABORT(comm,ierr);
	}
      else
	{
	  // But PETSc has no truly parallel ILU, instead you have to set
	  // an actual parallel preconditioner (e.g. block Jacobi) and then
	  // assign ILU sub-preconditioners.
	  ierr = PCSetType (pc, (char*) PCBJACOBI);
	  CHKERRABORT(comm,ierr);

	  // Set ILU as the sub preconditioner type
	  set_petsc_subpreconditioner_type(PCILU, pc);
	}
      break;
    }

  case LU_PRECOND:
    {
      // In serial, just set the LU preconditioner type
      if (communicator.size())
	{
	  ierr = PCSetType (pc, (char*) PCLU);
	  CHKERRABORT(comm,ierr);
	}
      else
	{
	  // But PETSc has no truly parallel LU, instead you have to set
	  // an actual parallel preconditioner (e.g. block Jacobi) and then
	  // assign LU sub-preconditioners.
	  ierr = PCSetType (pc, (char*) PCBJACOBI);
	  CHKERRABORT(comm,ierr);

	  // Set ILU as the sub preconditioner type
	  set_petsc_subpreconditioner_type(PCLU, pc);
	}
      break;
    }

  case ASM_PRECOND:
    {
      // In parallel, I think ASM uses ILU by default as the sub-preconditioner...
      // I tried setting a different sub-preconditioner here, but apparently the matrix
      // is not in the correct state (at this point) to call PCSetUp().
      ierr = PCSetType (pc, (char*) PCASM);
      CHKERRABORT(comm,ierr);
      break;
    }

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

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

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

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

  case AMG_PRECOND:
    ierr = PCSetType (pc, (char*) PCHYPRE);     CHKERRABORT(comm,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(comm,ierr); break;
#endif

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

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

  // Set additional options if we are doing AMG and
  // HYPRE is available
#ifdef LIBMESH_HAVE_PETSC_HYPRE
  if (preconditioner_type == AMG_PRECOND)
    {
      ierr = PCHYPRESetType(pc, "boomeramg");
      CHKERRABORT(comm,ierr);
    }
#endif

  // Let the commandline override stuff
  // FIXME: Unless we are doing AMG???
  if (preconditioner_type != AMG_PRECOND)
    {
      ierr = PCSetFromOptions(pc);
      CHKERRABORT(comm,ierr);
    }
}
예제 #4
0
std::pair<std::string,std::string>
RBConstructionBase<Base>::set_alternative_solver
(AutoPtr<LinearSolver<Number> >&
#ifdef LIBMESH_HAVE_PETSC
 ls
#endif
 )
{
  // It seems that setting it this generic way has no effect...
  // PreconditionerType orig_pc = this->linear_solver->preconditioner_type();
  // this->linear_solver->set_preconditioner_type(AMG_PRECOND);
  // so we do it the "hard" way.
  std::string orig_petsc_pc_type_string, orig_petsc_ksp_type_string;

#ifdef LIBMESH_HAVE_PETSC
  // ... but we can set it the "hard" way
  PetscLinearSolver<Number>* petsc_linear_solver =
    libmesh_cast_ptr<PetscLinearSolver<Number>*>(ls.get());

  // Note: #define PCType char*, and PCGetType just sets a pointer.  We'll use
  // the string below to make a real copy, and set the PC back to its original
  // type at the end of the function.
#if PETSC_VERSION_LESS_THAN(3,0,0) || !PETSC_VERSION_LESS_THAN(3,4,0)
  // Pre-3.0 and petsc-dev (as of October 2012) use non-const versions
  PCType orig_petsc_pc_type;
  KSPType orig_petsc_ksp_type;
#else
  const PCType orig_petsc_pc_type;
  const KSPType orig_petsc_ksp_type;
#endif

  if (petsc_linear_solver)
    {
      PC pc = petsc_linear_solver->pc();
      int ierr = PCGetType(pc, &orig_petsc_pc_type);
      LIBMESH_CHKERRABORT(ierr);

      KSP ksp = petsc_linear_solver->ksp();
      ierr = KSPGetType(ksp, &orig_petsc_ksp_type);
      LIBMESH_CHKERRABORT(ierr);

      // libMesh::out << "orig_petsc_pc_type (before)=" << orig_petsc_pc_type << std::endl;
      // Make actual copies of the original PC and KSP types
      orig_petsc_pc_type_string = orig_petsc_pc_type;
      orig_petsc_ksp_type_string = orig_petsc_ksp_type;

#ifdef LIBMESH_HAVE_PETSC_HYPRE
      // Set solver/PC combo specified in input file...
      if (this->alternative_solver == "amg")
        {
          // Set HYPRE and boomeramg PC types
          ierr = PCSetType(pc, PCHYPRE);
          LIBMESH_CHKERRABORT(ierr);
          ierr = PCHYPRESetType(pc, "boomeramg");
          LIBMESH_CHKERRABORT(ierr);
        }
#endif // LIBMESH_HAVE_PETSC_HYPRE
      if (this->alternative_solver == "mumps")
        {
          // We'll use MUMPS... TODO: configure libmesh to detect
          // when MUMPS is available via PETSc.

          // No initial guesses can be specified with KSPPREONLY.  We
          // can leave the solver as gmres or whatever and it should
          // converge in 1 iteration.  Otherwise, to use KSPPREONLY,
          // you may need to do:
          // KSPSetInitialGuessNonzero(ksp, PETSC_FALSE);
          // ierr = KSPSetType(ksp, KSPPREONLY);
          // LIBMESH_CHKERRABORT(ierr);

          // Need to call the equivalent for the command line options:
          // -ksp_type preonly -pc_type lu -pc_factor_mat_solver_package mumps
          ierr = PCSetType(pc, PCLU);
          LIBMESH_CHKERRABORT(ierr);
#if !(PETSC_VERSION_LESS_THAN(3,0,0))
          ierr = PCFactorSetMatSolverPackage(pc,"mumps");
          LIBMESH_CHKERRABORT(ierr);
#endif
        }
    }
  else
    {
      // Otherwise, the cast failed and we are not using PETSc...
      libMesh::out << "You are not using PETSc, so don't know how to set AMG PC." << std::endl;
      libMesh::out << "Returning empty string!" << std::endl;
    }
#endif // LIBMESH_HAVE_PETSC

  return std::make_pair(orig_petsc_pc_type_string, orig_petsc_ksp_type_string);
}
예제 #5
0
파일: Solver.c 프로젝트: haowu80s/turbins
/* This function returns the suitable solver for pressure. linear system */
KSP Solver_get_pressure_solver(Mat lhs, Parameters *params) {

    KSP solver;
    PC pc;
    double rtol;
    int ierr;
    PetscLogDouble T1, T2;

    rtol = params->resmax;
    ierr = KSPCreate(PETSC_COMM_WORLD, &solver); PETScErrAct(ierr);

    short int hasnullspace = NO;
    if (hasnullspace) {

        MatNullSpace nullsp;
        MatNullSpaceCreate(PETSC_COMM_WORLD, PETSC_TRUE, 0, PETSC_NULL, &nullsp);
        KSPSetNullSpace(solver, nullsp);
        //MatNullSpaceDestroy(nullsp);
    }

    ierr = KSPSetOperators(solver, lhs, lhs, SAME_PRECONDITIONER); PETScErrAct(ierr);
    ierr = KSPSetType(solver, KSPGMRES); PETScErrAct(ierr);
    ierr = KSPGMRESSetRestart(solver, 20); PETScErrAct(ierr);
    ierr = KSPSetTolerances(solver, rtol, PETSC_DEFAULT, PETSC_DEFAULT, 300); PETScErrAct(ierr);

    ierr = KSPGetPC(solver, &pc); PETScErrAct(ierr);
    //PCSetType(pc, PCNONE);
    //PCSetType(pc, PCASM);

    PCSetType(pc, PCHYPRE);
    PCHYPRESetType(pc,"boomeramg");

    ierr = PetscOptionsSetValue("-pc_hypre_boomeramg_max_levels", "25"); PETScErrAct(ierr);
    ierr = PetscOptionsSetValue("-pc_hypre_boomeramg_strong_threshold", "0.0"); PETScErrAct(ierr);
    ierr = PetscOptionsSetValue("-pc_hypre_boomeramg_relax_type_all", "SOR/Jacobi"); PETScErrAct(ierr);

    //ierr = PetscOptionsSetValue("-pc_hypre_boomeramg_cycle_type", ""); PETScErrAct(ierr);
    //ierr = PetscOptionsSetValue("-pc_hypre_boomeramg_cycle_type", "V"); PETScErrAct(ierr);
    //ierr = PetscOptionsSetValue("-pc_hypre_boomeramg_coarsen_type", "PMIS"); PETScErrAct(ierr);
    //ierr = PetscOptionsSetValue("-pc_hypre_boomeramg_truncfactor", "0.9"); PETScErrAct(ierr);

    /*******************************************************************************************************/
    /*******************************************************************************************************/
    /*******************************************************************************************************/
    /* Hypre-Petsc Interface.
The most important parameters to be set are
1- Strong Threshold
2- Truncation Factor
3- Coarsennig Type
*/ 

    /* Between 0 to 1 */
    /* "0 "gives better convergence rate (in 3D). */
    /* Suggested values (By Hypre manual): 0.25 for 2D, 0.5 for 3D

 ierr = PetscOptionsSetValue("-pc_hypre_boomeramg_strong_threshold", "0.0"); PETScErrAct(ierr);
*/
    /*******************************************************************************************************/

    /* Available Options:
 "CLJP","Ruge-Stueben","modifiedRuge-Stueben","Falgout", "PMIS", "HMIS"
 Falgout is usually the best.
 ierr = PetscOptionsSetValue("-pc_hypre_boomeramg_coarsen_type", "Falgout"); PETScErrAct(ierr);
*/
    /*******************************************************************************************************/

    /* Availble options:
 "local", "global"

 ierr = PetscOptionsSetValue("-pc_hypre_boomeramg_measure_type", "local"); PETScErrAct(ierr);
*/
    /*******************************************************************************************************/

    /* Availble options:
 Jacobi,sequential-Gauss-Seidel,
 SOR/Jacobi,backward-SOR/Jacobi,symmetric-SOR/Jacobi,Gaussian-elimination

 Important: If you are using a symmetric KSP solver (like CG), you should use a symmetric smoother
 here.

 ierr = PetscOptionsSetValue("-pc_hypre_boomeramg_relax_type_all", "symmetric-SOR/Jacobi"); PETScErrAct(ierr);
*/
    /*******************************************************************************************************/

    /* Available options:
 "V", "W"

 ierr = PetscOptionsSetValue("-pc_hypre_boomeramg_cycle_type", "V"); PETScErrAct(ierr);
*/
    /*******************************************************************************************************/

    /* Availble options:
 "classical", "", "", "direct", "multipass", "multipass-wts", "ext+i", "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"

 ierr = PetscOptionsSetValue("-pc_hypre_boomeramg_interp_type", ""); PETScErrAct(ierr);
*/
    /*******************************************************************************************************/
    /* Available options:
Greater than zero.
Use zero for the best convergence. However, if you have memory problems, use greate than zero to save some
memory.

 ierr = PetscOptionsSetValue("-pc_hypre_boomeramg_truncfactor", "0.0"); PETScErrAct(ierr);
 */




    /*
Preconditioner Generation Options
PCSetType(pc,PCHYPRE) or -pc_type hypre
-pc_hypre_boomeramg_max_levels nmax
-pc_hypre_boomeramg_truncfactor
-pc_hypre_boomeramg_strong_threshold
-pc_hypre_boomeramg_max_row_sum
-pc_hypre_boomeramg_no_CF
-pc_hypre_boomeramg_coarsen_type CLJP,Ruge-Stueben,modifiedRuge-Stueben,
-pc_hypre_boomeramg_measure_type local,global


Preconditioner Iteration Options
-pc_hypre_boomeramg_relax_type_all Jacobi,sequential-Gauss-Seidel,
   SOR/Jacobi,backward-SOR/Jacobi,symmetric-SOR/Jacobi,Gaussian-eliminat
-pc_hypre_boomeramg_relax_type_fine
-pc_hypre_boomeramg_relax_type_down
-pc_hypre_boomeramg_relax_type_up
-pc_hypre_boomeramg_relax_weight_all r
-pc_hypre_boomeramg_outer_relax_weight_all r
-pc_hypre_boomeramg_grid_sweeps_down n
-pc_hypre_boomeramg_grid_sweeps_up n
-pc_hypre_boomeramg_grid_sweeps_coarse n
-pc_hypre_boomeramg_tol tol
-pc_hypre_boomeramg_max_iter it

*/



    /*
 //ierr = PCSetType(pc, PCASM); PETScErrAct(ierr);
 ierr = PCSetType(pc, PCNONE); PETScErrAct(ierr);

 //ierr = PCSetType(pc, PCILU); PETScErrAct(ierr);

 //ierr = PCSetType(pc, PCBJACOBI); PETScErrAct(ierr);
 //ierr = PCSetType(pc, PCLU); PETScErrAct(ierr);
 //ierr = PCSetType(pc, PCEISENSTAT); PETScErrAct(ierr);
 //ierr = PCSetType(pc, PCSOR); PETScErrAct(ierr);
 //ierr = PCSetType(pc, PCJACOBI); PETScErrAct(ierr);
 //ierr = PCSetType(pc, PCNONE); PETScErrAct(ierr);

*/
    /*
 ierr = KSPGetPC(solver, &pc); PETScErrAct(ierr);
 ierr = PCSetType(pc, PCILU); PETScErrAct(ierr);
 ierr = PCFactorSetLevels(pc, 3); PETScErrAct(ierr);

 //ierr = PCFactorSetUseDropTolerance(pc, 1e-3, .1, 50); PETScErrAct(ierr);
 //ierr = PCFactorSetFill(pc, 30.7648); PETScErrAct(ierr);

 ierr = PCFactorSetReuseOrdering(pc, PETSC_TRUE); PETScErrAct(ierr);
 ierr = PCFactorSetReuseFill(pc, PETSC_TRUE); PETScErrAct(ierr);
 ierr = PCFactorSetAllowDiagonalFill(pc); PETScErrAct(ierr);

 //ierr = PCFactorSetUseInPlace(pc); PETScErrAct(ierr);
*/
    ierr = KSPSetInitialGuessNonzero(solver, PETSC_TRUE); PETScErrAct(ierr);
    ierr = PetscGetTime(&T1);PETScErrAct(ierr);
    ierr = KSPSetFromOptions(solver); PETScErrAct(ierr);

    ierr = PetscGetTime(&T2);PETScErrAct(ierr);
    PetscPrintf(PCW, "Setup time for the Pressure solver was:%f\n", (T2 - T1));
    ierr = KSPView(solver, PETSC_VIEWER_STDOUT_WORLD); PETScErrAct(ierr);
    return solver;

}