xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 30e6f737909d1fdaf5b96a56d43559fa7cd7884f)
116d9e3a6SLisandro Dalcin #define PETSCKSP_DLL
216d9e3a6SLisandro Dalcin 
316d9e3a6SLisandro Dalcin /*
416d9e3a6SLisandro Dalcin    Provides an interface to the LLNL package hypre
516d9e3a6SLisandro Dalcin */
60f1074feSSatish Balay 
70f1074feSSatish Balay /* Must use hypre 2.0.0 or more recent. */
80f1074feSSatish Balay 
916d9e3a6SLisandro Dalcin #include "private/pcimpl.h"          /*I "petscpc.h" I*/
102aedb7c8SJed Brown #include "../src/dm/impls/da/mhyp.h"
1116d9e3a6SLisandro Dalcin 
1216d9e3a6SLisandro Dalcin /*
1316d9e3a6SLisandro Dalcin    Private context (data structure) for the  preconditioner.
1416d9e3a6SLisandro Dalcin */
1516d9e3a6SLisandro Dalcin typedef struct {
1616d9e3a6SLisandro Dalcin   HYPRE_Solver       hsolver;
1716d9e3a6SLisandro Dalcin   HYPRE_IJMatrix     ij;
1816d9e3a6SLisandro Dalcin   HYPRE_IJVector     b,x;
1916d9e3a6SLisandro Dalcin 
2016d9e3a6SLisandro Dalcin   PetscErrorCode     (*destroy)(HYPRE_Solver);
2116d9e3a6SLisandro Dalcin   PetscErrorCode     (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
2216d9e3a6SLisandro Dalcin   PetscErrorCode     (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
2316d9e3a6SLisandro Dalcin 
2416d9e3a6SLisandro Dalcin   MPI_Comm           comm_hypre;
2516d9e3a6SLisandro Dalcin   char              *hypre_type;
2616d9e3a6SLisandro Dalcin 
2716d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
2816d9e3a6SLisandro Dalcin   int                maxiter;
2916d9e3a6SLisandro Dalcin   double             tol;
3016d9e3a6SLisandro Dalcin 
3116d9e3a6SLisandro Dalcin   /* options for Pilut */
3216d9e3a6SLisandro Dalcin   int                factorrowsize;
3316d9e3a6SLisandro Dalcin 
3416d9e3a6SLisandro Dalcin   /* options for ParaSails */
3516d9e3a6SLisandro Dalcin   int                nlevels;
3616d9e3a6SLisandro Dalcin   double             threshhold;
3716d9e3a6SLisandro Dalcin   double             filter;
3816d9e3a6SLisandro Dalcin   int                sym;
3916d9e3a6SLisandro Dalcin   double             loadbal;
4016d9e3a6SLisandro Dalcin   int                logging;
4116d9e3a6SLisandro Dalcin   int                ruse;
4216d9e3a6SLisandro Dalcin   int                symt;
4316d9e3a6SLisandro Dalcin 
4416d9e3a6SLisandro Dalcin   /* options for Euclid */
45ace3abfcSBarry Smith   PetscBool          bjilu;
4616d9e3a6SLisandro Dalcin   int                levels;
4716d9e3a6SLisandro Dalcin 
4816d9e3a6SLisandro Dalcin   /* options for Euclid and BoomerAMG */
49ace3abfcSBarry Smith   PetscBool          printstatistics;
5016d9e3a6SLisandro Dalcin 
5116d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
5216d9e3a6SLisandro Dalcin   int                cycletype;
5316d9e3a6SLisandro Dalcin   int                maxlevels;
5416d9e3a6SLisandro Dalcin   double             strongthreshold;
5516d9e3a6SLisandro Dalcin   double             maxrowsum;
560f1074feSSatish Balay   int                gridsweeps[3];
5716d9e3a6SLisandro Dalcin   int                coarsentype;
5816d9e3a6SLisandro Dalcin   int                measuretype;
590f1074feSSatish Balay   int                relaxtype[3];
6016d9e3a6SLisandro Dalcin   double             relaxweight;
6116d9e3a6SLisandro Dalcin   double             outerrelaxweight;
6216d9e3a6SLisandro Dalcin   int                relaxorder;
6316d9e3a6SLisandro Dalcin   double             truncfactor;
64ace3abfcSBarry Smith   PetscBool          applyrichardson;
650f1074feSSatish Balay   int                pmax;
660f1074feSSatish Balay   int                interptype;
670f1074feSSatish Balay   int                agg_nl;
680f1074feSSatish Balay   int                agg_num_paths;
698f87f92bSBarry Smith   int                nodal_coarsen;
70ace3abfcSBarry Smith   PetscBool          nodal_relax;
718f87f92bSBarry Smith   int                nodal_relax_levels;
7216d9e3a6SLisandro Dalcin } PC_HYPRE;
7316d9e3a6SLisandro Dalcin 
7416d9e3a6SLisandro Dalcin 
7516d9e3a6SLisandro Dalcin #undef __FUNCT__
7616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE"
7716d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
7816d9e3a6SLisandro Dalcin {
7916d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
8016d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
8116d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
8216d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
8316d9e3a6SLisandro Dalcin   PetscInt           bs;
8416d9e3a6SLisandro Dalcin 
8516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
8616d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
8702a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
8816d9e3a6SLisandro Dalcin   }
895f5c5b43SBarry Smith 
905f5c5b43SBarry Smith   if (pc->setupcalled) {
915f5c5b43SBarry Smith     /* always destroy the old matrix and create a new memory;
925f5c5b43SBarry Smith        hope this does not churn the memory too much. The problem
935f5c5b43SBarry Smith        is I do not know if it is possible to put the matrix back to
945f5c5b43SBarry Smith        its initial state so that we can directly copy the values
955f5c5b43SBarry Smith        the second time through. */
96*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_IJMatrixDestroy,(jac->ij));
975f5c5b43SBarry Smith     jac->ij = 0;
9816d9e3a6SLisandro Dalcin   }
995f5c5b43SBarry Smith 
10016d9e3a6SLisandro Dalcin   if (!jac->ij) { /* create the matrix the first time through */
10116d9e3a6SLisandro Dalcin     ierr = MatHYPRE_IJMatrixCreate(pc->pmat,&jac->ij);CHKERRQ(ierr);
10216d9e3a6SLisandro Dalcin   }
10316d9e3a6SLisandro Dalcin   if (!jac->b) { /* create the vectors the first time through */
10416d9e3a6SLisandro Dalcin     Vec x,b;
10516d9e3a6SLisandro Dalcin     ierr = MatGetVecs(pc->pmat,&x,&b);CHKERRQ(ierr);
10616d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(x,&jac->x);CHKERRQ(ierr);
10716d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(b,&jac->b);CHKERRQ(ierr);
10816d9e3a6SLisandro Dalcin     ierr = VecDestroy(x);CHKERRQ(ierr);
10916d9e3a6SLisandro Dalcin     ierr = VecDestroy(b);CHKERRQ(ierr);
11016d9e3a6SLisandro Dalcin   }
1115f5c5b43SBarry Smith 
11216d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
11316d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
11416d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
11516d9e3a6SLisandro Dalcin     if (bs > 1) {
116*30e6f737SJed Brown       PetscStackCallHypre(0,HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
11716d9e3a6SLisandro Dalcin     }
11816d9e3a6SLisandro Dalcin   };
11916d9e3a6SLisandro Dalcin   ierr = MatHYPRE_IJMatrixCopy(pc->pmat,jac->ij);CHKERRQ(ierr);
120*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
121*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_IJVectorGetObject,(jac->b,(void**)&bv));
122*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_IJVectorGetObject,(jac->x,(void**)&xv));
123*30e6f737SJed Brown   PetscStackCallHypre("HYPRE_SetupXXX",(*jac->setup),(jac->hsolver,hmat,bv,xv));
12416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
12516d9e3a6SLisandro Dalcin }
12616d9e3a6SLisandro Dalcin 
12716d9e3a6SLisandro Dalcin /*
12816d9e3a6SLisandro Dalcin     Replaces the address where the HYPRE vector points to its data with the address of
12916d9e3a6SLisandro Dalcin   PETSc's data. Saves the old address so it can be reset when we are finished with it.
13016d9e3a6SLisandro Dalcin   Allows use to get the data into a HYPRE vector without the cost of memcopies
13116d9e3a6SLisandro Dalcin */
13216d9e3a6SLisandro Dalcin #define HYPREReplacePointer(b,newvalue,savedvalue) {\
13316d9e3a6SLisandro Dalcin    hypre_ParVector *par_vector   = (hypre_ParVector *)hypre_IJVectorObject(((hypre_IJVector*)b));\
13416d9e3a6SLisandro Dalcin    hypre_Vector    *local_vector = hypre_ParVectorLocalVector(par_vector);\
13516d9e3a6SLisandro Dalcin    savedvalue         = local_vector->data;\
13616d9e3a6SLisandro Dalcin    local_vector->data = newvalue;}
13716d9e3a6SLisandro Dalcin 
13816d9e3a6SLisandro Dalcin #undef __FUNCT__
13916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE"
14016d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
14116d9e3a6SLisandro Dalcin {
14216d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
14316d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
14416d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
14516d9e3a6SLisandro Dalcin   PetscScalar        *bv,*xv;
14616d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
14716d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
14816d9e3a6SLisandro Dalcin   int                hierr;
14916d9e3a6SLisandro Dalcin 
15016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
15116d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
15216d9e3a6SLisandro Dalcin   ierr = VecGetArray(b,&bv);CHKERRQ(ierr);
15316d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
15416d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,bv,sbv);
15516d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
15616d9e3a6SLisandro Dalcin 
157*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
158*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
159*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
16016d9e3a6SLisandro Dalcin   hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
16165e19b50SBarry Smith   if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
16216d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
16316d9e3a6SLisandro Dalcin 
16416d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
16516d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
16616d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
16716d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(b,&bv);CHKERRQ(ierr);
16816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
16916d9e3a6SLisandro Dalcin }
17016d9e3a6SLisandro Dalcin 
17116d9e3a6SLisandro Dalcin #undef __FUNCT__
17216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE"
17316d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
17416d9e3a6SLisandro Dalcin {
17516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
17616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
17716d9e3a6SLisandro Dalcin 
17816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
179*30e6f737SJed Brown   if (jac->ij) PetscStackCallHypre(0,HYPRE_IJMatrixDestroy,(jac->ij));
180*30e6f737SJed Brown   if (jac->b)  PetscStackCallHypre(0,HYPRE_IJVectorDestroy,(jac->b));
181*30e6f737SJed Brown   if (jac->x)  PetscStackCallHypre(0,HYPRE_IJVectorDestroy,(jac->x));
182*30e6f737SJed Brown   if (jac->destroy) PetscStackCallHypre("HYPRE_DistroyXXX",(*jac->destroy),(jac->hsolver));
183503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
18416d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
18516d9e3a6SLisandro Dalcin   ierr = PetscFree(jac);CHKERRQ(ierr);
18616d9e3a6SLisandro Dalcin 
18716d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
18816d9e3a6SLisandro Dalcin   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCHYPRESetType_C","",PETSC_NULL);CHKERRQ(ierr);
18916d9e3a6SLisandro Dalcin   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCHYPREGetType_C","",PETSC_NULL);CHKERRQ(ierr);
19016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
19116d9e3a6SLisandro Dalcin }
19216d9e3a6SLisandro Dalcin 
19316d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
19416d9e3a6SLisandro Dalcin #undef __FUNCT__
19516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut"
19616d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PC pc)
19716d9e3a6SLisandro Dalcin {
19816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
19916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
200ace3abfcSBarry Smith   PetscBool      flag;
20116d9e3a6SLisandro Dalcin 
20216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
20316d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE Pilut Options");CHKERRQ(ierr);
20416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
205*30e6f737SJed Brown   if (flag) PetscStackCallHypre(0,HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
20616d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
207*30e6f737SJed Brown   if (flag) PetscStackCallHypre(0,HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
20816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
209*30e6f737SJed Brown   if (flag) PetscStackCallHypre(0,HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
21016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
21116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
21216d9e3a6SLisandro Dalcin }
21316d9e3a6SLisandro Dalcin 
21416d9e3a6SLisandro Dalcin #undef __FUNCT__
21516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut"
21616d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
21716d9e3a6SLisandro Dalcin {
21816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
21916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
220ace3abfcSBarry Smith   PetscBool      iascii;
22116d9e3a6SLisandro Dalcin 
22216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
2232692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
22416d9e3a6SLisandro Dalcin   if (iascii) {
22516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
22616d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
22716d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
22816d9e3a6SLisandro Dalcin     } else {
22916d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr);
23016d9e3a6SLisandro Dalcin     }
23116d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
23216d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: drop tolerance %G\n",jac->tol);CHKERRQ(ierr);
23316d9e3a6SLisandro Dalcin     } else {
23416d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr);
23516d9e3a6SLisandro Dalcin     }
23616d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
23716d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
23816d9e3a6SLisandro Dalcin     } else {
23916d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default factor row size \n");CHKERRQ(ierr);
24016d9e3a6SLisandro Dalcin     }
24116d9e3a6SLisandro Dalcin   }
24216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
24316d9e3a6SLisandro Dalcin }
24416d9e3a6SLisandro Dalcin 
24516d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
24616d9e3a6SLisandro Dalcin #undef __FUNCT__
24716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Euclid"
24816d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PC pc)
24916d9e3a6SLisandro Dalcin {
25016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
25116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
252ace3abfcSBarry Smith   PetscBool      flag;
253390e7148SBarry Smith   char           *args[8],levels[16];
254390e7148SBarry Smith   PetscInt       cnt = 0;
25516d9e3a6SLisandro Dalcin 
25616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
25716d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE Euclid Options");CHKERRQ(ierr);
25816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_euclid_levels","Number of levels of fill ILU(k)","None",jac->levels,&jac->levels,&flag);CHKERRQ(ierr);
25916d9e3a6SLisandro Dalcin   if (flag) {
26065e19b50SBarry Smith     if (jac->levels < 0) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be nonegative",jac->levels);
26116d9e3a6SLisandro Dalcin     sprintf(levels,"%d",jac->levels);
262390e7148SBarry Smith     args[cnt++] = (char*)"-level"; args[cnt++] = levels;
26316d9e3a6SLisandro Dalcin   }
264acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_euclid_bj","Use block Jacobi ILU(k)","None",jac->bjilu,&jac->bjilu,PETSC_NULL);CHKERRQ(ierr);
26516d9e3a6SLisandro Dalcin   if (jac->bjilu) {
266390e7148SBarry Smith     args[cnt++] =(char*) "-bj"; args[cnt++] = (char*)"1";
26716d9e3a6SLisandro Dalcin   }
26816d9e3a6SLisandro Dalcin 
269acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_euclid_print_statistics","Print statistics","None",jac->printstatistics,&jac->printstatistics,PETSC_NULL);CHKERRQ(ierr);
27016d9e3a6SLisandro Dalcin   if (jac->printstatistics) {
271390e7148SBarry Smith     args[cnt++] = (char*)"-eu_stats"; args[cnt++] = (char*)"1";
272390e7148SBarry Smith     args[cnt++] = (char*)"-eu_mem"; args[cnt++] = (char*)"1";
27316d9e3a6SLisandro Dalcin   }
27416d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
275*30e6f737SJed Brown   if (cnt) PetscStackCallHypre(0,HYPRE_EuclidSetParams,(jac->hsolver,cnt,args));
27616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
27716d9e3a6SLisandro Dalcin }
27816d9e3a6SLisandro Dalcin 
27916d9e3a6SLisandro Dalcin #undef __FUNCT__
28016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Euclid"
28116d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer)
28216d9e3a6SLisandro Dalcin {
28316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
28416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
285ace3abfcSBarry Smith   PetscBool      iascii;
28616d9e3a6SLisandro Dalcin 
28716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
2882692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
28916d9e3a6SLisandro Dalcin   if (iascii) {
29016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid preconditioning\n");CHKERRQ(ierr);
29116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid: number of levels %d\n",jac->levels);CHKERRQ(ierr);
29216d9e3a6SLisandro Dalcin     if (jac->bjilu) {
29316d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid: Using block Jacobi ILU instead of parallel ILU\n");CHKERRQ(ierr);
29416d9e3a6SLisandro Dalcin     }
29516d9e3a6SLisandro Dalcin   }
29616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
29716d9e3a6SLisandro Dalcin }
29816d9e3a6SLisandro Dalcin 
29916d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
30016d9e3a6SLisandro Dalcin 
30116d9e3a6SLisandro Dalcin #undef __FUNCT__
30216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG"
30316d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
30416d9e3a6SLisandro Dalcin {
30516d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
30616d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
30716d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
30816d9e3a6SLisandro Dalcin   PetscScalar        *bv,*xv;
30916d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
31016d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
31116d9e3a6SLisandro Dalcin   int                hierr;
31216d9e3a6SLisandro Dalcin 
31316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
31416d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
31516d9e3a6SLisandro Dalcin   ierr = VecGetArray(b,&bv);CHKERRQ(ierr);
31616d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
31716d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,bv,sbv);
31816d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
31916d9e3a6SLisandro Dalcin 
320*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
321*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
322*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
32316d9e3a6SLisandro Dalcin 
32416d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
32516d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
326e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
32716d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
32816d9e3a6SLisandro Dalcin 
32916d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
33016d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
33116d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
33216d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(b,&bv);CHKERRQ(ierr);
33316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
33416d9e3a6SLisandro Dalcin }
33516d9e3a6SLisandro Dalcin 
33616d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
3370f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
33816d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
3390f1074feSSatish Balay static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","","SOR/Jacobi","backward-SOR/Jacobi","","symmetric-SOR/Jacobi",
3400f1074feSSatish Balay                                                   "","","Gaussian-elimination"};
3410f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
3420f1074feSSatish Balay                                                   "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"};
34316d9e3a6SLisandro Dalcin #undef __FUNCT__
34416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG"
34516d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PC pc)
34616d9e3a6SLisandro Dalcin {
34716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
34816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
34916d9e3a6SLisandro Dalcin   int            n,indx;
350ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
35116d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
35216d9e3a6SLisandro Dalcin 
35316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
35416d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE BoomerAMG Options");CHKERRQ(ierr);
35516d9e3a6SLisandro Dalcin   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
35616d9e3a6SLisandro Dalcin   if (flg) {
35716d9e3a6SLisandro Dalcin     jac->cycletype = indx;
358*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
35916d9e3a6SLisandro Dalcin   }
36016d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
36116d9e3a6SLisandro Dalcin   if (flg) {
36265e19b50SBarry Smith     if (jac->maxlevels < 2) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
363*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
36416d9e3a6SLisandro Dalcin   }
36516d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
36616d9e3a6SLisandro Dalcin   if (flg) {
36765e19b50SBarry Smith     if (jac->maxiter < 1) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
368*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
36916d9e3a6SLisandro Dalcin   }
3700f1074feSSatish 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);
37116d9e3a6SLisandro Dalcin   if (flg) {
37265e19b50SBarry 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);
373*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
37416d9e3a6SLisandro Dalcin   }
37516d9e3a6SLisandro Dalcin 
3760f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
37716d9e3a6SLisandro Dalcin   if (flg) {
37865e19b50SBarry 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);
379*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
38016d9e3a6SLisandro Dalcin   }
38116d9e3a6SLisandro Dalcin 
3820f1074feSSatish 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);
3830f1074feSSatish Balay   if (flg) {
38465e19b50SBarry 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);
385*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
3860f1074feSSatish Balay   }
3870f1074feSSatish Balay 
3880f1074feSSatish Balay  ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
3890f1074feSSatish Balay   if (flg) {
39065e19b50SBarry 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);
3910f1074feSSatish Balay 
392*30e6f737SJed Brown      PetscStackCallHypre(0,HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
3930f1074feSSatish Balay   }
3940f1074feSSatish Balay 
3950f1074feSSatish Balay 
3960f1074feSSatish 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);
3970f1074feSSatish Balay   if (flg) {
39865e19b50SBarry 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);
3990f1074feSSatish Balay 
400*30e6f737SJed Brown      PetscStackCallHypre(0,HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
4010f1074feSSatish Balay   }
4020f1074feSSatish Balay 
4030f1074feSSatish Balay 
40416d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
40516d9e3a6SLisandro Dalcin   if (flg) {
40665e19b50SBarry 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);
407*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
40816d9e3a6SLisandro Dalcin   }
40916d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
41016d9e3a6SLisandro Dalcin   if (flg) {
41165e19b50SBarry 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);
41265e19b50SBarry 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);
413*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
41416d9e3a6SLisandro Dalcin   }
41516d9e3a6SLisandro Dalcin 
41616d9e3a6SLisandro Dalcin   /* Grid sweeps */
4170f1074feSSatish 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);
41816d9e3a6SLisandro Dalcin   if (flg) {
419*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
42016d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
42116d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
4220f1074feSSatish Balay     jac->gridsweeps[1] = indx;
4230f1074feSSatish Balay     /*defaults coarse to 1 */
4240f1074feSSatish Balay     jac->gridsweeps[2] = 1;
42516d9e3a6SLisandro Dalcin   }
4260f1074feSSatish Balay 
4270f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx ,&flg);CHKERRQ(ierr);
42816d9e3a6SLisandro Dalcin   if (flg) {
429*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
4300f1074feSSatish Balay     jac->gridsweeps[0] = indx;
43116d9e3a6SLisandro Dalcin   }
43216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
43316d9e3a6SLisandro Dalcin   if (flg) {
434*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
4350f1074feSSatish Balay     jac->gridsweeps[1] = indx;
43616d9e3a6SLisandro Dalcin   }
4370f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
43816d9e3a6SLisandro Dalcin   if (flg) {
439*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
4400f1074feSSatish Balay     jac->gridsweeps[2] = indx;
44116d9e3a6SLisandro Dalcin   }
44216d9e3a6SLisandro Dalcin 
44316d9e3a6SLisandro Dalcin   /* Relax type */
4440f1074feSSatish 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);
44516d9e3a6SLisandro Dalcin   if (flg) {
4460f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
447*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
4480f1074feSSatish Balay     /* by default, coarse type set to 9 */
4490f1074feSSatish Balay     jac->relaxtype[2] = 9;
4500f1074feSSatish Balay 
45116d9e3a6SLisandro Dalcin   }
4520f1074feSSatish Balay   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_down","Relax type for the down cycles","None",HYPREBoomerAMGRelaxType,10,HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr);
45316d9e3a6SLisandro Dalcin   if (flg) {
45416d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
455*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
45616d9e3a6SLisandro Dalcin   }
4570f1074feSSatish Balay   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_up","Relax type for the up cycles","None",HYPREBoomerAMGRelaxType,10,HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr);
45816d9e3a6SLisandro Dalcin   if (flg) {
4590f1074feSSatish Balay     jac->relaxtype[1] = indx;
460*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
46116d9e3a6SLisandro Dalcin   }
46216d9e3a6SLisandro Dalcin   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,10,HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
46316d9e3a6SLisandro Dalcin   if (flg) {
4640f1074feSSatish Balay     jac->relaxtype[2] = indx;
465*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
46616d9e3a6SLisandro Dalcin   }
46716d9e3a6SLisandro Dalcin 
46816d9e3a6SLisandro Dalcin   /* Relaxation Weight */
46916d9e3a6SLisandro 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);
47016d9e3a6SLisandro Dalcin   if (flg) {
471*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
47216d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
47316d9e3a6SLisandro Dalcin   }
47416d9e3a6SLisandro Dalcin 
47516d9e3a6SLisandro Dalcin   n=2;
47616d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
47716d9e3a6SLisandro 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);
47816d9e3a6SLisandro Dalcin   if (flg) {
47916d9e3a6SLisandro Dalcin     if (n == 2) {
48016d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
481*30e6f737SJed Brown       PetscStackCallHypre(0,HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
48216d9e3a6SLisandro Dalcin     } else {
48365e19b50SBarry 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);
48416d9e3a6SLisandro Dalcin     }
48516d9e3a6SLisandro Dalcin   }
48616d9e3a6SLisandro Dalcin 
48716d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
48816d9e3a6SLisandro 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);
48916d9e3a6SLisandro Dalcin   if (flg) {
490*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetOuterWt,( jac->hsolver, tmpdbl));
49116d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
49216d9e3a6SLisandro Dalcin   }
49316d9e3a6SLisandro Dalcin 
49416d9e3a6SLisandro Dalcin   n=2;
49516d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
49616d9e3a6SLisandro 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);
49716d9e3a6SLisandro Dalcin   if (flg) {
49816d9e3a6SLisandro Dalcin     if (n == 2) {
49916d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
500*30e6f737SJed Brown       PetscStackCallHypre(0,HYPRE_BoomerAMGSetLevelOuterWt,( jac->hsolver, twodbl[0], indx));
50116d9e3a6SLisandro Dalcin     } else {
50265e19b50SBarry 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);
50316d9e3a6SLisandro Dalcin     }
50416d9e3a6SLisandro Dalcin   }
50516d9e3a6SLisandro Dalcin 
50616d9e3a6SLisandro Dalcin   /* the Relax Order */
507acfcf0e5SJed Brown   ierr = PetscOptionsBool( "-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
50816d9e3a6SLisandro Dalcin 
50916d9e3a6SLisandro Dalcin   if (flg) {
51016d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
511*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
51216d9e3a6SLisandro Dalcin   }
51316d9e3a6SLisandro Dalcin   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,2,HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
51416d9e3a6SLisandro Dalcin   if (flg) {
51516d9e3a6SLisandro Dalcin     jac->measuretype = indx;
516*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
51716d9e3a6SLisandro Dalcin   }
5180f1074feSSatish Balay   /* update list length 3/07 */
5190f1074feSSatish Balay   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,11,HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
52016d9e3a6SLisandro Dalcin   if (flg) {
52116d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
522*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
52316d9e3a6SLisandro Dalcin   }
5240f1074feSSatish Balay 
5250f1074feSSatish Balay   /* new 3/07 */
5260f1074feSSatish Balay   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,14,HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
5270f1074feSSatish Balay   if (flg) {
5280f1074feSSatish Balay     jac->interptype = indx;
529*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
5300f1074feSSatish Balay   }
5310f1074feSSatish Balay 
53290d69ab7SBarry Smith   flg  = PETSC_FALSE;
533acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_print_statistics","Print statistics","None",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
53416d9e3a6SLisandro Dalcin   if (flg) {
53516d9e3a6SLisandro Dalcin     int level=3;
53616d9e3a6SLisandro Dalcin     jac->printstatistics = PETSC_TRUE;
53716d9e3a6SLisandro Dalcin     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,PETSC_NULL);CHKERRQ(ierr);
538*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
5392ae77aedSBarry Smith   }
5402ae77aedSBarry Smith 
54190d69ab7SBarry Smith   flg  = PETSC_FALSE;
542acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_print_debug","Print debug information","None",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
5432ae77aedSBarry Smith   if (flg) {
5442ae77aedSBarry Smith     int level=3;
5452ae77aedSBarry Smith     jac->printstatistics = PETSC_TRUE;
5462ae77aedSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,PETSC_NULL);CHKERRQ(ierr);
547*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
54816d9e3a6SLisandro Dalcin   }
5498f87f92bSBarry Smith 
550acfcf0e5SJed Brown   ierr = PetscOptionsBool( "-pc_hypre_boomeramg_nodal_coarsen", "HYPRE_BoomerAMGSetNodal()", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5518f87f92bSBarry Smith   if (flg && tmp_truth) {
5528f87f92bSBarry Smith     jac->nodal_coarsen = 1;
553*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetNodal,(jac->hsolver,1));
5548f87f92bSBarry Smith   }
5558f87f92bSBarry Smith 
556acfcf0e5SJed Brown   ierr = PetscOptionsBool( "-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5578f87f92bSBarry Smith   if (flg && tmp_truth) {
5588f87f92bSBarry Smith     PetscInt tmp_int;
5598f87f92bSBarry Smith     ierr = PetscOptionsInt( "-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
5608f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
561*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
562*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
563*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
564*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
5658f87f92bSBarry Smith   }
5668f87f92bSBarry Smith 
56716d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
56816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
56916d9e3a6SLisandro Dalcin }
57016d9e3a6SLisandro Dalcin 
57116d9e3a6SLisandro Dalcin #undef __FUNCT__
57216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG"
573ace3abfcSBarry 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)
57416d9e3a6SLisandro Dalcin {
57516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
57616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
5774d0a8057SBarry Smith   int            oits;
57816d9e3a6SLisandro Dalcin 
57916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
580*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
581*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
58216d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
58316d9e3a6SLisandro Dalcin   ierr = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
58416d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
585*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,&oits));
5864d0a8057SBarry Smith   *outits = oits;
5874d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
5884d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
589*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
590*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
59116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
59216d9e3a6SLisandro Dalcin }
59316d9e3a6SLisandro Dalcin 
59416d9e3a6SLisandro Dalcin 
59516d9e3a6SLisandro Dalcin #undef __FUNCT__
59616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG"
59716d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
59816d9e3a6SLisandro Dalcin {
59916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
60016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
601ace3abfcSBarry Smith   PetscBool      iascii;
60216d9e3a6SLisandro Dalcin 
60316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
6042692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
60516d9e3a6SLisandro Dalcin   if (iascii) {
60616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
60716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
60816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
60916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
61016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Convergence tolerance PER hypre call %G\n",jac->tol);CHKERRQ(ierr);
61116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Threshold for strong coupling %G\n",jac->strongthreshold);CHKERRQ(ierr);
6120f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation truncation factor %G\n",jac->truncfactor);CHKERRQ(ierr);
6130f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
6140f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
6150f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
6160f1074feSSatish Balay 
61716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum row sums %G\n",jac->maxrowsum);CHKERRQ(ierr);
61816d9e3a6SLisandro Dalcin 
6190f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
6200f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
6210f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
62216d9e3a6SLisandro Dalcin 
6230f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
6240f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
6250f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
62616d9e3a6SLisandro Dalcin 
62716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax weight  (all)      %G\n",jac->relaxweight);CHKERRQ(ierr);
62816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Outer relax weight (all) %G\n",jac->outerrelaxweight);CHKERRQ(ierr);
62916d9e3a6SLisandro Dalcin 
63016d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
63116d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr);
63216d9e3a6SLisandro Dalcin     } else {
63316d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr);
63416d9e3a6SLisandro Dalcin     }
63516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
63616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
6370f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
6388f87f92bSBarry Smith     if (jac->nodal_coarsen) {
6398f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal())\n");CHKERRQ(ierr);
6408f87f92bSBarry Smith     }
6418f87f92bSBarry Smith     if (jac->nodal_relax) {
6428f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
6438f87f92bSBarry Smith     }
64416d9e3a6SLisandro Dalcin   }
64516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
64616d9e3a6SLisandro Dalcin }
64716d9e3a6SLisandro Dalcin 
64816d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
64916d9e3a6SLisandro Dalcin #undef __FUNCT__
65016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails"
65116d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PC pc)
65216d9e3a6SLisandro Dalcin {
65316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
65416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
65516d9e3a6SLisandro Dalcin   int            indx;
656ace3abfcSBarry Smith   PetscBool      flag;
65716d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
65816d9e3a6SLisandro Dalcin 
65916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
66016d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE ParaSails Options");CHKERRQ(ierr);
66116d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
66216d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
66316d9e3a6SLisandro Dalcin   if (flag) {
664*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
66516d9e3a6SLisandro Dalcin   }
66616d9e3a6SLisandro Dalcin 
66716d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
66816d9e3a6SLisandro Dalcin   if (flag) {
669*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
67016d9e3a6SLisandro Dalcin   }
67116d9e3a6SLisandro Dalcin 
67216d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
67316d9e3a6SLisandro Dalcin   if (flag) {
674*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
67516d9e3a6SLisandro Dalcin   }
67616d9e3a6SLisandro Dalcin 
677acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
67816d9e3a6SLisandro Dalcin   if (flag) {
679*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
68016d9e3a6SLisandro Dalcin   }
68116d9e3a6SLisandro Dalcin 
682acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
68316d9e3a6SLisandro Dalcin   if (flag) {
684*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
68516d9e3a6SLisandro Dalcin   }
68616d9e3a6SLisandro Dalcin 
68716d9e3a6SLisandro Dalcin   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,3,symtlist[0],&indx,&flag);CHKERRQ(ierr);
68816d9e3a6SLisandro Dalcin   if (flag) {
68916d9e3a6SLisandro Dalcin     jac->symt = indx;
690*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
69116d9e3a6SLisandro Dalcin   }
69216d9e3a6SLisandro Dalcin 
69316d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
69416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
69516d9e3a6SLisandro Dalcin }
69616d9e3a6SLisandro Dalcin 
69716d9e3a6SLisandro Dalcin #undef __FUNCT__
69816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails"
69916d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
70016d9e3a6SLisandro Dalcin {
70116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
70216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
703ace3abfcSBarry Smith   PetscBool      iascii;
70416d9e3a6SLisandro Dalcin   const char     *symt = 0;;
70516d9e3a6SLisandro Dalcin 
70616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
7072692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
70816d9e3a6SLisandro Dalcin   if (iascii) {
70916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
71016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
71116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: threshold %G\n",jac->threshhold);CHKERRQ(ierr);
71216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: filter %G\n",jac->filter);CHKERRQ(ierr);
71316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: load balance %G\n",jac->loadbal);CHKERRQ(ierr);
714ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
715ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
71616d9e3a6SLisandro Dalcin     if (!jac->symt) {
71716d9e3a6SLisandro Dalcin       symt = "nonsymmetric matrix and preconditioner";
71816d9e3a6SLisandro Dalcin     } else if (jac->symt == 1) {
71916d9e3a6SLisandro Dalcin       symt = "SPD matrix and preconditioner";
72016d9e3a6SLisandro Dalcin     } else if (jac->symt == 2) {
72116d9e3a6SLisandro Dalcin       symt = "nonsymmetric matrix but SPD preconditioner";
72216d9e3a6SLisandro Dalcin     } else {
72365e19b50SBarry Smith       SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
72416d9e3a6SLisandro Dalcin     }
72516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr);
72616d9e3a6SLisandro Dalcin   }
72716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
72816d9e3a6SLisandro Dalcin }
72916d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
73016d9e3a6SLisandro Dalcin 
73116d9e3a6SLisandro Dalcin EXTERN_C_BEGIN
73216d9e3a6SLisandro Dalcin #undef __FUNCT__
73316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
73416d9e3a6SLisandro Dalcin PetscErrorCode PETSCKSP_DLLEXPORT PCHYPREGetType_HYPRE(PC pc,const char *name[])
73516d9e3a6SLisandro Dalcin {
73616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
73716d9e3a6SLisandro Dalcin 
73816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
73916d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
74016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
74116d9e3a6SLisandro Dalcin }
74216d9e3a6SLisandro Dalcin EXTERN_C_END
74316d9e3a6SLisandro Dalcin 
74416d9e3a6SLisandro Dalcin EXTERN_C_BEGIN
74516d9e3a6SLisandro Dalcin #undef __FUNCT__
74616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
74716d9e3a6SLisandro Dalcin PetscErrorCode PETSCKSP_DLLEXPORT PCHYPRESetType_HYPRE(PC pc,const char name[])
74816d9e3a6SLisandro Dalcin {
74916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
75016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
751ace3abfcSBarry Smith   PetscBool      flag;
75216d9e3a6SLisandro Dalcin 
75316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
75416d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
75516d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
756e7e72b3dSBarry Smith     if (!flag) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
75716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
75816d9e3a6SLisandro Dalcin   } else {
75916d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
76016d9e3a6SLisandro Dalcin   }
76116d9e3a6SLisandro Dalcin 
76216d9e3a6SLisandro Dalcin   jac->maxiter            = PETSC_DEFAULT;
76316d9e3a6SLisandro Dalcin   jac->tol                = PETSC_DEFAULT;
76416d9e3a6SLisandro Dalcin   jac->printstatistics    = PetscLogPrintInfo;
76516d9e3a6SLisandro Dalcin 
76616d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
76716d9e3a6SLisandro Dalcin   if (flag) {
768*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
76916d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
77016d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
77116d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
77216d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
77316d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
77416d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
77516d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
77616d9e3a6SLisandro Dalcin   }
77716d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
77816d9e3a6SLisandro Dalcin   if (flag) {
779*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
78016d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
78116d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
78216d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
78316d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
78416d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
78516d9e3a6SLisandro Dalcin     /* initialize */
78616d9e3a6SLisandro Dalcin     jac->nlevels     = 1;
78716d9e3a6SLisandro Dalcin     jac->threshhold  = .1;
78816d9e3a6SLisandro Dalcin     jac->filter      = .1;
78916d9e3a6SLisandro Dalcin     jac->loadbal     = 0;
79016d9e3a6SLisandro Dalcin     if (PetscLogPrintInfo) {
79116d9e3a6SLisandro Dalcin       jac->logging     = (int) PETSC_TRUE;
79216d9e3a6SLisandro Dalcin     } else {
79316d9e3a6SLisandro Dalcin       jac->logging     = (int) PETSC_FALSE;
79416d9e3a6SLisandro Dalcin     }
79516d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
79616d9e3a6SLisandro Dalcin     jac->symt   = 0;
797*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
798*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
799*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
800*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
801*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
802*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
80316d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
80416d9e3a6SLisandro Dalcin   }
80516d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("euclid",jac->hypre_type,&flag);CHKERRQ(ierr);
80616d9e3a6SLisandro Dalcin   if (flag) {
80716d9e3a6SLisandro Dalcin     ierr                    = HYPRE_EuclidCreate(jac->comm_hypre,&jac->hsolver);
80816d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
80916d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Euclid;
81016d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_EuclidDestroy;
81116d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_EuclidSetup;
81216d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_EuclidSolve;
81316d9e3a6SLisandro Dalcin     /* initialization */
81416d9e3a6SLisandro Dalcin     jac->bjilu              = PETSC_FALSE;
81516d9e3a6SLisandro Dalcin     jac->levels             = 1;
81616d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
81716d9e3a6SLisandro Dalcin   }
81816d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
81916d9e3a6SLisandro Dalcin   if (flag) {
82016d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
82116d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
82216d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
82316d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
82416d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
82516d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
82616d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
82716d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
82816d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
82916d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
83016d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
83116d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
83216d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
8338f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
83416d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
83516d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
83616d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
83716d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
83816d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
8390f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
8408f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
8410f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
84216d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
84316d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
84416d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
8450f1074feSSatish Balay     jac->interptype       = 0;
8460f1074feSSatish Balay     jac->agg_nl           = 0;
8470f1074feSSatish Balay     jac->pmax             = 0;
8480f1074feSSatish Balay     jac->truncfactor      = 0.0;
8490f1074feSSatish Balay     jac->agg_num_paths    = 1;
8508f87f92bSBarry Smith 
8518f87f92bSBarry Smith     jac->nodal_coarsen    = 0;
8528f87f92bSBarry Smith     jac->nodal_relax      = PETSC_FALSE;
8538f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
854*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
855*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
856*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
857*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
858*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
859*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
860*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
861*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
862*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
863*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
864*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
865*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
866*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
867*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
868*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
869*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
87016d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
87116d9e3a6SLisandro Dalcin   }
872503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
87316d9e3a6SLisandro Dalcin   jac->hypre_type = PETSC_NULL;
87465e19b50SBarry Smith   SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, euclid, boomeramg",name);
87516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
87616d9e3a6SLisandro Dalcin }
87716d9e3a6SLisandro Dalcin EXTERN_C_END
87816d9e3a6SLisandro Dalcin 
87916d9e3a6SLisandro Dalcin /*
88016d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
88116d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
88216d9e3a6SLisandro Dalcin */
88316d9e3a6SLisandro Dalcin #undef __FUNCT__
88416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
88516d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE(PC pc)
88616d9e3a6SLisandro Dalcin {
88716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
88816d9e3a6SLisandro Dalcin   int            indx;
88916d9e3a6SLisandro Dalcin   const char     *type[] = {"pilut","parasails","boomeramg","euclid"};
890ace3abfcSBarry Smith   PetscBool      flg;
89116d9e3a6SLisandro Dalcin 
89216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
89316d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE preconditioner options");CHKERRQ(ierr);
89402a17cd4SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
89516d9e3a6SLisandro Dalcin   if (flg) {
89616d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
89702a17cd4SBarry Smith   } else {
89802a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
89916d9e3a6SLisandro Dalcin   }
90016d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
90116d9e3a6SLisandro Dalcin     ierr = pc->ops->setfromoptions(pc);CHKERRQ(ierr);
90216d9e3a6SLisandro Dalcin   }
90316d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
90416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
90516d9e3a6SLisandro Dalcin }
90616d9e3a6SLisandro Dalcin 
90716d9e3a6SLisandro Dalcin #undef __FUNCT__
90816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
90916d9e3a6SLisandro Dalcin /*@C
91016d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
91116d9e3a6SLisandro Dalcin 
91216d9e3a6SLisandro Dalcin    Input Parameters:
91316d9e3a6SLisandro Dalcin +     pc - the preconditioner context
91416d9e3a6SLisandro Dalcin -     name - either  pilut, parasails, boomeramg, euclid
91516d9e3a6SLisandro Dalcin 
91616d9e3a6SLisandro Dalcin    Options Database Keys:
91716d9e3a6SLisandro Dalcin    -pc_hypre_type - One of pilut, parasails, boomeramg, euclid
91816d9e3a6SLisandro Dalcin 
91916d9e3a6SLisandro Dalcin    Level: intermediate
92016d9e3a6SLisandro Dalcin 
92116d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
92216d9e3a6SLisandro Dalcin            PCHYPRE
92316d9e3a6SLisandro Dalcin 
92416d9e3a6SLisandro Dalcin @*/
92516d9e3a6SLisandro Dalcin PetscErrorCode PETSCKSP_DLLEXPORT PCHYPRESetType(PC pc,const char name[])
92616d9e3a6SLisandro Dalcin {
9274ac538c5SBarry Smith   PetscErrorCode ierr;
92816d9e3a6SLisandro Dalcin 
92916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
9300700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
93116d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
9324ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
93316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
93416d9e3a6SLisandro Dalcin }
93516d9e3a6SLisandro Dalcin 
93616d9e3a6SLisandro Dalcin #undef __FUNCT__
93716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
93816d9e3a6SLisandro Dalcin /*@C
93916d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
94016d9e3a6SLisandro Dalcin 
94116d9e3a6SLisandro Dalcin    Input Parameter:
94216d9e3a6SLisandro Dalcin .     pc - the preconditioner context
94316d9e3a6SLisandro Dalcin 
94416d9e3a6SLisandro Dalcin    Output Parameter:
94516d9e3a6SLisandro Dalcin .     name - either  pilut, parasails, boomeramg, euclid
94616d9e3a6SLisandro Dalcin 
94716d9e3a6SLisandro Dalcin    Level: intermediate
94816d9e3a6SLisandro Dalcin 
94916d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
95016d9e3a6SLisandro Dalcin            PCHYPRE
95116d9e3a6SLisandro Dalcin 
95216d9e3a6SLisandro Dalcin @*/
95316d9e3a6SLisandro Dalcin PetscErrorCode PETSCKSP_DLLEXPORT PCHYPREGetType(PC pc,const char *name[])
95416d9e3a6SLisandro Dalcin {
9554ac538c5SBarry Smith   PetscErrorCode ierr;
95616d9e3a6SLisandro Dalcin 
95716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
9580700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
95916d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
9604ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
96116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
96216d9e3a6SLisandro Dalcin }
96316d9e3a6SLisandro Dalcin 
96416d9e3a6SLisandro Dalcin /*MC
96516d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
96616d9e3a6SLisandro Dalcin 
96716d9e3a6SLisandro Dalcin    Options Database Keys:
96816d9e3a6SLisandro Dalcin +   -pc_hypre_type - One of pilut, parasails, boomeramg, euclid
96916d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
97016d9e3a6SLisandro Dalcin           preconditioner
97116d9e3a6SLisandro Dalcin 
97216d9e3a6SLisandro Dalcin    Level: intermediate
97316d9e3a6SLisandro Dalcin 
97416d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
97516d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
97616d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
97716d9e3a6SLisandro Dalcin 
97816d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
9790f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
9800f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
9810f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
9828f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
9830f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
9840f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
98516d9e3a6SLisandro Dalcin 
9860f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
9870f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
9880f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
98916d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
99016d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
99116d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
99216d9e3a6SLisandro Dalcin 
99316d9e3a6SLisandro Dalcin 	  2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
99416d9e3a6SLisandro Dalcin 	  -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
99516d9e3a6SLisandro Dalcin 
9969e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
9979e5bc791SBarry Smith 
99816d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
9999e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
100016d9e3a6SLisandro Dalcin 
100116d9e3a6SLisandro Dalcin M*/
100216d9e3a6SLisandro Dalcin 
100316d9e3a6SLisandro Dalcin EXTERN_C_BEGIN
100416d9e3a6SLisandro Dalcin #undef __FUNCT__
100516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
100616d9e3a6SLisandro Dalcin PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_HYPRE(PC pc)
100716d9e3a6SLisandro Dalcin {
100816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
100916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
101016d9e3a6SLisandro Dalcin 
101116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
101238f2d2fdSLisandro Dalcin   ierr = PetscNewLog(pc,PC_HYPRE,&jac);CHKERRQ(ierr);
101316d9e3a6SLisandro Dalcin   pc->data                 = jac;
101416d9e3a6SLisandro Dalcin   pc->ops->destroy         = PCDestroy_HYPRE;
101516d9e3a6SLisandro Dalcin   pc->ops->setfromoptions  = PCSetFromOptions_HYPRE;
101616d9e3a6SLisandro Dalcin   pc->ops->setup           = PCSetUp_HYPRE;
101716d9e3a6SLisandro Dalcin   pc->ops->apply           = PCApply_HYPRE;
101816d9e3a6SLisandro Dalcin   jac->comm_hypre          = MPI_COMM_NULL;
101916d9e3a6SLisandro Dalcin   jac->hypre_type          = PETSC_NULL;
102016d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
10217adad957SLisandro Dalcin   ierr = MPI_Comm_dup(((PetscObject)pc)->comm,&(jac->comm_hypre));CHKERRQ(ierr);
102216d9e3a6SLisandro Dalcin   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCHYPRESetType_C","PCHYPRESetType_HYPRE",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
102316d9e3a6SLisandro Dalcin   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCHYPREGetType_C","PCHYPREGetType_HYPRE",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
102416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
102516d9e3a6SLisandro Dalcin }
102616d9e3a6SLisandro Dalcin EXTERN_C_END
1027ebc551c0SBarry Smith 
1028f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1029f91d8e95SBarry Smith 
1030b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
103168326731SBarry Smith #include "private/matimpl.h"
1032ebc551c0SBarry Smith 
1033ebc551c0SBarry Smith typedef struct {
103468326731SBarry Smith   MPI_Comm            hcomm;       /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1035f91d8e95SBarry Smith   HYPRE_StructSolver  hsolver;
10369e5bc791SBarry Smith 
10379e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
10389e5bc791SBarry Smith   int                 its;
10399e5bc791SBarry Smith   double              tol;
10409e5bc791SBarry Smith   int                 relax_type;
10419e5bc791SBarry Smith   int                 rap_type;
10429e5bc791SBarry Smith   int                 num_pre_relax,num_post_relax;
10433b46a515SGlenn Hammond   int                 max_levels;
1044ebc551c0SBarry Smith } PC_PFMG;
1045ebc551c0SBarry Smith 
1046ebc551c0SBarry Smith #undef __FUNCT__
1047ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1048ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1049ebc551c0SBarry Smith {
1050ebc551c0SBarry Smith   PetscErrorCode ierr;
1051f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1052ebc551c0SBarry Smith 
1053ebc551c0SBarry Smith   PetscFunctionBegin;
1054*30e6f737SJed Brown   if (ex->hsolver) {PetscStackCallHypre(0,HYPRE_StructPFMGDestroy,(ex->hsolver));}
1055f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1056f91d8e95SBarry Smith   ierr = PetscFree(ex);CHKERRQ(ierr);
1057ebc551c0SBarry Smith   PetscFunctionReturn(0);
1058ebc551c0SBarry Smith }
1059ebc551c0SBarry Smith 
10609e5bc791SBarry Smith static const char *PFMGRelaxType[]   = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
10619e5bc791SBarry Smith static const char *PFMGRAPType[]   = {"Galerkin","non-Galerkin"};
10629e5bc791SBarry Smith 
1063ebc551c0SBarry Smith #undef __FUNCT__
1064ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1065ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1066ebc551c0SBarry Smith {
1067ebc551c0SBarry Smith   PetscErrorCode ierr;
1068ace3abfcSBarry Smith   PetscBool      iascii;
1069f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1070ebc551c0SBarry Smith 
1071ebc551c0SBarry Smith   PetscFunctionBegin;
10722692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
10739e5bc791SBarry Smith   if (iascii) {
10749e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
10759e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
10769e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
10779e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
10789e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
10799e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
10803b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
10819e5bc791SBarry Smith   }
1082ebc551c0SBarry Smith   PetscFunctionReturn(0);
1083ebc551c0SBarry Smith }
1084ebc551c0SBarry Smith 
10859e5bc791SBarry Smith 
1086ebc551c0SBarry Smith #undef __FUNCT__
1087ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
1088ebc551c0SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PC pc)
1089ebc551c0SBarry Smith {
1090ebc551c0SBarry Smith   PetscErrorCode ierr;
1091f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1092ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1093ebc551c0SBarry Smith 
1094ebc551c0SBarry Smith   PetscFunctionBegin;
1095ebc551c0SBarry Smith   ierr = PetscOptionsHead("PFMG options");CHKERRQ(ierr);
1096acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
109768326731SBarry Smith   if (flg) {
1098a0324ebeSBarry Smith     int level=3;
1099*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
110068326731SBarry Smith   }
11019e5bc791SBarry 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);
1102*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
11039e5bc791SBarry 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);
1104*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
11059e5bc791SBarry 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);
1106*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
11079e5bc791SBarry Smith 
11083b46a515SGlenn Hammond   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,PETSC_NULL);CHKERRQ(ierr);
1109*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
11103b46a515SGlenn Hammond 
11119e5bc791SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,PETSC_NULL);CHKERRQ(ierr);
1112*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
11139e5bc791SBarry 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);
1114*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
11159e5bc791SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,2,PFMGRAPType[ex->rap_type],&ex->rap_type,PETSC_NULL);CHKERRQ(ierr);
1116*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1117ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1118ebc551c0SBarry Smith   PetscFunctionReturn(0);
1119ebc551c0SBarry Smith }
1120ebc551c0SBarry Smith 
1121f91d8e95SBarry Smith #undef __FUNCT__
1122f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1123f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1124f91d8e95SBarry Smith {
1125f91d8e95SBarry Smith   PetscErrorCode  ierr;
1126f91d8e95SBarry Smith   PC_PFMG         *ex = (PC_PFMG*) pc->data;
1127f91d8e95SBarry Smith   PetscScalar     *xx,*yy;
1128f91d8e95SBarry Smith   int             ilower[3],iupper[3];
112968326731SBarry Smith   Mat_HYPREStruct *mx = (Mat_HYPREStruct *)(pc->pmat->data);
1130f91d8e95SBarry Smith 
1131f91d8e95SBarry Smith   PetscFunctionBegin;
1132aa219208SBarry Smith   ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1133f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1134f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1135f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1136f91d8e95SBarry Smith 
1137f91d8e95SBarry Smith   /* copy x values over to hypre */
1138*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1139f91d8e95SBarry Smith   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
1140*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructVectorSetBoxValues,(mx->hb,ilower,iupper,xx));
1141f91d8e95SBarry Smith   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
1142*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructVectorAssemble,(mx->hb));
1143*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1144f91d8e95SBarry Smith 
1145f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1146f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
1147*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructVectorGetBoxValues,(mx->hx,ilower,iupper,yy));
1148f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1149f91d8e95SBarry Smith   PetscFunctionReturn(0);
1150f91d8e95SBarry Smith }
1151f91d8e95SBarry Smith 
11529e5bc791SBarry Smith #undef __FUNCT__
11539e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1154ace3abfcSBarry 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)
11559e5bc791SBarry Smith {
11569e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
11579e5bc791SBarry Smith   PetscErrorCode ierr;
11589e5bc791SBarry Smith   int            oits;
11599e5bc791SBarry Smith 
11609e5bc791SBarry Smith   PetscFunctionBegin;
1161*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1162*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
11639e5bc791SBarry Smith 
11649e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
1165*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGGetNumIterations,(jac->hsolver,&oits));
11669e5bc791SBarry Smith   *outits = oits;
11679e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
11689e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1169*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1170*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
11719e5bc791SBarry Smith   PetscFunctionReturn(0);
11729e5bc791SBarry Smith }
11739e5bc791SBarry Smith 
11749e5bc791SBarry Smith 
11753a32d3dbSGlenn Hammond #undef __FUNCT__
11763a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
11773a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
11783a32d3dbSGlenn Hammond {
11793a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
11803a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
11813a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct *)(pc->pmat->data);
1182ace3abfcSBarry Smith   PetscBool       flg;
11833a32d3dbSGlenn Hammond 
11843a32d3dbSGlenn Hammond   PetscFunctionBegin;
11853a32d3dbSGlenn Hammond   ierr = PetscTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1186e7e72b3dSBarry Smith   if (!flg) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
11873a32d3dbSGlenn Hammond 
11883a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
11893a32d3dbSGlenn Hammond   if (ex->hsolver) {
1190*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_StructPFMGDestroy,(ex->hsolver));
11913a32d3dbSGlenn Hammond   }
1192*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
11933a32d3dbSGlenn Hammond   ierr = PCSetFromOptions_PFMG(pc);CHKERRQ(ierr);
1194*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1195*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
11963a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
11973a32d3dbSGlenn Hammond }
11983a32d3dbSGlenn Hammond 
1199ebc551c0SBarry Smith 
1200ebc551c0SBarry Smith /*MC
1201ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1202ebc551c0SBarry Smith 
1203ebc551c0SBarry Smith    Level: advanced
1204ebc551c0SBarry Smith 
12059e5bc791SBarry Smith    Options Database:
12069e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
12079e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
12089e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
12099e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
12109e5bc791SBarry 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
12119e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
1212f91d8e95SBarry Smith 
12139e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
12149e5bc791SBarry Smith 
12158e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
1216aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
12179e5bc791SBarry Smith 
12189e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
1219ebc551c0SBarry Smith M*/
1220ebc551c0SBarry Smith 
1221ebc551c0SBarry Smith EXTERN_C_BEGIN
1222ebc551c0SBarry Smith #undef __FUNCT__
1223ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
1224ebc551c0SBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_PFMG(PC pc)
1225ebc551c0SBarry Smith {
1226ebc551c0SBarry Smith   PetscErrorCode ierr;
1227ebc551c0SBarry Smith   PC_PFMG        *ex;
1228ebc551c0SBarry Smith 
1229ebc551c0SBarry Smith   PetscFunctionBegin;
1230ebc551c0SBarry Smith   ierr = PetscNew(PC_PFMG,&ex);CHKERRQ(ierr);\
123168326731SBarry Smith   pc->data = ex;
1232ebc551c0SBarry Smith 
12339e5bc791SBarry Smith   ex->its            = 1;
12349e5bc791SBarry Smith   ex->tol            = 1.e-8;
12359e5bc791SBarry Smith   ex->relax_type     = 1;
12369e5bc791SBarry Smith   ex->rap_type       = 0;
12379e5bc791SBarry Smith   ex->num_pre_relax  = 1;
12389e5bc791SBarry Smith   ex->num_post_relax = 1;
12393b46a515SGlenn Hammond   ex->max_levels     = 0;
12409e5bc791SBarry Smith 
1241ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
1242ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
1243ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
1244f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
12459e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
124668326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
1247f91d8e95SBarry Smith   ierr = MPI_Comm_dup(((PetscObject)pc)->comm,&(ex->hcomm));CHKERRQ(ierr);
1248*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1249ebc551c0SBarry Smith   PetscFunctionReturn(0);
1250ebc551c0SBarry Smith }
1251ebc551c0SBarry Smith EXTERN_C_END
1252d851a50bSGlenn Hammond 
1253d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
1254d851a50bSGlenn Hammond typedef struct {
1255d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
1256d851a50bSGlenn Hammond   HYPRE_SStructSolver  ss_solver;
1257d851a50bSGlenn Hammond 
1258d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
1259d851a50bSGlenn Hammond   int                 its;
1260d851a50bSGlenn Hammond   double              tol;
1261d851a50bSGlenn Hammond   int                 relax_type;
1262d851a50bSGlenn Hammond   int                 num_pre_relax,num_post_relax;
1263d851a50bSGlenn Hammond } PC_SysPFMG;
1264d851a50bSGlenn Hammond 
1265d851a50bSGlenn Hammond #undef __FUNCT__
1266d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
1267d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
1268d851a50bSGlenn Hammond {
1269d851a50bSGlenn Hammond   PetscErrorCode ierr;
1270d851a50bSGlenn Hammond   PC_SysPFMG    *ex = (PC_SysPFMG*) pc->data;
1271d851a50bSGlenn Hammond 
1272d851a50bSGlenn Hammond   PetscFunctionBegin;
1273*30e6f737SJed Brown   if (ex->ss_solver) {PetscStackCallHypre(0,HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));}
1274d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1275d851a50bSGlenn Hammond   ierr = PetscFree(ex);CHKERRQ(ierr);
1276d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1277d851a50bSGlenn Hammond }
1278d851a50bSGlenn Hammond 
1279d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[]   = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
1280d851a50bSGlenn Hammond 
1281d851a50bSGlenn Hammond #undef __FUNCT__
1282d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
1283d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
1284d851a50bSGlenn Hammond {
1285d851a50bSGlenn Hammond   PetscErrorCode ierr;
1286ace3abfcSBarry Smith   PetscBool      iascii;
1287d851a50bSGlenn Hammond   PC_SysPFMG    *ex = (PC_SysPFMG*) pc->data;
1288d851a50bSGlenn Hammond 
1289d851a50bSGlenn Hammond   PetscFunctionBegin;
12902692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1291d851a50bSGlenn Hammond   if (iascii) {
1292d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
1293d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
1294d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
1295d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
1296d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
1297d851a50bSGlenn Hammond   }
1298d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1299d851a50bSGlenn Hammond }
1300d851a50bSGlenn Hammond 
1301d851a50bSGlenn Hammond 
1302d851a50bSGlenn Hammond #undef __FUNCT__
1303d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
1304d851a50bSGlenn Hammond PetscErrorCode PCSetFromOptions_SysPFMG(PC pc)
1305d851a50bSGlenn Hammond {
1306d851a50bSGlenn Hammond   PetscErrorCode ierr;
1307d851a50bSGlenn Hammond   PC_SysPFMG    *ex = (PC_SysPFMG*) pc->data;
1308ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1309d851a50bSGlenn Hammond 
1310d851a50bSGlenn Hammond   PetscFunctionBegin;
1311d851a50bSGlenn Hammond   ierr = PetscOptionsHead("SysPFMG options");CHKERRQ(ierr);
1312acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
1313d851a50bSGlenn Hammond   if (flg) {
1314d851a50bSGlenn Hammond     int level=3;
1315*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
1316d851a50bSGlenn Hammond   }
1317d851a50bSGlenn 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);
1318*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
1319d851a50bSGlenn 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);
1320*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
1321d851a50bSGlenn 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);
1322*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
1323d851a50bSGlenn Hammond 
1324d851a50bSGlenn Hammond   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,PETSC_NULL);CHKERRQ(ierr);
1325*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
1326d851a50bSGlenn 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);
1327*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
1328d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
1329d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1330d851a50bSGlenn Hammond }
1331d851a50bSGlenn Hammond 
1332d851a50bSGlenn Hammond #undef __FUNCT__
1333d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
1334d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
1335d851a50bSGlenn Hammond {
1336d851a50bSGlenn Hammond   PetscErrorCode    ierr;
1337d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
1338d851a50bSGlenn Hammond   PetscScalar      *xx,*yy;
1339d851a50bSGlenn Hammond   int               ilower[3],iupper[3];
1340d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct *)(pc->pmat->data);
1341d851a50bSGlenn Hammond   int               ordering= mx->dofs_order;
1342d851a50bSGlenn Hammond   int               nvars= mx->nvars;
1343d851a50bSGlenn Hammond   int               part= 0;
1344d851a50bSGlenn Hammond   int               size;
1345d851a50bSGlenn Hammond   int               i;
1346d851a50bSGlenn Hammond 
1347d851a50bSGlenn Hammond   PetscFunctionBegin;
1348aa219208SBarry Smith   ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1349d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
1350d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
1351d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
1352d851a50bSGlenn Hammond 
1353d851a50bSGlenn Hammond   size= 1;
1354d851a50bSGlenn Hammond   for (i= 0; i< 3; i++) {
1355d851a50bSGlenn Hammond      size*= (iupper[i]-ilower[i]+1);
1356d851a50bSGlenn Hammond   }
1357d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
1358d851a50bSGlenn Hammond   if (ordering) {
1359*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
1360d851a50bSGlenn Hammond      ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
1361d851a50bSGlenn Hammond      for (i= 0; i< nvars; i++) {
1362*30e6f737SJed Brown        PetscStackCallHypre(0,HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,ilower,iupper,i,xx+(size*i)));
1363d851a50bSGlenn Hammond      }
1364d851a50bSGlenn Hammond      ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
1365*30e6f737SJed Brown      PetscStackCallHypre(0,HYPRE_SStructVectorAssemble,(mx->ss_b));
1366*30e6f737SJed Brown      PetscStackCallHypre(0,HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
1367*30e6f737SJed Brown      PetscStackCallHypre(0,HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1368d851a50bSGlenn Hammond 
1369d851a50bSGlenn Hammond      /* copy solution values back to PETSc */
1370d851a50bSGlenn Hammond      ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
1371d851a50bSGlenn Hammond      for (i= 0; i< nvars; i++) {
1372*30e6f737SJed Brown        PetscStackCallHypre(0,HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,ilower,iupper,i,yy+(size*i)));
1373d851a50bSGlenn Hammond      }
1374d851a50bSGlenn Hammond      ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1375a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
1376d851a50bSGlenn Hammond      PetscScalar     *z;
1377d851a50bSGlenn Hammond      int              j, k;
1378d851a50bSGlenn Hammond 
1379d851a50bSGlenn Hammond      ierr = PetscMalloc(nvars*size*sizeof(PetscScalar),&z);CHKERRQ(ierr);
1380*30e6f737SJed Brown      PetscStackCallHypre(0,HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
1381d851a50bSGlenn Hammond      ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
1382d851a50bSGlenn Hammond 
1383d851a50bSGlenn Hammond      /* transform nodal to hypre's variable ordering for sys_pfmg */
1384d851a50bSGlenn Hammond      for (i= 0; i< size; i++) {
1385d851a50bSGlenn Hammond         k= i*nvars;
1386d851a50bSGlenn Hammond         for (j= 0; j< nvars; j++) {
1387d851a50bSGlenn Hammond            z[j*size+i]= xx[k+j];
1388d851a50bSGlenn Hammond         }
1389d851a50bSGlenn Hammond      }
1390d851a50bSGlenn Hammond      for (i= 0; i< nvars; i++) {
1391*30e6f737SJed Brown        PetscStackCallHypre(0,HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,ilower,iupper,i,z+(size*i)));
1392d851a50bSGlenn Hammond      }
1393d851a50bSGlenn Hammond      ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
1394*30e6f737SJed Brown      PetscStackCallHypre(0,HYPRE_SStructVectorAssemble,(mx->ss_b));
1395*30e6f737SJed Brown      PetscStackCallHypre(0,HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1396d851a50bSGlenn Hammond 
1397d851a50bSGlenn Hammond      /* copy solution values back to PETSc */
1398d851a50bSGlenn Hammond      ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
1399d851a50bSGlenn Hammond      for (i= 0; i< nvars; i++) {
1400*30e6f737SJed Brown        PetscStackCallHypre(0,HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,ilower,iupper,i,z+(size*i)));
1401d851a50bSGlenn Hammond      }
1402d851a50bSGlenn Hammond      /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
1403d851a50bSGlenn Hammond      for (i= 0; i< size; i++) {
1404d851a50bSGlenn Hammond         k= i*nvars;
1405d851a50bSGlenn Hammond         for (j= 0; j< nvars; j++) {
1406d851a50bSGlenn Hammond            yy[k+j]= z[j*size+i];
1407d851a50bSGlenn Hammond         }
1408d851a50bSGlenn Hammond      }
1409d851a50bSGlenn Hammond      ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1410d851a50bSGlenn Hammond      ierr = PetscFree(z);CHKERRQ(ierr);
1411d851a50bSGlenn Hammond   }
1412d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1413d851a50bSGlenn Hammond }
1414d851a50bSGlenn Hammond 
1415d851a50bSGlenn Hammond #undef __FUNCT__
1416d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
1417ace3abfcSBarry 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)
1418d851a50bSGlenn Hammond {
1419d851a50bSGlenn Hammond   PC_SysPFMG    *jac = (PC_SysPFMG*)pc->data;
1420d851a50bSGlenn Hammond   PetscErrorCode ierr;
1421d851a50bSGlenn Hammond   int            oits;
1422d851a50bSGlenn Hammond 
1423d851a50bSGlenn Hammond   PetscFunctionBegin;
1424*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
1425*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
1426d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
1427*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,&oits));
1428d851a50bSGlenn Hammond   *outits = oits;
1429d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
1430d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1431*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
1432*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
1433d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1434d851a50bSGlenn Hammond }
1435d851a50bSGlenn Hammond 
1436d851a50bSGlenn Hammond 
1437d851a50bSGlenn Hammond #undef __FUNCT__
1438d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
1439d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
1440d851a50bSGlenn Hammond {
1441d851a50bSGlenn Hammond   PetscErrorCode    ierr;
1442d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
1443d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx = (Mat_HYPRESStruct *)(pc->pmat->data);
1444ace3abfcSBarry Smith   PetscBool         flg;
1445d851a50bSGlenn Hammond 
1446d851a50bSGlenn Hammond   PetscFunctionBegin;
1447d851a50bSGlenn Hammond   ierr = PetscTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
1448e7e72b3dSBarry Smith   if (!flg) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
1449d851a50bSGlenn Hammond 
1450d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
1451d851a50bSGlenn Hammond   if (ex->ss_solver) {
1452*30e6f737SJed Brown     PetscStackCallHypre(0,HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1453d851a50bSGlenn Hammond   }
1454*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
1455d851a50bSGlenn Hammond   ierr = PCSetFromOptions_SysPFMG(pc);CHKERRQ(ierr);
1456*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
1457*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1458d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1459d851a50bSGlenn Hammond }
1460d851a50bSGlenn Hammond 
1461d851a50bSGlenn Hammond 
1462d851a50bSGlenn Hammond /*MC
1463d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
1464d851a50bSGlenn Hammond 
1465d851a50bSGlenn Hammond    Level: advanced
1466d851a50bSGlenn Hammond 
1467d851a50bSGlenn Hammond    Options Database:
1468d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
1469d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
1470d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
1471d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
1472d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
1473d851a50bSGlenn Hammond 
1474d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
1475d851a50bSGlenn Hammond 
1476f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
1477aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
1478d851a50bSGlenn Hammond            Also, only cell-centered variables.
1479d851a50bSGlenn Hammond 
1480d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
1481d851a50bSGlenn Hammond M*/
1482d851a50bSGlenn Hammond 
1483d851a50bSGlenn Hammond EXTERN_C_BEGIN
1484d851a50bSGlenn Hammond #undef __FUNCT__
1485d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
1486d851a50bSGlenn Hammond PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_SysPFMG(PC pc)
1487d851a50bSGlenn Hammond {
1488d851a50bSGlenn Hammond   PetscErrorCode     ierr;
1489d851a50bSGlenn Hammond   PC_SysPFMG        *ex;
1490d851a50bSGlenn Hammond 
1491d851a50bSGlenn Hammond   PetscFunctionBegin;
1492d851a50bSGlenn Hammond   ierr = PetscNew(PC_SysPFMG,&ex);CHKERRQ(ierr);\
1493d851a50bSGlenn Hammond   pc->data = ex;
1494d851a50bSGlenn Hammond 
1495d851a50bSGlenn Hammond   ex->its            = 1;
1496d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
1497d851a50bSGlenn Hammond   ex->relax_type     = 1;
1498d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
1499d851a50bSGlenn Hammond   ex->num_post_relax = 1;
1500d851a50bSGlenn Hammond 
1501d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
1502d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
1503d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
1504d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
1505d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
1506d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
1507d851a50bSGlenn Hammond   ierr = MPI_Comm_dup(((PetscObject)pc)->comm,&(ex->hcomm));CHKERRQ(ierr);
1508*30e6f737SJed Brown   PetscStackCallHypre(0,HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
1509d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1510d851a50bSGlenn Hammond }
1511d851a50bSGlenn Hammond EXTERN_C_END
1512