xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 12ddd1b61b070a8d32973724a83c9dbcd79b7f5e)
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>
104cb006feSStefano 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;
754cb006feSStefano Zampini 
764cb006feSStefano Zampini   /* options for AMS */
774cb006feSStefano Zampini   PetscInt  ams_print;
784cb006feSStefano Zampini   PetscInt  ams_max_iter;
794cb006feSStefano Zampini   PetscInt  ams_cycle_type;
804cb006feSStefano Zampini   PetscReal ams_tol;
814cb006feSStefano Zampini   PetscInt  ams_relax_type;
824cb006feSStefano Zampini   PetscInt  ams_relax_times;
834cb006feSStefano Zampini   PetscReal ams_relax_weight;
844cb006feSStefano Zampini   PetscReal ams_omega;
854cb006feSStefano Zampini   PetscInt  ams_amg_alpha_opts[5]; /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for vector Poisson */
864cb006feSStefano Zampini   PetscReal ams_amg_alpha_theta;   /* AMG strength for vector Poisson */
874cb006feSStefano Zampini   PetscInt  ams_amg_beta_opts[5];  /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for scalar Poisson */
884cb006feSStefano Zampini   PetscReal ams_amg_beta_theta;    /* AMG strength for scalar Poisson */
894cb006feSStefano Zampini 
904cb006feSStefano Zampini   /* additional data */
914cb006feSStefano Zampini   HYPRE_IJVector coords[3];
924cb006feSStefano Zampini   HYPRE_IJVector constants[3];
934cb006feSStefano Zampini   HYPRE_IJMatrix G;
944cb006feSStefano Zampini   HYPRE_IJMatrix alpha_Poisson;
954cb006feSStefano Zampini   HYPRE_IJMatrix beta_Poisson;
964cb006feSStefano 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));
1514cb006feSStefano Zampini   }
1524cb006feSStefano Zampini   /* special case for AMS */
1534cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
1544cb006feSStefano 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()");
1554cb006feSStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
1564cb006feSStefano 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));
2224cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
2234cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
2244cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
2254cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
2264cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
2274cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
2284cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
2294cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
2304cb006feSStefano 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);
2394cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
2404cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
2414cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
2424cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",NULL);CHKERRQ(ierr);
2434cb006feSStefano 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 }
7734cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
7744cb006feSStefano Zampini #undef __FUNCT__
7754cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS"
7764cb006feSStefano Zampini static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PC pc)
7774cb006feSStefano Zampini {
7784cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
7794cb006feSStefano Zampini   PetscErrorCode ierr;
7804cb006feSStefano Zampini   PetscInt       n;
7814cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
7824cb006feSStefano Zampini 
7834cb006feSStefano Zampini   PetscFunctionBegin;
7844cb006feSStefano Zampini   ierr = PetscOptionsHead("HYPRE AMS Options");CHKERRQ(ierr);
7854cb006feSStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->ams_print,&jac->ams_print,&flag);CHKERRQ(ierr);
7864cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->ams_print));
7874cb006feSStefano 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);
7884cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->ams_max_iter));
7894cb006feSStefano 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);
7904cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
7914cb006feSStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->ams_tol,&jac->ams_tol,&flag);CHKERRQ(ierr);
7924cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->ams_tol));
7934cb006feSStefano 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);
7944cb006feSStefano 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);
7954cb006feSStefano 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);
7964cb006feSStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->ams_omega,&jac->ams_omega,&flag4);CHKERRQ(ierr);
7974cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
7984cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->ams_relax_type,
7994cb006feSStefano Zampini                                                                       jac->ams_relax_times,
8004cb006feSStefano Zampini                                                                       jac->ams_relax_weight,
8014cb006feSStefano Zampini                                                                       jac->ams_omega));
8024cb006feSStefano Zampini   }
8034cb006feSStefano 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);
8044cb006feSStefano Zampini   n = 5;
8054cb006feSStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->ams_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
8064cb006feSStefano Zampini   if (flag || flag2) {
8074cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->ams_amg_alpha_opts[0],       /* AMG coarsen type */
8084cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[1],       /* AMG agg_levels */
8094cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[2],       /* AMG relax_type */
8104cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_theta,
8114cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[3],       /* AMG interp_type */
8124cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[4]));     /* AMG Pmax */
8134cb006feSStefano Zampini   }
8144cb006feSStefano 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);
8154cb006feSStefano Zampini   n = 5;
8164cb006feSStefano 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);
8174cb006feSStefano Zampini   if (flag || flag2) {
8184cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->ams_amg_beta_opts[0],       /* AMG coarsen type */
8194cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[1],       /* AMG agg_levels */
8204cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[2],       /* AMG relax_type */
8214cb006feSStefano Zampini                                                                     jac->ams_amg_beta_theta,
8224cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[3],       /* AMG interp_type */
8234cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[4]));     /* AMG Pmax */
8244cb006feSStefano Zampini   }
8254cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
8264cb006feSStefano Zampini   PetscFunctionReturn(0);
8274cb006feSStefano Zampini }
8284cb006feSStefano Zampini 
8294cb006feSStefano Zampini #undef __FUNCT__
8304cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS"
8314cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
8324cb006feSStefano Zampini {
8334cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
8344cb006feSStefano Zampini   PetscErrorCode ierr;
8354cb006feSStefano Zampini   PetscBool      iascii;
8364cb006feSStefano Zampini 
8374cb006feSStefano Zampini   PetscFunctionBegin;
8384cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
8394cb006feSStefano Zampini   if (iascii) {
8404cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
8414cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iterations per application %d\n",jac->ams_max_iter);CHKERRQ(ierr);
8424cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
8434cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iteration tolerance %g\n",jac->ams_tol);CHKERRQ(ierr);
8444cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother type %d\n",jac->ams_relax_type);CHKERRQ(ierr);
8454cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: number of smoothing steps %d\n",jac->ams_relax_times);CHKERRQ(ierr);
8464cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother weight %g\n",jac->ams_relax_weight);CHKERRQ(ierr);
8474cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother omega %g\n",jac->ams_omega);CHKERRQ(ierr);
8484cb006feSStefano Zampini     if (jac->alpha_Poisson) {
8494cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8504cb006feSStefano Zampini     } else {
8514cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr);
8524cb006feSStefano Zampini     }
8534cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->ams_amg_alpha_opts[0]);CHKERRQ(ierr);
8544cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->ams_amg_alpha_opts[1]);CHKERRQ(ierr);
8554cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->ams_amg_alpha_opts[2]);CHKERRQ(ierr);
8564cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->ams_amg_alpha_opts[3]);CHKERRQ(ierr);
8574cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->ams_amg_alpha_opts[4]);CHKERRQ(ierr);
8584cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->ams_amg_alpha_theta);CHKERRQ(ierr);
8594cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
8604cb006feSStefano Zampini       if (jac->beta_Poisson) {
8614cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8624cb006feSStefano Zampini       } else {
8634cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr);
8644cb006feSStefano Zampini       }
8654cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->ams_amg_beta_opts[0]);CHKERRQ(ierr);
8664cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->ams_amg_beta_opts[1]);CHKERRQ(ierr);
8674cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->ams_amg_beta_opts[2]);CHKERRQ(ierr);
8684cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->ams_amg_beta_opts[3]);CHKERRQ(ierr);
8694cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->ams_amg_beta_opts[4]);CHKERRQ(ierr);
8704cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->ams_amg_beta_theta);CHKERRQ(ierr);
8714cb006feSStefano Zampini     }
8724cb006feSStefano Zampini   }
8734cb006feSStefano Zampini   PetscFunctionReturn(0);
8744cb006feSStefano Zampini }
8754cb006feSStefano Zampini 
8764cb006feSStefano Zampini #undef __FUNCT__
8774cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE_AMS"
8784cb006feSStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE_AMS(PC pc, Mat G)
8794cb006feSStefano Zampini {
8804cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
8814cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_G;
8824cb006feSStefano Zampini   PetscErrorCode     ierr;
8834cb006feSStefano Zampini 
8844cb006feSStefano Zampini   PetscFunctionBegin;
8854cb006feSStefano Zampini   /* throw away any discrete gradient if already set */
8864cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
8874cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(G,&jac->G);CHKERRQ(ierr);
8884cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(G,jac->G);CHKERRQ(ierr);
8894cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->G,(void**)(&parcsr_G)));
8904cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr_G));
8914cb006feSStefano Zampini   PetscFunctionReturn(0);
8924cb006feSStefano Zampini }
8934cb006feSStefano Zampini 
8944cb006feSStefano Zampini #undef __FUNCT__
8954cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient"
8964cb006feSStefano Zampini /*@
8974cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
8984cb006feSStefano Zampini 
8994cb006feSStefano Zampini    Collective on PC
9004cb006feSStefano Zampini 
9014cb006feSStefano Zampini    Input Parameters:
9024cb006feSStefano Zampini +  pc - the preconditioning context
9034cb006feSStefano Zampini -  G - the discrete gradient
9044cb006feSStefano Zampini 
9054cb006feSStefano Zampini    Level: intermediate
9064cb006feSStefano Zampini 
9074cb006feSStefano 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
9084cb006feSStefano 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
9094cb006feSStefano Zampini 
9104cb006feSStefano Zampini .seealso:
9114cb006feSStefano Zampini @*/
9124cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
9134cb006feSStefano Zampini {
9144cb006feSStefano Zampini   PetscErrorCode ierr;
9154cb006feSStefano Zampini 
9164cb006feSStefano Zampini   PetscFunctionBegin;
9174cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
9184cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
9194cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
9204cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
9214cb006feSStefano Zampini   PetscFunctionReturn(0);
9224cb006feSStefano Zampini }
9234cb006feSStefano Zampini 
9244cb006feSStefano Zampini #undef __FUNCT__
9254cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS"
9264cb006feSStefano Zampini static PetscErrorCode PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
9274cb006feSStefano Zampini {
9284cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
9294cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_alpha_Poisson;
9304cb006feSStefano Zampini   PetscErrorCode     ierr;
9314cb006feSStefano Zampini 
9324cb006feSStefano Zampini   PetscFunctionBegin;
9334cb006feSStefano Zampini   /* throw away any matrix if already set */
9344cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
9354cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->alpha_Poisson);CHKERRQ(ierr);
9364cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->alpha_Poisson);CHKERRQ(ierr);
9374cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->alpha_Poisson,(void**)(&parcsr_alpha_Poisson)));
9384cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr_alpha_Poisson));
9394cb006feSStefano Zampini   PetscFunctionReturn(0);
9404cb006feSStefano Zampini }
9414cb006feSStefano Zampini 
9424cb006feSStefano Zampini #undef __FUNCT__
9434cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix"
9444cb006feSStefano Zampini /*@
9454cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
9464cb006feSStefano Zampini 
9474cb006feSStefano Zampini    Collective on PC
9484cb006feSStefano Zampini 
9494cb006feSStefano Zampini    Input Parameters:
9504cb006feSStefano Zampini +  pc - the preconditioning context
9514cb006feSStefano Zampini -  A - the matrix
9524cb006feSStefano Zampini 
9534cb006feSStefano Zampini    Level: intermediate
9544cb006feSStefano Zampini 
9554cb006feSStefano Zampini    Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
9564cb006feSStefano Zampini 
9574cb006feSStefano Zampini .seealso:
9584cb006feSStefano Zampini @*/
9594cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
9604cb006feSStefano Zampini {
9614cb006feSStefano Zampini   PetscErrorCode ierr;
9624cb006feSStefano Zampini 
9634cb006feSStefano Zampini   PetscFunctionBegin;
9644cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
9654cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
9664cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
9674cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetAlphaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
9684cb006feSStefano Zampini   PetscFunctionReturn(0);
9694cb006feSStefano Zampini }
9704cb006feSStefano Zampini 
9714cb006feSStefano Zampini #undef __FUNCT__
9724cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix_HYPRE_AMS"
9734cb006feSStefano Zampini static PetscErrorCode PCHYPRESetBetaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
9744cb006feSStefano Zampini {
9754cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
9764cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_beta_Poisson;
9774cb006feSStefano Zampini   PetscErrorCode     ierr;
9784cb006feSStefano Zampini 
9794cb006feSStefano Zampini   PetscFunctionBegin;
9804cb006feSStefano Zampini   if (!A) {
9814cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_TRUE;
9824cb006feSStefano Zampini     PetscFunctionReturn(0);
9834cb006feSStefano Zampini   }
9844cb006feSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
9854cb006feSStefano Zampini   /* throw away any matrix if already set */
9864cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
9874cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->beta_Poisson);CHKERRQ(ierr);
9884cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->beta_Poisson);CHKERRQ(ierr);
9894cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->beta_Poisson,(void**)(&parcsr_beta_Poisson)));
9904cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr_beta_Poisson));
9914cb006feSStefano Zampini   PetscFunctionReturn(0);
9924cb006feSStefano Zampini }
9934cb006feSStefano Zampini 
9944cb006feSStefano Zampini #undef __FUNCT__
9954cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix"
9964cb006feSStefano Zampini /*@
9974cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
9984cb006feSStefano Zampini 
9994cb006feSStefano Zampini    Collective on PC
10004cb006feSStefano Zampini 
10014cb006feSStefano Zampini    Input Parameters:
10024cb006feSStefano Zampini +  pc - the preconditioning context
10034cb006feSStefano Zampini -  A - the matrix
10044cb006feSStefano Zampini 
10054cb006feSStefano Zampini    Level: intermediate
10064cb006feSStefano Zampini 
10074cb006feSStefano Zampini    Notes: A should be obtained by discretizing the Poisson problem with linear finite elements.
10084cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
10094cb006feSStefano Zampini 
10104cb006feSStefano Zampini .seealso:
10114cb006feSStefano Zampini @*/
10124cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
10134cb006feSStefano Zampini {
10144cb006feSStefano Zampini   PetscErrorCode ierr;
10154cb006feSStefano Zampini 
10164cb006feSStefano Zampini   PetscFunctionBegin;
10174cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
10184cb006feSStefano Zampini   if (A) {
10194cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
10204cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
10214cb006feSStefano Zampini   }
10224cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetBetaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
10234cb006feSStefano Zampini   PetscFunctionReturn(0);
10244cb006feSStefano Zampini }
10254cb006feSStefano Zampini 
10264cb006feSStefano Zampini #undef __FUNCT__
10274cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE_AMS"
10284cb006feSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE_AMS(PC pc,Vec ozz, Vec zoz, Vec zzo)
10294cb006feSStefano Zampini {
10304cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
10314cb006feSStefano Zampini   HYPRE_ParVector    par_ozz,par_zoz,par_zzo;
1032*12ddd1b6SStefano Zampini   PetscInt           dim;
10334cb006feSStefano Zampini   PetscErrorCode     ierr;
10344cb006feSStefano Zampini 
10354cb006feSStefano Zampini   PetscFunctionBegin;
10364cb006feSStefano Zampini   /* throw away any vector if already set */
10374cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
10384cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
10394cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
10404cb006feSStefano Zampini   jac->constants[0] = NULL;
10414cb006feSStefano Zampini   jac->constants[1] = NULL;
10424cb006feSStefano Zampini   jac->constants[2] = NULL;
10434cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
10444cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
10454cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&par_ozz)));
10464cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
10474cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
10484cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&par_zoz)));
1049*12ddd1b6SStefano Zampini   dim = 2;
10504cb006feSStefano Zampini   if (zzo) {
10514cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
10524cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
10534cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&par_zzo)));
1054*12ddd1b6SStefano Zampini     dim++;
10554cb006feSStefano Zampini   }
10564cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,par_ozz,par_zoz,par_zzo));
1057*12ddd1b6SStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim));
10584cb006feSStefano Zampini   PetscFunctionReturn(0);
10594cb006feSStefano Zampini }
10604cb006feSStefano Zampini 
10614cb006feSStefano Zampini #undef __FUNCT__
10624cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors"
10634cb006feSStefano Zampini /*@
10644cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
10654cb006feSStefano Zampini 
10664cb006feSStefano Zampini    Collective on PC
10674cb006feSStefano Zampini 
10684cb006feSStefano Zampini    Input Parameters:
10694cb006feSStefano Zampini +  pc - the preconditioning context
10704cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
10714cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
10724cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
10734cb006feSStefano Zampini 
10744cb006feSStefano Zampini    Level: intermediate
10754cb006feSStefano Zampini 
10764cb006feSStefano Zampini    Notes:
10774cb006feSStefano Zampini 
10784cb006feSStefano Zampini .seealso:
10794cb006feSStefano Zampini @*/
10804cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
10814cb006feSStefano Zampini {
10824cb006feSStefano Zampini   PetscErrorCode ierr;
10834cb006feSStefano Zampini 
10844cb006feSStefano Zampini   PetscFunctionBegin;
10854cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
10864cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
10874cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
10884cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
10894cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
10904cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
10914cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
10924cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
10934cb006feSStefano Zampini   PetscFunctionReturn(0);
10944cb006feSStefano Zampini }
10954cb006feSStefano Zampini 
10964cb006feSStefano Zampini #undef __FUNCT__
10974cb006feSStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE_AMS"
10984cb006feSStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE_AMS(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
10994cb006feSStefano Zampini {
11004cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
11014cb006feSStefano Zampini   Vec             tv;
11024cb006feSStefano Zampini   HYPRE_ParVector par_coords[3];
11034cb006feSStefano Zampini   PetscInt        i;
11044cb006feSStefano Zampini   PetscErrorCode  ierr;
11054cb006feSStefano Zampini 
11064cb006feSStefano Zampini   PetscFunctionBegin;
11074cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
11084cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
11094cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
11104cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
11114cb006feSStefano Zampini   /* set problem's dimension */
11124cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim));
11134cb006feSStefano Zampini   /* compute IJ vector for coordinates */
11144cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
11154cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
11164cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
11174cb006feSStefano Zampini   for (i=0;i<dim;i++) {
11184cb006feSStefano Zampini     PetscScalar *array;
11194cb006feSStefano Zampini     PetscInt    j;
11204cb006feSStefano Zampini 
11214cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
11224cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
11234cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
11244cb006feSStefano Zampini       array[j] = coords[j*dim+i];
11254cb006feSStefano Zampini     }
11264cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
11274cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
11284cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
11294cb006feSStefano Zampini   }
11304cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
11314cb006feSStefano Zampini   /* pass parCSR vectors to AMS solver */
11324cb006feSStefano Zampini   par_coords[0] = NULL;
11334cb006feSStefano Zampini   par_coords[1] = NULL;
11344cb006feSStefano Zampini   par_coords[2] = NULL;
11354cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&par_coords[0])));
11364cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&par_coords[1])));
11374cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&par_coords[2])));
11384cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,par_coords[0],par_coords[1],par_coords[2]));
11394cb006feSStefano Zampini   PetscFunctionReturn(0);
11404cb006feSStefano Zampini }
11414cb006feSStefano Zampini 
114216d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
114316d9e3a6SLisandro Dalcin 
114416d9e3a6SLisandro Dalcin #undef __FUNCT__
114516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
1146f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
114716d9e3a6SLisandro Dalcin {
114816d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
114916d9e3a6SLisandro Dalcin 
115016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
115116d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
115216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
115316d9e3a6SLisandro Dalcin }
115416d9e3a6SLisandro Dalcin 
115516d9e3a6SLisandro Dalcin #undef __FUNCT__
115616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
1157f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
115816d9e3a6SLisandro Dalcin {
115916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
116016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1161ace3abfcSBarry Smith   PetscBool      flag;
116216d9e3a6SLisandro Dalcin 
116316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
116416d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
116516d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1166ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
116716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
116816d9e3a6SLisandro Dalcin   } else {
116916d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
117016d9e3a6SLisandro Dalcin   }
117116d9e3a6SLisandro Dalcin 
117216d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
117316d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
117416d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
117516d9e3a6SLisandro Dalcin 
117616d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
117716d9e3a6SLisandro Dalcin   if (flag) {
1178fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
117916d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
118016d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
118116d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
118216d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
118316d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
118416d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
118516d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
118616d9e3a6SLisandro Dalcin   }
118716d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
118816d9e3a6SLisandro Dalcin   if (flag) {
1189fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
119016d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
119116d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
119216d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
119316d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
119416d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
119516d9e3a6SLisandro Dalcin     /* initialize */
119616d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
119716d9e3a6SLisandro Dalcin     jac->threshhold = .1;
119816d9e3a6SLisandro Dalcin     jac->filter     = .1;
119916d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
12002fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
12012fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
12022fa5cd67SKarl Rupp 
120316d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
120416d9e3a6SLisandro Dalcin     jac->symt = 0;
1205fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1206fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1207fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1208fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1209fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1210fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
121116d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
121216d9e3a6SLisandro Dalcin   }
121316d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("euclid",jac->hypre_type,&flag);CHKERRQ(ierr);
121416d9e3a6SLisandro Dalcin   if (flag) {
121516d9e3a6SLisandro Dalcin     ierr                    = HYPRE_EuclidCreate(jac->comm_hypre,&jac->hsolver);
121616d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
121716d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Euclid;
121816d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_EuclidDestroy;
121916d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_EuclidSetup;
122016d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_EuclidSolve;
122116d9e3a6SLisandro Dalcin     /* initialization */
122216d9e3a6SLisandro Dalcin     jac->bjilu              = PETSC_FALSE;
122316d9e3a6SLisandro Dalcin     jac->levels             = 1;
122416d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
122516d9e3a6SLisandro Dalcin   }
122616d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
122716d9e3a6SLisandro Dalcin   if (flag) {
122816d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
122916d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
123016d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
123116d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
123216d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
123316d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
123416d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
123516d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
123616d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
123716d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
123816d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
123916d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
124016d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
12418f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
124216d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
124316d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
124416d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
124516d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
124616d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
12470f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
12488f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
12490f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
125016d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
125116d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
125216d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
12530f1074feSSatish Balay     jac->interptype       = 0;
12540f1074feSSatish Balay     jac->agg_nl           = 0;
12550f1074feSSatish Balay     jac->pmax             = 0;
12560f1074feSSatish Balay     jac->truncfactor      = 0.0;
12570f1074feSSatish Balay     jac->agg_num_paths    = 1;
12588f87f92bSBarry Smith 
12598f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
12608f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
12618f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1262fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1263fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1264fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1265fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1266fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1267fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1268fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1269fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1270fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1271fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1272fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1273fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1274fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1275fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1276fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1277fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
127816d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
127916d9e3a6SLisandro Dalcin   }
12804cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
12814cb006feSStefano Zampini   if (flag) {
12824cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
12834cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
12844cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
12854cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
12864cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
12874cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
12884cb006feSStefano Zampini     jac->coords[0]           = NULL;
12894cb006feSStefano Zampini     jac->coords[1]           = NULL;
12904cb006feSStefano Zampini     jac->coords[2]           = NULL;
12914cb006feSStefano Zampini     jac->G                   = NULL;
12924cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
12934cb006feSStefano Zampini     jac->ams_print           = 0;
12944cb006feSStefano Zampini     jac->ams_max_iter        = 1; /* used as a preconditioner */
12954cb006feSStefano Zampini     jac->ams_cycle_type      = 13;
12964cb006feSStefano Zampini     jac->ams_tol             = 0.; /* used as a preconditioner */
12974cb006feSStefano Zampini     /* Smoothing options */
12984cb006feSStefano Zampini     jac->ams_relax_type      = 2;
12994cb006feSStefano Zampini     jac->ams_relax_times     = 1;
13004cb006feSStefano Zampini     jac->ams_relax_weight    = 1.0;
13014cb006feSStefano Zampini     jac->ams_omega           = 1.0;
13024cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
13034cb006feSStefano Zampini     jac->ams_amg_alpha_opts[0] = 10;
13044cb006feSStefano Zampini     jac->ams_amg_alpha_opts[1] = 1;
13054cb006feSStefano Zampini     jac->ams_amg_alpha_opts[2] = 8;
13064cb006feSStefano Zampini     jac->ams_amg_alpha_opts[3] = 6;
13074cb006feSStefano Zampini     jac->ams_amg_alpha_opts[4] = 4;
13084cb006feSStefano Zampini     jac->ams_amg_alpha_theta   = 0.25;
13094cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
13104cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_FALSE;
13114cb006feSStefano Zampini     jac->ams_amg_beta_opts[0] = 10;
13124cb006feSStefano Zampini     jac->ams_amg_beta_opts[1] = 1;
13134cb006feSStefano Zampini     jac->ams_amg_beta_opts[2] = 8;
13144cb006feSStefano Zampini     jac->ams_amg_beta_opts[3] = 6;
13154cb006feSStefano Zampini     jac->ams_amg_beta_opts[4] = 4;
13164cb006feSStefano Zampini     jac->ams_amg_beta_theta   = 0.25;
13174cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->ams_print));
13184cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->ams_max_iter));
13194cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
13204cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->ams_tol));
13214cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->ams_relax_type,
13224cb006feSStefano Zampini                                                                       jac->ams_relax_times,
13234cb006feSStefano Zampini                                                                       jac->ams_relax_weight,
13244cb006feSStefano Zampini                                                                       jac->ams_omega));
13254cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->ams_amg_alpha_opts[0],       /* AMG coarsen type */
13264cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[1],       /* AMG agg_levels */
13274cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[2],       /* AMG relax_type */
13284cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_theta,
13294cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[3],       /* AMG interp_type */
13304cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[4]));     /* AMG Pmax */
13314cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->ams_amg_beta_opts[0],       /* AMG coarsen type */
13324cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[1],       /* AMG agg_levels */
13334cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[2],       /* AMG relax_type */
13344cb006feSStefano Zampini                                                                     jac->ams_amg_beta_theta,
13354cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[3],       /* AMG interp_type */
13364cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[4]));     /* AMG Pmax */
13374cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE_AMS);CHKERRQ(ierr);
13384cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE_AMS);CHKERRQ(ierr);
13394cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE_AMS);CHKERRQ(ierr);
13404cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
13414cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",PCHYPRESetBetaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
13424cb006feSStefano Zampini     PetscFunctionReturn(0);
13434cb006feSStefano Zampini   }
1344503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
13452fa5cd67SKarl Rupp 
13460298fd71SBarry Smith   jac->hypre_type = NULL;
13474cb006feSStefano Zampini   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, euclid, boomeramg, ams",name);
134816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
134916d9e3a6SLisandro Dalcin }
135016d9e3a6SLisandro Dalcin 
135116d9e3a6SLisandro Dalcin /*
135216d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
135316d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
135416d9e3a6SLisandro Dalcin */
135516d9e3a6SLisandro Dalcin #undef __FUNCT__
135616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
135716d9e3a6SLisandro Dalcin static PetscErrorCode PCSetFromOptions_HYPRE(PC pc)
135816d9e3a6SLisandro Dalcin {
135916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
13604ddd07fcSJed Brown   PetscInt       indx;
13614cb006feSStefano Zampini   const char     *type[] = {"pilut","parasails","boomeramg","euclid","ams"};
1362ace3abfcSBarry Smith   PetscBool      flg;
136316d9e3a6SLisandro Dalcin 
136416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
136516d9e3a6SLisandro Dalcin   ierr = PetscOptionsHead("HYPRE preconditioner options");CHKERRQ(ierr);
13664cb006feSStefano Zampini   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,5,"boomeramg",&indx,&flg);CHKERRQ(ierr);
136716d9e3a6SLisandro Dalcin   if (flg) {
136816d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
136902a17cd4SBarry Smith   } else {
137002a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
137116d9e3a6SLisandro Dalcin   }
137216d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
137316d9e3a6SLisandro Dalcin     ierr = pc->ops->setfromoptions(pc);CHKERRQ(ierr);
137416d9e3a6SLisandro Dalcin   }
137516d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
137616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
137716d9e3a6SLisandro Dalcin }
137816d9e3a6SLisandro Dalcin 
137916d9e3a6SLisandro Dalcin #undef __FUNCT__
138016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
138116d9e3a6SLisandro Dalcin /*@C
138216d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
138316d9e3a6SLisandro Dalcin 
138416d9e3a6SLisandro Dalcin    Input Parameters:
138516d9e3a6SLisandro Dalcin +     pc - the preconditioner context
13864cb006feSStefano Zampini -     name - either  pilut, parasails, boomeramg, euclid, ams
138716d9e3a6SLisandro Dalcin 
138816d9e3a6SLisandro Dalcin    Options Database Keys:
13894cb006feSStefano Zampini    -pc_hypre_type - One of pilut, parasails, boomeramg, euclid, ams
139016d9e3a6SLisandro Dalcin 
139116d9e3a6SLisandro Dalcin    Level: intermediate
139216d9e3a6SLisandro Dalcin 
139316d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
139416d9e3a6SLisandro Dalcin            PCHYPRE
139516d9e3a6SLisandro Dalcin 
139616d9e3a6SLisandro Dalcin @*/
13977087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
139816d9e3a6SLisandro Dalcin {
13994ac538c5SBarry Smith   PetscErrorCode ierr;
140016d9e3a6SLisandro Dalcin 
140116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
14020700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
140316d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
14044ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
140516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
140616d9e3a6SLisandro Dalcin }
140716d9e3a6SLisandro Dalcin 
140816d9e3a6SLisandro Dalcin #undef __FUNCT__
140916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
141016d9e3a6SLisandro Dalcin /*@C
141116d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
141216d9e3a6SLisandro Dalcin 
141316d9e3a6SLisandro Dalcin    Input Parameter:
141416d9e3a6SLisandro Dalcin .     pc - the preconditioner context
141516d9e3a6SLisandro Dalcin 
141616d9e3a6SLisandro Dalcin    Output Parameter:
14174cb006feSStefano Zampini .     name - either  pilut, parasails, boomeramg, euclid, ams
141816d9e3a6SLisandro Dalcin 
141916d9e3a6SLisandro Dalcin    Level: intermediate
142016d9e3a6SLisandro Dalcin 
142116d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
142216d9e3a6SLisandro Dalcin            PCHYPRE
142316d9e3a6SLisandro Dalcin 
142416d9e3a6SLisandro Dalcin @*/
14257087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
142616d9e3a6SLisandro Dalcin {
14274ac538c5SBarry Smith   PetscErrorCode ierr;
142816d9e3a6SLisandro Dalcin 
142916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
14300700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
143116d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
14324ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
143316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
143416d9e3a6SLisandro Dalcin }
143516d9e3a6SLisandro Dalcin 
143616d9e3a6SLisandro Dalcin /*MC
143716d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
143816d9e3a6SLisandro Dalcin 
143916d9e3a6SLisandro Dalcin    Options Database Keys:
14404cb006feSStefano Zampini +   -pc_hypre_type - One of pilut, parasails, boomeramg, euclid, ams
144116d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
144216d9e3a6SLisandro Dalcin           preconditioner
144316d9e3a6SLisandro Dalcin 
144416d9e3a6SLisandro Dalcin    Level: intermediate
144516d9e3a6SLisandro Dalcin 
144616d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
144716d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
144816d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
144916d9e3a6SLisandro Dalcin 
145016d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
14510f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
14520f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
14530f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
14548f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
14550f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
14560f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
145716d9e3a6SLisandro Dalcin 
14580f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
14590f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
14600f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
146116d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
146216d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
146316d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
146416d9e3a6SLisandro Dalcin 
146516d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
146616d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
146716d9e3a6SLisandro Dalcin 
14689e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
14699e5bc791SBarry Smith 
147016d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
14719e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
147216d9e3a6SLisandro Dalcin 
147316d9e3a6SLisandro Dalcin M*/
147416d9e3a6SLisandro Dalcin 
147516d9e3a6SLisandro Dalcin #undef __FUNCT__
147616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
14778cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
147816d9e3a6SLisandro Dalcin {
147916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
148016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
148116d9e3a6SLisandro Dalcin 
148216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1483b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
14842fa5cd67SKarl Rupp 
148516d9e3a6SLisandro Dalcin   pc->data                = jac;
148616d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
148716d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
148816d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
148916d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
149016d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
14910298fd71SBarry Smith   jac->hypre_type         = NULL;
14924cb006feSStefano Zampini   jac->coords[0]          = NULL;
14934cb006feSStefano Zampini   jac->coords[1]          = NULL;
14944cb006feSStefano Zampini   jac->coords[2]          = NULL;
14954cb006feSStefano Zampini   jac->constants[0]       = NULL;
14964cb006feSStefano Zampini   jac->constants[1]       = NULL;
14974cb006feSStefano Zampini   jac->constants[2]       = NULL;
149816d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1499ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1500bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1501bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
150216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
150316d9e3a6SLisandro Dalcin }
1504ebc551c0SBarry Smith 
1505f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1506f91d8e95SBarry Smith 
1507b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1508b45d2f2cSJed Brown #include <petsc-private/matimpl.h>
1509ebc551c0SBarry Smith 
1510ebc551c0SBarry Smith typedef struct {
151168326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1512f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
15139e5bc791SBarry Smith 
15149e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
15154ddd07fcSJed Brown   PetscInt its;
15169e5bc791SBarry Smith   double   tol;
15174ddd07fcSJed Brown   PetscInt relax_type;
15184ddd07fcSJed Brown   PetscInt rap_type;
15194ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
15204ddd07fcSJed Brown   PetscInt max_levels;
1521ebc551c0SBarry Smith } PC_PFMG;
1522ebc551c0SBarry Smith 
1523ebc551c0SBarry Smith #undef __FUNCT__
1524ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1525ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1526ebc551c0SBarry Smith {
1527ebc551c0SBarry Smith   PetscErrorCode ierr;
1528f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1529ebc551c0SBarry Smith 
1530ebc551c0SBarry Smith   PetscFunctionBegin;
15312fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1532f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1533c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1534ebc551c0SBarry Smith   PetscFunctionReturn(0);
1535ebc551c0SBarry Smith }
1536ebc551c0SBarry Smith 
15379e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
15389e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
15399e5bc791SBarry Smith 
1540ebc551c0SBarry Smith #undef __FUNCT__
1541ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1542ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1543ebc551c0SBarry Smith {
1544ebc551c0SBarry Smith   PetscErrorCode ierr;
1545ace3abfcSBarry Smith   PetscBool      iascii;
1546f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1547ebc551c0SBarry Smith 
1548ebc551c0SBarry Smith   PetscFunctionBegin;
1549251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
15509e5bc791SBarry Smith   if (iascii) {
15519e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
15529e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
15539e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
15549e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
15559e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
15569e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
15573b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
15589e5bc791SBarry Smith   }
1559ebc551c0SBarry Smith   PetscFunctionReturn(0);
1560ebc551c0SBarry Smith }
1561ebc551c0SBarry Smith 
15629e5bc791SBarry Smith 
1563ebc551c0SBarry Smith #undef __FUNCT__
1564ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
1565ebc551c0SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PC pc)
1566ebc551c0SBarry Smith {
1567ebc551c0SBarry Smith   PetscErrorCode ierr;
1568f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1569ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1570ebc551c0SBarry Smith 
1571ebc551c0SBarry Smith   PetscFunctionBegin;
1572ebc551c0SBarry Smith   ierr = PetscOptionsHead("PFMG options");CHKERRQ(ierr);
15730298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
157468326731SBarry Smith   if (flg) {
1575a0324ebeSBarry Smith     int level=3;
1576fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
157768326731SBarry Smith   }
15780298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1579fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
15800298fd71SBarry 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);
1581fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
15820298fd71SBarry 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);
1583fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
15849e5bc791SBarry Smith 
15850298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
1586fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
15873b46a515SGlenn Hammond 
15880298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1589fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
15900298fd71SBarry 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);
1591fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
15920298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
1593fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1594ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1595ebc551c0SBarry Smith   PetscFunctionReturn(0);
1596ebc551c0SBarry Smith }
1597ebc551c0SBarry Smith 
1598f91d8e95SBarry Smith #undef __FUNCT__
1599f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1600f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1601f91d8e95SBarry Smith {
1602f91d8e95SBarry Smith   PetscErrorCode  ierr;
1603f91d8e95SBarry Smith   PC_PFMG         *ex = (PC_PFMG*) pc->data;
1604f91d8e95SBarry Smith   PetscScalar     *xx,*yy;
16054ddd07fcSJed Brown   PetscInt        ilower[3],iupper[3];
160668326731SBarry Smith   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1607f91d8e95SBarry Smith 
1608f91d8e95SBarry Smith   PetscFunctionBegin;
1609dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1610aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1611f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1612f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1613f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1614f91d8e95SBarry Smith 
1615f91d8e95SBarry Smith   /* copy x values over to hypre */
1616fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1617f91d8e95SBarry Smith   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
16188b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,xx));
1619f91d8e95SBarry Smith   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
1620fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
1621fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1622f91d8e95SBarry Smith 
1623f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1624f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
16258b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
1626f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1627f91d8e95SBarry Smith   PetscFunctionReturn(0);
1628f91d8e95SBarry Smith }
1629f91d8e95SBarry Smith 
16309e5bc791SBarry Smith #undef __FUNCT__
16319e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1632ace3abfcSBarry 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)
16339e5bc791SBarry Smith {
16349e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
16359e5bc791SBarry Smith   PetscErrorCode ierr;
16364ddd07fcSJed Brown   PetscInt       oits;
16379e5bc791SBarry Smith 
16389e5bc791SBarry Smith   PetscFunctionBegin;
1639dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1640fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1641fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
16429e5bc791SBarry Smith 
16439e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
16448b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
16459e5bc791SBarry Smith   *outits = oits;
16469e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
16479e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1648fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1649fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
16509e5bc791SBarry Smith   PetscFunctionReturn(0);
16519e5bc791SBarry Smith }
16529e5bc791SBarry Smith 
16539e5bc791SBarry Smith 
16543a32d3dbSGlenn Hammond #undef __FUNCT__
16553a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
16563a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
16573a32d3dbSGlenn Hammond {
16583a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
16593a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
16603a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1661ace3abfcSBarry Smith   PetscBool       flg;
16623a32d3dbSGlenn Hammond 
16633a32d3dbSGlenn Hammond   PetscFunctionBegin;
1664251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1665ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
16663a32d3dbSGlenn Hammond 
16673a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
16682fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1669fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
16703a32d3dbSGlenn Hammond   ierr = PCSetFromOptions_PFMG(pc);CHKERRQ(ierr);
1671fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1672fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
16733a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
16743a32d3dbSGlenn Hammond }
16753a32d3dbSGlenn Hammond 
1676ebc551c0SBarry Smith 
1677ebc551c0SBarry Smith /*MC
1678ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1679ebc551c0SBarry Smith 
1680ebc551c0SBarry Smith    Level: advanced
1681ebc551c0SBarry Smith 
16829e5bc791SBarry Smith    Options Database:
16839e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
16849e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
16859e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
16869e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
16879e5bc791SBarry 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
16889e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
1689f91d8e95SBarry Smith 
16909e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
16919e5bc791SBarry Smith 
16928e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
1693aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
16949e5bc791SBarry Smith 
16959e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
1696ebc551c0SBarry Smith M*/
1697ebc551c0SBarry Smith 
1698ebc551c0SBarry Smith #undef __FUNCT__
1699ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
17008cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
1701ebc551c0SBarry Smith {
1702ebc551c0SBarry Smith   PetscErrorCode ierr;
1703ebc551c0SBarry Smith   PC_PFMG        *ex;
1704ebc551c0SBarry Smith 
1705ebc551c0SBarry Smith   PetscFunctionBegin;
1706b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
170768326731SBarry Smith   pc->data = ex;
1708ebc551c0SBarry Smith 
17099e5bc791SBarry Smith   ex->its            = 1;
17109e5bc791SBarry Smith   ex->tol            = 1.e-8;
17119e5bc791SBarry Smith   ex->relax_type     = 1;
17129e5bc791SBarry Smith   ex->rap_type       = 0;
17139e5bc791SBarry Smith   ex->num_pre_relax  = 1;
17149e5bc791SBarry Smith   ex->num_post_relax = 1;
17153b46a515SGlenn Hammond   ex->max_levels     = 0;
17169e5bc791SBarry Smith 
1717ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
1718ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
1719ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
1720f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
17219e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
172268326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
17232fa5cd67SKarl Rupp 
1724ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
1725fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1726ebc551c0SBarry Smith   PetscFunctionReturn(0);
1727ebc551c0SBarry Smith }
1728d851a50bSGlenn Hammond 
1729325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
1730325fc9f4SBarry Smith 
1731d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
1732d851a50bSGlenn Hammond typedef struct {
1733d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
1734d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
1735d851a50bSGlenn Hammond 
1736d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
17374ddd07fcSJed Brown   PetscInt its;
1738d851a50bSGlenn Hammond   double   tol;
17394ddd07fcSJed Brown   PetscInt relax_type;
17404ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
1741d851a50bSGlenn Hammond } PC_SysPFMG;
1742d851a50bSGlenn Hammond 
1743d851a50bSGlenn Hammond #undef __FUNCT__
1744d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
1745d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
1746d851a50bSGlenn Hammond {
1747d851a50bSGlenn Hammond   PetscErrorCode ierr;
1748d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1749d851a50bSGlenn Hammond 
1750d851a50bSGlenn Hammond   PetscFunctionBegin;
17512fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1752d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1753c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1754d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1755d851a50bSGlenn Hammond }
1756d851a50bSGlenn Hammond 
1757d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
1758d851a50bSGlenn Hammond 
1759d851a50bSGlenn Hammond #undef __FUNCT__
1760d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
1761d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
1762d851a50bSGlenn Hammond {
1763d851a50bSGlenn Hammond   PetscErrorCode ierr;
1764ace3abfcSBarry Smith   PetscBool      iascii;
1765d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1766d851a50bSGlenn Hammond 
1767d851a50bSGlenn Hammond   PetscFunctionBegin;
1768251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1769d851a50bSGlenn Hammond   if (iascii) {
1770d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
1771d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
1772d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
1773d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
1774d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
1775d851a50bSGlenn Hammond   }
1776d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1777d851a50bSGlenn Hammond }
1778d851a50bSGlenn Hammond 
1779d851a50bSGlenn Hammond 
1780d851a50bSGlenn Hammond #undef __FUNCT__
1781d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
1782d851a50bSGlenn Hammond PetscErrorCode PCSetFromOptions_SysPFMG(PC pc)
1783d851a50bSGlenn Hammond {
1784d851a50bSGlenn Hammond   PetscErrorCode ierr;
1785d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1786ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1787d851a50bSGlenn Hammond 
1788d851a50bSGlenn Hammond   PetscFunctionBegin;
1789d851a50bSGlenn Hammond   ierr = PetscOptionsHead("SysPFMG options");CHKERRQ(ierr);
17900298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
1791d851a50bSGlenn Hammond   if (flg) {
1792d851a50bSGlenn Hammond     int level=3;
1793fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
1794d851a50bSGlenn Hammond   }
17950298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1796fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
17970298fd71SBarry 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);
1798fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
17990298fd71SBarry 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);
1800fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
1801d851a50bSGlenn Hammond 
18020298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1803fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
18040298fd71SBarry 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);
1805fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
1806d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
1807d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1808d851a50bSGlenn Hammond }
1809d851a50bSGlenn Hammond 
1810d851a50bSGlenn Hammond #undef __FUNCT__
1811d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
1812d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
1813d851a50bSGlenn Hammond {
1814d851a50bSGlenn Hammond   PetscErrorCode   ierr;
1815d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
1816d851a50bSGlenn Hammond   PetscScalar      *xx,*yy;
18174ddd07fcSJed Brown   PetscInt         ilower[3],iupper[3];
1818d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
18194ddd07fcSJed Brown   PetscInt         ordering= mx->dofs_order;
18204ddd07fcSJed Brown   PetscInt         nvars   = mx->nvars;
18214ddd07fcSJed Brown   PetscInt         part    = 0;
18224ddd07fcSJed Brown   PetscInt         size;
18234ddd07fcSJed Brown   PetscInt         i;
1824d851a50bSGlenn Hammond 
1825d851a50bSGlenn Hammond   PetscFunctionBegin;
1826dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1827aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1828d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
1829d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
1830d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
1831d851a50bSGlenn Hammond 
1832d851a50bSGlenn Hammond   size = 1;
18332fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
18342fa5cd67SKarl Rupp 
1835d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
1836d851a50bSGlenn Hammond   if (ordering) {
1837fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
1838d851a50bSGlenn Hammond     ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
18398b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,xx+(size*i)));
1840d851a50bSGlenn Hammond     ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
1841fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
1842fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
1843fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1844d851a50bSGlenn Hammond 
1845d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
1846d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
18478b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
1848d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1849a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
1850d851a50bSGlenn Hammond     PetscScalar *z;
18514ddd07fcSJed Brown     PetscInt    j, k;
1852d851a50bSGlenn Hammond 
1853785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
1854fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
1855d851a50bSGlenn Hammond     ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
1856d851a50bSGlenn Hammond 
1857d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
1858d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
1859d851a50bSGlenn Hammond       k= i*nvars;
18602fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
1861d851a50bSGlenn Hammond     }
18628b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
1863d851a50bSGlenn Hammond     ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
1864fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
1865fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1866d851a50bSGlenn Hammond 
1867d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
1868d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
18698b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
1870d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
1871d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
1872d851a50bSGlenn Hammond       k= i*nvars;
18732fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
1874d851a50bSGlenn Hammond     }
1875d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1876d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
1877d851a50bSGlenn Hammond   }
1878d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1879d851a50bSGlenn Hammond }
1880d851a50bSGlenn Hammond 
1881d851a50bSGlenn Hammond #undef __FUNCT__
1882d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
1883ace3abfcSBarry 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)
1884d851a50bSGlenn Hammond {
1885d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
1886d851a50bSGlenn Hammond   PetscErrorCode ierr;
18874ddd07fcSJed Brown   PetscInt       oits;
1888d851a50bSGlenn Hammond 
1889d851a50bSGlenn Hammond   PetscFunctionBegin;
1890dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1891fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
1892fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
1893d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
18948b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
1895d851a50bSGlenn Hammond   *outits = oits;
1896d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
1897d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1898fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
1899fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
1900d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1901d851a50bSGlenn Hammond }
1902d851a50bSGlenn Hammond 
1903d851a50bSGlenn Hammond 
1904d851a50bSGlenn Hammond #undef __FUNCT__
1905d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
1906d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
1907d851a50bSGlenn Hammond {
1908d851a50bSGlenn Hammond   PetscErrorCode   ierr;
1909d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
1910d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
1911ace3abfcSBarry Smith   PetscBool        flg;
1912d851a50bSGlenn Hammond 
1913d851a50bSGlenn Hammond   PetscFunctionBegin;
1914251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
1915ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
1916d851a50bSGlenn Hammond 
1917d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
19182fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1919fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
1920d851a50bSGlenn Hammond   ierr = PCSetFromOptions_SysPFMG(pc);CHKERRQ(ierr);
1921fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
1922fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1923d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1924d851a50bSGlenn Hammond }
1925d851a50bSGlenn Hammond 
1926d851a50bSGlenn Hammond 
1927d851a50bSGlenn Hammond /*MC
1928d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
1929d851a50bSGlenn Hammond 
1930d851a50bSGlenn Hammond    Level: advanced
1931d851a50bSGlenn Hammond 
1932d851a50bSGlenn Hammond    Options Database:
1933d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
1934d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
1935d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
1936d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
1937d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
1938d851a50bSGlenn Hammond 
1939d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
1940d851a50bSGlenn Hammond 
1941f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
1942aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
1943d851a50bSGlenn Hammond            Also, only cell-centered variables.
1944d851a50bSGlenn Hammond 
1945d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
1946d851a50bSGlenn Hammond M*/
1947d851a50bSGlenn Hammond 
1948d851a50bSGlenn Hammond #undef __FUNCT__
1949d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
19508cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
1951d851a50bSGlenn Hammond {
1952d851a50bSGlenn Hammond   PetscErrorCode ierr;
1953d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
1954d851a50bSGlenn Hammond 
1955d851a50bSGlenn Hammond   PetscFunctionBegin;
1956b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
1957d851a50bSGlenn Hammond   pc->data = ex;
1958d851a50bSGlenn Hammond 
1959d851a50bSGlenn Hammond   ex->its            = 1;
1960d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
1961d851a50bSGlenn Hammond   ex->relax_type     = 1;
1962d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
1963d851a50bSGlenn Hammond   ex->num_post_relax = 1;
1964d851a50bSGlenn Hammond 
1965d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
1966d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
1967d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
1968d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
1969d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
1970d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
19712fa5cd67SKarl Rupp 
1972ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
1973fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
1974d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1975d851a50bSGlenn Hammond }
1976