xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision dff316460686d560279b4150f0e6054a48569f87)
116d9e3a6SLisandro Dalcin 
216d9e3a6SLisandro Dalcin /*
316d9e3a6SLisandro Dalcin    Provides an interface to the LLNL package hypre
416d9e3a6SLisandro Dalcin */
50f1074feSSatish Balay 
60f1074feSSatish Balay /* Must use hypre 2.0.0 or more recent. */
70f1074feSSatish Balay 
8b45d2f2cSJed Brown #include <petsc-private/pcimpl.h>          /*I "petscpc.h" I*/
9c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h>
1016d9e3a6SLisandro Dalcin 
11*dff31646SBarry Smith static PetscBool cite = PETSC_FALSE;
12*dff31646SBarry Smith static const char *hypreCitation = "Hypre\n";
1316d9e3a6SLisandro Dalcin /*
1416d9e3a6SLisandro Dalcin    Private context (data structure) for the  preconditioner.
1516d9e3a6SLisandro Dalcin */
1616d9e3a6SLisandro Dalcin typedef struct {
1716d9e3a6SLisandro Dalcin   HYPRE_Solver   hsolver;
1816d9e3a6SLisandro Dalcin   HYPRE_IJMatrix ij;
1916d9e3a6SLisandro Dalcin   HYPRE_IJVector b,x;
2016d9e3a6SLisandro Dalcin 
214ddd07fcSJed Brown   HYPRE_Int (*destroy)(HYPRE_Solver);
224ddd07fcSJed Brown   HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
234ddd07fcSJed Brown   HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
2416d9e3a6SLisandro Dalcin 
2516d9e3a6SLisandro Dalcin   MPI_Comm comm_hypre;
2616d9e3a6SLisandro Dalcin   char     *hypre_type;
2716d9e3a6SLisandro Dalcin 
2816d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
294ddd07fcSJed Brown   PetscInt maxiter;
3016d9e3a6SLisandro Dalcin   double   tol;
3116d9e3a6SLisandro Dalcin 
3216d9e3a6SLisandro Dalcin   /* options for Pilut */
334ddd07fcSJed Brown   PetscInt factorrowsize;
3416d9e3a6SLisandro Dalcin 
3516d9e3a6SLisandro Dalcin   /* options for ParaSails */
364ddd07fcSJed Brown   PetscInt nlevels;
3716d9e3a6SLisandro Dalcin   double   threshhold;
3816d9e3a6SLisandro Dalcin   double   filter;
394ddd07fcSJed Brown   PetscInt sym;
4016d9e3a6SLisandro Dalcin   double   loadbal;
414ddd07fcSJed Brown   PetscInt logging;
424ddd07fcSJed Brown   PetscInt ruse;
434ddd07fcSJed Brown   PetscInt symt;
4416d9e3a6SLisandro Dalcin 
4516d9e3a6SLisandro Dalcin   /* options for Euclid */
46ace3abfcSBarry Smith   PetscBool bjilu;
474ddd07fcSJed Brown   PetscInt  levels;
4816d9e3a6SLisandro Dalcin 
4916d9e3a6SLisandro Dalcin   /* options for Euclid and BoomerAMG */
50ace3abfcSBarry Smith   PetscBool printstatistics;
5116d9e3a6SLisandro Dalcin 
5216d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
534ddd07fcSJed Brown   PetscInt  cycletype;
544ddd07fcSJed Brown   PetscInt  maxlevels;
5516d9e3a6SLisandro Dalcin   double    strongthreshold;
5616d9e3a6SLisandro Dalcin   double    maxrowsum;
574ddd07fcSJed Brown   PetscInt  gridsweeps[3];
584ddd07fcSJed Brown   PetscInt  coarsentype;
594ddd07fcSJed Brown   PetscInt  measuretype;
604ddd07fcSJed Brown   PetscInt  relaxtype[3];
6116d9e3a6SLisandro Dalcin   double    relaxweight;
6216d9e3a6SLisandro Dalcin   double    outerrelaxweight;
634ddd07fcSJed Brown   PetscInt  relaxorder;
6416d9e3a6SLisandro Dalcin   double    truncfactor;
65ace3abfcSBarry Smith   PetscBool applyrichardson;
664ddd07fcSJed Brown   PetscInt  pmax;
674ddd07fcSJed Brown   PetscInt  interptype;
684ddd07fcSJed Brown   PetscInt  agg_nl;
694ddd07fcSJed Brown   PetscInt  agg_num_paths;
704ddd07fcSJed Brown   PetscInt  nodal_coarsen;
71ace3abfcSBarry Smith   PetscBool nodal_relax;
724ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
7316d9e3a6SLisandro Dalcin } PC_HYPRE;
7416d9e3a6SLisandro Dalcin 
75d2128fa2SBarry Smith #undef __FUNCT__
76d2128fa2SBarry Smith #define __FUNCT__ "PCHYPREGetSolver"
77d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
78d2128fa2SBarry Smith {
79d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
80d2128fa2SBarry Smith 
81d2128fa2SBarry Smith   PetscFunctionBegin;
82d2128fa2SBarry Smith   *hsolver = jac->hsolver;
83d2128fa2SBarry Smith   PetscFunctionReturn(0);
84d2128fa2SBarry Smith }
8516d9e3a6SLisandro Dalcin 
8616d9e3a6SLisandro Dalcin #undef __FUNCT__
8716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE"
8816d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
8916d9e3a6SLisandro Dalcin {
9016d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
9116d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
9216d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
9316d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
9416d9e3a6SLisandro Dalcin   PetscInt           bs;
9516d9e3a6SLisandro Dalcin 
9616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
9716d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
9802a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
9916d9e3a6SLisandro Dalcin   }
1005f5c5b43SBarry Smith 
1015f5c5b43SBarry Smith   if (pc->setupcalled) {
1025f5c5b43SBarry Smith     /* always destroy the old matrix and create a new memory;
1035f5c5b43SBarry Smith        hope this does not churn the memory too much. The problem
1045f5c5b43SBarry Smith        is I do not know if it is possible to put the matrix back to
1055f5c5b43SBarry Smith        its initial state so that we can directly copy the values
1065f5c5b43SBarry Smith        the second time through. */
107fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
1085f5c5b43SBarry Smith     jac->ij = 0;
10916d9e3a6SLisandro Dalcin   }
1105f5c5b43SBarry Smith 
11116d9e3a6SLisandro Dalcin   if (!jac->ij) { /* create the matrix the first time through */
11216d9e3a6SLisandro Dalcin     ierr = MatHYPRE_IJMatrixCreate(pc->pmat,&jac->ij);CHKERRQ(ierr);
11316d9e3a6SLisandro Dalcin   }
11416d9e3a6SLisandro Dalcin   if (!jac->b) { /* create the vectors the first time through */
11516d9e3a6SLisandro Dalcin     Vec x,b;
11616d9e3a6SLisandro Dalcin     ierr = MatGetVecs(pc->pmat,&x,&b);CHKERRQ(ierr);
11716d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(x,&jac->x);CHKERRQ(ierr);
11816d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(b,&jac->b);CHKERRQ(ierr);
1196bf464f9SBarry Smith     ierr = VecDestroy(&x);CHKERRQ(ierr);
1206bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
12116d9e3a6SLisandro Dalcin   }
1225f5c5b43SBarry Smith 
12316d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
12416d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
12516d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1262fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
12716d9e3a6SLisandro Dalcin   };
12816d9e3a6SLisandro Dalcin   ierr = MatHYPRE_IJMatrixCopy(pc->pmat,jac->ij);CHKERRQ(ierr);
129fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
130fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&bv));
131fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&xv));
132fd3f9acdSBarry Smith   PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr););
13316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
13416d9e3a6SLisandro Dalcin }
13516d9e3a6SLisandro Dalcin 
13616d9e3a6SLisandro Dalcin /*
13716d9e3a6SLisandro Dalcin     Replaces the address where the HYPRE vector points to its data with the address of
13816d9e3a6SLisandro Dalcin   PETSc's data. Saves the old address so it can be reset when we are finished with it.
13916d9e3a6SLisandro Dalcin   Allows use to get the data into a HYPRE vector without the cost of memcopies
14016d9e3a6SLisandro Dalcin */
14116d9e3a6SLisandro Dalcin #define HYPREReplacePointer(b,newvalue,savedvalue) { \
14216d9e3a6SLisandro Dalcin     hypre_ParVector *par_vector   = (hypre_ParVector*)hypre_IJVectorObject(((hypre_IJVector*)b)); \
14316d9e3a6SLisandro Dalcin     hypre_Vector    *local_vector = hypre_ParVectorLocalVector(par_vector); \
14416d9e3a6SLisandro Dalcin     savedvalue         = local_vector->data; \
1450ad7597dSKarl Rupp     local_vector->data = newvalue;          \
1460ad7597dSKarl Rupp }
14716d9e3a6SLisandro Dalcin 
14816d9e3a6SLisandro Dalcin #undef __FUNCT__
14916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE"
15016d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
15116d9e3a6SLisandro Dalcin {
15216d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
15316d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
15416d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
15516d9e3a6SLisandro Dalcin   PetscScalar        *bv,*xv;
15616d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
15716d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
1584ddd07fcSJed Brown   PetscInt           hierr;
15916d9e3a6SLisandro Dalcin 
16016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
161*dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
16216d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
16316d9e3a6SLisandro Dalcin   ierr = VecGetArray(b,&bv);CHKERRQ(ierr);
16416d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
16516d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,bv,sbv);
16616d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
16716d9e3a6SLisandro Dalcin 
168fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
169fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
170fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
171fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
17265e19b50SBarry Smith                                if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
173fd3f9acdSBarry Smith                                if (hierr) hypre__global_error = 0;);
17416d9e3a6SLisandro Dalcin 
17516d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
17616d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
17716d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
17816d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(b,&bv);CHKERRQ(ierr);
17916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
18016d9e3a6SLisandro Dalcin }
18116d9e3a6SLisandro Dalcin 
18216d9e3a6SLisandro Dalcin #undef __FUNCT__
18316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE"
18416d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
18516d9e3a6SLisandro Dalcin {
18616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
18716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
18816d9e3a6SLisandro Dalcin 
18916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
190fd3f9acdSBarry Smith   if (jac->ij) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
191fd3f9acdSBarry Smith   if (jac->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->b));
192fd3f9acdSBarry Smith   if (jac->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->x));
193fd3f9acdSBarry Smith   if (jac->destroy) PetscStackCall("HYPRE_DistroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr););
194503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
19516d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
196c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
19716d9e3a6SLisandro Dalcin 
19816d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
199bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
200bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
20116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
20216d9e3a6SLisandro Dalcin }
20316d9e3a6SLisandro Dalcin 
20416d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
20516d9e3a6SLisandro Dalcin #undef __FUNCT__
20616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut"
20716d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PC pc)
20816d9e3a6SLisandro Dalcin {
20916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
21016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
211ace3abfcSBarry Smith   PetscBool      flag;
21216d9e3a6SLisandro Dalcin 
21316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
21416d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE Pilut Options");CHKERRQ(ierr);
21516d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
216fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
21716d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
218fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
21916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
220fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
22116d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
22216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
22316d9e3a6SLisandro Dalcin }
22416d9e3a6SLisandro Dalcin 
22516d9e3a6SLisandro Dalcin #undef __FUNCT__
22616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut"
22716d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
22816d9e3a6SLisandro Dalcin {
22916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
23016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
231ace3abfcSBarry Smith   PetscBool      iascii;
23216d9e3a6SLisandro Dalcin 
23316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
234251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
23516d9e3a6SLisandro Dalcin   if (iascii) {
23616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
23716d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
23816d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
23916d9e3a6SLisandro Dalcin     } else {
24016d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr);
24116d9e3a6SLisandro Dalcin     }
24216d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
24316d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: drop tolerance %G\n",jac->tol);CHKERRQ(ierr);
24416d9e3a6SLisandro Dalcin     } else {
24516d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr);
24616d9e3a6SLisandro Dalcin     }
24716d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
24816d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
24916d9e3a6SLisandro Dalcin     } else {
25016d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default factor row size \n");CHKERRQ(ierr);
25116d9e3a6SLisandro Dalcin     }
25216d9e3a6SLisandro Dalcin   }
25316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
25416d9e3a6SLisandro Dalcin }
25516d9e3a6SLisandro Dalcin 
25616d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
25716d9e3a6SLisandro Dalcin #undef __FUNCT__
25816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Euclid"
25916d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PC pc)
26016d9e3a6SLisandro Dalcin {
26116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
26216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
263ace3abfcSBarry Smith   PetscBool      flag;
264390e7148SBarry Smith   char           *args[8],levels[16];
265390e7148SBarry Smith   PetscInt       cnt = 0;
26616d9e3a6SLisandro Dalcin 
26716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
26816d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE Euclid Options");CHKERRQ(ierr);
26916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_euclid_levels","Number of levels of fill ILU(k)","None",jac->levels,&jac->levels,&flag);CHKERRQ(ierr);
27016d9e3a6SLisandro Dalcin   if (flag) {
271ce94432eSBarry Smith     if (jac->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be nonegative",jac->levels);
2728caf3d72SBarry Smith     ierr        = PetscSNPrintf(levels,sizeof(levels),"%D",jac->levels);CHKERRQ(ierr);
273390e7148SBarry Smith     args[cnt++] = (char*)"-level"; args[cnt++] = levels;
27416d9e3a6SLisandro Dalcin   }
2750298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_hypre_euclid_bj","Use block Jacobi ILU(k)","None",jac->bjilu,&jac->bjilu,NULL);CHKERRQ(ierr);
27616d9e3a6SLisandro Dalcin   if (jac->bjilu) {
277390e7148SBarry Smith     args[cnt++] =(char*) "-bj"; args[cnt++] = (char*)"1";
27816d9e3a6SLisandro Dalcin   }
27916d9e3a6SLisandro Dalcin 
2800298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_hypre_euclid_print_statistics","Print statistics","None",jac->printstatistics,&jac->printstatistics,NULL);CHKERRQ(ierr);
28116d9e3a6SLisandro Dalcin   if (jac->printstatistics) {
282390e7148SBarry Smith     args[cnt++] = (char*)"-eu_stats"; args[cnt++] = (char*)"1";
283390e7148SBarry Smith     args[cnt++] = (char*)"-eu_mem"; args[cnt++] = (char*)"1";
28416d9e3a6SLisandro Dalcin   }
28516d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
286fd3f9acdSBarry Smith   if (cnt) PetscStackCallStandard(HYPRE_EuclidSetParams,(jac->hsolver,cnt,args));
28716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
28816d9e3a6SLisandro Dalcin }
28916d9e3a6SLisandro Dalcin 
29016d9e3a6SLisandro Dalcin #undef __FUNCT__
29116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Euclid"
29216d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer)
29316d9e3a6SLisandro Dalcin {
29416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
29516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
296ace3abfcSBarry Smith   PetscBool      iascii;
29716d9e3a6SLisandro Dalcin 
29816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
299251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
30016d9e3a6SLisandro Dalcin   if (iascii) {
30116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid preconditioning\n");CHKERRQ(ierr);
30216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid: number of levels %d\n",jac->levels);CHKERRQ(ierr);
30316d9e3a6SLisandro Dalcin     if (jac->bjilu) {
30416d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid: Using block Jacobi ILU instead of parallel ILU\n");CHKERRQ(ierr);
30516d9e3a6SLisandro Dalcin     }
30616d9e3a6SLisandro Dalcin   }
30716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
30816d9e3a6SLisandro Dalcin }
30916d9e3a6SLisandro Dalcin 
31016d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
31116d9e3a6SLisandro Dalcin 
31216d9e3a6SLisandro Dalcin #undef __FUNCT__
31316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG"
31416d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
31516d9e3a6SLisandro Dalcin {
31616d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
31716d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
31816d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
31916d9e3a6SLisandro Dalcin   PetscScalar        *bv,*xv;
32016d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
32116d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
3224ddd07fcSJed Brown   PetscInt           hierr;
32316d9e3a6SLisandro Dalcin 
32416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
325*dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
32616d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
32716d9e3a6SLisandro Dalcin   ierr = VecGetArray(b,&bv);CHKERRQ(ierr);
32816d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
32916d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,bv,sbv);
33016d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
33116d9e3a6SLisandro Dalcin 
332fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
333fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
334fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
33516d9e3a6SLisandro Dalcin 
33616d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
33716d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
338e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
33916d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
34016d9e3a6SLisandro Dalcin 
34116d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
34216d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
34316d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
34416d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(b,&bv);CHKERRQ(ierr);
34516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
34616d9e3a6SLisandro Dalcin }
34716d9e3a6SLisandro Dalcin 
348a669f990SJed Brown /* static array length */
349a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
350a669f990SJed Brown 
35116d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
3520f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
35316d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
35465de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
35565de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
35665de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
35765de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
35865de4495SJed Brown                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */,
35965de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
3600f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
3610f1074feSSatish Balay                                                   "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"};
36216d9e3a6SLisandro Dalcin #undef __FUNCT__
36316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG"
36416d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PC pc)
36516d9e3a6SLisandro Dalcin {
36616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
36716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
3684ddd07fcSJed Brown   PetscInt       n,indx,level;
369ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
37016d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
37116d9e3a6SLisandro Dalcin 
37216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
37316d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE BoomerAMG Options");CHKERRQ(ierr);
3744336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
37516d9e3a6SLisandro Dalcin   if (flg) {
3764336a9eeSBarry Smith     jac->cycletype = indx+1;
377fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
37816d9e3a6SLisandro Dalcin   }
37916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
38016d9e3a6SLisandro Dalcin   if (flg) {
381ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
382fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
38316d9e3a6SLisandro Dalcin   }
38416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
38516d9e3a6SLisandro Dalcin   if (flg) {
386ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
387fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
38816d9e3a6SLisandro Dalcin   }
3890f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_tol","Convergence tolerance PER hypre call (0.0 = use a fixed number of iterations)","None",jac->tol,&jac->tol,&flg);CHKERRQ(ierr);
39016d9e3a6SLisandro Dalcin   if (flg) {
391ce94432eSBarry Smith     if (jac->tol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Tolerance %G must be greater than or equal to zero",jac->tol);
392fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
39316d9e3a6SLisandro Dalcin   }
39416d9e3a6SLisandro Dalcin 
3950f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
39616d9e3a6SLisandro Dalcin   if (flg) {
397ce94432eSBarry Smith     if (jac->truncfactor < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Truncation factor %G must be great than or equal zero",jac->truncfactor);
398fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
39916d9e3a6SLisandro Dalcin   }
40016d9e3a6SLisandro Dalcin 
4010f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_P_max","Max elements per row for interpolation operator (0=unlimited)","None",jac->pmax,&jac->pmax,&flg);CHKERRQ(ierr);
4020f1074feSSatish Balay   if (flg) {
403ce94432eSBarry Smith     if (jac->pmax < 0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"P_max %G must be greater than or equal to zero",jac->pmax);
404fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
4050f1074feSSatish Balay   }
4060f1074feSSatish Balay 
4070f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
4080f1074feSSatish Balay   if (flg) {
409ce94432eSBarry Smith     if (jac->agg_nl < 0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %G must be greater than or equal to zero",jac->agg_nl);
4100f1074feSSatish Balay 
411fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
4120f1074feSSatish Balay   }
4130f1074feSSatish Balay 
4140f1074feSSatish Balay 
4150f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_num_paths","Number of paths for aggressive coarsening","None",jac->agg_num_paths,&jac->agg_num_paths,&flg);CHKERRQ(ierr);
4160f1074feSSatish Balay   if (flg) {
417ce94432eSBarry Smith     if (jac->agg_num_paths < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of paths %G must be greater than or equal to 1",jac->agg_num_paths);
4180f1074feSSatish Balay 
419fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
4200f1074feSSatish Balay   }
4210f1074feSSatish Balay 
4220f1074feSSatish Balay 
42316d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
42416d9e3a6SLisandro Dalcin   if (flg) {
425ce94432eSBarry Smith     if (jac->strongthreshold < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Strong threshold %G must be great than or equal zero",jac->strongthreshold);
426fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
42716d9e3a6SLisandro Dalcin   }
42816d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
42916d9e3a6SLisandro Dalcin   if (flg) {
430ce94432eSBarry Smith     if (jac->maxrowsum < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Maximum row sum %G must be greater than zero",jac->maxrowsum);
431ce94432eSBarry Smith     if (jac->maxrowsum > 1.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Maximum row sum %G must be less than or equal one",jac->maxrowsum);
432fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
43316d9e3a6SLisandro Dalcin   }
43416d9e3a6SLisandro Dalcin 
43516d9e3a6SLisandro Dalcin   /* Grid sweeps */
4360f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_all","Number of sweeps for the up and down grid levels","None",jac->gridsweeps[0],&indx,&flg);CHKERRQ(ierr);
43716d9e3a6SLisandro Dalcin   if (flg) {
438fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
43916d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
44016d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
4410f1074feSSatish Balay     jac->gridsweeps[1] = indx;
4420f1074feSSatish Balay     /*defaults coarse to 1 */
4430f1074feSSatish Balay     jac->gridsweeps[2] = 1;
44416d9e3a6SLisandro Dalcin   }
4450f1074feSSatish Balay 
4460f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
44716d9e3a6SLisandro Dalcin   if (flg) {
448fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
4490f1074feSSatish Balay     jac->gridsweeps[0] = indx;
45016d9e3a6SLisandro Dalcin   }
45116d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
45216d9e3a6SLisandro Dalcin   if (flg) {
453fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
4540f1074feSSatish Balay     jac->gridsweeps[1] = indx;
45516d9e3a6SLisandro Dalcin   }
4560f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
45716d9e3a6SLisandro Dalcin   if (flg) {
458fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
4590f1074feSSatish Balay     jac->gridsweeps[2] = indx;
46016d9e3a6SLisandro Dalcin   }
46116d9e3a6SLisandro Dalcin 
46216d9e3a6SLisandro Dalcin   /* Relax type */
463a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_all","Relax type for the up and down cycles","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr);
46416d9e3a6SLisandro Dalcin   if (flg) {
4650f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
466fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
4670f1074feSSatish Balay     /* by default, coarse type set to 9 */
4680f1074feSSatish Balay     jac->relaxtype[2] = 9;
4690f1074feSSatish Balay 
47016d9e3a6SLisandro Dalcin   }
471a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_down","Relax type for the down cycles","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr);
47216d9e3a6SLisandro Dalcin   if (flg) {
47316d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
474fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
47516d9e3a6SLisandro Dalcin   }
476a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_up","Relax type for the up cycles","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr);
47716d9e3a6SLisandro Dalcin   if (flg) {
4780f1074feSSatish Balay     jac->relaxtype[1] = indx;
479fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
48016d9e3a6SLisandro Dalcin   }
481a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
48216d9e3a6SLisandro Dalcin   if (flg) {
4830f1074feSSatish Balay     jac->relaxtype[2] = indx;
484fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
48516d9e3a6SLisandro Dalcin   }
48616d9e3a6SLisandro Dalcin 
48716d9e3a6SLisandro Dalcin   /* Relaxation Weight */
48816d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_boomeramg_relax_weight_all","Relaxation weight for all levels (0 = hypre estimates, -k = determined with k CG steps)","None",jac->relaxweight, &tmpdbl,&flg);CHKERRQ(ierr);
48916d9e3a6SLisandro Dalcin   if (flg) {
490fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
49116d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
49216d9e3a6SLisandro Dalcin   }
49316d9e3a6SLisandro Dalcin 
49416d9e3a6SLisandro Dalcin   n         = 2;
49516d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
49616d9e3a6SLisandro Dalcin   ierr      = PetscOptionsRealArray("-pc_hypre_boomeramg_relax_weight_level","Set the relaxation weight for a particular level (weight,level)","None",twodbl, &n, &flg);CHKERRQ(ierr);
49716d9e3a6SLisandro Dalcin   if (flg) {
49816d9e3a6SLisandro Dalcin     if (n == 2) {
49916d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
500fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
501ce94432eSBarry Smith     } else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Relax weight level: you must provide 2 values separated by a comma (and no space), you provided %d",n);
50216d9e3a6SLisandro Dalcin   }
50316d9e3a6SLisandro Dalcin 
50416d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
50516d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_boomeramg_outer_relax_weight_all","Outer relaxation weight for all levels (-k = determined with k CG steps)","None",jac->outerrelaxweight, &tmpdbl,&flg);CHKERRQ(ierr);
50616d9e3a6SLisandro Dalcin   if (flg) {
507fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
50816d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
50916d9e3a6SLisandro Dalcin   }
51016d9e3a6SLisandro Dalcin 
51116d9e3a6SLisandro Dalcin   n         = 2;
51216d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
51316d9e3a6SLisandro Dalcin   ierr      = PetscOptionsRealArray("-pc_hypre_boomeramg_outer_relax_weight_level","Set the outer relaxation weight for a particular level (weight,level)","None",twodbl, &n, &flg);CHKERRQ(ierr);
51416d9e3a6SLisandro Dalcin   if (flg) {
51516d9e3a6SLisandro Dalcin     if (n == 2) {
51616d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
517fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
518ce94432eSBarry Smith     } else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Relax weight outer level: You must provide 2 values separated by a comma (and no space), you provided %d",n);
51916d9e3a6SLisandro Dalcin   }
52016d9e3a6SLisandro Dalcin 
52116d9e3a6SLisandro Dalcin   /* the Relax Order */
522acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
52316d9e3a6SLisandro Dalcin 
52416d9e3a6SLisandro Dalcin   if (flg) {
52516d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
526fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
52716d9e3a6SLisandro Dalcin   }
528a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
52916d9e3a6SLisandro Dalcin   if (flg) {
53016d9e3a6SLisandro Dalcin     jac->measuretype = indx;
531fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
53216d9e3a6SLisandro Dalcin   }
5330f1074feSSatish Balay   /* update list length 3/07 */
534a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
53516d9e3a6SLisandro Dalcin   if (flg) {
53616d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
537fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
53816d9e3a6SLisandro Dalcin   }
5390f1074feSSatish Balay 
5400f1074feSSatish Balay   /* new 3/07 */
541a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
5420f1074feSSatish Balay   if (flg) {
5430f1074feSSatish Balay     jac->interptype = indx;
544fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
5450f1074feSSatish Balay   }
5460f1074feSSatish Balay 
547b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
54816d9e3a6SLisandro Dalcin   if (flg) {
549b96a4a96SBarry Smith     level = 3;
5500298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
5512fa5cd67SKarl Rupp 
552b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
553fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
5542ae77aedSBarry Smith   }
5552ae77aedSBarry Smith 
556b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
5572ae77aedSBarry Smith   if (flg) {
558b96a4a96SBarry Smith     level = 3;
5590298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
5602fa5cd67SKarl Rupp 
561b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
562fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
56316d9e3a6SLisandro Dalcin   }
5648f87f92bSBarry Smith 
565acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_coarsen", "HYPRE_BoomerAMGSetNodal()", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5668f87f92bSBarry Smith   if (flg && tmp_truth) {
5678f87f92bSBarry Smith     jac->nodal_coarsen = 1;
568fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,1));
5698f87f92bSBarry Smith   }
5708f87f92bSBarry Smith 
571acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5728f87f92bSBarry Smith   if (flg && tmp_truth) {
5738f87f92bSBarry Smith     PetscInt tmp_int;
5748f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
5758f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
576fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
577fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
578fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
579fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
5808f87f92bSBarry Smith   }
5818f87f92bSBarry Smith 
58216d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
58316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
58416d9e3a6SLisandro Dalcin }
58516d9e3a6SLisandro Dalcin 
58616d9e3a6SLisandro Dalcin #undef __FUNCT__
58716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG"
588ace3abfcSBarry Smith static PetscErrorCode PCApplyRichardson_HYPRE_BoomerAMG(PC pc,Vec b,Vec y,Vec w,PetscReal rtol,PetscReal abstol, PetscReal dtol,PetscInt its,PetscBool guesszero,PetscInt *outits,PCRichardsonConvergedReason *reason)
58916d9e3a6SLisandro Dalcin {
59016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
59116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
5924ddd07fcSJed Brown   PetscInt       oits;
59316d9e3a6SLisandro Dalcin 
59416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
595*dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
596fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
597fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
59816d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
59916d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
60016d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
601fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,&oits));
6024d0a8057SBarry Smith   *outits = oits;
6034d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
6044d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
605fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
606fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
60716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
60816d9e3a6SLisandro Dalcin }
60916d9e3a6SLisandro Dalcin 
61016d9e3a6SLisandro Dalcin 
61116d9e3a6SLisandro Dalcin #undef __FUNCT__
61216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG"
61316d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
61416d9e3a6SLisandro Dalcin {
61516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
61616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
617ace3abfcSBarry Smith   PetscBool      iascii;
61816d9e3a6SLisandro Dalcin 
61916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
620251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
62116d9e3a6SLisandro Dalcin   if (iascii) {
62216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
62316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
62416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
62516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
62616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Convergence tolerance PER hypre call %G\n",jac->tol);CHKERRQ(ierr);
62716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Threshold for strong coupling %G\n",jac->strongthreshold);CHKERRQ(ierr);
6280f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation truncation factor %G\n",jac->truncfactor);CHKERRQ(ierr);
6290f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
6300f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
6310f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
6320f1074feSSatish Balay 
63316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum row sums %G\n",jac->maxrowsum);CHKERRQ(ierr);
63416d9e3a6SLisandro Dalcin 
6350f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
6360f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
6370f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
63816d9e3a6SLisandro Dalcin 
6390f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
6400f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
6410f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
64216d9e3a6SLisandro Dalcin 
64316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax weight  (all)      %G\n",jac->relaxweight);CHKERRQ(ierr);
64416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Outer relax weight (all) %G\n",jac->outerrelaxweight);CHKERRQ(ierr);
64516d9e3a6SLisandro Dalcin 
64616d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
64716d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr);
64816d9e3a6SLisandro Dalcin     } else {
64916d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr);
65016d9e3a6SLisandro Dalcin     }
65116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
65216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
6530f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
6548f87f92bSBarry Smith     if (jac->nodal_coarsen) {
6558f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal())\n");CHKERRQ(ierr);
6568f87f92bSBarry Smith     }
6578f87f92bSBarry Smith     if (jac->nodal_relax) {
6588f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
6598f87f92bSBarry Smith     }
66016d9e3a6SLisandro Dalcin   }
66116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
66216d9e3a6SLisandro Dalcin }
66316d9e3a6SLisandro Dalcin 
66416d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
66516d9e3a6SLisandro Dalcin #undef __FUNCT__
66616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails"
66716d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PC pc)
66816d9e3a6SLisandro Dalcin {
66916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
67016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
6714ddd07fcSJed Brown   PetscInt       indx;
672ace3abfcSBarry Smith   PetscBool      flag;
67316d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
67416d9e3a6SLisandro Dalcin 
67516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
67616d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE ParaSails Options");CHKERRQ(ierr);
67716d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
67816d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
6792fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
68016d9e3a6SLisandro Dalcin 
68116d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
6822fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
68316d9e3a6SLisandro Dalcin 
68416d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
6852fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
68616d9e3a6SLisandro Dalcin 
687acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
6882fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
68916d9e3a6SLisandro Dalcin 
690acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
6912fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
69216d9e3a6SLisandro Dalcin 
693a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
69416d9e3a6SLisandro Dalcin   if (flag) {
69516d9e3a6SLisandro Dalcin     jac->symt = indx;
696fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
69716d9e3a6SLisandro Dalcin   }
69816d9e3a6SLisandro Dalcin 
69916d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
70016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
70116d9e3a6SLisandro Dalcin }
70216d9e3a6SLisandro Dalcin 
70316d9e3a6SLisandro Dalcin #undef __FUNCT__
70416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails"
70516d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
70616d9e3a6SLisandro Dalcin {
70716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
70816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
709ace3abfcSBarry Smith   PetscBool      iascii;
71016d9e3a6SLisandro Dalcin   const char     *symt = 0;;
71116d9e3a6SLisandro Dalcin 
71216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
713251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
71416d9e3a6SLisandro Dalcin   if (iascii) {
71516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
71616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
71716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: threshold %G\n",jac->threshhold);CHKERRQ(ierr);
71816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: filter %G\n",jac->filter);CHKERRQ(ierr);
71916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: load balance %G\n",jac->loadbal);CHKERRQ(ierr);
720ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
721ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
7222fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
7232fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
7242fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
725ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
72616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr);
72716d9e3a6SLisandro Dalcin   }
72816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
72916d9e3a6SLisandro Dalcin }
73016d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
73116d9e3a6SLisandro Dalcin 
73216d9e3a6SLisandro Dalcin #undef __FUNCT__
73316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
734f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
73516d9e3a6SLisandro Dalcin {
73616d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
73716d9e3a6SLisandro Dalcin 
73816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
73916d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
74016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
74116d9e3a6SLisandro Dalcin }
74216d9e3a6SLisandro Dalcin 
74316d9e3a6SLisandro Dalcin #undef __FUNCT__
74416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
745f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
74616d9e3a6SLisandro Dalcin {
74716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
74816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
749ace3abfcSBarry Smith   PetscBool      flag;
75016d9e3a6SLisandro Dalcin 
75116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
75216d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
75316d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
754ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
75516d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
75616d9e3a6SLisandro Dalcin   } else {
75716d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
75816d9e3a6SLisandro Dalcin   }
75916d9e3a6SLisandro Dalcin 
76016d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
76116d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
76216d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
76316d9e3a6SLisandro Dalcin 
76416d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
76516d9e3a6SLisandro Dalcin   if (flag) {
766fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
76716d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
76816d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
76916d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
77016d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
77116d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
77216d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
77316d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
77416d9e3a6SLisandro Dalcin   }
77516d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
77616d9e3a6SLisandro Dalcin   if (flag) {
777fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
77816d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
77916d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
78016d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
78116d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
78216d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
78316d9e3a6SLisandro Dalcin     /* initialize */
78416d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
78516d9e3a6SLisandro Dalcin     jac->threshhold = .1;
78616d9e3a6SLisandro Dalcin     jac->filter     = .1;
78716d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
7882fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
7892fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
7902fa5cd67SKarl Rupp 
79116d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
79216d9e3a6SLisandro Dalcin     jac->symt = 0;
793fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
794fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
795fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
796fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
797fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
798fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
79916d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
80016d9e3a6SLisandro Dalcin   }
80116d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("euclid",jac->hypre_type,&flag);CHKERRQ(ierr);
80216d9e3a6SLisandro Dalcin   if (flag) {
80316d9e3a6SLisandro Dalcin     ierr                    = HYPRE_EuclidCreate(jac->comm_hypre,&jac->hsolver);
80416d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
80516d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Euclid;
80616d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_EuclidDestroy;
80716d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_EuclidSetup;
80816d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_EuclidSolve;
80916d9e3a6SLisandro Dalcin     /* initialization */
81016d9e3a6SLisandro Dalcin     jac->bjilu              = PETSC_FALSE;
81116d9e3a6SLisandro Dalcin     jac->levels             = 1;
81216d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
81316d9e3a6SLisandro Dalcin   }
81416d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
81516d9e3a6SLisandro Dalcin   if (flag) {
81616d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
81716d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
81816d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
81916d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
82016d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
82116d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
82216d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
82316d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
82416d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
82516d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
82616d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
82716d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
82816d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
8298f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
83016d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
83116d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
83216d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
83316d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
83416d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
8350f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
8368f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
8370f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
83816d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
83916d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
84016d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
8410f1074feSSatish Balay     jac->interptype       = 0;
8420f1074feSSatish Balay     jac->agg_nl           = 0;
8430f1074feSSatish Balay     jac->pmax             = 0;
8440f1074feSSatish Balay     jac->truncfactor      = 0.0;
8450f1074feSSatish Balay     jac->agg_num_paths    = 1;
8468f87f92bSBarry Smith 
8478f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
8488f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
8498f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
850fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
851fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
852fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
853fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
854fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
855fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
856fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
857fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
858fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
859fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
860fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
861fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
862fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
863fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
864fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
865fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
86616d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
86716d9e3a6SLisandro Dalcin   }
868503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
8692fa5cd67SKarl Rupp 
8700298fd71SBarry Smith   jac->hypre_type = NULL;
871ce94432eSBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, euclid, boomeramg",name);
87216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
87316d9e3a6SLisandro Dalcin }
87416d9e3a6SLisandro Dalcin 
87516d9e3a6SLisandro Dalcin /*
87616d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
87716d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
87816d9e3a6SLisandro Dalcin */
87916d9e3a6SLisandro Dalcin #undef __FUNCT__
88016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
88116d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE(PC pc)
88216d9e3a6SLisandro Dalcin {
88316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
8844ddd07fcSJed Brown   PetscInt       indx;
88516d9e3a6SLisandro Dalcin   const char     *type[] = {"pilut","parasails","boomeramg","euclid"};
886ace3abfcSBarry Smith   PetscBool      flg;
88716d9e3a6SLisandro Dalcin 
88816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
88916d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE preconditioner options");CHKERRQ(ierr);
89002a17cd4SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
89116d9e3a6SLisandro Dalcin   if (flg) {
89216d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
89302a17cd4SBarry Smith   } else {
89402a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
89516d9e3a6SLisandro Dalcin   }
89616d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
89716d9e3a6SLisandro Dalcin     ierr = pc->ops->setfromoptions(pc);CHKERRQ(ierr);
89816d9e3a6SLisandro Dalcin   }
89916d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
90016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
90116d9e3a6SLisandro Dalcin }
90216d9e3a6SLisandro Dalcin 
90316d9e3a6SLisandro Dalcin #undef __FUNCT__
90416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
90516d9e3a6SLisandro Dalcin /*@C
90616d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
90716d9e3a6SLisandro Dalcin 
90816d9e3a6SLisandro Dalcin    Input Parameters:
90916d9e3a6SLisandro Dalcin +     pc - the preconditioner context
91016d9e3a6SLisandro Dalcin -     name - either  pilut, parasails, boomeramg, euclid
91116d9e3a6SLisandro Dalcin 
91216d9e3a6SLisandro Dalcin    Options Database Keys:
91316d9e3a6SLisandro Dalcin    -pc_hypre_type - One of pilut, parasails, boomeramg, euclid
91416d9e3a6SLisandro Dalcin 
91516d9e3a6SLisandro Dalcin    Level: intermediate
91616d9e3a6SLisandro Dalcin 
91716d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
91816d9e3a6SLisandro Dalcin            PCHYPRE
91916d9e3a6SLisandro Dalcin 
92016d9e3a6SLisandro Dalcin @*/
9217087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
92216d9e3a6SLisandro Dalcin {
9234ac538c5SBarry Smith   PetscErrorCode ierr;
92416d9e3a6SLisandro Dalcin 
92516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
9260700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
92716d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
9284ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
92916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
93016d9e3a6SLisandro Dalcin }
93116d9e3a6SLisandro Dalcin 
93216d9e3a6SLisandro Dalcin #undef __FUNCT__
93316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
93416d9e3a6SLisandro Dalcin /*@C
93516d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
93616d9e3a6SLisandro Dalcin 
93716d9e3a6SLisandro Dalcin    Input Parameter:
93816d9e3a6SLisandro Dalcin .     pc - the preconditioner context
93916d9e3a6SLisandro Dalcin 
94016d9e3a6SLisandro Dalcin    Output Parameter:
94116d9e3a6SLisandro Dalcin .     name - either  pilut, parasails, boomeramg, euclid
94216d9e3a6SLisandro Dalcin 
94316d9e3a6SLisandro Dalcin    Level: intermediate
94416d9e3a6SLisandro Dalcin 
94516d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
94616d9e3a6SLisandro Dalcin            PCHYPRE
94716d9e3a6SLisandro Dalcin 
94816d9e3a6SLisandro Dalcin @*/
9497087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
95016d9e3a6SLisandro Dalcin {
9514ac538c5SBarry Smith   PetscErrorCode ierr;
95216d9e3a6SLisandro Dalcin 
95316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
9540700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
95516d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
9564ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
95716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
95816d9e3a6SLisandro Dalcin }
95916d9e3a6SLisandro Dalcin 
96016d9e3a6SLisandro Dalcin /*MC
96116d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
96216d9e3a6SLisandro Dalcin 
96316d9e3a6SLisandro Dalcin    Options Database Keys:
96416d9e3a6SLisandro Dalcin +   -pc_hypre_type - One of pilut, parasails, boomeramg, euclid
96516d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
96616d9e3a6SLisandro Dalcin           preconditioner
96716d9e3a6SLisandro Dalcin 
96816d9e3a6SLisandro Dalcin    Level: intermediate
96916d9e3a6SLisandro Dalcin 
97016d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
97116d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
97216d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
97316d9e3a6SLisandro Dalcin 
97416d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
9750f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
9760f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
9770f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
9788f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
9790f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
9800f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
98116d9e3a6SLisandro Dalcin 
9820f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
9830f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
9840f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
98516d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
98616d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
98716d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
98816d9e3a6SLisandro Dalcin 
98916d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
99016d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
99116d9e3a6SLisandro Dalcin 
9929e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
9939e5bc791SBarry Smith 
99416d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
9959e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
99616d9e3a6SLisandro Dalcin 
99716d9e3a6SLisandro Dalcin M*/
99816d9e3a6SLisandro Dalcin 
99916d9e3a6SLisandro Dalcin #undef __FUNCT__
100016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
10018cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
100216d9e3a6SLisandro Dalcin {
100316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
100416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
100516d9e3a6SLisandro Dalcin 
100616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
100738f2d2fdSLisandro Dalcin   ierr = PetscNewLog(pc,PC_HYPRE,&jac);CHKERRQ(ierr);
10082fa5cd67SKarl Rupp 
100916d9e3a6SLisandro Dalcin   pc->data                = jac;
101016d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
101116d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
101216d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
101316d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
101416d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
10150298fd71SBarry Smith   jac->hypre_type         = NULL;
101616d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1017ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1018bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1019bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
102016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
102116d9e3a6SLisandro Dalcin }
1022ebc551c0SBarry Smith 
1023f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1024f91d8e95SBarry Smith 
1025b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1026b45d2f2cSJed Brown #include <petsc-private/matimpl.h>
1027ebc551c0SBarry Smith 
1028ebc551c0SBarry Smith typedef struct {
102968326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1030f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
10319e5bc791SBarry Smith 
10329e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
10334ddd07fcSJed Brown   PetscInt its;
10349e5bc791SBarry Smith   double   tol;
10354ddd07fcSJed Brown   PetscInt relax_type;
10364ddd07fcSJed Brown   PetscInt rap_type;
10374ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
10384ddd07fcSJed Brown   PetscInt max_levels;
1039ebc551c0SBarry Smith } PC_PFMG;
1040ebc551c0SBarry Smith 
1041ebc551c0SBarry Smith #undef __FUNCT__
1042ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1043ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1044ebc551c0SBarry Smith {
1045ebc551c0SBarry Smith   PetscErrorCode ierr;
1046f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1047ebc551c0SBarry Smith 
1048ebc551c0SBarry Smith   PetscFunctionBegin;
10492fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1050f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1051c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1052ebc551c0SBarry Smith   PetscFunctionReturn(0);
1053ebc551c0SBarry Smith }
1054ebc551c0SBarry Smith 
10559e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
10569e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
10579e5bc791SBarry Smith 
1058ebc551c0SBarry Smith #undef __FUNCT__
1059ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1060ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1061ebc551c0SBarry Smith {
1062ebc551c0SBarry Smith   PetscErrorCode ierr;
1063ace3abfcSBarry Smith   PetscBool      iascii;
1064f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1065ebc551c0SBarry Smith 
1066ebc551c0SBarry Smith   PetscFunctionBegin;
1067251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
10689e5bc791SBarry Smith   if (iascii) {
10699e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
10709e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
10719e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
10729e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
10739e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
10749e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
10753b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
10769e5bc791SBarry Smith   }
1077ebc551c0SBarry Smith   PetscFunctionReturn(0);
1078ebc551c0SBarry Smith }
1079ebc551c0SBarry Smith 
10809e5bc791SBarry Smith 
1081ebc551c0SBarry Smith #undef __FUNCT__
1082ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
1083ebc551c0SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PC pc)
1084ebc551c0SBarry Smith {
1085ebc551c0SBarry Smith   PetscErrorCode ierr;
1086f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1087ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1088ebc551c0SBarry Smith 
1089ebc551c0SBarry Smith   PetscFunctionBegin;
1090ebc551c0SBarry Smith   ierr = PetscOptionsHead("PFMG options");CHKERRQ(ierr);
10910298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
109268326731SBarry Smith   if (flg) {
1093a0324ebeSBarry Smith     int level=3;
1094fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
109568326731SBarry Smith   }
10960298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1097fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
10980298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_num_pre_relax","Number of smoothing steps before coarse grid","HYPRE_StructPFMGSetNumPreRelax",ex->num_pre_relax,&ex->num_pre_relax,NULL);CHKERRQ(ierr);
1099fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
11000298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_num_post_relax","Number of smoothing steps after coarse grid","HYPRE_StructPFMGSetNumPostRelax",ex->num_post_relax,&ex->num_post_relax,NULL);CHKERRQ(ierr);
1101fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
11029e5bc791SBarry Smith 
11030298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
1104fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
11053b46a515SGlenn Hammond 
11060298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1107fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
11080298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_relax_type","Relax type for the up and down cycles","HYPRE_StructPFMGSetRelaxType",PFMGRelaxType,ALEN(PFMGRelaxType),PFMGRelaxType[ex->relax_type],&ex->relax_type,NULL);CHKERRQ(ierr);
1109fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
11100298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
1111fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1112ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1113ebc551c0SBarry Smith   PetscFunctionReturn(0);
1114ebc551c0SBarry Smith }
1115ebc551c0SBarry Smith 
1116f91d8e95SBarry Smith #undef __FUNCT__
1117f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1118f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1119f91d8e95SBarry Smith {
1120f91d8e95SBarry Smith   PetscErrorCode  ierr;
1121f91d8e95SBarry Smith   PC_PFMG         *ex = (PC_PFMG*) pc->data;
1122f91d8e95SBarry Smith   PetscScalar     *xx,*yy;
11234ddd07fcSJed Brown   PetscInt        ilower[3],iupper[3];
112468326731SBarry Smith   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1125f91d8e95SBarry Smith 
1126f91d8e95SBarry Smith   PetscFunctionBegin;
1127*dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1128aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1129f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1130f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1131f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1132f91d8e95SBarry Smith 
1133f91d8e95SBarry Smith   /* copy x values over to hypre */
1134fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1135f91d8e95SBarry Smith   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
1136fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,ilower,iupper,xx));
1137f91d8e95SBarry Smith   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
1138fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
1139fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1140f91d8e95SBarry Smith 
1141f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1142f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
1143fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,ilower,iupper,yy));
1144f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1145f91d8e95SBarry Smith   PetscFunctionReturn(0);
1146f91d8e95SBarry Smith }
1147f91d8e95SBarry Smith 
11489e5bc791SBarry Smith #undef __FUNCT__
11499e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1150ace3abfcSBarry Smith static PetscErrorCode PCApplyRichardson_PFMG(PC pc,Vec b,Vec y,Vec w,PetscReal rtol,PetscReal abstol, PetscReal dtol,PetscInt its,PetscBool guesszero,PetscInt *outits,PCRichardsonConvergedReason *reason)
11519e5bc791SBarry Smith {
11529e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
11539e5bc791SBarry Smith   PetscErrorCode ierr;
11544ddd07fcSJed Brown   PetscInt       oits;
11559e5bc791SBarry Smith 
11569e5bc791SBarry Smith   PetscFunctionBegin;
1157*dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1158fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1159fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
11609e5bc791SBarry Smith 
11619e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
1162fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,&oits));
11639e5bc791SBarry Smith   *outits = oits;
11649e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
11659e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1166fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1167fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
11689e5bc791SBarry Smith   PetscFunctionReturn(0);
11699e5bc791SBarry Smith }
11709e5bc791SBarry Smith 
11719e5bc791SBarry Smith 
11723a32d3dbSGlenn Hammond #undef __FUNCT__
11733a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
11743a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
11753a32d3dbSGlenn Hammond {
11763a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
11773a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
11783a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1179ace3abfcSBarry Smith   PetscBool       flg;
11803a32d3dbSGlenn Hammond 
11813a32d3dbSGlenn Hammond   PetscFunctionBegin;
1182251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1183ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
11843a32d3dbSGlenn Hammond 
11853a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
11862fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1187fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
11883a32d3dbSGlenn Hammond   ierr = PCSetFromOptions_PFMG(pc);CHKERRQ(ierr);
1189fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1190fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
11913a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
11923a32d3dbSGlenn Hammond }
11933a32d3dbSGlenn Hammond 
1194ebc551c0SBarry Smith 
1195ebc551c0SBarry Smith /*MC
1196ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1197ebc551c0SBarry Smith 
1198ebc551c0SBarry Smith    Level: advanced
1199ebc551c0SBarry Smith 
12009e5bc791SBarry Smith    Options Database:
12019e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
12029e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
12039e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
12049e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
12059e5bc791SBarry Smith . -pc_pfmg_relax_type -relaxation type for the up and down cycles, one of Jacobi,Weighted-Jacobi,symmetric-Red/Black-Gauss-Seidel,Red/Black-Gauss-Seidel
12069e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
1207f91d8e95SBarry Smith 
12089e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
12099e5bc791SBarry Smith 
12108e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
1211aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
12129e5bc791SBarry Smith 
12139e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
1214ebc551c0SBarry Smith M*/
1215ebc551c0SBarry Smith 
1216ebc551c0SBarry Smith #undef __FUNCT__
1217ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
12188cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
1219ebc551c0SBarry Smith {
1220ebc551c0SBarry Smith   PetscErrorCode ierr;
1221ebc551c0SBarry Smith   PC_PFMG        *ex;
1222ebc551c0SBarry Smith 
1223ebc551c0SBarry Smith   PetscFunctionBegin;
1224ebc551c0SBarry Smith   ierr     = PetscNew(PC_PFMG,&ex);CHKERRQ(ierr); \
122568326731SBarry Smith   pc->data = ex;
1226ebc551c0SBarry Smith 
12279e5bc791SBarry Smith   ex->its            = 1;
12289e5bc791SBarry Smith   ex->tol            = 1.e-8;
12299e5bc791SBarry Smith   ex->relax_type     = 1;
12309e5bc791SBarry Smith   ex->rap_type       = 0;
12319e5bc791SBarry Smith   ex->num_pre_relax  = 1;
12329e5bc791SBarry Smith   ex->num_post_relax = 1;
12333b46a515SGlenn Hammond   ex->max_levels     = 0;
12349e5bc791SBarry Smith 
1235ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
1236ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
1237ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
1238f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
12399e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
124068326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
12412fa5cd67SKarl Rupp 
1242ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
1243fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1244ebc551c0SBarry Smith   PetscFunctionReturn(0);
1245ebc551c0SBarry Smith }
1246d851a50bSGlenn Hammond 
1247325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
1248325fc9f4SBarry Smith 
1249d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
1250d851a50bSGlenn Hammond typedef struct {
1251d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
1252d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
1253d851a50bSGlenn Hammond 
1254d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
12554ddd07fcSJed Brown   PetscInt its;
1256d851a50bSGlenn Hammond   double   tol;
12574ddd07fcSJed Brown   PetscInt relax_type;
12584ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
1259d851a50bSGlenn Hammond } PC_SysPFMG;
1260d851a50bSGlenn Hammond 
1261d851a50bSGlenn Hammond #undef __FUNCT__
1262d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
1263d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
1264d851a50bSGlenn Hammond {
1265d851a50bSGlenn Hammond   PetscErrorCode ierr;
1266d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1267d851a50bSGlenn Hammond 
1268d851a50bSGlenn Hammond   PetscFunctionBegin;
12692fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1270d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1271c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1272d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1273d851a50bSGlenn Hammond }
1274d851a50bSGlenn Hammond 
1275d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
1276d851a50bSGlenn Hammond 
1277d851a50bSGlenn Hammond #undef __FUNCT__
1278d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
1279d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
1280d851a50bSGlenn Hammond {
1281d851a50bSGlenn Hammond   PetscErrorCode ierr;
1282ace3abfcSBarry Smith   PetscBool      iascii;
1283d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1284d851a50bSGlenn Hammond 
1285d851a50bSGlenn Hammond   PetscFunctionBegin;
1286251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1287d851a50bSGlenn Hammond   if (iascii) {
1288d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
1289d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
1290d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
1291d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
1292d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
1293d851a50bSGlenn Hammond   }
1294d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1295d851a50bSGlenn Hammond }
1296d851a50bSGlenn Hammond 
1297d851a50bSGlenn Hammond 
1298d851a50bSGlenn Hammond #undef __FUNCT__
1299d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
1300d851a50bSGlenn Hammond PetscErrorCode PCSetFromOptions_SysPFMG(PC pc)
1301d851a50bSGlenn Hammond {
1302d851a50bSGlenn Hammond   PetscErrorCode ierr;
1303d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1304ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1305d851a50bSGlenn Hammond 
1306d851a50bSGlenn Hammond   PetscFunctionBegin;
1307d851a50bSGlenn Hammond   ierr = PetscOptionsHead("SysPFMG options");CHKERRQ(ierr);
13080298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
1309d851a50bSGlenn Hammond   if (flg) {
1310d851a50bSGlenn Hammond     int level=3;
1311fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
1312d851a50bSGlenn Hammond   }
13130298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1314fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
13150298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_num_pre_relax","Number of smoothing steps before coarse grid","HYPRE_SStructSysPFMGSetNumPreRelax",ex->num_pre_relax,&ex->num_pre_relax,NULL);CHKERRQ(ierr);
1316fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
13170298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_num_post_relax","Number of smoothing steps after coarse grid","HYPRE_SStructSysPFMGSetNumPostRelax",ex->num_post_relax,&ex->num_post_relax,NULL);CHKERRQ(ierr);
1318fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
1319d851a50bSGlenn Hammond 
13200298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1321fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
13220298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_syspfmg_relax_type","Relax type for the up and down cycles","HYPRE_SStructSysPFMGSetRelaxType",SysPFMGRelaxType,4,SysPFMGRelaxType[ex->relax_type],&ex->relax_type,NULL);CHKERRQ(ierr);
1323fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
1324d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
1325d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1326d851a50bSGlenn Hammond }
1327d851a50bSGlenn Hammond 
1328d851a50bSGlenn Hammond #undef __FUNCT__
1329d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
1330d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
1331d851a50bSGlenn Hammond {
1332d851a50bSGlenn Hammond   PetscErrorCode   ierr;
1333d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
1334d851a50bSGlenn Hammond   PetscScalar      *xx,*yy;
13354ddd07fcSJed Brown   PetscInt         ilower[3],iupper[3];
1336d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
13374ddd07fcSJed Brown   PetscInt         ordering= mx->dofs_order;
13384ddd07fcSJed Brown   PetscInt         nvars   = mx->nvars;
13394ddd07fcSJed Brown   PetscInt         part    = 0;
13404ddd07fcSJed Brown   PetscInt         size;
13414ddd07fcSJed Brown   PetscInt         i;
1342d851a50bSGlenn Hammond 
1343d851a50bSGlenn Hammond   PetscFunctionBegin;
1344*dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1345aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1346d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
1347d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
1348d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
1349d851a50bSGlenn Hammond 
1350d851a50bSGlenn Hammond   size = 1;
13512fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
13522fa5cd67SKarl Rupp 
1353d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
1354d851a50bSGlenn Hammond   if (ordering) {
1355fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
1356d851a50bSGlenn Hammond     ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
13572fa5cd67SKarl Rupp     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,ilower,iupper,i,xx+(size*i)));
1358d851a50bSGlenn Hammond     ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
1359fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
1360fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
1361fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1362d851a50bSGlenn Hammond 
1363d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
1364d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
13652fa5cd67SKarl Rupp     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,ilower,iupper,i,yy+(size*i)));
1366d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1367a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
1368d851a50bSGlenn Hammond     PetscScalar *z;
13694ddd07fcSJed Brown     PetscInt    j, k;
1370d851a50bSGlenn Hammond 
1371d851a50bSGlenn Hammond     ierr = PetscMalloc(nvars*size*sizeof(PetscScalar),&z);CHKERRQ(ierr);
1372fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
1373d851a50bSGlenn Hammond     ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
1374d851a50bSGlenn Hammond 
1375d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
1376d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
1377d851a50bSGlenn Hammond       k= i*nvars;
13782fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
1379d851a50bSGlenn Hammond     }
13802fa5cd67SKarl Rupp     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,ilower,iupper,i,z+(size*i)));
1381d851a50bSGlenn Hammond     ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
1382fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
1383fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1384d851a50bSGlenn Hammond 
1385d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
1386d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
13872fa5cd67SKarl Rupp     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,ilower,iupper,i,z+(size*i)));
1388d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
1389d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
1390d851a50bSGlenn Hammond       k= i*nvars;
13912fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
1392d851a50bSGlenn Hammond     }
1393d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1394d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
1395d851a50bSGlenn Hammond   }
1396d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1397d851a50bSGlenn Hammond }
1398d851a50bSGlenn Hammond 
1399d851a50bSGlenn Hammond #undef __FUNCT__
1400d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
1401ace3abfcSBarry Smith static PetscErrorCode PCApplyRichardson_SysPFMG(PC pc,Vec b,Vec y,Vec w,PetscReal rtol,PetscReal abstol, PetscReal dtol,PetscInt its,PetscBool guesszero,PetscInt *outits,PCRichardsonConvergedReason *reason)
1402d851a50bSGlenn Hammond {
1403d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
1404d851a50bSGlenn Hammond   PetscErrorCode ierr;
14054ddd07fcSJed Brown   PetscInt       oits;
1406d851a50bSGlenn Hammond 
1407d851a50bSGlenn Hammond   PetscFunctionBegin;
1408*dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1409fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
1410fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
1411d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
1412fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,&oits));
1413d851a50bSGlenn Hammond   *outits = oits;
1414d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
1415d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1416fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
1417fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
1418d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1419d851a50bSGlenn Hammond }
1420d851a50bSGlenn Hammond 
1421d851a50bSGlenn Hammond 
1422d851a50bSGlenn Hammond #undef __FUNCT__
1423d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
1424d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
1425d851a50bSGlenn Hammond {
1426d851a50bSGlenn Hammond   PetscErrorCode   ierr;
1427d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
1428d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
1429ace3abfcSBarry Smith   PetscBool        flg;
1430d851a50bSGlenn Hammond 
1431d851a50bSGlenn Hammond   PetscFunctionBegin;
1432251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
1433ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
1434d851a50bSGlenn Hammond 
1435d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
14362fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1437fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
1438d851a50bSGlenn Hammond   ierr = PCSetFromOptions_SysPFMG(pc);CHKERRQ(ierr);
1439fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
1440fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1441d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1442d851a50bSGlenn Hammond }
1443d851a50bSGlenn Hammond 
1444d851a50bSGlenn Hammond 
1445d851a50bSGlenn Hammond /*MC
1446d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
1447d851a50bSGlenn Hammond 
1448d851a50bSGlenn Hammond    Level: advanced
1449d851a50bSGlenn Hammond 
1450d851a50bSGlenn Hammond    Options Database:
1451d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
1452d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
1453d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
1454d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
1455d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
1456d851a50bSGlenn Hammond 
1457d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
1458d851a50bSGlenn Hammond 
1459f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
1460aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
1461d851a50bSGlenn Hammond            Also, only cell-centered variables.
1462d851a50bSGlenn Hammond 
1463d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
1464d851a50bSGlenn Hammond M*/
1465d851a50bSGlenn Hammond 
1466d851a50bSGlenn Hammond #undef __FUNCT__
1467d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
14688cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
1469d851a50bSGlenn Hammond {
1470d851a50bSGlenn Hammond   PetscErrorCode ierr;
1471d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
1472d851a50bSGlenn Hammond 
1473d851a50bSGlenn Hammond   PetscFunctionBegin;
1474d851a50bSGlenn Hammond   ierr     = PetscNew(PC_SysPFMG,&ex);CHKERRQ(ierr); \
1475d851a50bSGlenn Hammond   pc->data = ex;
1476d851a50bSGlenn Hammond 
1477d851a50bSGlenn Hammond   ex->its            = 1;
1478d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
1479d851a50bSGlenn Hammond   ex->relax_type     = 1;
1480d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
1481d851a50bSGlenn Hammond   ex->num_post_relax = 1;
1482d851a50bSGlenn Hammond 
1483d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
1484d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
1485d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
1486d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
1487d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
1488d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
14892fa5cd67SKarl Rupp 
1490ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
1491fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
1492d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1493d851a50bSGlenn Hammond }
1494