xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 4cb006fe7ed76f5682c0638f24af798e5120e749)
116d9e3a6SLisandro Dalcin 
216d9e3a6SLisandro Dalcin /*
316d9e3a6SLisandro Dalcin    Provides an interface to the LLNL package hypre
416d9e3a6SLisandro Dalcin */
50f1074feSSatish Balay 
60f1074feSSatish Balay /* Must use hypre 2.0.0 or more recent. */
70f1074feSSatish Balay 
8b45d2f2cSJed Brown #include <petsc-private/pcimpl.h>          /*I "petscpc.h" I*/
9c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h>
10*4cb006feSStefano Zampini #include <_hypre_parcsr_ls.h>
1116d9e3a6SLisandro Dalcin 
12dff31646SBarry Smith static PetscBool cite = PETSC_FALSE;
131f817a21SBarry Smith static const char hypreCitation[] = "@manual{hypre-web-page,\n  title  = {{\\sl hypre}: High Performance Preconditioners},\n  organization = {Lawrence Livermore National Laboratory},\n  note  = {\\url{http://www.llnl.gov/CASC/hypre/}}\n}\n";
141f817a21SBarry Smith 
1516d9e3a6SLisandro Dalcin /*
1616d9e3a6SLisandro Dalcin    Private context (data structure) for the  preconditioner.
1716d9e3a6SLisandro Dalcin */
1816d9e3a6SLisandro Dalcin typedef struct {
1916d9e3a6SLisandro Dalcin   HYPRE_Solver   hsolver;
2016d9e3a6SLisandro Dalcin   HYPRE_IJMatrix ij;
2116d9e3a6SLisandro Dalcin   HYPRE_IJVector b,x;
2216d9e3a6SLisandro Dalcin 
234ddd07fcSJed Brown   HYPRE_Int (*destroy)(HYPRE_Solver);
244ddd07fcSJed Brown   HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
254ddd07fcSJed Brown   HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
2616d9e3a6SLisandro Dalcin 
2716d9e3a6SLisandro Dalcin   MPI_Comm comm_hypre;
2816d9e3a6SLisandro Dalcin   char     *hypre_type;
2916d9e3a6SLisandro Dalcin 
3016d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
314ddd07fcSJed Brown   PetscInt maxiter;
3216d9e3a6SLisandro Dalcin   double   tol;
3316d9e3a6SLisandro Dalcin 
3416d9e3a6SLisandro Dalcin   /* options for Pilut */
354ddd07fcSJed Brown   PetscInt factorrowsize;
3616d9e3a6SLisandro Dalcin 
3716d9e3a6SLisandro Dalcin   /* options for ParaSails */
384ddd07fcSJed Brown   PetscInt nlevels;
3916d9e3a6SLisandro Dalcin   double   threshhold;
4016d9e3a6SLisandro Dalcin   double   filter;
414ddd07fcSJed Brown   PetscInt sym;
4216d9e3a6SLisandro Dalcin   double   loadbal;
434ddd07fcSJed Brown   PetscInt logging;
444ddd07fcSJed Brown   PetscInt ruse;
454ddd07fcSJed Brown   PetscInt symt;
4616d9e3a6SLisandro Dalcin 
4716d9e3a6SLisandro Dalcin   /* options for Euclid */
48ace3abfcSBarry Smith   PetscBool bjilu;
494ddd07fcSJed Brown   PetscInt  levels;
5016d9e3a6SLisandro Dalcin 
5116d9e3a6SLisandro Dalcin   /* options for Euclid and BoomerAMG */
52ace3abfcSBarry Smith   PetscBool printstatistics;
5316d9e3a6SLisandro Dalcin 
5416d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
554ddd07fcSJed Brown   PetscInt  cycletype;
564ddd07fcSJed Brown   PetscInt  maxlevels;
5716d9e3a6SLisandro Dalcin   double    strongthreshold;
5816d9e3a6SLisandro Dalcin   double    maxrowsum;
594ddd07fcSJed Brown   PetscInt  gridsweeps[3];
604ddd07fcSJed Brown   PetscInt  coarsentype;
614ddd07fcSJed Brown   PetscInt  measuretype;
624ddd07fcSJed Brown   PetscInt  relaxtype[3];
6316d9e3a6SLisandro Dalcin   double    relaxweight;
6416d9e3a6SLisandro Dalcin   double    outerrelaxweight;
654ddd07fcSJed Brown   PetscInt  relaxorder;
6616d9e3a6SLisandro Dalcin   double    truncfactor;
67ace3abfcSBarry Smith   PetscBool applyrichardson;
684ddd07fcSJed Brown   PetscInt  pmax;
694ddd07fcSJed Brown   PetscInt  interptype;
704ddd07fcSJed Brown   PetscInt  agg_nl;
714ddd07fcSJed Brown   PetscInt  agg_num_paths;
724ddd07fcSJed Brown   PetscInt  nodal_coarsen;
73ace3abfcSBarry Smith   PetscBool nodal_relax;
744ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
75*4cb006feSStefano Zampini 
76*4cb006feSStefano Zampini   /* options for AMS */
77*4cb006feSStefano Zampini   PetscInt  ams_print;
78*4cb006feSStefano Zampini   PetscInt  ams_max_iter;
79*4cb006feSStefano Zampini   PetscInt  ams_cycle_type;
80*4cb006feSStefano Zampini   PetscReal ams_tol;
81*4cb006feSStefano Zampini   PetscInt  ams_relax_type;
82*4cb006feSStefano Zampini   PetscInt  ams_relax_times;
83*4cb006feSStefano Zampini   PetscReal ams_relax_weight;
84*4cb006feSStefano Zampini   PetscReal ams_omega;
85*4cb006feSStefano Zampini   PetscInt  ams_amg_alpha_opts[5]; /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for vector Poisson */
86*4cb006feSStefano Zampini   PetscReal ams_amg_alpha_theta;   /* AMG strength for vector Poisson */
87*4cb006feSStefano Zampini   PetscInt  ams_amg_beta_opts[5];  /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for scalar Poisson */
88*4cb006feSStefano Zampini   PetscReal ams_amg_beta_theta;    /* AMG strength for scalar Poisson */
89*4cb006feSStefano Zampini 
90*4cb006feSStefano Zampini   /* additional data */
91*4cb006feSStefano Zampini   HYPRE_IJVector coords[3];
92*4cb006feSStefano Zampini   HYPRE_IJVector constants[3];
93*4cb006feSStefano Zampini   HYPRE_IJMatrix G;
94*4cb006feSStefano Zampini   HYPRE_IJMatrix alpha_Poisson;
95*4cb006feSStefano Zampini   HYPRE_IJMatrix beta_Poisson;
96*4cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
9716d9e3a6SLisandro Dalcin } PC_HYPRE;
9816d9e3a6SLisandro Dalcin 
99d2128fa2SBarry Smith #undef __FUNCT__
100d2128fa2SBarry Smith #define __FUNCT__ "PCHYPREGetSolver"
101d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
102d2128fa2SBarry Smith {
103d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
104d2128fa2SBarry Smith 
105d2128fa2SBarry Smith   PetscFunctionBegin;
106d2128fa2SBarry Smith   *hsolver = jac->hsolver;
107d2128fa2SBarry Smith   PetscFunctionReturn(0);
108d2128fa2SBarry Smith }
10916d9e3a6SLisandro Dalcin 
11016d9e3a6SLisandro Dalcin #undef __FUNCT__
11116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE"
11216d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
11316d9e3a6SLisandro Dalcin {
11416d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11516d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
11616d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
11716d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
11816d9e3a6SLisandro Dalcin   PetscInt           bs;
11916d9e3a6SLisandro Dalcin 
12016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
12116d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
12202a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
12316d9e3a6SLisandro Dalcin   }
1245f5c5b43SBarry Smith 
1255f5c5b43SBarry Smith   if (pc->setupcalled) {
1265f5c5b43SBarry Smith     /* always destroy the old matrix and create a new memory;
1275f5c5b43SBarry Smith        hope this does not churn the memory too much. The problem
1285f5c5b43SBarry Smith        is I do not know if it is possible to put the matrix back to
1295f5c5b43SBarry Smith        its initial state so that we can directly copy the values
1305f5c5b43SBarry Smith        the second time through. */
131fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
1325f5c5b43SBarry Smith     jac->ij = 0;
13316d9e3a6SLisandro Dalcin   }
1345f5c5b43SBarry Smith 
13516d9e3a6SLisandro Dalcin   if (!jac->ij) { /* create the matrix the first time through */
13616d9e3a6SLisandro Dalcin     ierr = MatHYPRE_IJMatrixCreate(pc->pmat,&jac->ij);CHKERRQ(ierr);
13716d9e3a6SLisandro Dalcin   }
13816d9e3a6SLisandro Dalcin   if (!jac->b) { /* create the vectors the first time through */
13916d9e3a6SLisandro Dalcin     Vec x,b;
14016d9e3a6SLisandro Dalcin     ierr = MatGetVecs(pc->pmat,&x,&b);CHKERRQ(ierr);
14116d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(x,&jac->x);CHKERRQ(ierr);
14216d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(b,&jac->b);CHKERRQ(ierr);
1436bf464f9SBarry Smith     ierr = VecDestroy(&x);CHKERRQ(ierr);
1446bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
14516d9e3a6SLisandro Dalcin   }
1465f5c5b43SBarry Smith 
14716d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
14816d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
14916d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1502fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
151*4cb006feSStefano Zampini   }
152*4cb006feSStefano Zampini   /* special case for AMS */
153*4cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
154*4cb006feSStefano Zampini     if (!jac->coords[0] && !jac->constants[0]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs either coordinate vectors via PCSetCoordinates() or edge constant vectors via PCHYPRESetEdgeConstantVectors()");
155*4cb006feSStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
156*4cb006feSStefano Zampini   }
15716d9e3a6SLisandro Dalcin   ierr = MatHYPRE_IJMatrixCopy(pc->pmat,jac->ij);CHKERRQ(ierr);
158fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
159fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&bv));
160fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&xv));
161fd3f9acdSBarry Smith   PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr););
16216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
16316d9e3a6SLisandro Dalcin }
16416d9e3a6SLisandro Dalcin 
16516d9e3a6SLisandro Dalcin /*
16616d9e3a6SLisandro Dalcin     Replaces the address where the HYPRE vector points to its data with the address of
16716d9e3a6SLisandro Dalcin   PETSc's data. Saves the old address so it can be reset when we are finished with it.
16816d9e3a6SLisandro Dalcin   Allows use to get the data into a HYPRE vector without the cost of memcopies
16916d9e3a6SLisandro Dalcin */
17016d9e3a6SLisandro Dalcin #define HYPREReplacePointer(b,newvalue,savedvalue) { \
17116d9e3a6SLisandro Dalcin     hypre_ParVector *par_vector   = (hypre_ParVector*)hypre_IJVectorObject(((hypre_IJVector*)b)); \
17216d9e3a6SLisandro Dalcin     hypre_Vector    *local_vector = hypre_ParVectorLocalVector(par_vector); \
17316d9e3a6SLisandro Dalcin     savedvalue         = local_vector->data; \
1740ad7597dSKarl Rupp     local_vector->data = newvalue;          \
1750ad7597dSKarl Rupp }
17616d9e3a6SLisandro Dalcin 
17716d9e3a6SLisandro Dalcin #undef __FUNCT__
17816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE"
17916d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
18016d9e3a6SLisandro Dalcin {
18116d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
18216d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
18316d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
18416d9e3a6SLisandro Dalcin   PetscScalar        *bv,*xv;
18516d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
18616d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
1874ddd07fcSJed Brown   PetscInt           hierr;
18816d9e3a6SLisandro Dalcin 
18916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
190dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
19116d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
19216d9e3a6SLisandro Dalcin   ierr = VecGetArray(b,&bv);CHKERRQ(ierr);
19316d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
19416d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,bv,sbv);
19516d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
19616d9e3a6SLisandro Dalcin 
197fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
198fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
199fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
200fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
20165e19b50SBarry Smith                                if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
202fd3f9acdSBarry Smith                                if (hierr) hypre__global_error = 0;);
20316d9e3a6SLisandro Dalcin 
20416d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
20516d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
20616d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
20716d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(b,&bv);CHKERRQ(ierr);
20816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
20916d9e3a6SLisandro Dalcin }
21016d9e3a6SLisandro Dalcin 
21116d9e3a6SLisandro Dalcin #undef __FUNCT__
21216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE"
21316d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
21416d9e3a6SLisandro Dalcin {
21516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
21616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
21716d9e3a6SLisandro Dalcin 
21816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
219fd3f9acdSBarry Smith   if (jac->ij) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
220fd3f9acdSBarry Smith   if (jac->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->b));
221fd3f9acdSBarry Smith   if (jac->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->x));
222*4cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
223*4cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
224*4cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
225*4cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
226*4cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
227*4cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
228*4cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
229*4cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
230*4cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
231226b0620SJed Brown   if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr););
232503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
23316d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
234c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
23516d9e3a6SLisandro Dalcin 
23616d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
237bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
238bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
239*4cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
240*4cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
241*4cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
242*4cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",NULL);CHKERRQ(ierr);
243*4cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",NULL);CHKERRQ(ierr);
24416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
24516d9e3a6SLisandro Dalcin }
24616d9e3a6SLisandro Dalcin 
24716d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
24816d9e3a6SLisandro Dalcin #undef __FUNCT__
24916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut"
25016d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PC pc)
25116d9e3a6SLisandro Dalcin {
25216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
25316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
254ace3abfcSBarry Smith   PetscBool      flag;
25516d9e3a6SLisandro Dalcin 
25616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
25716d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE Pilut Options");CHKERRQ(ierr);
25816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
259fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
26016d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
261fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
26216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
263fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
26416d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
26516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
26616d9e3a6SLisandro Dalcin }
26716d9e3a6SLisandro Dalcin 
26816d9e3a6SLisandro Dalcin #undef __FUNCT__
26916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut"
27016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
27116d9e3a6SLisandro Dalcin {
27216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
27316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
274ace3abfcSBarry Smith   PetscBool      iascii;
27516d9e3a6SLisandro Dalcin 
27616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
277251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
27816d9e3a6SLisandro Dalcin   if (iascii) {
27916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
28016d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
28116d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
28216d9e3a6SLisandro Dalcin     } else {
28316d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr);
28416d9e3a6SLisandro Dalcin     }
28516d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
28657622a8eSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
28716d9e3a6SLisandro Dalcin     } else {
28816d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr);
28916d9e3a6SLisandro Dalcin     }
29016d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
29116d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
29216d9e3a6SLisandro Dalcin     } else {
29316d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default factor row size \n");CHKERRQ(ierr);
29416d9e3a6SLisandro Dalcin     }
29516d9e3a6SLisandro Dalcin   }
29616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
29716d9e3a6SLisandro Dalcin }
29816d9e3a6SLisandro Dalcin 
29916d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
30016d9e3a6SLisandro Dalcin #undef __FUNCT__
30116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Euclid"
30216d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PC pc)
30316d9e3a6SLisandro Dalcin {
30416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
30516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
306ace3abfcSBarry Smith   PetscBool      flag;
307390e7148SBarry Smith   char           *args[8],levels[16];
308390e7148SBarry Smith   PetscInt       cnt = 0;
30916d9e3a6SLisandro Dalcin 
31016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
31116d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE Euclid Options");CHKERRQ(ierr);
31216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_euclid_levels","Number of levels of fill ILU(k)","None",jac->levels,&jac->levels,&flag);CHKERRQ(ierr);
31316d9e3a6SLisandro Dalcin   if (flag) {
314ce94432eSBarry Smith     if (jac->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be nonegative",jac->levels);
3158caf3d72SBarry Smith     ierr        = PetscSNPrintf(levels,sizeof(levels),"%D",jac->levels);CHKERRQ(ierr);
316390e7148SBarry Smith     args[cnt++] = (char*)"-level"; args[cnt++] = levels;
31716d9e3a6SLisandro Dalcin   }
3180298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_hypre_euclid_bj","Use block Jacobi ILU(k)","None",jac->bjilu,&jac->bjilu,NULL);CHKERRQ(ierr);
31916d9e3a6SLisandro Dalcin   if (jac->bjilu) {
320390e7148SBarry Smith     args[cnt++] =(char*) "-bj"; args[cnt++] = (char*)"1";
32116d9e3a6SLisandro Dalcin   }
32216d9e3a6SLisandro Dalcin 
3230298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_hypre_euclid_print_statistics","Print statistics","None",jac->printstatistics,&jac->printstatistics,NULL);CHKERRQ(ierr);
32416d9e3a6SLisandro Dalcin   if (jac->printstatistics) {
325390e7148SBarry Smith     args[cnt++] = (char*)"-eu_stats"; args[cnt++] = (char*)"1";
326390e7148SBarry Smith     args[cnt++] = (char*)"-eu_mem"; args[cnt++] = (char*)"1";
32716d9e3a6SLisandro Dalcin   }
32816d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
329fd3f9acdSBarry Smith   if (cnt) PetscStackCallStandard(HYPRE_EuclidSetParams,(jac->hsolver,cnt,args));
33016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
33116d9e3a6SLisandro Dalcin }
33216d9e3a6SLisandro Dalcin 
33316d9e3a6SLisandro Dalcin #undef __FUNCT__
33416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Euclid"
33516d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer)
33616d9e3a6SLisandro Dalcin {
33716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
33816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
339ace3abfcSBarry Smith   PetscBool      iascii;
34016d9e3a6SLisandro Dalcin 
34116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
342251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
34316d9e3a6SLisandro Dalcin   if (iascii) {
34416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid preconditioning\n");CHKERRQ(ierr);
34516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid: number of levels %d\n",jac->levels);CHKERRQ(ierr);
34616d9e3a6SLisandro Dalcin     if (jac->bjilu) {
34716d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid: Using block Jacobi ILU instead of parallel ILU\n");CHKERRQ(ierr);
34816d9e3a6SLisandro Dalcin     }
34916d9e3a6SLisandro Dalcin   }
35016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
35116d9e3a6SLisandro Dalcin }
35216d9e3a6SLisandro Dalcin 
35316d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
35416d9e3a6SLisandro Dalcin 
35516d9e3a6SLisandro Dalcin #undef __FUNCT__
35616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG"
35716d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
35816d9e3a6SLisandro Dalcin {
35916d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
36016d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
36116d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
36216d9e3a6SLisandro Dalcin   PetscScalar        *bv,*xv;
36316d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
36416d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
3654ddd07fcSJed Brown   PetscInt           hierr;
36616d9e3a6SLisandro Dalcin 
36716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
368dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
36916d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
37016d9e3a6SLisandro Dalcin   ierr = VecGetArray(b,&bv);CHKERRQ(ierr);
37116d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
37216d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,bv,sbv);
37316d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
37416d9e3a6SLisandro Dalcin 
375fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
376fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
377fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
37816d9e3a6SLisandro Dalcin 
37916d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
38016d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
381e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
38216d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
38316d9e3a6SLisandro Dalcin 
38416d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
38516d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
38616d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
38716d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(b,&bv);CHKERRQ(ierr);
38816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
38916d9e3a6SLisandro Dalcin }
39016d9e3a6SLisandro Dalcin 
391a669f990SJed Brown /* static array length */
392a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
393a669f990SJed Brown 
39416d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
3950f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
39616d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
39765de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
39865de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
39965de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
40065de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
40165de4495SJed Brown                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */,
40265de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
4030f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
4040f1074feSSatish Balay                                                   "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"};
40516d9e3a6SLisandro Dalcin #undef __FUNCT__
40616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG"
40716d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PC pc)
40816d9e3a6SLisandro Dalcin {
40916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
41016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
4114ddd07fcSJed Brown   PetscInt       n,indx,level;
412ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
41316d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
41416d9e3a6SLisandro Dalcin 
41516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
41616d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE BoomerAMG Options");CHKERRQ(ierr);
4174336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
41816d9e3a6SLisandro Dalcin   if (flg) {
4194336a9eeSBarry Smith     jac->cycletype = indx+1;
420fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
42116d9e3a6SLisandro Dalcin   }
42216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
42316d9e3a6SLisandro Dalcin   if (flg) {
424ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
425fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
42616d9e3a6SLisandro Dalcin   }
42716d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
42816d9e3a6SLisandro Dalcin   if (flg) {
429ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
430fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
43116d9e3a6SLisandro Dalcin   }
4320f1074feSSatish 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);
43316d9e3a6SLisandro Dalcin   if (flg) {
43457622a8eSBarry Smith     if (jac->tol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Tolerance %g must be greater than or equal to zero",(double)jac->tol);
435fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
43616d9e3a6SLisandro Dalcin   }
43716d9e3a6SLisandro Dalcin 
4380f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
43916d9e3a6SLisandro Dalcin   if (flg) {
44057622a8eSBarry Smith     if (jac->truncfactor < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Truncation factor %g must be great than or equal zero",(double)jac->truncfactor);
441fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
44216d9e3a6SLisandro Dalcin   }
44316d9e3a6SLisandro Dalcin 
4440f1074feSSatish 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);
4450f1074feSSatish Balay   if (flg) {
44657622a8eSBarry Smith     if (jac->pmax < 0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"P_max %g must be greater than or equal to zero",(double)jac->pmax);
447fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
4480f1074feSSatish Balay   }
4490f1074feSSatish Balay 
4500f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
4510f1074feSSatish Balay   if (flg) {
45257622a8eSBarry Smith     if (jac->agg_nl < 0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %g must be greater than or equal to zero",(double)jac->agg_nl);
4530f1074feSSatish Balay 
454fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
4550f1074feSSatish Balay   }
4560f1074feSSatish Balay 
4570f1074feSSatish Balay 
4580f1074feSSatish 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);
4590f1074feSSatish Balay   if (flg) {
46057622a8eSBarry Smith     if (jac->agg_num_paths < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of paths %g must be greater than or equal to 1",(double)jac->agg_num_paths);
4610f1074feSSatish Balay 
462fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
4630f1074feSSatish Balay   }
4640f1074feSSatish Balay 
4650f1074feSSatish Balay 
46616d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
46716d9e3a6SLisandro Dalcin   if (flg) {
46857622a8eSBarry Smith     if (jac->strongthreshold < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Strong threshold %g must be great than or equal zero",(double)jac->strongthreshold);
469fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
47016d9e3a6SLisandro Dalcin   }
47116d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
47216d9e3a6SLisandro Dalcin   if (flg) {
47357622a8eSBarry Smith     if (jac->maxrowsum < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Maximum row sum %g must be greater than zero",(double)jac->maxrowsum);
47457622a8eSBarry Smith     if (jac->maxrowsum > 1.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Maximum row sum %g must be less than or equal one",(double)jac->maxrowsum);
475fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
47616d9e3a6SLisandro Dalcin   }
47716d9e3a6SLisandro Dalcin 
47816d9e3a6SLisandro Dalcin   /* Grid sweeps */
4790f1074feSSatish 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);
48016d9e3a6SLisandro Dalcin   if (flg) {
481fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
48216d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
48316d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
4840f1074feSSatish Balay     jac->gridsweeps[1] = indx;
4850f1074feSSatish Balay     /*defaults coarse to 1 */
4860f1074feSSatish Balay     jac->gridsweeps[2] = 1;
48716d9e3a6SLisandro Dalcin   }
4880f1074feSSatish Balay 
4890f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
49016d9e3a6SLisandro Dalcin   if (flg) {
491fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
4920f1074feSSatish Balay     jac->gridsweeps[0] = indx;
49316d9e3a6SLisandro Dalcin   }
49416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
49516d9e3a6SLisandro Dalcin   if (flg) {
496fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
4970f1074feSSatish Balay     jac->gridsweeps[1] = indx;
49816d9e3a6SLisandro Dalcin   }
4990f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
50016d9e3a6SLisandro Dalcin   if (flg) {
501fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
5020f1074feSSatish Balay     jac->gridsweeps[2] = indx;
50316d9e3a6SLisandro Dalcin   }
50416d9e3a6SLisandro Dalcin 
50516d9e3a6SLisandro Dalcin   /* Relax type */
506a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_all","Relax type for the up and down cycles","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr);
50716d9e3a6SLisandro Dalcin   if (flg) {
5080f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
509fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
5100f1074feSSatish Balay     /* by default, coarse type set to 9 */
5110f1074feSSatish Balay     jac->relaxtype[2] = 9;
5120f1074feSSatish Balay 
51316d9e3a6SLisandro Dalcin   }
514a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_down","Relax type for the down cycles","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr);
51516d9e3a6SLisandro Dalcin   if (flg) {
51616d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
517fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
51816d9e3a6SLisandro Dalcin   }
519a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_up","Relax type for the up cycles","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr);
52016d9e3a6SLisandro Dalcin   if (flg) {
5210f1074feSSatish Balay     jac->relaxtype[1] = indx;
522fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
52316d9e3a6SLisandro Dalcin   }
524a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
52516d9e3a6SLisandro Dalcin   if (flg) {
5260f1074feSSatish Balay     jac->relaxtype[2] = indx;
527fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
52816d9e3a6SLisandro Dalcin   }
52916d9e3a6SLisandro Dalcin 
53016d9e3a6SLisandro Dalcin   /* Relaxation Weight */
53116d9e3a6SLisandro 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);
53216d9e3a6SLisandro Dalcin   if (flg) {
533fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
53416d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
53516d9e3a6SLisandro Dalcin   }
53616d9e3a6SLisandro Dalcin 
53716d9e3a6SLisandro Dalcin   n         = 2;
53816d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
53916d9e3a6SLisandro 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);
54016d9e3a6SLisandro Dalcin   if (flg) {
54116d9e3a6SLisandro Dalcin     if (n == 2) {
54216d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
543fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
544ce94432eSBarry Smith     } else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Relax weight level: you must provide 2 values separated by a comma (and no space), you provided %d",n);
54516d9e3a6SLisandro Dalcin   }
54616d9e3a6SLisandro Dalcin 
54716d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
54816d9e3a6SLisandro 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);
54916d9e3a6SLisandro Dalcin   if (flg) {
550fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
55116d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
55216d9e3a6SLisandro Dalcin   }
55316d9e3a6SLisandro Dalcin 
55416d9e3a6SLisandro Dalcin   n         = 2;
55516d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
55616d9e3a6SLisandro 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);
55716d9e3a6SLisandro Dalcin   if (flg) {
55816d9e3a6SLisandro Dalcin     if (n == 2) {
55916d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
560fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
561ce94432eSBarry Smith     } else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Relax weight outer level: You must provide 2 values separated by a comma (and no space), you provided %d",n);
56216d9e3a6SLisandro Dalcin   }
56316d9e3a6SLisandro Dalcin 
56416d9e3a6SLisandro Dalcin   /* the Relax Order */
565acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
56616d9e3a6SLisandro Dalcin 
56716d9e3a6SLisandro Dalcin   if (flg) {
56816d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
569fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
57016d9e3a6SLisandro Dalcin   }
571a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
57216d9e3a6SLisandro Dalcin   if (flg) {
57316d9e3a6SLisandro Dalcin     jac->measuretype = indx;
574fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
57516d9e3a6SLisandro Dalcin   }
5760f1074feSSatish Balay   /* update list length 3/07 */
577a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
57816d9e3a6SLisandro Dalcin   if (flg) {
57916d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
580fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
58116d9e3a6SLisandro Dalcin   }
5820f1074feSSatish Balay 
5830f1074feSSatish Balay   /* new 3/07 */
584a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
5850f1074feSSatish Balay   if (flg) {
5860f1074feSSatish Balay     jac->interptype = indx;
587fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
5880f1074feSSatish Balay   }
5890f1074feSSatish Balay 
590b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
59116d9e3a6SLisandro Dalcin   if (flg) {
592b96a4a96SBarry Smith     level = 3;
5930298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
5942fa5cd67SKarl Rupp 
595b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
596fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
5972ae77aedSBarry Smith   }
5982ae77aedSBarry Smith 
599b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
6002ae77aedSBarry Smith   if (flg) {
601b96a4a96SBarry Smith     level = 3;
6020298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
6032fa5cd67SKarl Rupp 
604b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
605fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
60616d9e3a6SLisandro Dalcin   }
6078f87f92bSBarry Smith 
608acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_coarsen", "HYPRE_BoomerAMGSetNodal()", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
6098f87f92bSBarry Smith   if (flg && tmp_truth) {
6108f87f92bSBarry Smith     jac->nodal_coarsen = 1;
611fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,1));
6128f87f92bSBarry Smith   }
6138f87f92bSBarry Smith 
614acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
6158f87f92bSBarry Smith   if (flg && tmp_truth) {
6168f87f92bSBarry Smith     PetscInt tmp_int;
6178f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
6188f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
619fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
620fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
621fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
622fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
6238f87f92bSBarry Smith   }
6248f87f92bSBarry Smith 
62516d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
62616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
62716d9e3a6SLisandro Dalcin }
62816d9e3a6SLisandro Dalcin 
62916d9e3a6SLisandro Dalcin #undef __FUNCT__
63016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG"
631ace3abfcSBarry 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)
63216d9e3a6SLisandro Dalcin {
63316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
63416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
6354ddd07fcSJed Brown   PetscInt       oits;
63616d9e3a6SLisandro Dalcin 
63716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
638dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
639fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
640fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
64116d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
64216d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
64316d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
6448b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
6454d0a8057SBarry Smith   *outits = oits;
6464d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
6474d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
648fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
649fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
65016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
65116d9e3a6SLisandro Dalcin }
65216d9e3a6SLisandro Dalcin 
65316d9e3a6SLisandro Dalcin 
65416d9e3a6SLisandro Dalcin #undef __FUNCT__
65516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG"
65616d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
65716d9e3a6SLisandro Dalcin {
65816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
65916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
660ace3abfcSBarry Smith   PetscBool      iascii;
66116d9e3a6SLisandro Dalcin 
66216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
663251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
66416d9e3a6SLisandro Dalcin   if (iascii) {
66516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
66616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
66716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
66816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
66957622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
67057622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
67157622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
6720f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
6730f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
6740f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
6750f1074feSSatish Balay 
67657622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
67716d9e3a6SLisandro Dalcin 
6780f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
6790f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
6800f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
68116d9e3a6SLisandro Dalcin 
6820f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
6830f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
6840f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
68516d9e3a6SLisandro Dalcin 
68657622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
68757622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
68816d9e3a6SLisandro Dalcin 
68916d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
69016d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr);
69116d9e3a6SLisandro Dalcin     } else {
69216d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr);
69316d9e3a6SLisandro Dalcin     }
69416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
69516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
6960f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
6978f87f92bSBarry Smith     if (jac->nodal_coarsen) {
6988f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal())\n");CHKERRQ(ierr);
6998f87f92bSBarry Smith     }
7008f87f92bSBarry Smith     if (jac->nodal_relax) {
7018f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
7028f87f92bSBarry Smith     }
70316d9e3a6SLisandro Dalcin   }
70416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
70516d9e3a6SLisandro Dalcin }
70616d9e3a6SLisandro Dalcin 
70716d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
70816d9e3a6SLisandro Dalcin #undef __FUNCT__
70916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails"
71016d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PC pc)
71116d9e3a6SLisandro Dalcin {
71216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
71316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
7144ddd07fcSJed Brown   PetscInt       indx;
715ace3abfcSBarry Smith   PetscBool      flag;
71616d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
71716d9e3a6SLisandro Dalcin 
71816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
71916d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE ParaSails Options");CHKERRQ(ierr);
72016d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
72116d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
7222fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
72316d9e3a6SLisandro Dalcin 
72416d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
7252fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
72616d9e3a6SLisandro Dalcin 
72716d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
7282fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
72916d9e3a6SLisandro Dalcin 
730acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
7312fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
73216d9e3a6SLisandro Dalcin 
733acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
7342fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
73516d9e3a6SLisandro Dalcin 
736a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
73716d9e3a6SLisandro Dalcin   if (flag) {
73816d9e3a6SLisandro Dalcin     jac->symt = indx;
739fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
74016d9e3a6SLisandro Dalcin   }
74116d9e3a6SLisandro Dalcin 
74216d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
74316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
74416d9e3a6SLisandro Dalcin }
74516d9e3a6SLisandro Dalcin 
74616d9e3a6SLisandro Dalcin #undef __FUNCT__
74716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails"
74816d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
74916d9e3a6SLisandro Dalcin {
75016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
75116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
752ace3abfcSBarry Smith   PetscBool      iascii;
75316d9e3a6SLisandro Dalcin   const char     *symt = 0;;
75416d9e3a6SLisandro Dalcin 
75516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
756251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
75716d9e3a6SLisandro Dalcin   if (iascii) {
75816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
75916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
76057622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
76157622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: filter %g\n",(double)jac->filter);CHKERRQ(ierr);
76257622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
763ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
764ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
7652fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
7662fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
7672fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
768ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
76916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr);
77016d9e3a6SLisandro Dalcin   }
77116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
77216d9e3a6SLisandro Dalcin }
773*4cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
774*4cb006feSStefano Zampini #undef __FUNCT__
775*4cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS"
776*4cb006feSStefano Zampini static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PC pc)
777*4cb006feSStefano Zampini {
778*4cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
779*4cb006feSStefano Zampini   PetscErrorCode ierr;
780*4cb006feSStefano Zampini   PetscInt       n;
781*4cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
782*4cb006feSStefano Zampini 
783*4cb006feSStefano Zampini   PetscFunctionBegin;
784*4cb006feSStefano Zampini   ierr = PetscOptionsHead("HYPRE AMS Options");CHKERRQ(ierr);
785*4cb006feSStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->ams_print,&jac->ams_print,&flag);CHKERRQ(ierr);
786*4cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->ams_print));
787*4cb006feSStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_max_iter","Maximum number of AMS multigrid iterations within PCApply","None",jac->ams_max_iter,&jac->ams_max_iter,&flag);CHKERRQ(ierr);
788*4cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->ams_max_iter));
789*4cb006feSStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_cycle_type","Cycle type for AMS multigrid","None",jac->ams_cycle_type,&jac->ams_cycle_type,&flag);CHKERRQ(ierr);
790*4cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
791*4cb006feSStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->ams_tol,&jac->ams_tol,&flag);CHKERRQ(ierr);
792*4cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->ams_tol));
793*4cb006feSStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_relax_type","Relaxation type for AMS smoother","None",jac->ams_relax_type,&jac->ams_relax_type,&flag);CHKERRQ(ierr);
794*4cb006feSStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_relax_times","Number of relaxation steps for AMS smoother","None",jac->ams_relax_times,&jac->ams_relax_times,&flag2);CHKERRQ(ierr);
795*4cb006feSStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_relax_weight","Relaxation weight for AMS smoother","None",jac->ams_relax_weight,&jac->ams_relax_weight,&flag3);CHKERRQ(ierr);
796*4cb006feSStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->ams_omega,&jac->ams_omega,&flag4);CHKERRQ(ierr);
797*4cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
798*4cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->ams_relax_type,
799*4cb006feSStefano Zampini                                                                       jac->ams_relax_times,
800*4cb006feSStefano Zampini                                                                       jac->ams_relax_weight,
801*4cb006feSStefano Zampini                                                                       jac->ams_omega));
802*4cb006feSStefano Zampini   }
803*4cb006feSStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_amg_alpha_theta","Threshold for strong coupling of vector Poisson AMG solver","None",jac->ams_amg_alpha_theta,&jac->ams_amg_alpha_theta,&flag);CHKERRQ(ierr);
804*4cb006feSStefano Zampini   n = 5;
805*4cb006feSStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->ams_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
806*4cb006feSStefano Zampini   if (flag || flag2) {
807*4cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->ams_amg_alpha_opts[0],       /* AMG coarsen type */
808*4cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[1],       /* AMG agg_levels */
809*4cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[2],       /* AMG relax_type */
810*4cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_theta,
811*4cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[3],       /* AMG interp_type */
812*4cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[4]));     /* AMG Pmax */
813*4cb006feSStefano Zampini   }
814*4cb006feSStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_amg_beta_theta","Threshold for strong coupling of scalar Poisson AMG solver","None",jac->ams_amg_beta_theta,&jac->ams_amg_beta_theta,&flag);CHKERRQ(ierr);
815*4cb006feSStefano Zampini   n = 5;
816*4cb006feSStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_beta_options","AMG options for scalar Poisson solver","None",jac->ams_amg_beta_opts,&n,&flag2);CHKERRQ(ierr);
817*4cb006feSStefano Zampini   if (flag || flag2) {
818*4cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->ams_amg_beta_opts[0],       /* AMG coarsen type */
819*4cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[1],       /* AMG agg_levels */
820*4cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[2],       /* AMG relax_type */
821*4cb006feSStefano Zampini                                                                     jac->ams_amg_beta_theta,
822*4cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[3],       /* AMG interp_type */
823*4cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[4]));     /* AMG Pmax */
824*4cb006feSStefano Zampini   }
825*4cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
826*4cb006feSStefano Zampini   PetscFunctionReturn(0);
827*4cb006feSStefano Zampini }
828*4cb006feSStefano Zampini 
829*4cb006feSStefano Zampini #undef __FUNCT__
830*4cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS"
831*4cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
832*4cb006feSStefano Zampini {
833*4cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
834*4cb006feSStefano Zampini   PetscErrorCode ierr;
835*4cb006feSStefano Zampini   PetscBool      iascii;
836*4cb006feSStefano Zampini 
837*4cb006feSStefano Zampini   PetscFunctionBegin;
838*4cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
839*4cb006feSStefano Zampini   if (iascii) {
840*4cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
841*4cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iterations per application %d\n",jac->ams_max_iter);CHKERRQ(ierr);
842*4cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
843*4cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iteration tolerance %g\n",jac->ams_tol);CHKERRQ(ierr);
844*4cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother type %d\n",jac->ams_relax_type);CHKERRQ(ierr);
845*4cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: number of smoothing steps %d\n",jac->ams_relax_times);CHKERRQ(ierr);
846*4cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother weight %g\n",jac->ams_relax_weight);CHKERRQ(ierr);
847*4cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother omega %g\n",jac->ams_omega);CHKERRQ(ierr);
848*4cb006feSStefano Zampini     if (jac->alpha_Poisson) {
849*4cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
850*4cb006feSStefano Zampini     } else {
851*4cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr);
852*4cb006feSStefano Zampini     }
853*4cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->ams_amg_alpha_opts[0]);CHKERRQ(ierr);
854*4cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->ams_amg_alpha_opts[1]);CHKERRQ(ierr);
855*4cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->ams_amg_alpha_opts[2]);CHKERRQ(ierr);
856*4cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->ams_amg_alpha_opts[3]);CHKERRQ(ierr);
857*4cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->ams_amg_alpha_opts[4]);CHKERRQ(ierr);
858*4cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->ams_amg_alpha_theta);CHKERRQ(ierr);
859*4cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
860*4cb006feSStefano Zampini       if (jac->beta_Poisson) {
861*4cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
862*4cb006feSStefano Zampini       } else {
863*4cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr);
864*4cb006feSStefano Zampini       }
865*4cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->ams_amg_beta_opts[0]);CHKERRQ(ierr);
866*4cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->ams_amg_beta_opts[1]);CHKERRQ(ierr);
867*4cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->ams_amg_beta_opts[2]);CHKERRQ(ierr);
868*4cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->ams_amg_beta_opts[3]);CHKERRQ(ierr);
869*4cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->ams_amg_beta_opts[4]);CHKERRQ(ierr);
870*4cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->ams_amg_beta_theta);CHKERRQ(ierr);
871*4cb006feSStefano Zampini     }
872*4cb006feSStefano Zampini   }
873*4cb006feSStefano Zampini   PetscFunctionReturn(0);
874*4cb006feSStefano Zampini }
875*4cb006feSStefano Zampini 
876*4cb006feSStefano Zampini #undef __FUNCT__
877*4cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE_AMS"
878*4cb006feSStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE_AMS(PC pc, Mat G)
879*4cb006feSStefano Zampini {
880*4cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
881*4cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_G;
882*4cb006feSStefano Zampini   PetscErrorCode     ierr;
883*4cb006feSStefano Zampini 
884*4cb006feSStefano Zampini   PetscFunctionBegin;
885*4cb006feSStefano Zampini   /* throw away any discrete gradient if already set */
886*4cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
887*4cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(G,&jac->G);CHKERRQ(ierr);
888*4cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(G,jac->G);CHKERRQ(ierr);
889*4cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->G,(void**)(&parcsr_G)));
890*4cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr_G));
891*4cb006feSStefano Zampini   PetscFunctionReturn(0);
892*4cb006feSStefano Zampini }
893*4cb006feSStefano Zampini 
894*4cb006feSStefano Zampini #undef __FUNCT__
895*4cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient"
896*4cb006feSStefano Zampini /*@
897*4cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
898*4cb006feSStefano Zampini 
899*4cb006feSStefano Zampini    Collective on PC
900*4cb006feSStefano Zampini 
901*4cb006feSStefano Zampini    Input Parameters:
902*4cb006feSStefano Zampini +  pc - the preconditioning context
903*4cb006feSStefano Zampini -  G - the discrete gradient
904*4cb006feSStefano Zampini 
905*4cb006feSStefano Zampini    Level: intermediate
906*4cb006feSStefano Zampini 
907*4cb006feSStefano Zampini    Notes: G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh
908*4cb006feSStefano Zampini           Each row of G has 2 nonzeros, with column indexes being the global indexes of edge's endpoints: matrix values are +1 and -1 depending on edge orientation
909*4cb006feSStefano Zampini 
910*4cb006feSStefano Zampini .seealso:
911*4cb006feSStefano Zampini @*/
912*4cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
913*4cb006feSStefano Zampini {
914*4cb006feSStefano Zampini   PetscErrorCode ierr;
915*4cb006feSStefano Zampini 
916*4cb006feSStefano Zampini   PetscFunctionBegin;
917*4cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
918*4cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
919*4cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
920*4cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
921*4cb006feSStefano Zampini   PetscFunctionReturn(0);
922*4cb006feSStefano Zampini }
923*4cb006feSStefano Zampini 
924*4cb006feSStefano Zampini #undef __FUNCT__
925*4cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS"
926*4cb006feSStefano Zampini static PetscErrorCode PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
927*4cb006feSStefano Zampini {
928*4cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
929*4cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_alpha_Poisson;
930*4cb006feSStefano Zampini   PetscErrorCode     ierr;
931*4cb006feSStefano Zampini 
932*4cb006feSStefano Zampini   PetscFunctionBegin;
933*4cb006feSStefano Zampini   /* throw away any matrix if already set */
934*4cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
935*4cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->alpha_Poisson);CHKERRQ(ierr);
936*4cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->alpha_Poisson);CHKERRQ(ierr);
937*4cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->alpha_Poisson,(void**)(&parcsr_alpha_Poisson)));
938*4cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr_alpha_Poisson));
939*4cb006feSStefano Zampini   PetscFunctionReturn(0);
940*4cb006feSStefano Zampini }
941*4cb006feSStefano Zampini 
942*4cb006feSStefano Zampini #undef __FUNCT__
943*4cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix"
944*4cb006feSStefano Zampini /*@
945*4cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
946*4cb006feSStefano Zampini 
947*4cb006feSStefano Zampini    Collective on PC
948*4cb006feSStefano Zampini 
949*4cb006feSStefano Zampini    Input Parameters:
950*4cb006feSStefano Zampini +  pc - the preconditioning context
951*4cb006feSStefano Zampini -  A - the matrix
952*4cb006feSStefano Zampini 
953*4cb006feSStefano Zampini    Level: intermediate
954*4cb006feSStefano Zampini 
955*4cb006feSStefano Zampini    Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
956*4cb006feSStefano Zampini 
957*4cb006feSStefano Zampini .seealso:
958*4cb006feSStefano Zampini @*/
959*4cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
960*4cb006feSStefano Zampini {
961*4cb006feSStefano Zampini   PetscErrorCode ierr;
962*4cb006feSStefano Zampini 
963*4cb006feSStefano Zampini   PetscFunctionBegin;
964*4cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
965*4cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
966*4cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
967*4cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetAlphaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
968*4cb006feSStefano Zampini   PetscFunctionReturn(0);
969*4cb006feSStefano Zampini }
970*4cb006feSStefano Zampini 
971*4cb006feSStefano Zampini #undef __FUNCT__
972*4cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix_HYPRE_AMS"
973*4cb006feSStefano Zampini static PetscErrorCode PCHYPRESetBetaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
974*4cb006feSStefano Zampini {
975*4cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
976*4cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_beta_Poisson;
977*4cb006feSStefano Zampini   PetscErrorCode     ierr;
978*4cb006feSStefano Zampini 
979*4cb006feSStefano Zampini   PetscFunctionBegin;
980*4cb006feSStefano Zampini   if (!A) {
981*4cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_TRUE;
982*4cb006feSStefano Zampini     PetscFunctionReturn(0);
983*4cb006feSStefano Zampini   }
984*4cb006feSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
985*4cb006feSStefano Zampini   /* throw away any matrix if already set */
986*4cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
987*4cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->beta_Poisson);CHKERRQ(ierr);
988*4cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->beta_Poisson);CHKERRQ(ierr);
989*4cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->beta_Poisson,(void**)(&parcsr_beta_Poisson)));
990*4cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr_beta_Poisson));
991*4cb006feSStefano Zampini   PetscFunctionReturn(0);
992*4cb006feSStefano Zampini }
993*4cb006feSStefano Zampini 
994*4cb006feSStefano Zampini #undef __FUNCT__
995*4cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix"
996*4cb006feSStefano Zampini /*@
997*4cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
998*4cb006feSStefano Zampini 
999*4cb006feSStefano Zampini    Collective on PC
1000*4cb006feSStefano Zampini 
1001*4cb006feSStefano Zampini    Input Parameters:
1002*4cb006feSStefano Zampini +  pc - the preconditioning context
1003*4cb006feSStefano Zampini -  A - the matrix
1004*4cb006feSStefano Zampini 
1005*4cb006feSStefano Zampini    Level: intermediate
1006*4cb006feSStefano Zampini 
1007*4cb006feSStefano Zampini    Notes: A should be obtained by discretizing the Poisson problem with linear finite elements.
1008*4cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
1009*4cb006feSStefano Zampini 
1010*4cb006feSStefano Zampini .seealso:
1011*4cb006feSStefano Zampini @*/
1012*4cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
1013*4cb006feSStefano Zampini {
1014*4cb006feSStefano Zampini   PetscErrorCode ierr;
1015*4cb006feSStefano Zampini 
1016*4cb006feSStefano Zampini   PetscFunctionBegin;
1017*4cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1018*4cb006feSStefano Zampini   if (A) {
1019*4cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
1020*4cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
1021*4cb006feSStefano Zampini   }
1022*4cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetBetaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
1023*4cb006feSStefano Zampini   PetscFunctionReturn(0);
1024*4cb006feSStefano Zampini }
1025*4cb006feSStefano Zampini 
1026*4cb006feSStefano Zampini #undef __FUNCT__
1027*4cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE_AMS"
1028*4cb006feSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE_AMS(PC pc,Vec ozz, Vec zoz, Vec zzo)
1029*4cb006feSStefano Zampini {
1030*4cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
1031*4cb006feSStefano Zampini   HYPRE_ParVector    par_ozz,par_zoz,par_zzo;
1032*4cb006feSStefano Zampini   PetscErrorCode     ierr;
1033*4cb006feSStefano Zampini 
1034*4cb006feSStefano Zampini   PetscFunctionBegin;
1035*4cb006feSStefano Zampini   /* throw away any vector if already set */
1036*4cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
1037*4cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
1038*4cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
1039*4cb006feSStefano Zampini   jac->constants[0] = NULL;
1040*4cb006feSStefano Zampini   jac->constants[1] = NULL;
1041*4cb006feSStefano Zampini   jac->constants[2] = NULL;
1042*4cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
1043*4cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
1044*4cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&par_ozz)));
1045*4cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
1046*4cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
1047*4cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&par_zoz)));
1048*4cb006feSStefano Zampini   if (zzo) {
1049*4cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
1050*4cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
1051*4cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&par_zzo)));
1052*4cb006feSStefano Zampini   }
1053*4cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,par_ozz,par_zoz,par_zzo));
1054*4cb006feSStefano Zampini   PetscFunctionReturn(0);
1055*4cb006feSStefano Zampini }
1056*4cb006feSStefano Zampini 
1057*4cb006feSStefano Zampini #undef __FUNCT__
1058*4cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors"
1059*4cb006feSStefano Zampini /*@
1060*4cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
1061*4cb006feSStefano Zampini 
1062*4cb006feSStefano Zampini    Collective on PC
1063*4cb006feSStefano Zampini 
1064*4cb006feSStefano Zampini    Input Parameters:
1065*4cb006feSStefano Zampini +  pc - the preconditioning context
1066*4cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
1067*4cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
1068*4cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
1069*4cb006feSStefano Zampini 
1070*4cb006feSStefano Zampini    Level: intermediate
1071*4cb006feSStefano Zampini 
1072*4cb006feSStefano Zampini    Notes:
1073*4cb006feSStefano Zampini 
1074*4cb006feSStefano Zampini .seealso:
1075*4cb006feSStefano Zampini @*/
1076*4cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
1077*4cb006feSStefano Zampini {
1078*4cb006feSStefano Zampini   PetscErrorCode ierr;
1079*4cb006feSStefano Zampini 
1080*4cb006feSStefano Zampini   PetscFunctionBegin;
1081*4cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1082*4cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
1083*4cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
1084*4cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
1085*4cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
1086*4cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
1087*4cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
1088*4cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
1089*4cb006feSStefano Zampini   PetscFunctionReturn(0);
1090*4cb006feSStefano Zampini }
1091*4cb006feSStefano Zampini 
1092*4cb006feSStefano Zampini #undef __FUNCT__
1093*4cb006feSStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE_AMS"
1094*4cb006feSStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE_AMS(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
1095*4cb006feSStefano Zampini {
1096*4cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
1097*4cb006feSStefano Zampini   Vec             tv;
1098*4cb006feSStefano Zampini   HYPRE_ParVector par_coords[3];
1099*4cb006feSStefano Zampini   PetscInt        i;
1100*4cb006feSStefano Zampini   PetscErrorCode  ierr;
1101*4cb006feSStefano Zampini 
1102*4cb006feSStefano Zampini   PetscFunctionBegin;
1103*4cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
1104*4cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
1105*4cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
1106*4cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
1107*4cb006feSStefano Zampini   /* set problem's dimension */
1108*4cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim));
1109*4cb006feSStefano Zampini   /* compute IJ vector for coordinates */
1110*4cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
1111*4cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
1112*4cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
1113*4cb006feSStefano Zampini   for (i=0;i<dim;i++) {
1114*4cb006feSStefano Zampini     PetscScalar *array;
1115*4cb006feSStefano Zampini     PetscInt    j;
1116*4cb006feSStefano Zampini 
1117*4cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
1118*4cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
1119*4cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
1120*4cb006feSStefano Zampini       array[j] = coords[j*dim+i];
1121*4cb006feSStefano Zampini     }
1122*4cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
1123*4cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
1124*4cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
1125*4cb006feSStefano Zampini   }
1126*4cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
1127*4cb006feSStefano Zampini   /* pass parCSR vectors to AMS solver */
1128*4cb006feSStefano Zampini   par_coords[0] = NULL;
1129*4cb006feSStefano Zampini   par_coords[1] = NULL;
1130*4cb006feSStefano Zampini   par_coords[2] = NULL;
1131*4cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&par_coords[0])));
1132*4cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&par_coords[1])));
1133*4cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&par_coords[2])));
1134*4cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,par_coords[0],par_coords[1],par_coords[2]));
1135*4cb006feSStefano Zampini   PetscFunctionReturn(0);
1136*4cb006feSStefano Zampini }
1137*4cb006feSStefano Zampini 
113816d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
113916d9e3a6SLisandro Dalcin 
114016d9e3a6SLisandro Dalcin #undef __FUNCT__
114116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
1142f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
114316d9e3a6SLisandro Dalcin {
114416d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
114516d9e3a6SLisandro Dalcin 
114616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
114716d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
114816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
114916d9e3a6SLisandro Dalcin }
115016d9e3a6SLisandro Dalcin 
115116d9e3a6SLisandro Dalcin #undef __FUNCT__
115216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
1153f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
115416d9e3a6SLisandro Dalcin {
115516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
115616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1157ace3abfcSBarry Smith   PetscBool      flag;
115816d9e3a6SLisandro Dalcin 
115916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
116016d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
116116d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1162ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
116316d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
116416d9e3a6SLisandro Dalcin   } else {
116516d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
116616d9e3a6SLisandro Dalcin   }
116716d9e3a6SLisandro Dalcin 
116816d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
116916d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
117016d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
117116d9e3a6SLisandro Dalcin 
117216d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
117316d9e3a6SLisandro Dalcin   if (flag) {
1174fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
117516d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
117616d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
117716d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
117816d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
117916d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
118016d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
118116d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
118216d9e3a6SLisandro Dalcin   }
118316d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
118416d9e3a6SLisandro Dalcin   if (flag) {
1185fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
118616d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
118716d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
118816d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
118916d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
119016d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
119116d9e3a6SLisandro Dalcin     /* initialize */
119216d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
119316d9e3a6SLisandro Dalcin     jac->threshhold = .1;
119416d9e3a6SLisandro Dalcin     jac->filter     = .1;
119516d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
11962fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
11972fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
11982fa5cd67SKarl Rupp 
119916d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
120016d9e3a6SLisandro Dalcin     jac->symt = 0;
1201fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1202fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1203fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1204fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1205fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1206fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
120716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
120816d9e3a6SLisandro Dalcin   }
120916d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("euclid",jac->hypre_type,&flag);CHKERRQ(ierr);
121016d9e3a6SLisandro Dalcin   if (flag) {
121116d9e3a6SLisandro Dalcin     ierr                    = HYPRE_EuclidCreate(jac->comm_hypre,&jac->hsolver);
121216d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
121316d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Euclid;
121416d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_EuclidDestroy;
121516d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_EuclidSetup;
121616d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_EuclidSolve;
121716d9e3a6SLisandro Dalcin     /* initialization */
121816d9e3a6SLisandro Dalcin     jac->bjilu              = PETSC_FALSE;
121916d9e3a6SLisandro Dalcin     jac->levels             = 1;
122016d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
122116d9e3a6SLisandro Dalcin   }
122216d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
122316d9e3a6SLisandro Dalcin   if (flag) {
122416d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
122516d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
122616d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
122716d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
122816d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
122916d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
123016d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
123116d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
123216d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
123316d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
123416d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
123516d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
123616d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
12378f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
123816d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
123916d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
124016d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
124116d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
124216d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
12430f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
12448f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
12450f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
124616d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
124716d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
124816d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
12490f1074feSSatish Balay     jac->interptype       = 0;
12500f1074feSSatish Balay     jac->agg_nl           = 0;
12510f1074feSSatish Balay     jac->pmax             = 0;
12520f1074feSSatish Balay     jac->truncfactor      = 0.0;
12530f1074feSSatish Balay     jac->agg_num_paths    = 1;
12548f87f92bSBarry Smith 
12558f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
12568f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
12578f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1258fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1259fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1260fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1261fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1262fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1263fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1264fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1265fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1266fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1267fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1268fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1269fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1270fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1271fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1272fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1273fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
127416d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
127516d9e3a6SLisandro Dalcin   }
1276*4cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
1277*4cb006feSStefano Zampini   if (flag) {
1278*4cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
1279*4cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
1280*4cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
1281*4cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
1282*4cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
1283*4cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
1284*4cb006feSStefano Zampini     jac->coords[0]           = NULL;
1285*4cb006feSStefano Zampini     jac->coords[1]           = NULL;
1286*4cb006feSStefano Zampini     jac->coords[2]           = NULL;
1287*4cb006feSStefano Zampini     jac->G                   = NULL;
1288*4cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1289*4cb006feSStefano Zampini     jac->ams_print           = 0;
1290*4cb006feSStefano Zampini     jac->ams_max_iter        = 1; /* used as a preconditioner */
1291*4cb006feSStefano Zampini     jac->ams_cycle_type      = 13;
1292*4cb006feSStefano Zampini     jac->ams_tol             = 0.; /* used as a preconditioner */
1293*4cb006feSStefano Zampini     /* Smoothing options */
1294*4cb006feSStefano Zampini     jac->ams_relax_type      = 2;
1295*4cb006feSStefano Zampini     jac->ams_relax_times     = 1;
1296*4cb006feSStefano Zampini     jac->ams_relax_weight    = 1.0;
1297*4cb006feSStefano Zampini     jac->ams_omega           = 1.0;
1298*4cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1299*4cb006feSStefano Zampini     jac->ams_amg_alpha_opts[0] = 10;
1300*4cb006feSStefano Zampini     jac->ams_amg_alpha_opts[1] = 1;
1301*4cb006feSStefano Zampini     jac->ams_amg_alpha_opts[2] = 8;
1302*4cb006feSStefano Zampini     jac->ams_amg_alpha_opts[3] = 6;
1303*4cb006feSStefano Zampini     jac->ams_amg_alpha_opts[4] = 4;
1304*4cb006feSStefano Zampini     jac->ams_amg_alpha_theta   = 0.25;
1305*4cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1306*4cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_FALSE;
1307*4cb006feSStefano Zampini     jac->ams_amg_beta_opts[0] = 10;
1308*4cb006feSStefano Zampini     jac->ams_amg_beta_opts[1] = 1;
1309*4cb006feSStefano Zampini     jac->ams_amg_beta_opts[2] = 8;
1310*4cb006feSStefano Zampini     jac->ams_amg_beta_opts[3] = 6;
1311*4cb006feSStefano Zampini     jac->ams_amg_beta_opts[4] = 4;
1312*4cb006feSStefano Zampini     jac->ams_amg_beta_theta   = 0.25;
1313*4cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->ams_print));
1314*4cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->ams_max_iter));
1315*4cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1316*4cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->ams_tol));
1317*4cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->ams_relax_type,
1318*4cb006feSStefano Zampini                                                                       jac->ams_relax_times,
1319*4cb006feSStefano Zampini                                                                       jac->ams_relax_weight,
1320*4cb006feSStefano Zampini                                                                       jac->ams_omega));
1321*4cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->ams_amg_alpha_opts[0],       /* AMG coarsen type */
1322*4cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[1],       /* AMG agg_levels */
1323*4cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[2],       /* AMG relax_type */
1324*4cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_theta,
1325*4cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[3],       /* AMG interp_type */
1326*4cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[4]));     /* AMG Pmax */
1327*4cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->ams_amg_beta_opts[0],       /* AMG coarsen type */
1328*4cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[1],       /* AMG agg_levels */
1329*4cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[2],       /* AMG relax_type */
1330*4cb006feSStefano Zampini                                                                     jac->ams_amg_beta_theta,
1331*4cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[3],       /* AMG interp_type */
1332*4cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[4]));     /* AMG Pmax */
1333*4cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE_AMS);CHKERRQ(ierr);
1334*4cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE_AMS);CHKERRQ(ierr);
1335*4cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE_AMS);CHKERRQ(ierr);
1336*4cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
1337*4cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",PCHYPRESetBetaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
1338*4cb006feSStefano Zampini     PetscFunctionReturn(0);
1339*4cb006feSStefano Zampini   }
1340503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
13412fa5cd67SKarl Rupp 
13420298fd71SBarry Smith   jac->hypre_type = NULL;
1343*4cb006feSStefano Zampini   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, euclid, boomeramg, ams",name);
134416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
134516d9e3a6SLisandro Dalcin }
134616d9e3a6SLisandro Dalcin 
134716d9e3a6SLisandro Dalcin /*
134816d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
134916d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
135016d9e3a6SLisandro Dalcin */
135116d9e3a6SLisandro Dalcin #undef __FUNCT__
135216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
135316d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE(PC pc)
135416d9e3a6SLisandro Dalcin {
135516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
13564ddd07fcSJed Brown   PetscInt       indx;
1357*4cb006feSStefano Zampini   const char     *type[] = {"pilut","parasails","boomeramg","euclid","ams"};
1358ace3abfcSBarry Smith   PetscBool      flg;
135916d9e3a6SLisandro Dalcin 
136016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
136116d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE preconditioner options");CHKERRQ(ierr);
1362*4cb006feSStefano Zampini   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,5,"boomeramg",&indx,&flg);CHKERRQ(ierr);
136316d9e3a6SLisandro Dalcin   if (flg) {
136416d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
136502a17cd4SBarry Smith   } else {
136602a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
136716d9e3a6SLisandro Dalcin   }
136816d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
136916d9e3a6SLisandro Dalcin     ierr = pc->ops->setfromoptions(pc);CHKERRQ(ierr);
137016d9e3a6SLisandro Dalcin   }
137116d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
137216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
137316d9e3a6SLisandro Dalcin }
137416d9e3a6SLisandro Dalcin 
137516d9e3a6SLisandro Dalcin #undef __FUNCT__
137616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
137716d9e3a6SLisandro Dalcin /*@C
137816d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
137916d9e3a6SLisandro Dalcin 
138016d9e3a6SLisandro Dalcin    Input Parameters:
138116d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1382*4cb006feSStefano Zampini -     name - either  pilut, parasails, boomeramg, euclid, ams
138316d9e3a6SLisandro Dalcin 
138416d9e3a6SLisandro Dalcin    Options Database Keys:
1385*4cb006feSStefano Zampini    -pc_hypre_type - One of pilut, parasails, boomeramg, euclid, ams
138616d9e3a6SLisandro Dalcin 
138716d9e3a6SLisandro Dalcin    Level: intermediate
138816d9e3a6SLisandro Dalcin 
138916d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
139016d9e3a6SLisandro Dalcin            PCHYPRE
139116d9e3a6SLisandro Dalcin 
139216d9e3a6SLisandro Dalcin @*/
13937087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
139416d9e3a6SLisandro Dalcin {
13954ac538c5SBarry Smith   PetscErrorCode ierr;
139616d9e3a6SLisandro Dalcin 
139716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
13980700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
139916d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
14004ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
140116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
140216d9e3a6SLisandro Dalcin }
140316d9e3a6SLisandro Dalcin 
140416d9e3a6SLisandro Dalcin #undef __FUNCT__
140516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
140616d9e3a6SLisandro Dalcin /*@C
140716d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
140816d9e3a6SLisandro Dalcin 
140916d9e3a6SLisandro Dalcin    Input Parameter:
141016d9e3a6SLisandro Dalcin .     pc - the preconditioner context
141116d9e3a6SLisandro Dalcin 
141216d9e3a6SLisandro Dalcin    Output Parameter:
1413*4cb006feSStefano Zampini .     name - either  pilut, parasails, boomeramg, euclid, ams
141416d9e3a6SLisandro Dalcin 
141516d9e3a6SLisandro Dalcin    Level: intermediate
141616d9e3a6SLisandro Dalcin 
141716d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
141816d9e3a6SLisandro Dalcin            PCHYPRE
141916d9e3a6SLisandro Dalcin 
142016d9e3a6SLisandro Dalcin @*/
14217087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
142216d9e3a6SLisandro Dalcin {
14234ac538c5SBarry Smith   PetscErrorCode ierr;
142416d9e3a6SLisandro Dalcin 
142516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
14260700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
142716d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
14284ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
142916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
143016d9e3a6SLisandro Dalcin }
143116d9e3a6SLisandro Dalcin 
143216d9e3a6SLisandro Dalcin /*MC
143316d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
143416d9e3a6SLisandro Dalcin 
143516d9e3a6SLisandro Dalcin    Options Database Keys:
1436*4cb006feSStefano Zampini +   -pc_hypre_type - One of pilut, parasails, boomeramg, euclid, ams
143716d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
143816d9e3a6SLisandro Dalcin           preconditioner
143916d9e3a6SLisandro Dalcin 
144016d9e3a6SLisandro Dalcin    Level: intermediate
144116d9e3a6SLisandro Dalcin 
144216d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
144316d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
144416d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
144516d9e3a6SLisandro Dalcin 
144616d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
14470f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
14480f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
14490f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
14508f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
14510f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
14520f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
145316d9e3a6SLisandro Dalcin 
14540f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
14550f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
14560f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
145716d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
145816d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
145916d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
146016d9e3a6SLisandro Dalcin 
146116d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
146216d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
146316d9e3a6SLisandro Dalcin 
14649e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
14659e5bc791SBarry Smith 
146616d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
14679e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
146816d9e3a6SLisandro Dalcin 
146916d9e3a6SLisandro Dalcin M*/
147016d9e3a6SLisandro Dalcin 
147116d9e3a6SLisandro Dalcin #undef __FUNCT__
147216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
14738cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
147416d9e3a6SLisandro Dalcin {
147516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
147616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
147716d9e3a6SLisandro Dalcin 
147816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1479b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
14802fa5cd67SKarl Rupp 
148116d9e3a6SLisandro Dalcin   pc->data                = jac;
148216d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
148316d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
148416d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
148516d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
148616d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
14870298fd71SBarry Smith   jac->hypre_type         = NULL;
1488*4cb006feSStefano Zampini   jac->coords[0]          = NULL;
1489*4cb006feSStefano Zampini   jac->coords[1]          = NULL;
1490*4cb006feSStefano Zampini   jac->coords[2]          = NULL;
1491*4cb006feSStefano Zampini   jac->constants[0]       = NULL;
1492*4cb006feSStefano Zampini   jac->constants[1]       = NULL;
1493*4cb006feSStefano Zampini   jac->constants[2]       = NULL;
149416d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1495ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1496bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1497bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
149816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
149916d9e3a6SLisandro Dalcin }
1500ebc551c0SBarry Smith 
1501f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1502f91d8e95SBarry Smith 
1503b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1504b45d2f2cSJed Brown #include <petsc-private/matimpl.h>
1505ebc551c0SBarry Smith 
1506ebc551c0SBarry Smith typedef struct {
150768326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1508f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
15099e5bc791SBarry Smith 
15109e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
15114ddd07fcSJed Brown   PetscInt its;
15129e5bc791SBarry Smith   double   tol;
15134ddd07fcSJed Brown   PetscInt relax_type;
15144ddd07fcSJed Brown   PetscInt rap_type;
15154ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
15164ddd07fcSJed Brown   PetscInt max_levels;
1517ebc551c0SBarry Smith } PC_PFMG;
1518ebc551c0SBarry Smith 
1519ebc551c0SBarry Smith #undef __FUNCT__
1520ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1521ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1522ebc551c0SBarry Smith {
1523ebc551c0SBarry Smith   PetscErrorCode ierr;
1524f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1525ebc551c0SBarry Smith 
1526ebc551c0SBarry Smith   PetscFunctionBegin;
15272fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1528f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1529c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1530ebc551c0SBarry Smith   PetscFunctionReturn(0);
1531ebc551c0SBarry Smith }
1532ebc551c0SBarry Smith 
15339e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
15349e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
15359e5bc791SBarry Smith 
1536ebc551c0SBarry Smith #undef __FUNCT__
1537ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1538ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1539ebc551c0SBarry Smith {
1540ebc551c0SBarry Smith   PetscErrorCode ierr;
1541ace3abfcSBarry Smith   PetscBool      iascii;
1542f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1543ebc551c0SBarry Smith 
1544ebc551c0SBarry Smith   PetscFunctionBegin;
1545251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
15469e5bc791SBarry Smith   if (iascii) {
15479e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
15489e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
15499e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
15509e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
15519e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
15529e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
15533b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
15549e5bc791SBarry Smith   }
1555ebc551c0SBarry Smith   PetscFunctionReturn(0);
1556ebc551c0SBarry Smith }
1557ebc551c0SBarry Smith 
15589e5bc791SBarry Smith 
1559ebc551c0SBarry Smith #undef __FUNCT__
1560ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
1561ebc551c0SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PC pc)
1562ebc551c0SBarry Smith {
1563ebc551c0SBarry Smith   PetscErrorCode ierr;
1564f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1565ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1566ebc551c0SBarry Smith 
1567ebc551c0SBarry Smith   PetscFunctionBegin;
1568ebc551c0SBarry Smith   ierr = PetscOptionsHead("PFMG options");CHKERRQ(ierr);
15690298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
157068326731SBarry Smith   if (flg) {
1571a0324ebeSBarry Smith     int level=3;
1572fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
157368326731SBarry Smith   }
15740298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1575fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
15760298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_num_pre_relax","Number of smoothing steps before coarse grid","HYPRE_StructPFMGSetNumPreRelax",ex->num_pre_relax,&ex->num_pre_relax,NULL);CHKERRQ(ierr);
1577fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
15780298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_num_post_relax","Number of smoothing steps after coarse grid","HYPRE_StructPFMGSetNumPostRelax",ex->num_post_relax,&ex->num_post_relax,NULL);CHKERRQ(ierr);
1579fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
15809e5bc791SBarry Smith 
15810298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
1582fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
15833b46a515SGlenn Hammond 
15840298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1585fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
15860298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_relax_type","Relax type for the up and down cycles","HYPRE_StructPFMGSetRelaxType",PFMGRelaxType,ALEN(PFMGRelaxType),PFMGRelaxType[ex->relax_type],&ex->relax_type,NULL);CHKERRQ(ierr);
1587fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
15880298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
1589fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1590ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1591ebc551c0SBarry Smith   PetscFunctionReturn(0);
1592ebc551c0SBarry Smith }
1593ebc551c0SBarry Smith 
1594f91d8e95SBarry Smith #undef __FUNCT__
1595f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1596f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1597f91d8e95SBarry Smith {
1598f91d8e95SBarry Smith   PetscErrorCode  ierr;
1599f91d8e95SBarry Smith   PC_PFMG         *ex = (PC_PFMG*) pc->data;
1600f91d8e95SBarry Smith   PetscScalar     *xx,*yy;
16014ddd07fcSJed Brown   PetscInt        ilower[3],iupper[3];
160268326731SBarry Smith   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1603f91d8e95SBarry Smith 
1604f91d8e95SBarry Smith   PetscFunctionBegin;
1605dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1606aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1607f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1608f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1609f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1610f91d8e95SBarry Smith 
1611f91d8e95SBarry Smith   /* copy x values over to hypre */
1612fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1613f91d8e95SBarry Smith   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
16148b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,xx));
1615f91d8e95SBarry Smith   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
1616fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
1617fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1618f91d8e95SBarry Smith 
1619f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1620f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
16218b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
1622f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1623f91d8e95SBarry Smith   PetscFunctionReturn(0);
1624f91d8e95SBarry Smith }
1625f91d8e95SBarry Smith 
16269e5bc791SBarry Smith #undef __FUNCT__
16279e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1628ace3abfcSBarry 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)
16299e5bc791SBarry Smith {
16309e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
16319e5bc791SBarry Smith   PetscErrorCode ierr;
16324ddd07fcSJed Brown   PetscInt       oits;
16339e5bc791SBarry Smith 
16349e5bc791SBarry Smith   PetscFunctionBegin;
1635dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1636fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1637fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
16389e5bc791SBarry Smith 
16399e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
16408b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
16419e5bc791SBarry Smith   *outits = oits;
16429e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
16439e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1644fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1645fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
16469e5bc791SBarry Smith   PetscFunctionReturn(0);
16479e5bc791SBarry Smith }
16489e5bc791SBarry Smith 
16499e5bc791SBarry Smith 
16503a32d3dbSGlenn Hammond #undef __FUNCT__
16513a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
16523a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
16533a32d3dbSGlenn Hammond {
16543a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
16553a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
16563a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1657ace3abfcSBarry Smith   PetscBool       flg;
16583a32d3dbSGlenn Hammond 
16593a32d3dbSGlenn Hammond   PetscFunctionBegin;
1660251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1661ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
16623a32d3dbSGlenn Hammond 
16633a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
16642fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1665fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
16663a32d3dbSGlenn Hammond   ierr = PCSetFromOptions_PFMG(pc);CHKERRQ(ierr);
1667fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1668fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
16693a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
16703a32d3dbSGlenn Hammond }
16713a32d3dbSGlenn Hammond 
1672ebc551c0SBarry Smith 
1673ebc551c0SBarry Smith /*MC
1674ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1675ebc551c0SBarry Smith 
1676ebc551c0SBarry Smith    Level: advanced
1677ebc551c0SBarry Smith 
16789e5bc791SBarry Smith    Options Database:
16799e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
16809e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
16819e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
16829e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
16839e5bc791SBarry 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
16849e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
1685f91d8e95SBarry Smith 
16869e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
16879e5bc791SBarry Smith 
16888e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
1689aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
16909e5bc791SBarry Smith 
16919e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
1692ebc551c0SBarry Smith M*/
1693ebc551c0SBarry Smith 
1694ebc551c0SBarry Smith #undef __FUNCT__
1695ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
16968cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
1697ebc551c0SBarry Smith {
1698ebc551c0SBarry Smith   PetscErrorCode ierr;
1699ebc551c0SBarry Smith   PC_PFMG        *ex;
1700ebc551c0SBarry Smith 
1701ebc551c0SBarry Smith   PetscFunctionBegin;
1702b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
170368326731SBarry Smith   pc->data = ex;
1704ebc551c0SBarry Smith 
17059e5bc791SBarry Smith   ex->its            = 1;
17069e5bc791SBarry Smith   ex->tol            = 1.e-8;
17079e5bc791SBarry Smith   ex->relax_type     = 1;
17089e5bc791SBarry Smith   ex->rap_type       = 0;
17099e5bc791SBarry Smith   ex->num_pre_relax  = 1;
17109e5bc791SBarry Smith   ex->num_post_relax = 1;
17113b46a515SGlenn Hammond   ex->max_levels     = 0;
17129e5bc791SBarry Smith 
1713ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
1714ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
1715ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
1716f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
17179e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
171868326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
17192fa5cd67SKarl Rupp 
1720ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
1721fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1722ebc551c0SBarry Smith   PetscFunctionReturn(0);
1723ebc551c0SBarry Smith }
1724d851a50bSGlenn Hammond 
1725325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
1726325fc9f4SBarry Smith 
1727d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
1728d851a50bSGlenn Hammond typedef struct {
1729d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
1730d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
1731d851a50bSGlenn Hammond 
1732d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
17334ddd07fcSJed Brown   PetscInt its;
1734d851a50bSGlenn Hammond   double   tol;
17354ddd07fcSJed Brown   PetscInt relax_type;
17364ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
1737d851a50bSGlenn Hammond } PC_SysPFMG;
1738d851a50bSGlenn Hammond 
1739d851a50bSGlenn Hammond #undef __FUNCT__
1740d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
1741d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
1742d851a50bSGlenn Hammond {
1743d851a50bSGlenn Hammond   PetscErrorCode ierr;
1744d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1745d851a50bSGlenn Hammond 
1746d851a50bSGlenn Hammond   PetscFunctionBegin;
17472fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1748d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1749c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1750d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1751d851a50bSGlenn Hammond }
1752d851a50bSGlenn Hammond 
1753d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
1754d851a50bSGlenn Hammond 
1755d851a50bSGlenn Hammond #undef __FUNCT__
1756d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
1757d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
1758d851a50bSGlenn Hammond {
1759d851a50bSGlenn Hammond   PetscErrorCode ierr;
1760ace3abfcSBarry Smith   PetscBool      iascii;
1761d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1762d851a50bSGlenn Hammond 
1763d851a50bSGlenn Hammond   PetscFunctionBegin;
1764251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1765d851a50bSGlenn Hammond   if (iascii) {
1766d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
1767d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
1768d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
1769d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
1770d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
1771d851a50bSGlenn Hammond   }
1772d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1773d851a50bSGlenn Hammond }
1774d851a50bSGlenn Hammond 
1775d851a50bSGlenn Hammond 
1776d851a50bSGlenn Hammond #undef __FUNCT__
1777d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
1778d851a50bSGlenn Hammond PetscErrorCode PCSetFromOptions_SysPFMG(PC pc)
1779d851a50bSGlenn Hammond {
1780d851a50bSGlenn Hammond   PetscErrorCode ierr;
1781d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1782ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1783d851a50bSGlenn Hammond 
1784d851a50bSGlenn Hammond   PetscFunctionBegin;
1785d851a50bSGlenn Hammond   ierr = PetscOptionsHead("SysPFMG options");CHKERRQ(ierr);
17860298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
1787d851a50bSGlenn Hammond   if (flg) {
1788d851a50bSGlenn Hammond     int level=3;
1789fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
1790d851a50bSGlenn Hammond   }
17910298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1792fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
17930298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_num_pre_relax","Number of smoothing steps before coarse grid","HYPRE_SStructSysPFMGSetNumPreRelax",ex->num_pre_relax,&ex->num_pre_relax,NULL);CHKERRQ(ierr);
1794fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
17950298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_num_post_relax","Number of smoothing steps after coarse grid","HYPRE_SStructSysPFMGSetNumPostRelax",ex->num_post_relax,&ex->num_post_relax,NULL);CHKERRQ(ierr);
1796fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
1797d851a50bSGlenn Hammond 
17980298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1799fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
18000298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_syspfmg_relax_type","Relax type for the up and down cycles","HYPRE_SStructSysPFMGSetRelaxType",SysPFMGRelaxType,4,SysPFMGRelaxType[ex->relax_type],&ex->relax_type,NULL);CHKERRQ(ierr);
1801fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
1802d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
1803d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1804d851a50bSGlenn Hammond }
1805d851a50bSGlenn Hammond 
1806d851a50bSGlenn Hammond #undef __FUNCT__
1807d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
1808d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
1809d851a50bSGlenn Hammond {
1810d851a50bSGlenn Hammond   PetscErrorCode   ierr;
1811d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
1812d851a50bSGlenn Hammond   PetscScalar      *xx,*yy;
18134ddd07fcSJed Brown   PetscInt         ilower[3],iupper[3];
1814d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
18154ddd07fcSJed Brown   PetscInt         ordering= mx->dofs_order;
18164ddd07fcSJed Brown   PetscInt         nvars   = mx->nvars;
18174ddd07fcSJed Brown   PetscInt         part    = 0;
18184ddd07fcSJed Brown   PetscInt         size;
18194ddd07fcSJed Brown   PetscInt         i;
1820d851a50bSGlenn Hammond 
1821d851a50bSGlenn Hammond   PetscFunctionBegin;
1822dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1823aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1824d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
1825d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
1826d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
1827d851a50bSGlenn Hammond 
1828d851a50bSGlenn Hammond   size = 1;
18292fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
18302fa5cd67SKarl Rupp 
1831d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
1832d851a50bSGlenn Hammond   if (ordering) {
1833fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
1834d851a50bSGlenn Hammond     ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
18358b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,xx+(size*i)));
1836d851a50bSGlenn Hammond     ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
1837fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
1838fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
1839fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1840d851a50bSGlenn Hammond 
1841d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
1842d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
18438b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
1844d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1845a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
1846d851a50bSGlenn Hammond     PetscScalar *z;
18474ddd07fcSJed Brown     PetscInt    j, k;
1848d851a50bSGlenn Hammond 
1849785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
1850fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
1851d851a50bSGlenn Hammond     ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
1852d851a50bSGlenn Hammond 
1853d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
1854d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
1855d851a50bSGlenn Hammond       k= i*nvars;
18562fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
1857d851a50bSGlenn Hammond     }
18588b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
1859d851a50bSGlenn Hammond     ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
1860fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
1861fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1862d851a50bSGlenn Hammond 
1863d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
1864d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
18658b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
1866d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
1867d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
1868d851a50bSGlenn Hammond       k= i*nvars;
18692fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
1870d851a50bSGlenn Hammond     }
1871d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1872d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
1873d851a50bSGlenn Hammond   }
1874d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1875d851a50bSGlenn Hammond }
1876d851a50bSGlenn Hammond 
1877d851a50bSGlenn Hammond #undef __FUNCT__
1878d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
1879ace3abfcSBarry 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)
1880d851a50bSGlenn Hammond {
1881d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
1882d851a50bSGlenn Hammond   PetscErrorCode ierr;
18834ddd07fcSJed Brown   PetscInt       oits;
1884d851a50bSGlenn Hammond 
1885d851a50bSGlenn Hammond   PetscFunctionBegin;
1886dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1887fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
1888fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
1889d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
18908b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
1891d851a50bSGlenn Hammond   *outits = oits;
1892d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
1893d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1894fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
1895fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
1896d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1897d851a50bSGlenn Hammond }
1898d851a50bSGlenn Hammond 
1899d851a50bSGlenn Hammond 
1900d851a50bSGlenn Hammond #undef __FUNCT__
1901d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
1902d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
1903d851a50bSGlenn Hammond {
1904d851a50bSGlenn Hammond   PetscErrorCode   ierr;
1905d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
1906d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
1907ace3abfcSBarry Smith   PetscBool        flg;
1908d851a50bSGlenn Hammond 
1909d851a50bSGlenn Hammond   PetscFunctionBegin;
1910251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
1911ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
1912d851a50bSGlenn Hammond 
1913d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
19142fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1915fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
1916d851a50bSGlenn Hammond   ierr = PCSetFromOptions_SysPFMG(pc);CHKERRQ(ierr);
1917fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
1918fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1919d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1920d851a50bSGlenn Hammond }
1921d851a50bSGlenn Hammond 
1922d851a50bSGlenn Hammond 
1923d851a50bSGlenn Hammond /*MC
1924d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
1925d851a50bSGlenn Hammond 
1926d851a50bSGlenn Hammond    Level: advanced
1927d851a50bSGlenn Hammond 
1928d851a50bSGlenn Hammond    Options Database:
1929d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
1930d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
1931d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
1932d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
1933d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
1934d851a50bSGlenn Hammond 
1935d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
1936d851a50bSGlenn Hammond 
1937f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
1938aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
1939d851a50bSGlenn Hammond            Also, only cell-centered variables.
1940d851a50bSGlenn Hammond 
1941d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
1942d851a50bSGlenn Hammond M*/
1943d851a50bSGlenn Hammond 
1944d851a50bSGlenn Hammond #undef __FUNCT__
1945d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
19468cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
1947d851a50bSGlenn Hammond {
1948d851a50bSGlenn Hammond   PetscErrorCode ierr;
1949d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
1950d851a50bSGlenn Hammond 
1951d851a50bSGlenn Hammond   PetscFunctionBegin;
1952b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
1953d851a50bSGlenn Hammond   pc->data = ex;
1954d851a50bSGlenn Hammond 
1955d851a50bSGlenn Hammond   ex->its            = 1;
1956d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
1957d851a50bSGlenn Hammond   ex->relax_type     = 1;
1958d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
1959d851a50bSGlenn Hammond   ex->num_post_relax = 1;
1960d851a50bSGlenn Hammond 
1961d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
1962d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
1963d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
1964d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
1965d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
1966d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
19672fa5cd67SKarl Rupp 
1968ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
1969fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
1970d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1971d851a50bSGlenn Hammond }
1972