xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision c6db04a5321582041def2b1e244c75985478b3ef)
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 
8*c6db04a5SJed Brown #include <private/pcimpl.h>          /*I "petscpc.h" I*/
9*c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h>
1016d9e3a6SLisandro Dalcin 
1116d9e3a6SLisandro Dalcin /*
1216d9e3a6SLisandro Dalcin    Private context (data structure) for the  preconditioner.
1316d9e3a6SLisandro Dalcin */
1416d9e3a6SLisandro Dalcin typedef struct {
1516d9e3a6SLisandro Dalcin   HYPRE_Solver       hsolver;
1616d9e3a6SLisandro Dalcin   HYPRE_IJMatrix     ij;
1716d9e3a6SLisandro Dalcin   HYPRE_IJVector     b,x;
1816d9e3a6SLisandro Dalcin 
1916d9e3a6SLisandro Dalcin   PetscErrorCode     (*destroy)(HYPRE_Solver);
2016d9e3a6SLisandro Dalcin   PetscErrorCode     (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
2116d9e3a6SLisandro Dalcin   PetscErrorCode     (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
2216d9e3a6SLisandro Dalcin 
2316d9e3a6SLisandro Dalcin   MPI_Comm           comm_hypre;
2416d9e3a6SLisandro Dalcin   char              *hypre_type;
2516d9e3a6SLisandro Dalcin 
2616d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
2716d9e3a6SLisandro Dalcin   int                maxiter;
2816d9e3a6SLisandro Dalcin   double             tol;
2916d9e3a6SLisandro Dalcin 
3016d9e3a6SLisandro Dalcin   /* options for Pilut */
3116d9e3a6SLisandro Dalcin   int                factorrowsize;
3216d9e3a6SLisandro Dalcin 
3316d9e3a6SLisandro Dalcin   /* options for ParaSails */
3416d9e3a6SLisandro Dalcin   int                nlevels;
3516d9e3a6SLisandro Dalcin   double             threshhold;
3616d9e3a6SLisandro Dalcin   double             filter;
3716d9e3a6SLisandro Dalcin   int                sym;
3816d9e3a6SLisandro Dalcin   double             loadbal;
3916d9e3a6SLisandro Dalcin   int                logging;
4016d9e3a6SLisandro Dalcin   int                ruse;
4116d9e3a6SLisandro Dalcin   int                symt;
4216d9e3a6SLisandro Dalcin 
4316d9e3a6SLisandro Dalcin   /* options for Euclid */
44ace3abfcSBarry Smith   PetscBool          bjilu;
4516d9e3a6SLisandro Dalcin   int                levels;
4616d9e3a6SLisandro Dalcin 
4716d9e3a6SLisandro Dalcin   /* options for Euclid and BoomerAMG */
48ace3abfcSBarry Smith   PetscBool          printstatistics;
4916d9e3a6SLisandro Dalcin 
5016d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
5116d9e3a6SLisandro Dalcin   int                cycletype;
5216d9e3a6SLisandro Dalcin   int                maxlevels;
5316d9e3a6SLisandro Dalcin   double             strongthreshold;
5416d9e3a6SLisandro Dalcin   double             maxrowsum;
550f1074feSSatish Balay   int                gridsweeps[3];
5616d9e3a6SLisandro Dalcin   int                coarsentype;
5716d9e3a6SLisandro Dalcin   int                measuretype;
580f1074feSSatish Balay   int                relaxtype[3];
5916d9e3a6SLisandro Dalcin   double             relaxweight;
6016d9e3a6SLisandro Dalcin   double             outerrelaxweight;
6116d9e3a6SLisandro Dalcin   int                relaxorder;
6216d9e3a6SLisandro Dalcin   double             truncfactor;
63ace3abfcSBarry Smith   PetscBool          applyrichardson;
640f1074feSSatish Balay   int                pmax;
650f1074feSSatish Balay   int                interptype;
660f1074feSSatish Balay   int                agg_nl;
670f1074feSSatish Balay   int                agg_num_paths;
688f87f92bSBarry Smith   int                nodal_coarsen;
69ace3abfcSBarry Smith   PetscBool          nodal_relax;
708f87f92bSBarry Smith   int                nodal_relax_levels;
7116d9e3a6SLisandro Dalcin } PC_HYPRE;
7216d9e3a6SLisandro Dalcin 
7316d9e3a6SLisandro Dalcin 
7416d9e3a6SLisandro Dalcin #undef __FUNCT__
7516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE"
7616d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
7716d9e3a6SLisandro Dalcin {
7816d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
7916d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
8016d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
8116d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
8216d9e3a6SLisandro Dalcin   PetscInt           bs;
8316d9e3a6SLisandro Dalcin 
8416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
8516d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
8602a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
8716d9e3a6SLisandro Dalcin   }
885f5c5b43SBarry Smith 
895f5c5b43SBarry Smith   if (pc->setupcalled) {
905f5c5b43SBarry Smith     /* always destroy the old matrix and create a new memory;
915f5c5b43SBarry Smith        hope this does not churn the memory too much. The problem
925f5c5b43SBarry Smith        is I do not know if it is possible to put the matrix back to
935f5c5b43SBarry Smith        its initial state so that we can directly copy the values
945f5c5b43SBarry Smith        the second time through. */
9530e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_IJMatrixDestroy,(jac->ij));
965f5c5b43SBarry Smith     jac->ij = 0;
9716d9e3a6SLisandro Dalcin   }
985f5c5b43SBarry Smith 
9916d9e3a6SLisandro Dalcin   if (!jac->ij) { /* create the matrix the first time through */
10016d9e3a6SLisandro Dalcin     ierr = MatHYPRE_IJMatrixCreate(pc->pmat,&jac->ij);CHKERRQ(ierr);
10116d9e3a6SLisandro Dalcin   }
10216d9e3a6SLisandro Dalcin   if (!jac->b) { /* create the vectors the first time through */
10316d9e3a6SLisandro Dalcin     Vec x,b;
10416d9e3a6SLisandro Dalcin     ierr = MatGetVecs(pc->pmat,&x,&b);CHKERRQ(ierr);
10516d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(x,&jac->x);CHKERRQ(ierr);
10616d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(b,&jac->b);CHKERRQ(ierr);
10716d9e3a6SLisandro Dalcin     ierr = VecDestroy(x);CHKERRQ(ierr);
10816d9e3a6SLisandro Dalcin     ierr = VecDestroy(b);CHKERRQ(ierr);
10916d9e3a6SLisandro Dalcin   }
1105f5c5b43SBarry Smith 
11116d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
11216d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
11316d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
11416d9e3a6SLisandro Dalcin     if (bs > 1) {
11530e6f737SJed Brown       PetscStackCallHypre(0,HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
11616d9e3a6SLisandro Dalcin     }
11716d9e3a6SLisandro Dalcin   };
11816d9e3a6SLisandro Dalcin   ierr = MatHYPRE_IJMatrixCopy(pc->pmat,jac->ij);CHKERRQ(ierr);
11930e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
12030e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_IJVectorGetObject,(jac->b,(void**)&bv));
12130e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_IJVectorGetObject,(jac->x,(void**)&xv));
12230e6f737SJed Brown   PetscStackCallHypre("HYPRE_SetupXXX",(*jac->setup),(jac->hsolver,hmat,bv,xv));
12316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
12416d9e3a6SLisandro Dalcin }
12516d9e3a6SLisandro Dalcin 
12616d9e3a6SLisandro Dalcin /*
12716d9e3a6SLisandro Dalcin     Replaces the address where the HYPRE vector points to its data with the address of
12816d9e3a6SLisandro Dalcin   PETSc's data. Saves the old address so it can be reset when we are finished with it.
12916d9e3a6SLisandro Dalcin   Allows use to get the data into a HYPRE vector without the cost of memcopies
13016d9e3a6SLisandro Dalcin */
13116d9e3a6SLisandro Dalcin #define HYPREReplacePointer(b,newvalue,savedvalue) {\
13216d9e3a6SLisandro Dalcin    hypre_ParVector *par_vector   = (hypre_ParVector *)hypre_IJVectorObject(((hypre_IJVector*)b));\
13316d9e3a6SLisandro Dalcin    hypre_Vector    *local_vector = hypre_ParVectorLocalVector(par_vector);\
13416d9e3a6SLisandro Dalcin    savedvalue         = local_vector->data;\
13516d9e3a6SLisandro Dalcin    local_vector->data = newvalue;}
13616d9e3a6SLisandro Dalcin 
13716d9e3a6SLisandro Dalcin #undef __FUNCT__
13816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE"
13916d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
14016d9e3a6SLisandro Dalcin {
14116d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
14216d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
14316d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
14416d9e3a6SLisandro Dalcin   PetscScalar        *bv,*xv;
14516d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
14616d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
14716d9e3a6SLisandro Dalcin   int                hierr;
14816d9e3a6SLisandro Dalcin 
14916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
15016d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
15116d9e3a6SLisandro Dalcin   ierr = VecGetArray(b,&bv);CHKERRQ(ierr);
15216d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
15316d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,bv,sbv);
15416d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
15516d9e3a6SLisandro Dalcin 
15630e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
15730e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
15830e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
15916d9e3a6SLisandro Dalcin   hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
16065e19b50SBarry Smith   if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
16116d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
16216d9e3a6SLisandro Dalcin 
16316d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
16416d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
16516d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
16616d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(b,&bv);CHKERRQ(ierr);
16716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
16816d9e3a6SLisandro Dalcin }
16916d9e3a6SLisandro Dalcin 
17016d9e3a6SLisandro Dalcin #undef __FUNCT__
17116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE"
17216d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
17316d9e3a6SLisandro Dalcin {
17416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
17516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
17616d9e3a6SLisandro Dalcin 
17716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
17830e6f737SJed Brown   if (jac->ij) PetscStackCallHypre(0,HYPRE_IJMatrixDestroy,(jac->ij));
17930e6f737SJed Brown   if (jac->b)  PetscStackCallHypre(0,HYPRE_IJVectorDestroy,(jac->b));
18030e6f737SJed Brown   if (jac->x)  PetscStackCallHypre(0,HYPRE_IJVectorDestroy,(jac->x));
18130e6f737SJed Brown   if (jac->destroy) PetscStackCallHypre("HYPRE_DistroyXXX",(*jac->destroy),(jac->hsolver));
182503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
18316d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
184c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
18516d9e3a6SLisandro Dalcin 
18616d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
18716d9e3a6SLisandro Dalcin   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCHYPRESetType_C","",PETSC_NULL);CHKERRQ(ierr);
18816d9e3a6SLisandro Dalcin   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCHYPREGetType_C","",PETSC_NULL);CHKERRQ(ierr);
18916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
19016d9e3a6SLisandro Dalcin }
19116d9e3a6SLisandro Dalcin 
19216d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
19316d9e3a6SLisandro Dalcin #undef __FUNCT__
19416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut"
19516d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PC pc)
19616d9e3a6SLisandro Dalcin {
19716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
19816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
199ace3abfcSBarry Smith   PetscBool      flag;
20016d9e3a6SLisandro Dalcin 
20116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
20216d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE Pilut Options");CHKERRQ(ierr);
20316d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
20430e6f737SJed Brown   if (flag) PetscStackCallHypre(0,HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
20516d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
20630e6f737SJed Brown   if (flag) PetscStackCallHypre(0,HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
20716d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
20830e6f737SJed Brown   if (flag) PetscStackCallHypre(0,HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
20916d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
21016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
21116d9e3a6SLisandro Dalcin }
21216d9e3a6SLisandro Dalcin 
21316d9e3a6SLisandro Dalcin #undef __FUNCT__
21416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut"
21516d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
21616d9e3a6SLisandro Dalcin {
21716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
21816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
219ace3abfcSBarry Smith   PetscBool      iascii;
22016d9e3a6SLisandro Dalcin 
22116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
2222692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
22316d9e3a6SLisandro Dalcin   if (iascii) {
22416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
22516d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
22616d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
22716d9e3a6SLisandro Dalcin     } else {
22816d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr);
22916d9e3a6SLisandro Dalcin     }
23016d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
23116d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: drop tolerance %G\n",jac->tol);CHKERRQ(ierr);
23216d9e3a6SLisandro Dalcin     } else {
23316d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr);
23416d9e3a6SLisandro Dalcin     }
23516d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
23616d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
23716d9e3a6SLisandro Dalcin     } else {
23816d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default factor row size \n");CHKERRQ(ierr);
23916d9e3a6SLisandro Dalcin     }
24016d9e3a6SLisandro Dalcin   }
24116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
24216d9e3a6SLisandro Dalcin }
24316d9e3a6SLisandro Dalcin 
24416d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
24516d9e3a6SLisandro Dalcin #undef __FUNCT__
24616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Euclid"
24716d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PC pc)
24816d9e3a6SLisandro Dalcin {
24916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
25016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
251ace3abfcSBarry Smith   PetscBool      flag;
252390e7148SBarry Smith   char           *args[8],levels[16];
253390e7148SBarry Smith   PetscInt       cnt = 0;
25416d9e3a6SLisandro Dalcin 
25516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
25616d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE Euclid Options");CHKERRQ(ierr);
25716d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_euclid_levels","Number of levels of fill ILU(k)","None",jac->levels,&jac->levels,&flag);CHKERRQ(ierr);
25816d9e3a6SLisandro Dalcin   if (flag) {
25965e19b50SBarry Smith     if (jac->levels < 0) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be nonegative",jac->levels);
26016d9e3a6SLisandro Dalcin     sprintf(levels,"%d",jac->levels);
261390e7148SBarry Smith     args[cnt++] = (char*)"-level"; args[cnt++] = levels;
26216d9e3a6SLisandro Dalcin   }
263acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_euclid_bj","Use block Jacobi ILU(k)","None",jac->bjilu,&jac->bjilu,PETSC_NULL);CHKERRQ(ierr);
26416d9e3a6SLisandro Dalcin   if (jac->bjilu) {
265390e7148SBarry Smith     args[cnt++] =(char*) "-bj"; args[cnt++] = (char*)"1";
26616d9e3a6SLisandro Dalcin   }
26716d9e3a6SLisandro Dalcin 
268acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_euclid_print_statistics","Print statistics","None",jac->printstatistics,&jac->printstatistics,PETSC_NULL);CHKERRQ(ierr);
26916d9e3a6SLisandro Dalcin   if (jac->printstatistics) {
270390e7148SBarry Smith     args[cnt++] = (char*)"-eu_stats"; args[cnt++] = (char*)"1";
271390e7148SBarry Smith     args[cnt++] = (char*)"-eu_mem"; args[cnt++] = (char*)"1";
27216d9e3a6SLisandro Dalcin   }
27316d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
27430e6f737SJed Brown   if (cnt) PetscStackCallHypre(0,HYPRE_EuclidSetParams,(jac->hsolver,cnt,args));
27516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
27616d9e3a6SLisandro Dalcin }
27716d9e3a6SLisandro Dalcin 
27816d9e3a6SLisandro Dalcin #undef __FUNCT__
27916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Euclid"
28016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer)
28116d9e3a6SLisandro Dalcin {
28216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
28316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
284ace3abfcSBarry Smith   PetscBool      iascii;
28516d9e3a6SLisandro Dalcin 
28616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
2872692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
28816d9e3a6SLisandro Dalcin   if (iascii) {
28916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid preconditioning\n");CHKERRQ(ierr);
29016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid: number of levels %d\n",jac->levels);CHKERRQ(ierr);
29116d9e3a6SLisandro Dalcin     if (jac->bjilu) {
29216d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid: Using block Jacobi ILU instead of parallel ILU\n");CHKERRQ(ierr);
29316d9e3a6SLisandro Dalcin     }
29416d9e3a6SLisandro Dalcin   }
29516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
29616d9e3a6SLisandro Dalcin }
29716d9e3a6SLisandro Dalcin 
29816d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
29916d9e3a6SLisandro Dalcin 
30016d9e3a6SLisandro Dalcin #undef __FUNCT__
30116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG"
30216d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
30316d9e3a6SLisandro Dalcin {
30416d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
30516d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
30616d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
30716d9e3a6SLisandro Dalcin   PetscScalar        *bv,*xv;
30816d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
30916d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
31016d9e3a6SLisandro Dalcin   int                hierr;
31116d9e3a6SLisandro Dalcin 
31216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
31316d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
31416d9e3a6SLisandro Dalcin   ierr = VecGetArray(b,&bv);CHKERRQ(ierr);
31516d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
31616d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,bv,sbv);
31716d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
31816d9e3a6SLisandro Dalcin 
31930e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
32030e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
32130e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
32216d9e3a6SLisandro Dalcin 
32316d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
32416d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
325e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
32616d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
32716d9e3a6SLisandro Dalcin 
32816d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
32916d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
33016d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
33116d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(b,&bv);CHKERRQ(ierr);
33216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
33316d9e3a6SLisandro Dalcin }
33416d9e3a6SLisandro Dalcin 
33516d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
3360f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
33716d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
3380f1074feSSatish Balay static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","","SOR/Jacobi","backward-SOR/Jacobi","","symmetric-SOR/Jacobi",
3390f1074feSSatish Balay                                                   "","","Gaussian-elimination"};
3400f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
3410f1074feSSatish Balay                                                   "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"};
34216d9e3a6SLisandro Dalcin #undef __FUNCT__
34316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG"
34416d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PC pc)
34516d9e3a6SLisandro Dalcin {
34616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
34716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
34816d9e3a6SLisandro Dalcin   int            n,indx;
349ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
35016d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
35116d9e3a6SLisandro Dalcin 
35216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
35316d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE BoomerAMG Options");CHKERRQ(ierr);
35416d9e3a6SLisandro Dalcin   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
35516d9e3a6SLisandro Dalcin   if (flg) {
35616d9e3a6SLisandro Dalcin     jac->cycletype = indx;
35730e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
35816d9e3a6SLisandro Dalcin   }
35916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
36016d9e3a6SLisandro Dalcin   if (flg) {
36165e19b50SBarry Smith     if (jac->maxlevels < 2) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
36230e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
36316d9e3a6SLisandro Dalcin   }
36416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
36516d9e3a6SLisandro Dalcin   if (flg) {
36665e19b50SBarry Smith     if (jac->maxiter < 1) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
36730e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
36816d9e3a6SLisandro Dalcin   }
3690f1074feSSatish 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);
37016d9e3a6SLisandro Dalcin   if (flg) {
37165e19b50SBarry Smith     if (jac->tol < 0.0) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Tolerance %G must be greater than or equal to zero",jac->tol);
37230e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
37316d9e3a6SLisandro Dalcin   }
37416d9e3a6SLisandro Dalcin 
3750f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
37616d9e3a6SLisandro Dalcin   if (flg) {
37765e19b50SBarry Smith     if (jac->truncfactor < 0.0) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Truncation factor %G must be great than or equal zero",jac->truncfactor);
37830e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
37916d9e3a6SLisandro Dalcin   }
38016d9e3a6SLisandro Dalcin 
3810f1074feSSatish 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);
3820f1074feSSatish Balay   if (flg) {
38365e19b50SBarry Smith     if (jac->pmax < 0) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"P_max %G must be greater than or equal to zero",jac->pmax);
38430e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
3850f1074feSSatish Balay   }
3860f1074feSSatish Balay 
3870f1074feSSatish Balay  ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
3880f1074feSSatish Balay   if (flg) {
38965e19b50SBarry Smith      if (jac->agg_nl < 0) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %G must be greater than or equal to zero",jac->agg_nl);
3900f1074feSSatish Balay 
39130e6f737SJed Brown      PetscStackCallHypre(0,HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
3920f1074feSSatish Balay   }
3930f1074feSSatish Balay 
3940f1074feSSatish Balay 
3950f1074feSSatish 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);
3960f1074feSSatish Balay   if (flg) {
39765e19b50SBarry Smith      if (jac->agg_num_paths < 1) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Number of paths %G must be greater than or equal to 1",jac->agg_num_paths);
3980f1074feSSatish Balay 
39930e6f737SJed Brown      PetscStackCallHypre(0,HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
4000f1074feSSatish Balay   }
4010f1074feSSatish Balay 
4020f1074feSSatish Balay 
40316d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
40416d9e3a6SLisandro Dalcin   if (flg) {
40565e19b50SBarry Smith     if (jac->strongthreshold < 0.0) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Strong threshold %G must be great than or equal zero",jac->strongthreshold);
40630e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
40716d9e3a6SLisandro Dalcin   }
40816d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
40916d9e3a6SLisandro Dalcin   if (flg) {
41065e19b50SBarry Smith     if (jac->maxrowsum < 0.0) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum row sum %G must be greater than zero",jac->maxrowsum);
41165e19b50SBarry Smith     if (jac->maxrowsum > 1.0) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum row sum %G must be less than or equal one",jac->maxrowsum);
41230e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
41316d9e3a6SLisandro Dalcin   }
41416d9e3a6SLisandro Dalcin 
41516d9e3a6SLisandro Dalcin   /* Grid sweeps */
4160f1074feSSatish 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);
41716d9e3a6SLisandro Dalcin   if (flg) {
41830e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
41916d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
42016d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
4210f1074feSSatish Balay     jac->gridsweeps[1] = indx;
4220f1074feSSatish Balay     /*defaults coarse to 1 */
4230f1074feSSatish Balay     jac->gridsweeps[2] = 1;
42416d9e3a6SLisandro Dalcin   }
4250f1074feSSatish Balay 
4260f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx ,&flg);CHKERRQ(ierr);
42716d9e3a6SLisandro Dalcin   if (flg) {
42830e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
4290f1074feSSatish Balay     jac->gridsweeps[0] = indx;
43016d9e3a6SLisandro Dalcin   }
43116d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
43216d9e3a6SLisandro Dalcin   if (flg) {
43330e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
4340f1074feSSatish Balay     jac->gridsweeps[1] = indx;
43516d9e3a6SLisandro Dalcin   }
4360f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
43716d9e3a6SLisandro Dalcin   if (flg) {
43830e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
4390f1074feSSatish Balay     jac->gridsweeps[2] = indx;
44016d9e3a6SLisandro Dalcin   }
44116d9e3a6SLisandro Dalcin 
44216d9e3a6SLisandro Dalcin   /* Relax type */
4430f1074feSSatish Balay   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_all","Relax type for the up and down cycles","None",HYPREBoomerAMGRelaxType,10,HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr);
44416d9e3a6SLisandro Dalcin   if (flg) {
4450f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
44630e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
4470f1074feSSatish Balay     /* by default, coarse type set to 9 */
4480f1074feSSatish Balay     jac->relaxtype[2] = 9;
4490f1074feSSatish Balay 
45016d9e3a6SLisandro Dalcin   }
4510f1074feSSatish Balay   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_down","Relax type for the down cycles","None",HYPREBoomerAMGRelaxType,10,HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr);
45216d9e3a6SLisandro Dalcin   if (flg) {
45316d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
45430e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
45516d9e3a6SLisandro Dalcin   }
4560f1074feSSatish Balay   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_up","Relax type for the up cycles","None",HYPREBoomerAMGRelaxType,10,HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr);
45716d9e3a6SLisandro Dalcin   if (flg) {
4580f1074feSSatish Balay     jac->relaxtype[1] = indx;
45930e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
46016d9e3a6SLisandro Dalcin   }
46116d9e3a6SLisandro Dalcin   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,10,HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
46216d9e3a6SLisandro Dalcin   if (flg) {
4630f1074feSSatish Balay     jac->relaxtype[2] = indx;
46430e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
46516d9e3a6SLisandro Dalcin   }
46616d9e3a6SLisandro Dalcin 
46716d9e3a6SLisandro Dalcin   /* Relaxation Weight */
46816d9e3a6SLisandro 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);
46916d9e3a6SLisandro Dalcin   if (flg) {
47030e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
47116d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
47216d9e3a6SLisandro Dalcin   }
47316d9e3a6SLisandro Dalcin 
47416d9e3a6SLisandro Dalcin   n=2;
47516d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
47616d9e3a6SLisandro 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);
47716d9e3a6SLisandro Dalcin   if (flg) {
47816d9e3a6SLisandro Dalcin     if (n == 2) {
47916d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
48030e6f737SJed Brown       PetscStackCallHypre(0,HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
48116d9e3a6SLisandro Dalcin     } else {
48265e19b50SBarry Smith       SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Relax weight level: you must provide 2 values separated by a comma (and no space), you provided %d",n);
48316d9e3a6SLisandro Dalcin     }
48416d9e3a6SLisandro Dalcin   }
48516d9e3a6SLisandro Dalcin 
48616d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
48716d9e3a6SLisandro 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);
48816d9e3a6SLisandro Dalcin   if (flg) {
48930e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetOuterWt,( jac->hsolver, tmpdbl));
49016d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
49116d9e3a6SLisandro Dalcin   }
49216d9e3a6SLisandro Dalcin 
49316d9e3a6SLisandro Dalcin   n=2;
49416d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
49516d9e3a6SLisandro 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);
49616d9e3a6SLisandro Dalcin   if (flg) {
49716d9e3a6SLisandro Dalcin     if (n == 2) {
49816d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
49930e6f737SJed Brown       PetscStackCallHypre(0,HYPRE_BoomerAMGSetLevelOuterWt,( jac->hsolver, twodbl[0], indx));
50016d9e3a6SLisandro Dalcin     } else {
50165e19b50SBarry Smith       SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Relax weight outer level: You must provide 2 values separated by a comma (and no space), you provided %d",n);
50216d9e3a6SLisandro Dalcin     }
50316d9e3a6SLisandro Dalcin   }
50416d9e3a6SLisandro Dalcin 
50516d9e3a6SLisandro Dalcin   /* the Relax Order */
506acfcf0e5SJed Brown   ierr = PetscOptionsBool( "-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
50716d9e3a6SLisandro Dalcin 
50816d9e3a6SLisandro Dalcin   if (flg) {
50916d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
51030e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
51116d9e3a6SLisandro Dalcin   }
51216d9e3a6SLisandro Dalcin   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,2,HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
51316d9e3a6SLisandro Dalcin   if (flg) {
51416d9e3a6SLisandro Dalcin     jac->measuretype = indx;
51530e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
51616d9e3a6SLisandro Dalcin   }
5170f1074feSSatish Balay   /* update list length 3/07 */
5180f1074feSSatish Balay   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,11,HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
51916d9e3a6SLisandro Dalcin   if (flg) {
52016d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
52130e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
52216d9e3a6SLisandro Dalcin   }
5230f1074feSSatish Balay 
5240f1074feSSatish Balay   /* new 3/07 */
5250f1074feSSatish Balay   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,14,HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
5260f1074feSSatish Balay   if (flg) {
5270f1074feSSatish Balay     jac->interptype = indx;
52830e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
5290f1074feSSatish Balay   }
5300f1074feSSatish Balay 
53190d69ab7SBarry Smith   flg  = PETSC_FALSE;
532acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_print_statistics","Print statistics","None",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
53316d9e3a6SLisandro Dalcin   if (flg) {
53416d9e3a6SLisandro Dalcin     int level=3;
53516d9e3a6SLisandro Dalcin     jac->printstatistics = PETSC_TRUE;
53616d9e3a6SLisandro Dalcin     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,PETSC_NULL);CHKERRQ(ierr);
53730e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
5382ae77aedSBarry Smith   }
5392ae77aedSBarry Smith 
54090d69ab7SBarry Smith   flg  = PETSC_FALSE;
541acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_print_debug","Print debug information","None",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
5422ae77aedSBarry Smith   if (flg) {
5432ae77aedSBarry Smith     int level=3;
5442ae77aedSBarry Smith     jac->printstatistics = PETSC_TRUE;
5452ae77aedSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,PETSC_NULL);CHKERRQ(ierr);
54630e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
54716d9e3a6SLisandro Dalcin   }
5488f87f92bSBarry Smith 
549acfcf0e5SJed Brown   ierr = PetscOptionsBool( "-pc_hypre_boomeramg_nodal_coarsen", "HYPRE_BoomerAMGSetNodal()", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5508f87f92bSBarry Smith   if (flg && tmp_truth) {
5518f87f92bSBarry Smith     jac->nodal_coarsen = 1;
55230e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetNodal,(jac->hsolver,1));
5538f87f92bSBarry Smith   }
5548f87f92bSBarry Smith 
555acfcf0e5SJed Brown   ierr = PetscOptionsBool( "-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5568f87f92bSBarry Smith   if (flg && tmp_truth) {
5578f87f92bSBarry Smith     PetscInt tmp_int;
5588f87f92bSBarry Smith     ierr = PetscOptionsInt( "-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
5598f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
56030e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
56130e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
56230e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
56330e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
5648f87f92bSBarry Smith   }
5658f87f92bSBarry Smith 
56616d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
56716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
56816d9e3a6SLisandro Dalcin }
56916d9e3a6SLisandro Dalcin 
57016d9e3a6SLisandro Dalcin #undef __FUNCT__
57116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG"
572ace3abfcSBarry 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)
57316d9e3a6SLisandro Dalcin {
57416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
57516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
5764d0a8057SBarry Smith   int            oits;
57716d9e3a6SLisandro Dalcin 
57816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
57930e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
58030e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
58116d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
58216d9e3a6SLisandro Dalcin   ierr = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
58316d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
58430e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,&oits));
5854d0a8057SBarry Smith   *outits = oits;
5864d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
5874d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
58830e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
58930e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
59016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
59116d9e3a6SLisandro Dalcin }
59216d9e3a6SLisandro Dalcin 
59316d9e3a6SLisandro Dalcin 
59416d9e3a6SLisandro Dalcin #undef __FUNCT__
59516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG"
59616d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
59716d9e3a6SLisandro Dalcin {
59816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
59916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
600ace3abfcSBarry Smith   PetscBool      iascii;
60116d9e3a6SLisandro Dalcin 
60216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
6032692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
60416d9e3a6SLisandro Dalcin   if (iascii) {
60516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
60616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
60716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
60816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
60916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Convergence tolerance PER hypre call %G\n",jac->tol);CHKERRQ(ierr);
61016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Threshold for strong coupling %G\n",jac->strongthreshold);CHKERRQ(ierr);
6110f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation truncation factor %G\n",jac->truncfactor);CHKERRQ(ierr);
6120f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
6130f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
6140f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
6150f1074feSSatish Balay 
61616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum row sums %G\n",jac->maxrowsum);CHKERRQ(ierr);
61716d9e3a6SLisandro Dalcin 
6180f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
6190f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
6200f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
62116d9e3a6SLisandro Dalcin 
6220f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
6230f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
6240f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
62516d9e3a6SLisandro Dalcin 
62616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax weight  (all)      %G\n",jac->relaxweight);CHKERRQ(ierr);
62716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Outer relax weight (all) %G\n",jac->outerrelaxweight);CHKERRQ(ierr);
62816d9e3a6SLisandro Dalcin 
62916d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
63016d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr);
63116d9e3a6SLisandro Dalcin     } else {
63216d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr);
63316d9e3a6SLisandro Dalcin     }
63416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
63516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
6360f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
6378f87f92bSBarry Smith     if (jac->nodal_coarsen) {
6388f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal())\n");CHKERRQ(ierr);
6398f87f92bSBarry Smith     }
6408f87f92bSBarry Smith     if (jac->nodal_relax) {
6418f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
6428f87f92bSBarry Smith     }
64316d9e3a6SLisandro Dalcin   }
64416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
64516d9e3a6SLisandro Dalcin }
64616d9e3a6SLisandro Dalcin 
64716d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
64816d9e3a6SLisandro Dalcin #undef __FUNCT__
64916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails"
65016d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PC pc)
65116d9e3a6SLisandro Dalcin {
65216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
65316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
65416d9e3a6SLisandro Dalcin   int            indx;
655ace3abfcSBarry Smith   PetscBool      flag;
65616d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
65716d9e3a6SLisandro Dalcin 
65816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
65916d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE ParaSails Options");CHKERRQ(ierr);
66016d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
66116d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
66216d9e3a6SLisandro Dalcin   if (flag) {
66330e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
66416d9e3a6SLisandro Dalcin   }
66516d9e3a6SLisandro Dalcin 
66616d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
66716d9e3a6SLisandro Dalcin   if (flag) {
66830e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
66916d9e3a6SLisandro Dalcin   }
67016d9e3a6SLisandro Dalcin 
67116d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
67216d9e3a6SLisandro Dalcin   if (flag) {
67330e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
67416d9e3a6SLisandro Dalcin   }
67516d9e3a6SLisandro Dalcin 
676acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
67716d9e3a6SLisandro Dalcin   if (flag) {
67830e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
67916d9e3a6SLisandro Dalcin   }
68016d9e3a6SLisandro Dalcin 
681acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
68216d9e3a6SLisandro Dalcin   if (flag) {
68330e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
68416d9e3a6SLisandro Dalcin   }
68516d9e3a6SLisandro Dalcin 
68616d9e3a6SLisandro Dalcin   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,3,symtlist[0],&indx,&flag);CHKERRQ(ierr);
68716d9e3a6SLisandro Dalcin   if (flag) {
68816d9e3a6SLisandro Dalcin     jac->symt = indx;
68930e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
69016d9e3a6SLisandro Dalcin   }
69116d9e3a6SLisandro Dalcin 
69216d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
69316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
69416d9e3a6SLisandro Dalcin }
69516d9e3a6SLisandro Dalcin 
69616d9e3a6SLisandro Dalcin #undef __FUNCT__
69716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails"
69816d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
69916d9e3a6SLisandro Dalcin {
70016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
70116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
702ace3abfcSBarry Smith   PetscBool      iascii;
70316d9e3a6SLisandro Dalcin   const char     *symt = 0;;
70416d9e3a6SLisandro Dalcin 
70516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
7062692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
70716d9e3a6SLisandro Dalcin   if (iascii) {
70816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
70916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
71016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: threshold %G\n",jac->threshhold);CHKERRQ(ierr);
71116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: filter %G\n",jac->filter);CHKERRQ(ierr);
71216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: load balance %G\n",jac->loadbal);CHKERRQ(ierr);
713ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
714ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
71516d9e3a6SLisandro Dalcin     if (!jac->symt) {
71616d9e3a6SLisandro Dalcin       symt = "nonsymmetric matrix and preconditioner";
71716d9e3a6SLisandro Dalcin     } else if (jac->symt == 1) {
71816d9e3a6SLisandro Dalcin       symt = "SPD matrix and preconditioner";
71916d9e3a6SLisandro Dalcin     } else if (jac->symt == 2) {
72016d9e3a6SLisandro Dalcin       symt = "nonsymmetric matrix but SPD preconditioner";
72116d9e3a6SLisandro Dalcin     } else {
72265e19b50SBarry Smith       SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
72316d9e3a6SLisandro Dalcin     }
72416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr);
72516d9e3a6SLisandro Dalcin   }
72616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
72716d9e3a6SLisandro Dalcin }
72816d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
72916d9e3a6SLisandro Dalcin 
73016d9e3a6SLisandro Dalcin EXTERN_C_BEGIN
73116d9e3a6SLisandro Dalcin #undef __FUNCT__
73216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
7337087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
73416d9e3a6SLisandro Dalcin {
73516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
73616d9e3a6SLisandro Dalcin 
73716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
73816d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
73916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
74016d9e3a6SLisandro Dalcin }
74116d9e3a6SLisandro Dalcin EXTERN_C_END
74216d9e3a6SLisandro Dalcin 
74316d9e3a6SLisandro Dalcin EXTERN_C_BEGIN
74416d9e3a6SLisandro Dalcin #undef __FUNCT__
74516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
7467087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
74716d9e3a6SLisandro Dalcin {
74816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
74916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
750ace3abfcSBarry Smith   PetscBool      flag;
75116d9e3a6SLisandro Dalcin 
75216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
75316d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
75416d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
755e7e72b3dSBarry Smith     if (!flag) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
75616d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
75716d9e3a6SLisandro Dalcin   } else {
75816d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
75916d9e3a6SLisandro Dalcin   }
76016d9e3a6SLisandro Dalcin 
76116d9e3a6SLisandro Dalcin   jac->maxiter            = PETSC_DEFAULT;
76216d9e3a6SLisandro Dalcin   jac->tol                = PETSC_DEFAULT;
76316d9e3a6SLisandro Dalcin   jac->printstatistics    = PetscLogPrintInfo;
76416d9e3a6SLisandro Dalcin 
76516d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
76616d9e3a6SLisandro Dalcin   if (flag) {
76730e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
76816d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
76916d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
77016d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
77116d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
77216d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
77316d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
77416d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
77516d9e3a6SLisandro Dalcin   }
77616d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
77716d9e3a6SLisandro Dalcin   if (flag) {
77830e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
77916d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
78016d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
78116d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
78216d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
78316d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
78416d9e3a6SLisandro Dalcin     /* initialize */
78516d9e3a6SLisandro Dalcin     jac->nlevels     = 1;
78616d9e3a6SLisandro Dalcin     jac->threshhold  = .1;
78716d9e3a6SLisandro Dalcin     jac->filter      = .1;
78816d9e3a6SLisandro Dalcin     jac->loadbal     = 0;
78916d9e3a6SLisandro Dalcin     if (PetscLogPrintInfo) {
79016d9e3a6SLisandro Dalcin       jac->logging     = (int) PETSC_TRUE;
79116d9e3a6SLisandro Dalcin     } else {
79216d9e3a6SLisandro Dalcin       jac->logging     = (int) PETSC_FALSE;
79316d9e3a6SLisandro Dalcin     }
79416d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
79516d9e3a6SLisandro Dalcin     jac->symt   = 0;
79630e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
79730e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
79830e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
79930e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
80030e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
80130e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
80216d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
80316d9e3a6SLisandro Dalcin   }
80416d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("euclid",jac->hypre_type,&flag);CHKERRQ(ierr);
80516d9e3a6SLisandro Dalcin   if (flag) {
80616d9e3a6SLisandro Dalcin     ierr                    = HYPRE_EuclidCreate(jac->comm_hypre,&jac->hsolver);
80716d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
80816d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Euclid;
80916d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_EuclidDestroy;
81016d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_EuclidSetup;
81116d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_EuclidSolve;
81216d9e3a6SLisandro Dalcin     /* initialization */
81316d9e3a6SLisandro Dalcin     jac->bjilu              = PETSC_FALSE;
81416d9e3a6SLisandro Dalcin     jac->levels             = 1;
81516d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
81616d9e3a6SLisandro Dalcin   }
81716d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
81816d9e3a6SLisandro Dalcin   if (flag) {
81916d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
82016d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
82116d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
82216d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
82316d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
82416d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
82516d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
82616d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
82716d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
82816d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
82916d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
83016d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
83116d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
8328f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
83316d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
83416d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
83516d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
83616d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
83716d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
8380f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
8398f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
8400f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
84116d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
84216d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
84316d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
8440f1074feSSatish Balay     jac->interptype       = 0;
8450f1074feSSatish Balay     jac->agg_nl           = 0;
8460f1074feSSatish Balay     jac->pmax             = 0;
8470f1074feSSatish Balay     jac->truncfactor      = 0.0;
8480f1074feSSatish Balay     jac->agg_num_paths    = 1;
8498f87f92bSBarry Smith 
8508f87f92bSBarry Smith     jac->nodal_coarsen    = 0;
8518f87f92bSBarry Smith     jac->nodal_relax      = PETSC_FALSE;
8528f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
85330e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
85430e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
85530e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
85630e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
85730e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
85830e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
85930e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
86030e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
86130e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
86230e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
86330e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
86430e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
86530e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
86630e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
86730e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
86830e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
86916d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
87016d9e3a6SLisandro Dalcin   }
871503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
87216d9e3a6SLisandro Dalcin   jac->hypre_type = PETSC_NULL;
87365e19b50SBarry Smith   SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, euclid, boomeramg",name);
87416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
87516d9e3a6SLisandro Dalcin }
87616d9e3a6SLisandro Dalcin EXTERN_C_END
87716d9e3a6SLisandro Dalcin 
87816d9e3a6SLisandro Dalcin /*
87916d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
88016d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
88116d9e3a6SLisandro Dalcin */
88216d9e3a6SLisandro Dalcin #undef __FUNCT__
88316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
88416d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE(PC pc)
88516d9e3a6SLisandro Dalcin {
88616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
88716d9e3a6SLisandro Dalcin   int            indx;
88816d9e3a6SLisandro Dalcin   const char     *type[] = {"pilut","parasails","boomeramg","euclid"};
889ace3abfcSBarry Smith   PetscBool      flg;
89016d9e3a6SLisandro Dalcin 
89116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
89216d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE preconditioner options");CHKERRQ(ierr);
89302a17cd4SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
89416d9e3a6SLisandro Dalcin   if (flg) {
89516d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
89602a17cd4SBarry Smith   } else {
89702a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
89816d9e3a6SLisandro Dalcin   }
89916d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
90016d9e3a6SLisandro Dalcin     ierr = pc->ops->setfromoptions(pc);CHKERRQ(ierr);
90116d9e3a6SLisandro Dalcin   }
90216d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
90316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
90416d9e3a6SLisandro Dalcin }
90516d9e3a6SLisandro Dalcin 
90616d9e3a6SLisandro Dalcin #undef __FUNCT__
90716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
90816d9e3a6SLisandro Dalcin /*@C
90916d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
91016d9e3a6SLisandro Dalcin 
91116d9e3a6SLisandro Dalcin    Input Parameters:
91216d9e3a6SLisandro Dalcin +     pc - the preconditioner context
91316d9e3a6SLisandro Dalcin -     name - either  pilut, parasails, boomeramg, euclid
91416d9e3a6SLisandro Dalcin 
91516d9e3a6SLisandro Dalcin    Options Database Keys:
91616d9e3a6SLisandro Dalcin    -pc_hypre_type - One of pilut, parasails, boomeramg, euclid
91716d9e3a6SLisandro Dalcin 
91816d9e3a6SLisandro Dalcin    Level: intermediate
91916d9e3a6SLisandro Dalcin 
92016d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
92116d9e3a6SLisandro Dalcin            PCHYPRE
92216d9e3a6SLisandro Dalcin 
92316d9e3a6SLisandro Dalcin @*/
9247087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
92516d9e3a6SLisandro Dalcin {
9264ac538c5SBarry Smith   PetscErrorCode ierr;
92716d9e3a6SLisandro Dalcin 
92816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
9290700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
93016d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
9314ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
93216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
93316d9e3a6SLisandro Dalcin }
93416d9e3a6SLisandro Dalcin 
93516d9e3a6SLisandro Dalcin #undef __FUNCT__
93616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
93716d9e3a6SLisandro Dalcin /*@C
93816d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
93916d9e3a6SLisandro Dalcin 
94016d9e3a6SLisandro Dalcin    Input Parameter:
94116d9e3a6SLisandro Dalcin .     pc - the preconditioner context
94216d9e3a6SLisandro Dalcin 
94316d9e3a6SLisandro Dalcin    Output Parameter:
94416d9e3a6SLisandro Dalcin .     name - either  pilut, parasails, boomeramg, euclid
94516d9e3a6SLisandro Dalcin 
94616d9e3a6SLisandro Dalcin    Level: intermediate
94716d9e3a6SLisandro Dalcin 
94816d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
94916d9e3a6SLisandro Dalcin            PCHYPRE
95016d9e3a6SLisandro Dalcin 
95116d9e3a6SLisandro Dalcin @*/
9527087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
95316d9e3a6SLisandro Dalcin {
9544ac538c5SBarry Smith   PetscErrorCode ierr;
95516d9e3a6SLisandro Dalcin 
95616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
9570700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
95816d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
9594ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
96016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
96116d9e3a6SLisandro Dalcin }
96216d9e3a6SLisandro Dalcin 
96316d9e3a6SLisandro Dalcin /*MC
96416d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
96516d9e3a6SLisandro Dalcin 
96616d9e3a6SLisandro Dalcin    Options Database Keys:
96716d9e3a6SLisandro Dalcin +   -pc_hypre_type - One of pilut, parasails, boomeramg, euclid
96816d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
96916d9e3a6SLisandro Dalcin           preconditioner
97016d9e3a6SLisandro Dalcin 
97116d9e3a6SLisandro Dalcin    Level: intermediate
97216d9e3a6SLisandro Dalcin 
97316d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
97416d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
97516d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
97616d9e3a6SLisandro Dalcin 
97716d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
9780f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
9790f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
9800f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
9818f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
9820f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
9830f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
98416d9e3a6SLisandro Dalcin 
9850f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
9860f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
9870f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
98816d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
98916d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
99016d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
99116d9e3a6SLisandro Dalcin 
99216d9e3a6SLisandro Dalcin 	  2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
99316d9e3a6SLisandro Dalcin 	  -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
99416d9e3a6SLisandro Dalcin 
9959e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
9969e5bc791SBarry Smith 
99716d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
9989e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
99916d9e3a6SLisandro Dalcin 
100016d9e3a6SLisandro Dalcin M*/
100116d9e3a6SLisandro Dalcin 
100216d9e3a6SLisandro Dalcin EXTERN_C_BEGIN
100316d9e3a6SLisandro Dalcin #undef __FUNCT__
100416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
10057087cfbeSBarry Smith PetscErrorCode  PCCreate_HYPRE(PC pc)
100616d9e3a6SLisandro Dalcin {
100716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
100816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
100916d9e3a6SLisandro Dalcin 
101016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
101138f2d2fdSLisandro Dalcin   ierr = PetscNewLog(pc,PC_HYPRE,&jac);CHKERRQ(ierr);
101216d9e3a6SLisandro Dalcin   pc->data                 = jac;
101316d9e3a6SLisandro Dalcin   pc->ops->destroy         = PCDestroy_HYPRE;
101416d9e3a6SLisandro Dalcin   pc->ops->setfromoptions  = PCSetFromOptions_HYPRE;
101516d9e3a6SLisandro Dalcin   pc->ops->setup           = PCSetUp_HYPRE;
101616d9e3a6SLisandro Dalcin   pc->ops->apply           = PCApply_HYPRE;
101716d9e3a6SLisandro Dalcin   jac->comm_hypre          = MPI_COMM_NULL;
101816d9e3a6SLisandro Dalcin   jac->hypre_type          = PETSC_NULL;
101916d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
10207adad957SLisandro Dalcin   ierr = MPI_Comm_dup(((PetscObject)pc)->comm,&(jac->comm_hypre));CHKERRQ(ierr);
102116d9e3a6SLisandro Dalcin   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCHYPRESetType_C","PCHYPRESetType_HYPRE",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
102216d9e3a6SLisandro Dalcin   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCHYPREGetType_C","PCHYPREGetType_HYPRE",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
102316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
102416d9e3a6SLisandro Dalcin }
102516d9e3a6SLisandro Dalcin EXTERN_C_END
1026ebc551c0SBarry Smith 
1027f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1028f91d8e95SBarry Smith 
1029b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1030*c6db04a5SJed Brown #include <private/matimpl.h>
1031ebc551c0SBarry Smith 
1032ebc551c0SBarry Smith typedef struct {
103368326731SBarry Smith   MPI_Comm            hcomm;       /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1034f91d8e95SBarry Smith   HYPRE_StructSolver  hsolver;
10359e5bc791SBarry Smith 
10369e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
10379e5bc791SBarry Smith   int                 its;
10389e5bc791SBarry Smith   double              tol;
10399e5bc791SBarry Smith   int                 relax_type;
10409e5bc791SBarry Smith   int                 rap_type;
10419e5bc791SBarry Smith   int                 num_pre_relax,num_post_relax;
10423b46a515SGlenn Hammond   int                 max_levels;
1043ebc551c0SBarry Smith } PC_PFMG;
1044ebc551c0SBarry Smith 
1045ebc551c0SBarry Smith #undef __FUNCT__
1046ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1047ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1048ebc551c0SBarry Smith {
1049ebc551c0SBarry Smith   PetscErrorCode ierr;
1050f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1051ebc551c0SBarry Smith 
1052ebc551c0SBarry Smith   PetscFunctionBegin;
105330e6f737SJed Brown   if (ex->hsolver) {PetscStackCallHypre(0,HYPRE_StructPFMGDestroy,(ex->hsolver));}
1054f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1055c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1056ebc551c0SBarry Smith   PetscFunctionReturn(0);
1057ebc551c0SBarry Smith }
1058ebc551c0SBarry Smith 
10599e5bc791SBarry Smith static const char *PFMGRelaxType[]   = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
10609e5bc791SBarry Smith static const char *PFMGRAPType[]   = {"Galerkin","non-Galerkin"};
10619e5bc791SBarry Smith 
1062ebc551c0SBarry Smith #undef __FUNCT__
1063ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1064ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1065ebc551c0SBarry Smith {
1066ebc551c0SBarry Smith   PetscErrorCode ierr;
1067ace3abfcSBarry Smith   PetscBool      iascii;
1068f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1069ebc551c0SBarry Smith 
1070ebc551c0SBarry Smith   PetscFunctionBegin;
10712692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
10729e5bc791SBarry Smith   if (iascii) {
10739e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
10749e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
10759e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
10769e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
10779e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
10789e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
10793b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
10809e5bc791SBarry Smith   }
1081ebc551c0SBarry Smith   PetscFunctionReturn(0);
1082ebc551c0SBarry Smith }
1083ebc551c0SBarry Smith 
10849e5bc791SBarry Smith 
1085ebc551c0SBarry Smith #undef __FUNCT__
1086ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
1087ebc551c0SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PC pc)
1088ebc551c0SBarry Smith {
1089ebc551c0SBarry Smith   PetscErrorCode ierr;
1090f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1091ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1092ebc551c0SBarry Smith 
1093ebc551c0SBarry Smith   PetscFunctionBegin;
1094ebc551c0SBarry Smith   ierr = PetscOptionsHead("PFMG options");CHKERRQ(ierr);
1095acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
109668326731SBarry Smith   if (flg) {
1097a0324ebeSBarry Smith     int level=3;
109830e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
109968326731SBarry Smith   }
11009e5bc791SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,PETSC_NULL);CHKERRQ(ierr);
110130e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
11029e5bc791SBarry 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,PETSC_NULL);CHKERRQ(ierr);
110330e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
11049e5bc791SBarry 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,PETSC_NULL);CHKERRQ(ierr);
110530e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
11069e5bc791SBarry Smith 
11073b46a515SGlenn Hammond   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,PETSC_NULL);CHKERRQ(ierr);
110830e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
11093b46a515SGlenn Hammond 
11109e5bc791SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,PETSC_NULL);CHKERRQ(ierr);
111130e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
11129e5bc791SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_relax_type","Relax type for the up and down cycles","HYPRE_StructPFMGSetRelaxType",PFMGRelaxType,4,PFMGRelaxType[ex->relax_type],&ex->relax_type,PETSC_NULL);CHKERRQ(ierr);
111330e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
11149e5bc791SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,2,PFMGRAPType[ex->rap_type],&ex->rap_type,PETSC_NULL);CHKERRQ(ierr);
111530e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1116ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1117ebc551c0SBarry Smith   PetscFunctionReturn(0);
1118ebc551c0SBarry Smith }
1119ebc551c0SBarry Smith 
1120f91d8e95SBarry Smith #undef __FUNCT__
1121f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1122f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1123f91d8e95SBarry Smith {
1124f91d8e95SBarry Smith   PetscErrorCode  ierr;
1125f91d8e95SBarry Smith   PC_PFMG         *ex = (PC_PFMG*) pc->data;
1126f91d8e95SBarry Smith   PetscScalar     *xx,*yy;
1127f91d8e95SBarry Smith   int             ilower[3],iupper[3];
112868326731SBarry Smith   Mat_HYPREStruct *mx = (Mat_HYPREStruct *)(pc->pmat->data);
1129f91d8e95SBarry Smith 
1130f91d8e95SBarry Smith   PetscFunctionBegin;
1131aa219208SBarry Smith   ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1132f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1133f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1134f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1135f91d8e95SBarry Smith 
1136f91d8e95SBarry Smith   /* copy x values over to hypre */
113730e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1138f91d8e95SBarry Smith   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
113930e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructVectorSetBoxValues,(mx->hb,ilower,iupper,xx));
1140f91d8e95SBarry Smith   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
114130e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructVectorAssemble,(mx->hb));
114230e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1143f91d8e95SBarry Smith 
1144f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1145f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
114630e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructVectorGetBoxValues,(mx->hx,ilower,iupper,yy));
1147f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1148f91d8e95SBarry Smith   PetscFunctionReturn(0);
1149f91d8e95SBarry Smith }
1150f91d8e95SBarry Smith 
11519e5bc791SBarry Smith #undef __FUNCT__
11529e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1153ace3abfcSBarry 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)
11549e5bc791SBarry Smith {
11559e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
11569e5bc791SBarry Smith   PetscErrorCode ierr;
11579e5bc791SBarry Smith   int            oits;
11589e5bc791SBarry Smith 
11599e5bc791SBarry Smith   PetscFunctionBegin;
116030e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
116130e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
11629e5bc791SBarry Smith 
11639e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
116430e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGGetNumIterations,(jac->hsolver,&oits));
11659e5bc791SBarry Smith   *outits = oits;
11669e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
11679e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
116830e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
116930e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
11709e5bc791SBarry Smith   PetscFunctionReturn(0);
11719e5bc791SBarry Smith }
11729e5bc791SBarry Smith 
11739e5bc791SBarry Smith 
11743a32d3dbSGlenn Hammond #undef __FUNCT__
11753a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
11763a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
11773a32d3dbSGlenn Hammond {
11783a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
11793a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
11803a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct *)(pc->pmat->data);
1181ace3abfcSBarry Smith   PetscBool       flg;
11823a32d3dbSGlenn Hammond 
11833a32d3dbSGlenn Hammond   PetscFunctionBegin;
11843a32d3dbSGlenn Hammond   ierr = PetscTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1185e7e72b3dSBarry Smith   if (!flg) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
11863a32d3dbSGlenn Hammond 
11873a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
11883a32d3dbSGlenn Hammond   if (ex->hsolver) {
118930e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_StructPFMGDestroy,(ex->hsolver));
11903a32d3dbSGlenn Hammond   }
119130e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
11923a32d3dbSGlenn Hammond   ierr = PCSetFromOptions_PFMG(pc);CHKERRQ(ierr);
119330e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
119430e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
11953a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
11963a32d3dbSGlenn Hammond }
11973a32d3dbSGlenn Hammond 
1198ebc551c0SBarry Smith 
1199ebc551c0SBarry Smith /*MC
1200ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1201ebc551c0SBarry Smith 
1202ebc551c0SBarry Smith    Level: advanced
1203ebc551c0SBarry Smith 
12049e5bc791SBarry Smith    Options Database:
12059e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
12069e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
12079e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
12089e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
12099e5bc791SBarry 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
12109e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
1211f91d8e95SBarry Smith 
12129e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
12139e5bc791SBarry Smith 
12148e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
1215aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
12169e5bc791SBarry Smith 
12179e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
1218ebc551c0SBarry Smith M*/
1219ebc551c0SBarry Smith 
1220ebc551c0SBarry Smith EXTERN_C_BEGIN
1221ebc551c0SBarry Smith #undef __FUNCT__
1222ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
12237087cfbeSBarry Smith PetscErrorCode  PCCreate_PFMG(PC pc)
1224ebc551c0SBarry Smith {
1225ebc551c0SBarry Smith   PetscErrorCode ierr;
1226ebc551c0SBarry Smith   PC_PFMG        *ex;
1227ebc551c0SBarry Smith 
1228ebc551c0SBarry Smith   PetscFunctionBegin;
1229ebc551c0SBarry Smith   ierr = PetscNew(PC_PFMG,&ex);CHKERRQ(ierr);\
123068326731SBarry Smith   pc->data = ex;
1231ebc551c0SBarry Smith 
12329e5bc791SBarry Smith   ex->its            = 1;
12339e5bc791SBarry Smith   ex->tol            = 1.e-8;
12349e5bc791SBarry Smith   ex->relax_type     = 1;
12359e5bc791SBarry Smith   ex->rap_type       = 0;
12369e5bc791SBarry Smith   ex->num_pre_relax  = 1;
12379e5bc791SBarry Smith   ex->num_post_relax = 1;
12383b46a515SGlenn Hammond   ex->max_levels     = 0;
12399e5bc791SBarry Smith 
1240ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
1241ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
1242ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
1243f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
12449e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
124568326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
1246f91d8e95SBarry Smith   ierr = MPI_Comm_dup(((PetscObject)pc)->comm,&(ex->hcomm));CHKERRQ(ierr);
124730e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1248ebc551c0SBarry Smith   PetscFunctionReturn(0);
1249ebc551c0SBarry Smith }
1250ebc551c0SBarry Smith EXTERN_C_END
1251d851a50bSGlenn Hammond 
1252325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
1253325fc9f4SBarry Smith 
1254d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
1255d851a50bSGlenn Hammond typedef struct {
1256d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
1257d851a50bSGlenn Hammond   HYPRE_SStructSolver  ss_solver;
1258d851a50bSGlenn Hammond 
1259d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
1260d851a50bSGlenn Hammond   int                 its;
1261d851a50bSGlenn Hammond   double              tol;
1262d851a50bSGlenn Hammond   int                 relax_type;
1263d851a50bSGlenn Hammond   int                 num_pre_relax,num_post_relax;
1264d851a50bSGlenn Hammond } PC_SysPFMG;
1265d851a50bSGlenn Hammond 
1266d851a50bSGlenn Hammond #undef __FUNCT__
1267d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
1268d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
1269d851a50bSGlenn Hammond {
1270d851a50bSGlenn Hammond   PetscErrorCode ierr;
1271d851a50bSGlenn Hammond   PC_SysPFMG    *ex = (PC_SysPFMG*) pc->data;
1272d851a50bSGlenn Hammond 
1273d851a50bSGlenn Hammond   PetscFunctionBegin;
127430e6f737SJed Brown   if (ex->ss_solver) {PetscStackCallHypre(0,HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));}
1275d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1276c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1277d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1278d851a50bSGlenn Hammond }
1279d851a50bSGlenn Hammond 
1280d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[]   = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
1281d851a50bSGlenn Hammond 
1282d851a50bSGlenn Hammond #undef __FUNCT__
1283d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
1284d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
1285d851a50bSGlenn Hammond {
1286d851a50bSGlenn Hammond   PetscErrorCode ierr;
1287ace3abfcSBarry Smith   PetscBool      iascii;
1288d851a50bSGlenn Hammond   PC_SysPFMG    *ex = (PC_SysPFMG*) pc->data;
1289d851a50bSGlenn Hammond 
1290d851a50bSGlenn Hammond   PetscFunctionBegin;
12912692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1292d851a50bSGlenn Hammond   if (iascii) {
1293d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
1294d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
1295d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
1296d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
1297d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
1298d851a50bSGlenn Hammond   }
1299d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1300d851a50bSGlenn Hammond }
1301d851a50bSGlenn Hammond 
1302d851a50bSGlenn Hammond 
1303d851a50bSGlenn Hammond #undef __FUNCT__
1304d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
1305d851a50bSGlenn Hammond PetscErrorCode PCSetFromOptions_SysPFMG(PC pc)
1306d851a50bSGlenn Hammond {
1307d851a50bSGlenn Hammond   PetscErrorCode ierr;
1308d851a50bSGlenn Hammond   PC_SysPFMG    *ex = (PC_SysPFMG*) pc->data;
1309ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1310d851a50bSGlenn Hammond 
1311d851a50bSGlenn Hammond   PetscFunctionBegin;
1312d851a50bSGlenn Hammond   ierr = PetscOptionsHead("SysPFMG options");CHKERRQ(ierr);
1313acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
1314d851a50bSGlenn Hammond   if (flg) {
1315d851a50bSGlenn Hammond     int level=3;
131630e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
1317d851a50bSGlenn Hammond   }
1318d851a50bSGlenn Hammond   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,PETSC_NULL);CHKERRQ(ierr);
131930e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
1320d851a50bSGlenn Hammond   ierr = PetscOptionsInt("-pc_syspfmg_num_pre_relax","Number of smoothing steps before coarse grid","HYPRE_SStructSysPFMGSetNumPreRelax",ex->num_pre_relax,&ex->num_pre_relax,PETSC_NULL);CHKERRQ(ierr);
132130e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
1322d851a50bSGlenn Hammond   ierr = PetscOptionsInt("-pc_syspfmg_num_post_relax","Number of smoothing steps after coarse grid","HYPRE_SStructSysPFMGSetNumPostRelax",ex->num_post_relax,&ex->num_post_relax,PETSC_NULL);CHKERRQ(ierr);
132330e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
1324d851a50bSGlenn Hammond 
1325d851a50bSGlenn Hammond   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,PETSC_NULL);CHKERRQ(ierr);
132630e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
1327d851a50bSGlenn Hammond   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,PETSC_NULL);CHKERRQ(ierr);
132830e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
1329d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
1330d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1331d851a50bSGlenn Hammond }
1332d851a50bSGlenn Hammond 
1333d851a50bSGlenn Hammond #undef __FUNCT__
1334d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
1335d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
1336d851a50bSGlenn Hammond {
1337d851a50bSGlenn Hammond   PetscErrorCode    ierr;
1338d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
1339d851a50bSGlenn Hammond   PetscScalar      *xx,*yy;
1340d851a50bSGlenn Hammond   int               ilower[3],iupper[3];
1341d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct *)(pc->pmat->data);
1342d851a50bSGlenn Hammond   int               ordering= mx->dofs_order;
1343d851a50bSGlenn Hammond   int               nvars= mx->nvars;
1344d851a50bSGlenn Hammond   int               part= 0;
1345d851a50bSGlenn Hammond   int               size;
1346d851a50bSGlenn Hammond   int               i;
1347d851a50bSGlenn Hammond 
1348d851a50bSGlenn Hammond   PetscFunctionBegin;
1349aa219208SBarry Smith   ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1350d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
1351d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
1352d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
1353d851a50bSGlenn Hammond 
1354d851a50bSGlenn Hammond   size= 1;
1355d851a50bSGlenn Hammond   for (i= 0; i< 3; i++) {
1356d851a50bSGlenn Hammond      size*= (iupper[i]-ilower[i]+1);
1357d851a50bSGlenn Hammond   }
1358d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
1359d851a50bSGlenn Hammond   if (ordering) {
136030e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
1361d851a50bSGlenn Hammond      ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
1362d851a50bSGlenn Hammond      for (i= 0; i< nvars; i++) {
136330e6f737SJed Brown        PetscStackCallHypre(0,HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,ilower,iupper,i,xx+(size*i)));
1364d851a50bSGlenn Hammond      }
1365d851a50bSGlenn Hammond      ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
136630e6f737SJed Brown      PetscStackCallHypre(0,HYPRE_SStructVectorAssemble,(mx->ss_b));
136730e6f737SJed Brown      PetscStackCallHypre(0,HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
136830e6f737SJed Brown      PetscStackCallHypre(0,HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1369d851a50bSGlenn Hammond 
1370d851a50bSGlenn Hammond      /* copy solution values back to PETSc */
1371d851a50bSGlenn Hammond      ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
1372d851a50bSGlenn Hammond      for (i= 0; i< nvars; i++) {
137330e6f737SJed Brown        PetscStackCallHypre(0,HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,ilower,iupper,i,yy+(size*i)));
1374d851a50bSGlenn Hammond      }
1375d851a50bSGlenn Hammond      ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1376a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
1377d851a50bSGlenn Hammond      PetscScalar     *z;
1378d851a50bSGlenn Hammond      int              j, k;
1379d851a50bSGlenn Hammond 
1380d851a50bSGlenn Hammond      ierr = PetscMalloc(nvars*size*sizeof(PetscScalar),&z);CHKERRQ(ierr);
138130e6f737SJed Brown      PetscStackCallHypre(0,HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
1382d851a50bSGlenn Hammond      ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
1383d851a50bSGlenn Hammond 
1384d851a50bSGlenn Hammond      /* transform nodal to hypre's variable ordering for sys_pfmg */
1385d851a50bSGlenn Hammond      for (i= 0; i< size; i++) {
1386d851a50bSGlenn Hammond         k= i*nvars;
1387d851a50bSGlenn Hammond         for (j= 0; j< nvars; j++) {
1388d851a50bSGlenn Hammond            z[j*size+i]= xx[k+j];
1389d851a50bSGlenn Hammond         }
1390d851a50bSGlenn Hammond      }
1391d851a50bSGlenn Hammond      for (i= 0; i< nvars; i++) {
139230e6f737SJed Brown        PetscStackCallHypre(0,HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,ilower,iupper,i,z+(size*i)));
1393d851a50bSGlenn Hammond      }
1394d851a50bSGlenn Hammond      ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
139530e6f737SJed Brown      PetscStackCallHypre(0,HYPRE_SStructVectorAssemble,(mx->ss_b));
139630e6f737SJed Brown      PetscStackCallHypre(0,HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1397d851a50bSGlenn Hammond 
1398d851a50bSGlenn Hammond      /* copy solution values back to PETSc */
1399d851a50bSGlenn Hammond      ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
1400d851a50bSGlenn Hammond      for (i= 0; i< nvars; i++) {
140130e6f737SJed Brown        PetscStackCallHypre(0,HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,ilower,iupper,i,z+(size*i)));
1402d851a50bSGlenn Hammond      }
1403d851a50bSGlenn Hammond      /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
1404d851a50bSGlenn Hammond      for (i= 0; i< size; i++) {
1405d851a50bSGlenn Hammond         k= i*nvars;
1406d851a50bSGlenn Hammond         for (j= 0; j< nvars; j++) {
1407d851a50bSGlenn Hammond            yy[k+j]= z[j*size+i];
1408d851a50bSGlenn Hammond         }
1409d851a50bSGlenn Hammond      }
1410d851a50bSGlenn Hammond      ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1411d851a50bSGlenn Hammond      ierr = PetscFree(z);CHKERRQ(ierr);
1412d851a50bSGlenn Hammond   }
1413d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1414d851a50bSGlenn Hammond }
1415d851a50bSGlenn Hammond 
1416d851a50bSGlenn Hammond #undef __FUNCT__
1417d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
1418ace3abfcSBarry 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)
1419d851a50bSGlenn Hammond {
1420d851a50bSGlenn Hammond   PC_SysPFMG    *jac = (PC_SysPFMG*)pc->data;
1421d851a50bSGlenn Hammond   PetscErrorCode ierr;
1422d851a50bSGlenn Hammond   int            oits;
1423d851a50bSGlenn Hammond 
1424d851a50bSGlenn Hammond   PetscFunctionBegin;
142530e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
142630e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
1427d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
142830e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,&oits));
1429d851a50bSGlenn Hammond   *outits = oits;
1430d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
1431d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
143230e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
143330e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
1434d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1435d851a50bSGlenn Hammond }
1436d851a50bSGlenn Hammond 
1437d851a50bSGlenn Hammond 
1438d851a50bSGlenn Hammond #undef __FUNCT__
1439d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
1440d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
1441d851a50bSGlenn Hammond {
1442d851a50bSGlenn Hammond   PetscErrorCode    ierr;
1443d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
1444d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx = (Mat_HYPRESStruct *)(pc->pmat->data);
1445ace3abfcSBarry Smith   PetscBool         flg;
1446d851a50bSGlenn Hammond 
1447d851a50bSGlenn Hammond   PetscFunctionBegin;
1448d851a50bSGlenn Hammond   ierr = PetscTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
1449e7e72b3dSBarry Smith   if (!flg) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
1450d851a50bSGlenn Hammond 
1451d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
1452d851a50bSGlenn Hammond   if (ex->ss_solver) {
145330e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1454d851a50bSGlenn Hammond   }
145530e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
1456d851a50bSGlenn Hammond   ierr = PCSetFromOptions_SysPFMG(pc);CHKERRQ(ierr);
145730e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
145830e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1459d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1460d851a50bSGlenn Hammond }
1461d851a50bSGlenn Hammond 
1462d851a50bSGlenn Hammond 
1463d851a50bSGlenn Hammond /*MC
1464d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
1465d851a50bSGlenn Hammond 
1466d851a50bSGlenn Hammond    Level: advanced
1467d851a50bSGlenn Hammond 
1468d851a50bSGlenn Hammond    Options Database:
1469d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
1470d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
1471d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
1472d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
1473d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
1474d851a50bSGlenn Hammond 
1475d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
1476d851a50bSGlenn Hammond 
1477f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
1478aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
1479d851a50bSGlenn Hammond            Also, only cell-centered variables.
1480d851a50bSGlenn Hammond 
1481d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
1482d851a50bSGlenn Hammond M*/
1483d851a50bSGlenn Hammond 
1484d851a50bSGlenn Hammond EXTERN_C_BEGIN
1485d851a50bSGlenn Hammond #undef __FUNCT__
1486d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
14877087cfbeSBarry Smith PetscErrorCode  PCCreate_SysPFMG(PC pc)
1488d851a50bSGlenn Hammond {
1489d851a50bSGlenn Hammond   PetscErrorCode     ierr;
1490d851a50bSGlenn Hammond   PC_SysPFMG        *ex;
1491d851a50bSGlenn Hammond 
1492d851a50bSGlenn Hammond   PetscFunctionBegin;
1493d851a50bSGlenn Hammond   ierr = PetscNew(PC_SysPFMG,&ex);CHKERRQ(ierr);\
1494d851a50bSGlenn Hammond   pc->data = ex;
1495d851a50bSGlenn Hammond 
1496d851a50bSGlenn Hammond   ex->its            = 1;
1497d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
1498d851a50bSGlenn Hammond   ex->relax_type     = 1;
1499d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
1500d851a50bSGlenn Hammond   ex->num_post_relax = 1;
1501d851a50bSGlenn Hammond 
1502d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
1503d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
1504d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
1505d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
1506d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
1507d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
1508d851a50bSGlenn Hammond   ierr = MPI_Comm_dup(((PetscObject)pc)->comm,&(ex->hcomm));CHKERRQ(ierr);
150930e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
1510d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1511d851a50bSGlenn Hammond }
1512d851a50bSGlenn Hammond EXTERN_C_END
1513