xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 863406b81038dc6b198ffea763ffc7671f56849a)
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);
26*863406b8SStefano Zampini   HYPRE_Int (*setdgrad)(HYPRE_Solver,HYPRE_ParCSRMatrix);
27*863406b8SStefano Zampini   HYPRE_Int (*setdcurl)(HYPRE_Solver,HYPRE_ParCSRMatrix);
28*863406b8SStefano Zampini   HYPRE_Int (*setcoord)(HYPRE_Solver,HYPRE_ParVector,HYPRE_ParVector,HYPRE_ParVector);
29*863406b8SStefano Zampini   HYPRE_Int (*setdim)(HYPRE_Solver,HYPRE_Int);
3016d9e3a6SLisandro Dalcin 
3116d9e3a6SLisandro Dalcin   MPI_Comm comm_hypre;
3216d9e3a6SLisandro Dalcin   char     *hypre_type;
3316d9e3a6SLisandro Dalcin 
3416d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
354ddd07fcSJed Brown   PetscInt maxiter;
3616d9e3a6SLisandro Dalcin   double   tol;
3716d9e3a6SLisandro Dalcin 
3816d9e3a6SLisandro Dalcin   /* options for Pilut */
394ddd07fcSJed Brown   PetscInt factorrowsize;
4016d9e3a6SLisandro Dalcin 
4116d9e3a6SLisandro Dalcin   /* options for ParaSails */
424ddd07fcSJed Brown   PetscInt nlevels;
4316d9e3a6SLisandro Dalcin   double   threshhold;
4416d9e3a6SLisandro Dalcin   double   filter;
454ddd07fcSJed Brown   PetscInt sym;
4616d9e3a6SLisandro Dalcin   double   loadbal;
474ddd07fcSJed Brown   PetscInt logging;
484ddd07fcSJed Brown   PetscInt ruse;
494ddd07fcSJed Brown   PetscInt symt;
5016d9e3a6SLisandro Dalcin 
5122b6d1caSBarry Smith   /* options for 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 
76*863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
77*863406b8SStefano Zampini   PetscInt  as_print;
78*863406b8SStefano Zampini   PetscInt  as_max_iter;
79*863406b8SStefano Zampini   PetscReal as_tol;
80*863406b8SStefano Zampini   PetscInt  as_relax_type;
81*863406b8SStefano Zampini   PetscInt  as_relax_times;
82*863406b8SStefano Zampini   PetscReal as_relax_weight;
83*863406b8SStefano Zampini   PetscReal as_omega;
84*863406b8SStefano Zampini   PetscInt  as_amg_alpha_opts[5]; /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for vector Poisson (AMS) or Curl problem (ADS) */
85*863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
86*863406b8SStefano Zampini   PetscInt  as_amg_beta_opts[5];  /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for scalar Poisson (AMS) or vector Poisson (ADS) */
87*863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
884cb006feSStefano Zampini   PetscInt  ams_cycle_type;
89*863406b8SStefano Zampini   PetscInt  ads_cycle_type;
904cb006feSStefano Zampini 
914cb006feSStefano Zampini   /* additional data */
924cb006feSStefano Zampini   HYPRE_IJVector coords[3];
934cb006feSStefano Zampini   HYPRE_IJVector constants[3];
944cb006feSStefano Zampini   HYPRE_IJMatrix G;
95*863406b8SStefano Zampini   HYPRE_IJMatrix C;
964cb006feSStefano Zampini   HYPRE_IJMatrix alpha_Poisson;
974cb006feSStefano Zampini   HYPRE_IJMatrix beta_Poisson;
984cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
9916d9e3a6SLisandro Dalcin } PC_HYPRE;
10016d9e3a6SLisandro Dalcin 
101d2128fa2SBarry Smith #undef __FUNCT__
102d2128fa2SBarry Smith #define __FUNCT__ "PCHYPREGetSolver"
103d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
104d2128fa2SBarry Smith {
105d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
106d2128fa2SBarry Smith 
107d2128fa2SBarry Smith   PetscFunctionBegin;
108d2128fa2SBarry Smith   *hsolver = jac->hsolver;
109d2128fa2SBarry Smith   PetscFunctionReturn(0);
110d2128fa2SBarry Smith }
11116d9e3a6SLisandro Dalcin 
11216d9e3a6SLisandro Dalcin #undef __FUNCT__
11316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE"
11416d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
11516d9e3a6SLisandro Dalcin {
11616d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11716d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
11816d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
11916d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
12016d9e3a6SLisandro Dalcin   PetscInt           bs;
12116d9e3a6SLisandro Dalcin 
12216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
12316d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
12402a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
12516d9e3a6SLisandro Dalcin   }
1265f5c5b43SBarry Smith 
1275f5c5b43SBarry Smith   if (pc->setupcalled) {
1285f5c5b43SBarry Smith     /* always destroy the old matrix and create a new memory;
1295f5c5b43SBarry Smith        hope this does not churn the memory too much. The problem
1305f5c5b43SBarry Smith        is I do not know if it is possible to put the matrix back to
1315f5c5b43SBarry Smith        its initial state so that we can directly copy the values
1325f5c5b43SBarry Smith        the second time through. */
133fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
1345f5c5b43SBarry Smith     jac->ij = 0;
13516d9e3a6SLisandro Dalcin   }
1365f5c5b43SBarry Smith 
13716d9e3a6SLisandro Dalcin   if (!jac->ij) { /* create the matrix the first time through */
13816d9e3a6SLisandro Dalcin     ierr = MatHYPRE_IJMatrixCreate(pc->pmat,&jac->ij);CHKERRQ(ierr);
13916d9e3a6SLisandro Dalcin   }
14016d9e3a6SLisandro Dalcin   if (!jac->b) { /* create the vectors the first time through */
14116d9e3a6SLisandro Dalcin     Vec x,b;
1422a7a6963SBarry Smith     ierr = MatCreateVecs(pc->pmat,&x,&b);CHKERRQ(ierr);
14316d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(x,&jac->x);CHKERRQ(ierr);
14416d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(b,&jac->b);CHKERRQ(ierr);
1456bf464f9SBarry Smith     ierr = VecDestroy(&x);CHKERRQ(ierr);
1466bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
14716d9e3a6SLisandro Dalcin   }
1485f5c5b43SBarry Smith 
14916d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
15016d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
15116d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1522fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
1534cb006feSStefano Zampini   }
154*863406b8SStefano Zampini 
1554cb006feSStefano Zampini   /* special case for AMS */
1564cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
1574cb006feSStefano 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()");
1584cb006feSStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
1594cb006feSStefano Zampini   }
160*863406b8SStefano Zampini   /* special case for ADS */
161*863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
162*863406b8SStefano Zampini     if (!jac->coords[0]) {
163*863406b8SStefano Zampini       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs coordinate vectors via PCSetCoordinates()");
164*863406b8SStefano Zampini     } else if (!jac->coords[1] && !jac->coords[2]) {
165*863406b8SStefano Zampini       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner works three dimensional problems! For two dimensional problems, use HYPRE AMS instead");
166*863406b8SStefano Zampini     }
167*863406b8SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
168*863406b8SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete curl operator via PCHYPRESetDiscreteGradient");
169*863406b8SStefano Zampini   }
17016d9e3a6SLisandro Dalcin   ierr = MatHYPRE_IJMatrixCopy(pc->pmat,jac->ij);CHKERRQ(ierr);
171fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
172fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&bv));
173fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&xv));
174fd3f9acdSBarry Smith   PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr););
17516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
17616d9e3a6SLisandro Dalcin }
17716d9e3a6SLisandro Dalcin 
17816d9e3a6SLisandro Dalcin /*
17916d9e3a6SLisandro Dalcin     Replaces the address where the HYPRE vector points to its data with the address of
18016d9e3a6SLisandro Dalcin   PETSc's data. Saves the old address so it can be reset when we are finished with it.
18116d9e3a6SLisandro Dalcin   Allows use to get the data into a HYPRE vector without the cost of memcopies
18216d9e3a6SLisandro Dalcin */
18316d9e3a6SLisandro Dalcin #define HYPREReplacePointer(b,newvalue,savedvalue) { \
18416d9e3a6SLisandro Dalcin     hypre_ParVector *par_vector   = (hypre_ParVector*)hypre_IJVectorObject(((hypre_IJVector*)b)); \
18516d9e3a6SLisandro Dalcin     hypre_Vector    *local_vector = hypre_ParVectorLocalVector(par_vector); \
18616d9e3a6SLisandro Dalcin     savedvalue         = local_vector->data; \
1870ad7597dSKarl Rupp     local_vector->data = newvalue;          \
1880ad7597dSKarl Rupp }
18916d9e3a6SLisandro Dalcin 
19016d9e3a6SLisandro Dalcin #undef __FUNCT__
19116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE"
19216d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
19316d9e3a6SLisandro Dalcin {
19416d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
19516d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
19616d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
197d9ca1df4SBarry Smith   PetscScalar        *xv;
198d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
19916d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
200d9ca1df4SBarry Smith   PetscScalar        *sxv;
2014ddd07fcSJed Brown   PetscInt           hierr;
20216d9e3a6SLisandro Dalcin 
20316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
204dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
20516d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
206d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
20716d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
208d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
20916d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
21016d9e3a6SLisandro Dalcin 
211fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
212fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
213fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
214fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
21565e19b50SBarry Smith                                if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
216fd3f9acdSBarry Smith                                if (hierr) hypre__global_error = 0;);
21716d9e3a6SLisandro Dalcin 
218d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)sbv,bv);
21916d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
22016d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
221d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
22216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
22316d9e3a6SLisandro Dalcin }
22416d9e3a6SLisandro Dalcin 
22516d9e3a6SLisandro Dalcin #undef __FUNCT__
22616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE"
22716d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
22816d9e3a6SLisandro Dalcin {
22916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
23016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
23116d9e3a6SLisandro Dalcin 
23216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
233fd3f9acdSBarry Smith   if (jac->ij) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
234fd3f9acdSBarry Smith   if (jac->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->b));
235fd3f9acdSBarry Smith   if (jac->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->x));
2364cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
2374cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
2384cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
2394cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
2404cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
2414cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
2424cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
243*863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
2444cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
2454cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
246226b0620SJed Brown   if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr););
247503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
24816d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
249c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
25016d9e3a6SLisandro Dalcin 
25116d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
252bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
253bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
2544cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
2554cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
256*863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
2574cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
2584cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",NULL);CHKERRQ(ierr);
2594cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",NULL);CHKERRQ(ierr);
26016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
26116d9e3a6SLisandro Dalcin }
26216d9e3a6SLisandro Dalcin 
26316d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
26416d9e3a6SLisandro Dalcin #undef __FUNCT__
26516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut"
2668c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptions *PetscOptionsObject,PC pc)
26716d9e3a6SLisandro Dalcin {
26816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
26916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
270ace3abfcSBarry Smith   PetscBool      flag;
27116d9e3a6SLisandro Dalcin 
27216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
273e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
27416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
275fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
27616d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
277fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
27816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
279fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
28016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
28116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
28216d9e3a6SLisandro Dalcin }
28316d9e3a6SLisandro Dalcin 
28416d9e3a6SLisandro Dalcin #undef __FUNCT__
28516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut"
28616d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
28716d9e3a6SLisandro Dalcin {
28816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
28916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
290ace3abfcSBarry Smith   PetscBool      iascii;
29116d9e3a6SLisandro Dalcin 
29216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
293251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
29416d9e3a6SLisandro Dalcin   if (iascii) {
29516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
29616d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
29716d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
29816d9e3a6SLisandro Dalcin     } else {
29916d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr);
30016d9e3a6SLisandro Dalcin     }
30116d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
30257622a8eSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
30316d9e3a6SLisandro Dalcin     } else {
30416d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr);
30516d9e3a6SLisandro Dalcin     }
30616d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
30716d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
30816d9e3a6SLisandro Dalcin     } else {
30916d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default factor row size \n");CHKERRQ(ierr);
31016d9e3a6SLisandro Dalcin     }
31116d9e3a6SLisandro Dalcin   }
31216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
31316d9e3a6SLisandro Dalcin }
31416d9e3a6SLisandro Dalcin 
31516d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
31616d9e3a6SLisandro Dalcin 
31716d9e3a6SLisandro Dalcin #undef __FUNCT__
31816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG"
31916d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
32016d9e3a6SLisandro Dalcin {
32116d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
32216d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
32316d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
324d9ca1df4SBarry Smith   PetscScalar        *xv;
325d9ca1df4SBarry Smith   const PetscScalar  *bv;
32616d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
32716d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
3284ddd07fcSJed Brown   PetscInt           hierr;
32916d9e3a6SLisandro Dalcin 
33016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
331dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
33216d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
333d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
33416d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
335d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
33616d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
33716d9e3a6SLisandro Dalcin 
338fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
339fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
340fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
34116d9e3a6SLisandro Dalcin 
34216d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
34316d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
344e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
34516d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
34616d9e3a6SLisandro Dalcin 
34716d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
34816d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
34916d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
350d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
35116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
35216d9e3a6SLisandro Dalcin }
35316d9e3a6SLisandro Dalcin 
354a669f990SJed Brown /* static array length */
355a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
356a669f990SJed Brown 
35716d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
3580f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
35916d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
36065de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
36165de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
36265de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
36365de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
36465de4495SJed Brown                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */,
36565de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
3660f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
3670f1074feSSatish Balay                                                   "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"};
36816d9e3a6SLisandro Dalcin #undef __FUNCT__
36916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG"
3708c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptions *PetscOptionsObject,PC pc)
37116d9e3a6SLisandro Dalcin {
37216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
37316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
3744ddd07fcSJed Brown   PetscInt       n,indx,level;
375ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
37616d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
37716d9e3a6SLisandro Dalcin 
37816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
379e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
3804336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
38116d9e3a6SLisandro Dalcin   if (flg) {
3824336a9eeSBarry Smith     jac->cycletype = indx+1;
383fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
38416d9e3a6SLisandro Dalcin   }
38516d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
38616d9e3a6SLisandro Dalcin   if (flg) {
387ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
388fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
38916d9e3a6SLisandro Dalcin   }
39016d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
39116d9e3a6SLisandro Dalcin   if (flg) {
392ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
393fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
39416d9e3a6SLisandro Dalcin   }
3950f1074feSSatish 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);
39616d9e3a6SLisandro Dalcin   if (flg) {
39757622a8eSBarry 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);
398fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
39916d9e3a6SLisandro Dalcin   }
40016d9e3a6SLisandro Dalcin 
4010f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
40216d9e3a6SLisandro Dalcin   if (flg) {
40357622a8eSBarry 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);
404fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
40516d9e3a6SLisandro Dalcin   }
40616d9e3a6SLisandro Dalcin 
4070f1074feSSatish 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);
4080f1074feSSatish Balay   if (flg) {
40957622a8eSBarry 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);
410fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
4110f1074feSSatish Balay   }
4120f1074feSSatish Balay 
4130f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
4140f1074feSSatish Balay   if (flg) {
41557622a8eSBarry 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);
4160f1074feSSatish Balay 
417fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
4180f1074feSSatish Balay   }
4190f1074feSSatish Balay 
4200f1074feSSatish Balay 
4210f1074feSSatish 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);
4220f1074feSSatish Balay   if (flg) {
42357622a8eSBarry 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);
4240f1074feSSatish Balay 
425fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
4260f1074feSSatish Balay   }
4270f1074feSSatish Balay 
4280f1074feSSatish Balay 
42916d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
43016d9e3a6SLisandro Dalcin   if (flg) {
43157622a8eSBarry 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);
432fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
43316d9e3a6SLisandro Dalcin   }
43416d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
43516d9e3a6SLisandro Dalcin   if (flg) {
43657622a8eSBarry 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);
43757622a8eSBarry 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);
438fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
43916d9e3a6SLisandro Dalcin   }
44016d9e3a6SLisandro Dalcin 
44116d9e3a6SLisandro Dalcin   /* Grid sweeps */
4420f1074feSSatish 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);
44316d9e3a6SLisandro Dalcin   if (flg) {
444fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
44516d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
44616d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
4470f1074feSSatish Balay     jac->gridsweeps[1] = indx;
4480f1074feSSatish Balay     /*defaults coarse to 1 */
4490f1074feSSatish Balay     jac->gridsweeps[2] = 1;
45016d9e3a6SLisandro Dalcin   }
4510f1074feSSatish Balay 
4520f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
45316d9e3a6SLisandro Dalcin   if (flg) {
454fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
4550f1074feSSatish Balay     jac->gridsweeps[0] = indx;
45616d9e3a6SLisandro Dalcin   }
45716d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
45816d9e3a6SLisandro Dalcin   if (flg) {
459fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
4600f1074feSSatish Balay     jac->gridsweeps[1] = indx;
46116d9e3a6SLisandro Dalcin   }
4620f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
46316d9e3a6SLisandro Dalcin   if (flg) {
464fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
4650f1074feSSatish Balay     jac->gridsweeps[2] = indx;
46616d9e3a6SLisandro Dalcin   }
46716d9e3a6SLisandro Dalcin 
46816d9e3a6SLisandro Dalcin   /* Relax type */
469a669f990SJed 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);
47016d9e3a6SLisandro Dalcin   if (flg) {
4710f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
472fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
4730f1074feSSatish Balay     /* by default, coarse type set to 9 */
4740f1074feSSatish Balay     jac->relaxtype[2] = 9;
4750f1074feSSatish Balay 
47616d9e3a6SLisandro Dalcin   }
477a669f990SJed 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);
47816d9e3a6SLisandro Dalcin   if (flg) {
47916d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
480fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
48116d9e3a6SLisandro Dalcin   }
482a669f990SJed 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);
48316d9e3a6SLisandro Dalcin   if (flg) {
4840f1074feSSatish Balay     jac->relaxtype[1] = indx;
485fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
48616d9e3a6SLisandro Dalcin   }
487a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
48816d9e3a6SLisandro Dalcin   if (flg) {
4890f1074feSSatish Balay     jac->relaxtype[2] = indx;
490fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
49116d9e3a6SLisandro Dalcin   }
49216d9e3a6SLisandro Dalcin 
49316d9e3a6SLisandro Dalcin   /* Relaxation Weight */
49416d9e3a6SLisandro 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);
49516d9e3a6SLisandro Dalcin   if (flg) {
496fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
49716d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
49816d9e3a6SLisandro Dalcin   }
49916d9e3a6SLisandro Dalcin 
50016d9e3a6SLisandro Dalcin   n         = 2;
50116d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
50216d9e3a6SLisandro 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);
50316d9e3a6SLisandro Dalcin   if (flg) {
50416d9e3a6SLisandro Dalcin     if (n == 2) {
50516d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
506fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
507ce94432eSBarry 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);
50816d9e3a6SLisandro Dalcin   }
50916d9e3a6SLisandro Dalcin 
51016d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
51116d9e3a6SLisandro 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);
51216d9e3a6SLisandro Dalcin   if (flg) {
513fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
51416d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
51516d9e3a6SLisandro Dalcin   }
51616d9e3a6SLisandro Dalcin 
51716d9e3a6SLisandro Dalcin   n         = 2;
51816d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
51916d9e3a6SLisandro 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);
52016d9e3a6SLisandro Dalcin   if (flg) {
52116d9e3a6SLisandro Dalcin     if (n == 2) {
52216d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
523fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
524ce94432eSBarry 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);
52516d9e3a6SLisandro Dalcin   }
52616d9e3a6SLisandro Dalcin 
52716d9e3a6SLisandro Dalcin   /* the Relax Order */
528acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
52916d9e3a6SLisandro Dalcin 
5308afaa268SBarry Smith   if (flg && tmp_truth) {
53116d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
532fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
53316d9e3a6SLisandro Dalcin   }
534a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
53516d9e3a6SLisandro Dalcin   if (flg) {
53616d9e3a6SLisandro Dalcin     jac->measuretype = indx;
537fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
53816d9e3a6SLisandro Dalcin   }
5390f1074feSSatish Balay   /* update list length 3/07 */
540a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
54116d9e3a6SLisandro Dalcin   if (flg) {
54216d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
543fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
54416d9e3a6SLisandro Dalcin   }
5450f1074feSSatish Balay 
5460f1074feSSatish Balay   /* new 3/07 */
547a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
5480f1074feSSatish Balay   if (flg) {
5490f1074feSSatish Balay     jac->interptype = indx;
550fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
5510f1074feSSatish Balay   }
5520f1074feSSatish Balay 
553b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
55416d9e3a6SLisandro Dalcin   if (flg) {
555b96a4a96SBarry Smith     level = 3;
5560298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
5572fa5cd67SKarl Rupp 
558b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
559fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
5602ae77aedSBarry Smith   }
5612ae77aedSBarry Smith 
562b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
5632ae77aedSBarry Smith   if (flg) {
564b96a4a96SBarry Smith     level = 3;
5650298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
5662fa5cd67SKarl Rupp 
567b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
568fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
56916d9e3a6SLisandro Dalcin   }
5708f87f92bSBarry Smith 
5718afaa268SBarry Smith   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_coarsen", "HYPRE_BoomerAMGSetNodal()", "None", jac->nodal_coarsen ? PETSC_TRUE : PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5728f87f92bSBarry Smith   if (flg && tmp_truth) {
5738f87f92bSBarry Smith     jac->nodal_coarsen = 1;
574fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,1));
5758f87f92bSBarry Smith   }
5768f87f92bSBarry Smith 
577acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5788f87f92bSBarry Smith   if (flg && tmp_truth) {
5798f87f92bSBarry Smith     PetscInt tmp_int;
5808f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
5818f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
582fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
583fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
584fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
585fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
5868f87f92bSBarry Smith   }
5878f87f92bSBarry Smith 
58816d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
58916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
59016d9e3a6SLisandro Dalcin }
59116d9e3a6SLisandro Dalcin 
59216d9e3a6SLisandro Dalcin #undef __FUNCT__
59316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG"
594ace3abfcSBarry 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)
59516d9e3a6SLisandro Dalcin {
59616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
59716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
5984ddd07fcSJed Brown   PetscInt       oits;
59916d9e3a6SLisandro Dalcin 
60016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
601dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
602fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
603fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
60416d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
60516d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
60616d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
6078b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
6084d0a8057SBarry Smith   *outits = oits;
6094d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
6104d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
611fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
612fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
61316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
61416d9e3a6SLisandro Dalcin }
61516d9e3a6SLisandro Dalcin 
61616d9e3a6SLisandro Dalcin 
61716d9e3a6SLisandro Dalcin #undef __FUNCT__
61816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG"
61916d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
62016d9e3a6SLisandro Dalcin {
62116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
62216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
623ace3abfcSBarry Smith   PetscBool      iascii;
62416d9e3a6SLisandro Dalcin 
62516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
626251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
62716d9e3a6SLisandro Dalcin   if (iascii) {
62816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
62916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
63016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
63116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
63257622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
63357622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
63457622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
6350f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
6360f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
6370f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
6380f1074feSSatish Balay 
63957622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
64016d9e3a6SLisandro Dalcin 
6410f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
6420f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
6430f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
64416d9e3a6SLisandro Dalcin 
6450f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
6460f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
6470f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
64816d9e3a6SLisandro Dalcin 
64957622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
65057622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
65116d9e3a6SLisandro Dalcin 
65216d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
65316d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr);
65416d9e3a6SLisandro Dalcin     } else {
65516d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr);
65616d9e3a6SLisandro Dalcin     }
65716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
65816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
6590f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
6608f87f92bSBarry Smith     if (jac->nodal_coarsen) {
6618f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal())\n");CHKERRQ(ierr);
6628f87f92bSBarry Smith     }
6638f87f92bSBarry Smith     if (jac->nodal_relax) {
6648f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
6658f87f92bSBarry Smith     }
66616d9e3a6SLisandro Dalcin   }
66716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
66816d9e3a6SLisandro Dalcin }
66916d9e3a6SLisandro Dalcin 
67016d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
67116d9e3a6SLisandro Dalcin #undef __FUNCT__
67216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails"
6738c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptions *PetscOptionsObject,PC pc)
67416d9e3a6SLisandro Dalcin {
67516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
67616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
6774ddd07fcSJed Brown   PetscInt       indx;
678ace3abfcSBarry Smith   PetscBool      flag;
67916d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
68016d9e3a6SLisandro Dalcin 
68116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
682e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
68316d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
68416d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
6852fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
68616d9e3a6SLisandro Dalcin 
68716d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
6882fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
68916d9e3a6SLisandro Dalcin 
69016d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
6912fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
69216d9e3a6SLisandro Dalcin 
693acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
6942fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
69516d9e3a6SLisandro Dalcin 
696acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
6972fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
69816d9e3a6SLisandro Dalcin 
699a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
70016d9e3a6SLisandro Dalcin   if (flag) {
70116d9e3a6SLisandro Dalcin     jac->symt = indx;
702fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
70316d9e3a6SLisandro Dalcin   }
70416d9e3a6SLisandro Dalcin 
70516d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
70616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
70716d9e3a6SLisandro Dalcin }
70816d9e3a6SLisandro Dalcin 
70916d9e3a6SLisandro Dalcin #undef __FUNCT__
71016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails"
71116d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
71216d9e3a6SLisandro Dalcin {
71316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
71416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
715ace3abfcSBarry Smith   PetscBool      iascii;
71616d9e3a6SLisandro Dalcin   const char     *symt = 0;;
71716d9e3a6SLisandro Dalcin 
71816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
719251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
72016d9e3a6SLisandro Dalcin   if (iascii) {
72116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
72216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
72357622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
72457622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: filter %g\n",(double)jac->filter);CHKERRQ(ierr);
72557622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
726ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
727ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
7282fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
7292fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
7302fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
731ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
73216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr);
73316d9e3a6SLisandro Dalcin   }
73416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
73516d9e3a6SLisandro Dalcin }
7364cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
7374cb006feSStefano Zampini #undef __FUNCT__
7384cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS"
7399fa463a7SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptions *PetscOptionsObject,PC pc)
7404cb006feSStefano Zampini {
7414cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
7424cb006feSStefano Zampini   PetscErrorCode ierr;
7434cb006feSStefano Zampini   PetscInt       n;
7444cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
7454cb006feSStefano Zampini 
7464cb006feSStefano Zampini   PetscFunctionBegin;
7479fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
748*863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
749*863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
750*863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_max_iter","Maximum number of AMS multigrid iterations within PCApply","None",jac->as_max_iter,&jac->as_max_iter,&flag);CHKERRQ(ierr);
751*863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
7524cb006feSStefano 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);
7534cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
754*863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
755*863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
756*863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_relax_type","Relaxation type for AMS smoother","None",jac->as_relax_type,&jac->as_relax_type,&flag);CHKERRQ(ierr);
757*863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_relax_times","Number of relaxation steps for AMS smoother","None",jac->as_relax_times,&jac->as_relax_times,&flag2);CHKERRQ(ierr);
758*863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_relax_weight","Relaxation weight for AMS smoother","None",jac->as_relax_weight,&jac->as_relax_weight,&flag3);CHKERRQ(ierr);
759*863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
7604cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
761*863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
762*863406b8SStefano Zampini                                                                       jac->as_relax_times,
763*863406b8SStefano Zampini                                                                       jac->as_relax_weight,
764*863406b8SStefano Zampini                                                                       jac->as_omega));
7654cb006feSStefano Zampini   }
766*863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_amg_alpha_theta","Threshold for strong coupling of vector Poisson AMG solver","None",jac->as_amg_alpha_theta,&jac->as_amg_alpha_theta,&flag);CHKERRQ(ierr);
7674cb006feSStefano Zampini   n = 5;
768*863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
7694cb006feSStefano Zampini   if (flag || flag2) {
770*863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
771*863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
772*863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
773*863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
774*863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
775*863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
7764cb006feSStefano Zampini   }
777*863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_amg_beta_theta","Threshold for strong coupling of scalar Poisson AMG solver","None",jac->as_amg_beta_theta,&jac->as_amg_beta_theta,&flag);CHKERRQ(ierr);
7784cb006feSStefano Zampini   n = 5;
779*863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_beta_options","AMG options for scalar Poisson solver","None",jac->as_amg_beta_opts,&n,&flag2);CHKERRQ(ierr);
7804cb006feSStefano Zampini   if (flag || flag2) {
781*863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
782*863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
783*863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
784*863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
785*863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
786*863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
7874cb006feSStefano Zampini   }
7884cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
7894cb006feSStefano Zampini   PetscFunctionReturn(0);
7904cb006feSStefano Zampini }
7914cb006feSStefano Zampini 
7924cb006feSStefano Zampini #undef __FUNCT__
7934cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS"
7944cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
7954cb006feSStefano Zampini {
7964cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
7974cb006feSStefano Zampini   PetscErrorCode ierr;
7984cb006feSStefano Zampini   PetscBool      iascii;
7994cb006feSStefano Zampini 
8004cb006feSStefano Zampini   PetscFunctionBegin;
8014cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
8024cb006feSStefano Zampini   if (iascii) {
8034cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
804*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
8054cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
806*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
807*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
808*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
809*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
810*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
8114cb006feSStefano Zampini     if (jac->alpha_Poisson) {
8124cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8134cb006feSStefano Zampini     } else {
8144cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr);
8154cb006feSStefano Zampini     }
816*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
817*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
818*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
819*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
820*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
821*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
8224cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
8234cb006feSStefano Zampini       if (jac->beta_Poisson) {
8244cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8254cb006feSStefano Zampini       } else {
8264cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr);
8274cb006feSStefano Zampini       }
828*863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
829*863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
830*863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
831*863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
832*863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
833*863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
8344cb006feSStefano Zampini     }
8354cb006feSStefano Zampini   }
8364cb006feSStefano Zampini   PetscFunctionReturn(0);
8374cb006feSStefano Zampini }
8384cb006feSStefano Zampini 
8394cb006feSStefano Zampini #undef __FUNCT__
840*863406b8SStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_ADS"
841*863406b8SStefano Zampini static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptions *PetscOptionsObject,PC pc)
842*863406b8SStefano Zampini {
843*863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
844*863406b8SStefano Zampini   PetscErrorCode ierr;
845*863406b8SStefano Zampini   PetscInt       n;
846*863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
847*863406b8SStefano Zampini 
848*863406b8SStefano Zampini   PetscFunctionBegin;
849*863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
850*863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
851*863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
852*863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_max_iter","Maximum number of ADS multigrid iterations within PCApply","None",jac->as_max_iter,&jac->as_max_iter,&flag);CHKERRQ(ierr);
853*863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
854*863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_cycle_type","Cycle type for ADS multigrid","None",jac->ads_cycle_type,&jac->ads_cycle_type,&flag);CHKERRQ(ierr);
855*863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
856*863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
857*863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
858*863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_relax_type","Relaxation type for ADS smoother","None",jac->as_relax_type,&jac->as_relax_type,&flag);CHKERRQ(ierr);
859*863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_relax_times","Number of relaxation steps for ADS smoother","None",jac->as_relax_times,&jac->as_relax_times,&flag2);CHKERRQ(ierr);
860*863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_relax_weight","Relaxation weight for ADS smoother","None",jac->as_relax_weight,&jac->as_relax_weight,&flag3);CHKERRQ(ierr);
861*863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
862*863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
863*863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
864*863406b8SStefano Zampini                                                                       jac->as_relax_times,
865*863406b8SStefano Zampini                                                                       jac->as_relax_weight,
866*863406b8SStefano Zampini                                                                       jac->as_omega));
867*863406b8SStefano Zampini   }
868*863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_ams_theta","Threshold for strong coupling of AMS solver inside ADS","None",jac->as_amg_alpha_theta,&jac->as_amg_alpha_theta,&flag);CHKERRQ(ierr);
869*863406b8SStefano Zampini   n = 5;
870*863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ads_ams_options","AMG options for AMS solver inside ADS","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
871*863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_ams_cycle_type","Cycle type for AMS solver inside ADS","None",jac->ams_cycle_type,&jac->ams_cycle_type,&flag3);CHKERRQ(ierr);
872*863406b8SStefano Zampini   if (flag || flag2 || flag3) {
873*863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
874*863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
875*863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
876*863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
877*863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
878*863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
879*863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
880*863406b8SStefano Zampini   }
881*863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_amg_theta","Threshold for strong coupling of vector AMG solver inside ADS","None",jac->as_amg_beta_theta,&jac->as_amg_beta_theta,&flag);CHKERRQ(ierr);
882*863406b8SStefano Zampini   n = 5;
883*863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ads_amg_options","AMG options for vector AMG solver inside ADS","None",jac->as_amg_beta_opts,&n,&flag2);CHKERRQ(ierr);
884*863406b8SStefano Zampini   if (flag || flag2) {
885*863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
886*863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
887*863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
888*863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
889*863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
890*863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
891*863406b8SStefano Zampini   }
892*863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
893*863406b8SStefano Zampini   PetscFunctionReturn(0);
894*863406b8SStefano Zampini }
895*863406b8SStefano Zampini 
896*863406b8SStefano Zampini #undef __FUNCT__
897*863406b8SStefano Zampini #define __FUNCT__ "PCView_HYPRE_ADS"
898*863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
899*863406b8SStefano Zampini {
900*863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
901*863406b8SStefano Zampini   PetscErrorCode ierr;
902*863406b8SStefano Zampini   PetscBool      iascii;
903*863406b8SStefano Zampini 
904*863406b8SStefano Zampini   PetscFunctionBegin;
905*863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
906*863406b8SStefano Zampini   if (iascii) {
907*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
908*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
909*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
910*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
911*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
912*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
913*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
914*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
915*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: AMS solver\n");CHKERRQ(ierr);
916*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
917*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
918*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
919*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
920*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
921*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
922*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
923*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: vector Poisson solver\n");CHKERRQ(ierr);
924*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
925*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
926*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
927*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
928*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
929*863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
930*863406b8SStefano Zampini   }
931*863406b8SStefano Zampini   PetscFunctionReturn(0);
932*863406b8SStefano Zampini }
933*863406b8SStefano Zampini 
934*863406b8SStefano Zampini #undef __FUNCT__
935*863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE"
936*863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
9374cb006feSStefano Zampini {
9384cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
9394cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_G;
9404cb006feSStefano Zampini   PetscErrorCode     ierr;
9414cb006feSStefano Zampini 
9424cb006feSStefano Zampini   PetscFunctionBegin;
9434cb006feSStefano Zampini   /* throw away any discrete gradient if already set */
9444cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
9454cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(G,&jac->G);CHKERRQ(ierr);
9464cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(G,jac->G);CHKERRQ(ierr);
9474cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->G,(void**)(&parcsr_G)));
948*863406b8SStefano Zampini   PetscStackCall("Hypre set gradient",ierr = (*jac->setdgrad)(jac->hsolver,parcsr_G);CHKERRQ(ierr););
9494cb006feSStefano Zampini   PetscFunctionReturn(0);
9504cb006feSStefano Zampini }
9514cb006feSStefano Zampini 
9524cb006feSStefano Zampini #undef __FUNCT__
9534cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient"
9544cb006feSStefano Zampini /*@
9554cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
9564cb006feSStefano Zampini 
9574cb006feSStefano Zampini    Collective on PC
9584cb006feSStefano Zampini 
9594cb006feSStefano Zampini    Input Parameters:
9604cb006feSStefano Zampini +  pc - the preconditioning context
9614cb006feSStefano Zampini -  G - the discrete gradient
9624cb006feSStefano Zampini 
9634cb006feSStefano Zampini    Level: intermediate
9644cb006feSStefano Zampini 
9654cb006feSStefano 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
966*863406b8SStefano Zampini           Each row of G has 2 nonzeros, with column indexes being the global indexes of edge's endpoints: matrix entries are +1 and -1 depending on edge orientation
9674cb006feSStefano Zampini 
9684cb006feSStefano Zampini .seealso:
9694cb006feSStefano Zampini @*/
9704cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
9714cb006feSStefano Zampini {
9724cb006feSStefano Zampini   PetscErrorCode ierr;
9734cb006feSStefano Zampini 
9744cb006feSStefano Zampini   PetscFunctionBegin;
9754cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
9764cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
9774cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
9784cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
9794cb006feSStefano Zampini   PetscFunctionReturn(0);
9804cb006feSStefano Zampini }
9814cb006feSStefano Zampini 
9824cb006feSStefano Zampini #undef __FUNCT__
983*863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl_HYPRE"
984*863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
985*863406b8SStefano Zampini {
986*863406b8SStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
987*863406b8SStefano Zampini   HYPRE_ParCSRMatrix parcsr_C;
988*863406b8SStefano Zampini   PetscErrorCode     ierr;
989*863406b8SStefano Zampini 
990*863406b8SStefano Zampini   PetscFunctionBegin;
991*863406b8SStefano Zampini   /* throw away any discrete curl if already set */
992*863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
993*863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(C,&jac->C);CHKERRQ(ierr);
994*863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(C,jac->C);CHKERRQ(ierr);
995*863406b8SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->C,(void**)(&parcsr_C)));
996*863406b8SStefano Zampini   PetscStackCall("Hypre set curl",ierr = (*jac->setdcurl)(jac->hsolver,parcsr_C);CHKERRQ(ierr););
997*863406b8SStefano Zampini   PetscFunctionReturn(0);
998*863406b8SStefano Zampini }
999*863406b8SStefano Zampini 
1000*863406b8SStefano Zampini #undef __FUNCT__
1001*863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl"
1002*863406b8SStefano Zampini /*@
1003*863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1004*863406b8SStefano Zampini 
1005*863406b8SStefano Zampini    Collective on PC
1006*863406b8SStefano Zampini 
1007*863406b8SStefano Zampini    Input Parameters:
1008*863406b8SStefano Zampini +  pc - the preconditioning context
1009*863406b8SStefano Zampini -  C - the discrete curl
1010*863406b8SStefano Zampini 
1011*863406b8SStefano Zampini    Level: intermediate
1012*863406b8SStefano Zampini 
1013*863406b8SStefano Zampini    Notes: C should have as many rows as the number of faces and as many columns as the number of edges in the mesh
1014*863406b8SStefano Zampini           Each row of G has as many nonzeros as the number of edges of a face, with column indexes being the global indexes of the corresponding edge: matrix entries are +1 and -1 depending on edge orientation with respect to the face orientation
1015*863406b8SStefano Zampini 
1016*863406b8SStefano Zampini .seealso:
1017*863406b8SStefano Zampini @*/
1018*863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1019*863406b8SStefano Zampini {
1020*863406b8SStefano Zampini   PetscErrorCode ierr;
1021*863406b8SStefano Zampini 
1022*863406b8SStefano Zampini   PetscFunctionBegin;
1023*863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1024*863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1025*863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1026*863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1027*863406b8SStefano Zampini   PetscFunctionReturn(0);
1028*863406b8SStefano Zampini }
1029*863406b8SStefano Zampini 
1030*863406b8SStefano Zampini #undef __FUNCT__
10314cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS"
10324cb006feSStefano Zampini static PetscErrorCode PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
10334cb006feSStefano Zampini {
10344cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
10354cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_alpha_Poisson;
10364cb006feSStefano Zampini   PetscErrorCode     ierr;
10374cb006feSStefano Zampini 
10384cb006feSStefano Zampini   PetscFunctionBegin;
10394cb006feSStefano Zampini   /* throw away any matrix if already set */
10404cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
10414cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->alpha_Poisson);CHKERRQ(ierr);
10424cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->alpha_Poisson);CHKERRQ(ierr);
10434cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->alpha_Poisson,(void**)(&parcsr_alpha_Poisson)));
10444cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr_alpha_Poisson));
10454cb006feSStefano Zampini   PetscFunctionReturn(0);
10464cb006feSStefano Zampini }
10474cb006feSStefano Zampini 
10484cb006feSStefano Zampini #undef __FUNCT__
10494cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix"
10504cb006feSStefano Zampini /*@
10514cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
10524cb006feSStefano Zampini 
10534cb006feSStefano Zampini    Collective on PC
10544cb006feSStefano Zampini 
10554cb006feSStefano Zampini    Input Parameters:
10564cb006feSStefano Zampini +  pc - the preconditioning context
10574cb006feSStefano Zampini -  A - the matrix
10584cb006feSStefano Zampini 
10594cb006feSStefano Zampini    Level: intermediate
10604cb006feSStefano Zampini 
10614cb006feSStefano Zampini    Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
10624cb006feSStefano Zampini 
10634cb006feSStefano Zampini .seealso:
10644cb006feSStefano Zampini @*/
10654cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
10664cb006feSStefano Zampini {
10674cb006feSStefano Zampini   PetscErrorCode ierr;
10684cb006feSStefano Zampini 
10694cb006feSStefano Zampini   PetscFunctionBegin;
10704cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
10714cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
10724cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
10734cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetAlphaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
10744cb006feSStefano Zampini   PetscFunctionReturn(0);
10754cb006feSStefano Zampini }
10764cb006feSStefano Zampini 
10774cb006feSStefano Zampini #undef __FUNCT__
10784cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix_HYPRE_AMS"
10794cb006feSStefano Zampini static PetscErrorCode PCHYPRESetBetaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
10804cb006feSStefano Zampini {
10814cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
10824cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_beta_Poisson;
10834cb006feSStefano Zampini   PetscErrorCode     ierr;
10844cb006feSStefano Zampini 
10854cb006feSStefano Zampini   PetscFunctionBegin;
10864cb006feSStefano Zampini   if (!A) {
10874cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_TRUE;
10884cb006feSStefano Zampini     PetscFunctionReturn(0);
10894cb006feSStefano Zampini   }
10904cb006feSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
10914cb006feSStefano Zampini   /* throw away any matrix if already set */
10924cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
10934cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->beta_Poisson);CHKERRQ(ierr);
10944cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->beta_Poisson);CHKERRQ(ierr);
10954cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->beta_Poisson,(void**)(&parcsr_beta_Poisson)));
10964cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr_beta_Poisson));
10974cb006feSStefano Zampini   PetscFunctionReturn(0);
10984cb006feSStefano Zampini }
10994cb006feSStefano Zampini 
11004cb006feSStefano Zampini #undef __FUNCT__
11014cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix"
11024cb006feSStefano Zampini /*@
11034cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
11044cb006feSStefano Zampini 
11054cb006feSStefano Zampini    Collective on PC
11064cb006feSStefano Zampini 
11074cb006feSStefano Zampini    Input Parameters:
11084cb006feSStefano Zampini +  pc - the preconditioning context
11094cb006feSStefano Zampini -  A - the matrix
11104cb006feSStefano Zampini 
11114cb006feSStefano Zampini    Level: intermediate
11124cb006feSStefano Zampini 
11134cb006feSStefano Zampini    Notes: A should be obtained by discretizing the Poisson problem with linear finite elements.
11144cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
11154cb006feSStefano Zampini 
11164cb006feSStefano Zampini .seealso:
11174cb006feSStefano Zampini @*/
11184cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
11194cb006feSStefano Zampini {
11204cb006feSStefano Zampini   PetscErrorCode ierr;
11214cb006feSStefano Zampini 
11224cb006feSStefano Zampini   PetscFunctionBegin;
11234cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11244cb006feSStefano Zampini   if (A) {
11254cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
11264cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
11274cb006feSStefano Zampini   }
11284cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetBetaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
11294cb006feSStefano Zampini   PetscFunctionReturn(0);
11304cb006feSStefano Zampini }
11314cb006feSStefano Zampini 
11324cb006feSStefano Zampini #undef __FUNCT__
11334cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE_AMS"
11344cb006feSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE_AMS(PC pc,Vec ozz, Vec zoz, Vec zzo)
11354cb006feSStefano Zampini {
11364cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11374cb006feSStefano Zampini   HYPRE_ParVector    par_ozz,par_zoz,par_zzo;
113812ddd1b6SStefano Zampini   PetscInt           dim;
11394cb006feSStefano Zampini   PetscErrorCode     ierr;
11404cb006feSStefano Zampini 
11414cb006feSStefano Zampini   PetscFunctionBegin;
11424cb006feSStefano Zampini   /* throw away any vector if already set */
11434cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
11444cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
11454cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
11464cb006feSStefano Zampini   jac->constants[0] = NULL;
11474cb006feSStefano Zampini   jac->constants[1] = NULL;
11484cb006feSStefano Zampini   jac->constants[2] = NULL;
11494cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
11504cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
11514cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&par_ozz)));
11524cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
11534cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
11544cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&par_zoz)));
115512ddd1b6SStefano Zampini   dim = 2;
11564cb006feSStefano Zampini   if (zzo) {
11574cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
11584cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
11594cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&par_zzo)));
116012ddd1b6SStefano Zampini     dim++;
11614cb006feSStefano Zampini   }
11624cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,par_ozz,par_zoz,par_zzo));
116312ddd1b6SStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim));
11644cb006feSStefano Zampini   PetscFunctionReturn(0);
11654cb006feSStefano Zampini }
11664cb006feSStefano Zampini 
11674cb006feSStefano Zampini #undef __FUNCT__
11684cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors"
11694cb006feSStefano Zampini /*@
11704cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
11714cb006feSStefano Zampini 
11724cb006feSStefano Zampini    Collective on PC
11734cb006feSStefano Zampini 
11744cb006feSStefano Zampini    Input Parameters:
11754cb006feSStefano Zampini +  pc - the preconditioning context
11764cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
11774cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
11784cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
11794cb006feSStefano Zampini 
11804cb006feSStefano Zampini    Level: intermediate
11814cb006feSStefano Zampini 
11824cb006feSStefano Zampini    Notes:
11834cb006feSStefano Zampini 
11844cb006feSStefano Zampini .seealso:
11854cb006feSStefano Zampini @*/
11864cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
11874cb006feSStefano Zampini {
11884cb006feSStefano Zampini   PetscErrorCode ierr;
11894cb006feSStefano Zampini 
11904cb006feSStefano Zampini   PetscFunctionBegin;
11914cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11924cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
11934cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
11944cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
11954cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
11964cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
11974cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
11984cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
11994cb006feSStefano Zampini   PetscFunctionReturn(0);
12004cb006feSStefano Zampini }
12014cb006feSStefano Zampini 
12024cb006feSStefano Zampini #undef __FUNCT__
1203*863406b8SStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE"
1204*863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
12054cb006feSStefano Zampini {
12064cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
12074cb006feSStefano Zampini   Vec             tv;
12084cb006feSStefano Zampini   HYPRE_ParVector par_coords[3];
12094cb006feSStefano Zampini   PetscInt        i;
12104cb006feSStefano Zampini   PetscErrorCode  ierr;
12114cb006feSStefano Zampini 
12124cb006feSStefano Zampini   PetscFunctionBegin;
12134cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
12144cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
12154cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
12164cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
12174cb006feSStefano Zampini   /* set problem's dimension */
1218*863406b8SStefano Zampini   if (jac->setdim) {
1219*863406b8SStefano Zampini     PetscStackCall("Hypre set dim",ierr = (*jac->setdim)(jac->hsolver,dim);CHKERRQ(ierr););
1220*863406b8SStefano Zampini   }
12214cb006feSStefano Zampini   /* compute IJ vector for coordinates */
12224cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
12234cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
12244cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
12254cb006feSStefano Zampini   for (i=0;i<dim;i++) {
12264cb006feSStefano Zampini     PetscScalar *array;
12274cb006feSStefano Zampini     PetscInt    j;
12284cb006feSStefano Zampini 
12294cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
12304cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
12314cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
12324cb006feSStefano Zampini       array[j] = coords[j*dim+i];
12334cb006feSStefano Zampini     }
12344cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
12354cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
12364cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
12374cb006feSStefano Zampini   }
12384cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
12394cb006feSStefano Zampini   /* pass parCSR vectors to AMS solver */
12404cb006feSStefano Zampini   par_coords[0] = NULL;
12414cb006feSStefano Zampini   par_coords[1] = NULL;
12424cb006feSStefano Zampini   par_coords[2] = NULL;
12434cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&par_coords[0])));
12444cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&par_coords[1])));
12454cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&par_coords[2])));
1246*863406b8SStefano Zampini   PetscStackCall("Hypre set coords",ierr = (*jac->setcoord)(jac->hsolver,par_coords[0],par_coords[1],par_coords[2]);CHKERRQ(ierr););
12474cb006feSStefano Zampini   PetscFunctionReturn(0);
12484cb006feSStefano Zampini }
12494cb006feSStefano Zampini 
125016d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
125116d9e3a6SLisandro Dalcin 
125216d9e3a6SLisandro Dalcin #undef __FUNCT__
125316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
1254f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
125516d9e3a6SLisandro Dalcin {
125616d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
125716d9e3a6SLisandro Dalcin 
125816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
125916d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
126016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
126116d9e3a6SLisandro Dalcin }
126216d9e3a6SLisandro Dalcin 
126316d9e3a6SLisandro Dalcin #undef __FUNCT__
126416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
1265f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
126616d9e3a6SLisandro Dalcin {
126716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
126816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1269ace3abfcSBarry Smith   PetscBool      flag;
127016d9e3a6SLisandro Dalcin 
127116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
127216d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
127316d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1274ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
127516d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
127616d9e3a6SLisandro Dalcin   } else {
127716d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
127816d9e3a6SLisandro Dalcin   }
127916d9e3a6SLisandro Dalcin 
128016d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
128116d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
128216d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
128316d9e3a6SLisandro Dalcin 
128416d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
128516d9e3a6SLisandro Dalcin   if (flag) {
1286fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
128716d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
128816d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
128916d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
129016d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
129116d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
129216d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
129316d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
129416d9e3a6SLisandro Dalcin   }
129516d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
129616d9e3a6SLisandro Dalcin   if (flag) {
1297fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
129816d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
129916d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
130016d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
130116d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
130216d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
130316d9e3a6SLisandro Dalcin     /* initialize */
130416d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
130516d9e3a6SLisandro Dalcin     jac->threshhold = .1;
130616d9e3a6SLisandro Dalcin     jac->filter     = .1;
130716d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
13082fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
13092fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
13102fa5cd67SKarl Rupp 
131116d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
131216d9e3a6SLisandro Dalcin     jac->symt = 0;
1313fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1314fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1315fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1316fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1317fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1318fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
131916d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
132016d9e3a6SLisandro Dalcin   }
132116d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
132216d9e3a6SLisandro Dalcin   if (flag) {
132316d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
132416d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
132516d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
132616d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
132716d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
132816d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
132916d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
133016d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
133116d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
133216d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
133316d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
133416d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
133516d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
13368f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
133716d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
133816d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
133916d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
134016d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
134116d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
13420f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
13438f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
13440f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
134516d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
134616d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
134716d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
13480f1074feSSatish Balay     jac->interptype       = 0;
13490f1074feSSatish Balay     jac->agg_nl           = 0;
13500f1074feSSatish Balay     jac->pmax             = 0;
13510f1074feSSatish Balay     jac->truncfactor      = 0.0;
13520f1074feSSatish Balay     jac->agg_num_paths    = 1;
13538f87f92bSBarry Smith 
13548f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
13558f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
13568f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1357fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1358fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1359fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1360fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1361fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1362fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1363fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1364fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1365fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1366fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1367fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1368fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1369fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1370fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1371fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1372fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
137316d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
137416d9e3a6SLisandro Dalcin   }
13754cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
13764cb006feSStefano Zampini   if (flag) {
13774cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
13784cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
13794cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
13804cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
13814cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
13824cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
1383*863406b8SStefano Zampini     jac->setdgrad            = HYPRE_AMSSetDiscreteGradient;
1384*863406b8SStefano Zampini     jac->setcoord            = HYPRE_AMSSetCoordinateVectors;
1385*863406b8SStefano Zampini     jac->setdim              = HYPRE_AMSSetDimension;
13864cb006feSStefano Zampini     jac->coords[0]           = NULL;
13874cb006feSStefano Zampini     jac->coords[1]           = NULL;
13884cb006feSStefano Zampini     jac->coords[2]           = NULL;
13894cb006feSStefano Zampini     jac->G                   = NULL;
13904cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1391*863406b8SStefano Zampini     jac->as_print           = 0;
1392*863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1393*863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
13944cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
13954cb006feSStefano Zampini     /* Smoothing options */
1396*863406b8SStefano Zampini     jac->as_relax_type      = 2;
1397*863406b8SStefano Zampini     jac->as_relax_times     = 1;
1398*863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1399*863406b8SStefano Zampini     jac->as_omega           = 1.0;
14004cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1401*863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1402*863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1403*863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 8;
1404*863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1405*863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1406*863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
14074cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
14084cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_FALSE;
1409*863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1410*863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1411*863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 8;
1412*863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1413*863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1414*863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1415*863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1416*863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
14174cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1418*863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1419*863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1420*863406b8SStefano Zampini                                                                       jac->as_relax_times,
1421*863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1422*863406b8SStefano Zampini                                                                       jac->as_omega));
1423*863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1424*863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1425*863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1426*863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1427*863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1428*863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1429*863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1430*863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1431*863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1432*863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1433*863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1434*863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1435*863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1436*863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
14374cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE_AMS);CHKERRQ(ierr);
14384cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
14394cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",PCHYPRESetBetaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
14404cb006feSStefano Zampini     PetscFunctionReturn(0);
14414cb006feSStefano Zampini   }
1442*863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1443*863406b8SStefano Zampini   if (flag) {
1444*863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1445*863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1446*863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1447*863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1448*863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1449*863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1450*863406b8SStefano Zampini     jac->setdgrad            = HYPRE_ADSSetDiscreteGradient;
1451*863406b8SStefano Zampini     jac->setdcurl            = HYPRE_ADSSetDiscreteCurl;
1452*863406b8SStefano Zampini     jac->setcoord            = HYPRE_ADSSetCoordinateVectors;
1453*863406b8SStefano Zampini     jac->coords[0]           = NULL;
1454*863406b8SStefano Zampini     jac->coords[1]           = NULL;
1455*863406b8SStefano Zampini     jac->coords[2]           = NULL;
1456*863406b8SStefano Zampini     jac->G                   = NULL;
1457*863406b8SStefano Zampini     jac->C                   = NULL;
1458*863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1459*863406b8SStefano Zampini     jac->as_print           = 0;
1460*863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1461*863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1462*863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1463*863406b8SStefano Zampini     /* Smoothing options */
1464*863406b8SStefano Zampini     jac->as_relax_type      = 2;
1465*863406b8SStefano Zampini     jac->as_relax_times     = 1;
1466*863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1467*863406b8SStefano Zampini     jac->as_omega           = 1.0;
1468*863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1469*863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1470*863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1471*863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1472*863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1473*863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1474*863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1475*863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1476*863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1477*863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1478*863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1479*863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1480*863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1481*863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1482*863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1483*863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1484*863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1485*863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1486*863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1487*863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1488*863406b8SStefano Zampini                                                                       jac->as_relax_times,
1489*863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1490*863406b8SStefano Zampini                                                                       jac->as_omega));
1491*863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1492*863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1493*863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1494*863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1495*863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1496*863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1497*863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1498*863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1499*863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1500*863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1501*863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1502*863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1503*863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1504*863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1505*863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
1506*863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
1507*863406b8SStefano Zampini     PetscFunctionReturn(0);
1508*863406b8SStefano Zampini   }
1509503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
15102fa5cd67SKarl Rupp 
15110298fd71SBarry Smith   jac->hypre_type = NULL;
151233263987SBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, boomeramg, ams",name);
151316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
151416d9e3a6SLisandro Dalcin }
151516d9e3a6SLisandro Dalcin 
151616d9e3a6SLisandro Dalcin /*
151716d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
151816d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
151916d9e3a6SLisandro Dalcin */
152016d9e3a6SLisandro Dalcin #undef __FUNCT__
152116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
15228c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptions *PetscOptionsObject,PC pc)
152316d9e3a6SLisandro Dalcin {
152416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
15254ddd07fcSJed Brown   PetscInt       indx;
1526*863406b8SStefano Zampini   const char     *type[] = {"pilut","parasails","boomeramg","ams","ads"};
1527ace3abfcSBarry Smith   PetscBool      flg;
152816d9e3a6SLisandro Dalcin 
152916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
15309fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
15319c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
153216d9e3a6SLisandro Dalcin   if (flg) {
153316d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
153402a17cd4SBarry Smith   } else {
153502a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
153616d9e3a6SLisandro Dalcin   }
153716d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
15383931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
153916d9e3a6SLisandro Dalcin   }
154016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
154116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
154216d9e3a6SLisandro Dalcin }
154316d9e3a6SLisandro Dalcin 
154416d9e3a6SLisandro Dalcin #undef __FUNCT__
154516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
154616d9e3a6SLisandro Dalcin /*@C
154716d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
154816d9e3a6SLisandro Dalcin 
154916d9e3a6SLisandro Dalcin    Input Parameters:
155016d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1551*863406b8SStefano Zampini -     name - either  pilut, parasails, boomeramg, ams, ads
155216d9e3a6SLisandro Dalcin 
155316d9e3a6SLisandro Dalcin    Options Database Keys:
1554*863406b8SStefano Zampini    -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
155516d9e3a6SLisandro Dalcin 
155616d9e3a6SLisandro Dalcin    Level: intermediate
155716d9e3a6SLisandro Dalcin 
155816d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
155916d9e3a6SLisandro Dalcin            PCHYPRE
156016d9e3a6SLisandro Dalcin 
156116d9e3a6SLisandro Dalcin @*/
15627087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
156316d9e3a6SLisandro Dalcin {
15644ac538c5SBarry Smith   PetscErrorCode ierr;
156516d9e3a6SLisandro Dalcin 
156616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
15670700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
156816d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
15694ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
157016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
157116d9e3a6SLisandro Dalcin }
157216d9e3a6SLisandro Dalcin 
157316d9e3a6SLisandro Dalcin #undef __FUNCT__
157416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
157516d9e3a6SLisandro Dalcin /*@C
157616d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
157716d9e3a6SLisandro Dalcin 
157816d9e3a6SLisandro Dalcin    Input Parameter:
157916d9e3a6SLisandro Dalcin .     pc - the preconditioner context
158016d9e3a6SLisandro Dalcin 
158116d9e3a6SLisandro Dalcin    Output Parameter:
1582*863406b8SStefano Zampini .     name - either  pilut, parasails, boomeramg, ams, ads
158316d9e3a6SLisandro Dalcin 
158416d9e3a6SLisandro Dalcin    Level: intermediate
158516d9e3a6SLisandro Dalcin 
158616d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
158716d9e3a6SLisandro Dalcin            PCHYPRE
158816d9e3a6SLisandro Dalcin 
158916d9e3a6SLisandro Dalcin @*/
15907087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
159116d9e3a6SLisandro Dalcin {
15924ac538c5SBarry Smith   PetscErrorCode ierr;
159316d9e3a6SLisandro Dalcin 
159416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
15950700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
159616d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
15974ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
159816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
159916d9e3a6SLisandro Dalcin }
160016d9e3a6SLisandro Dalcin 
160116d9e3a6SLisandro Dalcin /*MC
160216d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
160316d9e3a6SLisandro Dalcin 
160416d9e3a6SLisandro Dalcin    Options Database Keys:
1605*863406b8SStefano Zampini +   -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
160616d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
160716d9e3a6SLisandro Dalcin           preconditioner
160816d9e3a6SLisandro Dalcin 
160916d9e3a6SLisandro Dalcin    Level: intermediate
161016d9e3a6SLisandro Dalcin 
161116d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
161216d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
161316d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
161416d9e3a6SLisandro Dalcin 
161516d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
16160f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
16170f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
16180f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
16198f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
16200f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
16210f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
162216d9e3a6SLisandro Dalcin 
16230f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
16240f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
16250f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
162616d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
162716d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
162816d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
162916d9e3a6SLisandro Dalcin 
163016d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
163116d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
163216d9e3a6SLisandro Dalcin 
16339e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
16349e5bc791SBarry Smith 
163516d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
16369e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
163716d9e3a6SLisandro Dalcin 
163816d9e3a6SLisandro Dalcin M*/
163916d9e3a6SLisandro Dalcin 
164016d9e3a6SLisandro Dalcin #undef __FUNCT__
164116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
16428cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
164316d9e3a6SLisandro Dalcin {
164416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
164516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
164616d9e3a6SLisandro Dalcin 
164716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1648b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
16492fa5cd67SKarl Rupp 
165016d9e3a6SLisandro Dalcin   pc->data                = jac;
165116d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
165216d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
165316d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
165416d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
165516d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
16560298fd71SBarry Smith   jac->hypre_type         = NULL;
16574cb006feSStefano Zampini   jac->coords[0]          = NULL;
16584cb006feSStefano Zampini   jac->coords[1]          = NULL;
16594cb006feSStefano Zampini   jac->coords[2]          = NULL;
16604cb006feSStefano Zampini   jac->constants[0]       = NULL;
16614cb006feSStefano Zampini   jac->constants[1]       = NULL;
16624cb006feSStefano Zampini   jac->constants[2]       = NULL;
1663*863406b8SStefano Zampini   jac->G                  = NULL;
1664*863406b8SStefano Zampini   jac->C                  = NULL;
1665*863406b8SStefano Zampini   jac->alpha_Poisson      = NULL;
1666*863406b8SStefano Zampini   jac->beta_Poisson       = NULL;
166716d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1668ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1669bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1670bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
167116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
167216d9e3a6SLisandro Dalcin }
1673ebc551c0SBarry Smith 
1674f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1675f91d8e95SBarry Smith 
1676b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1677b45d2f2cSJed Brown #include <petsc-private/matimpl.h>
1678ebc551c0SBarry Smith 
1679ebc551c0SBarry Smith typedef struct {
168068326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1681f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
16829e5bc791SBarry Smith 
16839e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
16844ddd07fcSJed Brown   PetscInt its;
16859e5bc791SBarry Smith   double   tol;
16864ddd07fcSJed Brown   PetscInt relax_type;
16874ddd07fcSJed Brown   PetscInt rap_type;
16884ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
16894ddd07fcSJed Brown   PetscInt max_levels;
1690ebc551c0SBarry Smith } PC_PFMG;
1691ebc551c0SBarry Smith 
1692ebc551c0SBarry Smith #undef __FUNCT__
1693ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1694ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1695ebc551c0SBarry Smith {
1696ebc551c0SBarry Smith   PetscErrorCode ierr;
1697f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1698ebc551c0SBarry Smith 
1699ebc551c0SBarry Smith   PetscFunctionBegin;
17002fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1701f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1702c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1703ebc551c0SBarry Smith   PetscFunctionReturn(0);
1704ebc551c0SBarry Smith }
1705ebc551c0SBarry Smith 
17069e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
17079e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
17089e5bc791SBarry Smith 
1709ebc551c0SBarry Smith #undef __FUNCT__
1710ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1711ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1712ebc551c0SBarry Smith {
1713ebc551c0SBarry Smith   PetscErrorCode ierr;
1714ace3abfcSBarry Smith   PetscBool      iascii;
1715f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1716ebc551c0SBarry Smith 
1717ebc551c0SBarry Smith   PetscFunctionBegin;
1718251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
17199e5bc791SBarry Smith   if (iascii) {
17209e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
17219e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
17229e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
17239e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
17249e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
17259e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
17263b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
17279e5bc791SBarry Smith   }
1728ebc551c0SBarry Smith   PetscFunctionReturn(0);
1729ebc551c0SBarry Smith }
1730ebc551c0SBarry Smith 
17319e5bc791SBarry Smith 
1732ebc551c0SBarry Smith #undef __FUNCT__
1733ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
17348c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptions *PetscOptionsObject,PC pc)
1735ebc551c0SBarry Smith {
1736ebc551c0SBarry Smith   PetscErrorCode ierr;
1737f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1738ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1739ebc551c0SBarry Smith 
1740ebc551c0SBarry Smith   PetscFunctionBegin;
1741e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
17420298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
174368326731SBarry Smith   if (flg) {
1744a0324ebeSBarry Smith     int level=3;
1745fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
174668326731SBarry Smith   }
17470298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1748fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
17490298fd71SBarry 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);
1750fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
17510298fd71SBarry 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);
1752fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
17539e5bc791SBarry Smith 
17540298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
1755fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
17563b46a515SGlenn Hammond 
17570298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1758fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
17590298fd71SBarry 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);
1760fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
17610298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
1762fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1763ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1764ebc551c0SBarry Smith   PetscFunctionReturn(0);
1765ebc551c0SBarry Smith }
1766ebc551c0SBarry Smith 
1767f91d8e95SBarry Smith #undef __FUNCT__
1768f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1769f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1770f91d8e95SBarry Smith {
1771f91d8e95SBarry Smith   PetscErrorCode    ierr;
1772f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
1773d9ca1df4SBarry Smith   PetscScalar       *yy;
1774d9ca1df4SBarry Smith   const PetscScalar *xx;
17754ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
177668326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1777f91d8e95SBarry Smith 
1778f91d8e95SBarry Smith   PetscFunctionBegin;
1779dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1780aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1781f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1782f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1783f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1784f91d8e95SBarry Smith 
1785f91d8e95SBarry Smith   /* copy x values over to hypre */
1786fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1787d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1788d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
1789d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1790fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
1791fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1792f91d8e95SBarry Smith 
1793f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1794f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
17958b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
1796f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1797f91d8e95SBarry Smith   PetscFunctionReturn(0);
1798f91d8e95SBarry Smith }
1799f91d8e95SBarry Smith 
18009e5bc791SBarry Smith #undef __FUNCT__
18019e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1802ace3abfcSBarry 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)
18039e5bc791SBarry Smith {
18049e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
18059e5bc791SBarry Smith   PetscErrorCode ierr;
18064ddd07fcSJed Brown   PetscInt       oits;
18079e5bc791SBarry Smith 
18089e5bc791SBarry Smith   PetscFunctionBegin;
1809dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1810fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1811fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
18129e5bc791SBarry Smith 
18139e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
18148b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
18159e5bc791SBarry Smith   *outits = oits;
18169e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
18179e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1818fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1819fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
18209e5bc791SBarry Smith   PetscFunctionReturn(0);
18219e5bc791SBarry Smith }
18229e5bc791SBarry Smith 
18239e5bc791SBarry Smith 
18243a32d3dbSGlenn Hammond #undef __FUNCT__
18253a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
18263a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
18273a32d3dbSGlenn Hammond {
18283a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
18293a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
18303a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1831ace3abfcSBarry Smith   PetscBool       flg;
18323a32d3dbSGlenn Hammond 
18333a32d3dbSGlenn Hammond   PetscFunctionBegin;
1834251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1835ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
18363a32d3dbSGlenn Hammond 
18373a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
18382fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1839fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1840fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1841fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
18423a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
18433a32d3dbSGlenn Hammond }
18443a32d3dbSGlenn Hammond 
1845ebc551c0SBarry Smith 
1846ebc551c0SBarry Smith /*MC
1847ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1848ebc551c0SBarry Smith 
1849ebc551c0SBarry Smith    Level: advanced
1850ebc551c0SBarry Smith 
18519e5bc791SBarry Smith    Options Database:
18529e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
18539e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
18549e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
18559e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
18569e5bc791SBarry 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
18579e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
1858f91d8e95SBarry Smith 
18599e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
18609e5bc791SBarry Smith 
18618e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
1862aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
18639e5bc791SBarry Smith 
18649e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
1865ebc551c0SBarry Smith M*/
1866ebc551c0SBarry Smith 
1867ebc551c0SBarry Smith #undef __FUNCT__
1868ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
18698cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
1870ebc551c0SBarry Smith {
1871ebc551c0SBarry Smith   PetscErrorCode ierr;
1872ebc551c0SBarry Smith   PC_PFMG        *ex;
1873ebc551c0SBarry Smith 
1874ebc551c0SBarry Smith   PetscFunctionBegin;
1875b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
187668326731SBarry Smith   pc->data = ex;
1877ebc551c0SBarry Smith 
18789e5bc791SBarry Smith   ex->its            = 1;
18799e5bc791SBarry Smith   ex->tol            = 1.e-8;
18809e5bc791SBarry Smith   ex->relax_type     = 1;
18819e5bc791SBarry Smith   ex->rap_type       = 0;
18829e5bc791SBarry Smith   ex->num_pre_relax  = 1;
18839e5bc791SBarry Smith   ex->num_post_relax = 1;
18843b46a515SGlenn Hammond   ex->max_levels     = 0;
18859e5bc791SBarry Smith 
1886ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
1887ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
1888ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
1889f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
18909e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
189168326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
18922fa5cd67SKarl Rupp 
1893ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
1894fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1895ebc551c0SBarry Smith   PetscFunctionReturn(0);
1896ebc551c0SBarry Smith }
1897d851a50bSGlenn Hammond 
1898325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
1899325fc9f4SBarry Smith 
1900d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
1901d851a50bSGlenn Hammond typedef struct {
1902d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
1903d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
1904d851a50bSGlenn Hammond 
1905d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
19064ddd07fcSJed Brown   PetscInt its;
1907d851a50bSGlenn Hammond   double   tol;
19084ddd07fcSJed Brown   PetscInt relax_type;
19094ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
1910d851a50bSGlenn Hammond } PC_SysPFMG;
1911d851a50bSGlenn Hammond 
1912d851a50bSGlenn Hammond #undef __FUNCT__
1913d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
1914d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
1915d851a50bSGlenn Hammond {
1916d851a50bSGlenn Hammond   PetscErrorCode ierr;
1917d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1918d851a50bSGlenn Hammond 
1919d851a50bSGlenn Hammond   PetscFunctionBegin;
19202fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1921d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1922c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1923d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1924d851a50bSGlenn Hammond }
1925d851a50bSGlenn Hammond 
1926d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
1927d851a50bSGlenn Hammond 
1928d851a50bSGlenn Hammond #undef __FUNCT__
1929d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
1930d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
1931d851a50bSGlenn Hammond {
1932d851a50bSGlenn Hammond   PetscErrorCode ierr;
1933ace3abfcSBarry Smith   PetscBool      iascii;
1934d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1935d851a50bSGlenn Hammond 
1936d851a50bSGlenn Hammond   PetscFunctionBegin;
1937251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1938d851a50bSGlenn Hammond   if (iascii) {
1939d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
1940d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
1941d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
1942d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
1943d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
1944d851a50bSGlenn Hammond   }
1945d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1946d851a50bSGlenn Hammond }
1947d851a50bSGlenn Hammond 
1948d851a50bSGlenn Hammond 
1949d851a50bSGlenn Hammond #undef __FUNCT__
1950d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
19518c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptions *PetscOptionsObject,PC pc)
1952d851a50bSGlenn Hammond {
1953d851a50bSGlenn Hammond   PetscErrorCode ierr;
1954d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1955ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1956d851a50bSGlenn Hammond 
1957d851a50bSGlenn Hammond   PetscFunctionBegin;
1958e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
19590298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
1960d851a50bSGlenn Hammond   if (flg) {
1961d851a50bSGlenn Hammond     int level=3;
1962fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
1963d851a50bSGlenn Hammond   }
19640298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1965fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
19660298fd71SBarry 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);
1967fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
19680298fd71SBarry 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);
1969fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
1970d851a50bSGlenn Hammond 
19710298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1972fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
19730298fd71SBarry 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);
1974fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
1975d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
1976d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1977d851a50bSGlenn Hammond }
1978d851a50bSGlenn Hammond 
1979d851a50bSGlenn Hammond #undef __FUNCT__
1980d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
1981d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
1982d851a50bSGlenn Hammond {
1983d851a50bSGlenn Hammond   PetscErrorCode    ierr;
1984d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
1985d9ca1df4SBarry Smith   PetscScalar       *yy;
1986d9ca1df4SBarry Smith   const PetscScalar *xx;
19874ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
1988d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
19894ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
19904ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
19914ddd07fcSJed Brown   PetscInt          part    = 0;
19924ddd07fcSJed Brown   PetscInt          size;
19934ddd07fcSJed Brown   PetscInt          i;
1994d851a50bSGlenn Hammond 
1995d851a50bSGlenn Hammond   PetscFunctionBegin;
1996dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1997aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1998d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
1999d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2000d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2001d851a50bSGlenn Hammond 
2002d851a50bSGlenn Hammond   size = 1;
20032fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
20042fa5cd67SKarl Rupp 
2005d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2006d851a50bSGlenn Hammond   if (ordering) {
2007fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2008d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2009d9ca1df4SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,(PetscScalar*)xx+(size*i)));
2010d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2011fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2012fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2013fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2014d851a50bSGlenn Hammond 
2015d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2016d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
20178b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2018d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2019a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2020d851a50bSGlenn Hammond     PetscScalar *z;
20214ddd07fcSJed Brown     PetscInt    j, k;
2022d851a50bSGlenn Hammond 
2023785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2024fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2025d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2026d851a50bSGlenn Hammond 
2027d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2028d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2029d851a50bSGlenn Hammond       k= i*nvars;
20302fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2031d851a50bSGlenn Hammond     }
20328b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2033d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2034fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2035fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2036d851a50bSGlenn Hammond 
2037d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2038d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
20398b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2040d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2041d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2042d851a50bSGlenn Hammond       k= i*nvars;
20432fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2044d851a50bSGlenn Hammond     }
2045d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2046d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2047d851a50bSGlenn Hammond   }
2048d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2049d851a50bSGlenn Hammond }
2050d851a50bSGlenn Hammond 
2051d851a50bSGlenn Hammond #undef __FUNCT__
2052d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
2053ace3abfcSBarry 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)
2054d851a50bSGlenn Hammond {
2055d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2056d851a50bSGlenn Hammond   PetscErrorCode ierr;
20574ddd07fcSJed Brown   PetscInt       oits;
2058d851a50bSGlenn Hammond 
2059d851a50bSGlenn Hammond   PetscFunctionBegin;
2060dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2061fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2062fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2063d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
20648b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2065d851a50bSGlenn Hammond   *outits = oits;
2066d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2067d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2068fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2069fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2070d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2071d851a50bSGlenn Hammond }
2072d851a50bSGlenn Hammond 
2073d851a50bSGlenn Hammond 
2074d851a50bSGlenn Hammond #undef __FUNCT__
2075d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
2076d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2077d851a50bSGlenn Hammond {
2078d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2079d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2080d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2081ace3abfcSBarry Smith   PetscBool        flg;
2082d851a50bSGlenn Hammond 
2083d851a50bSGlenn Hammond   PetscFunctionBegin;
2084251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2085ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2086d851a50bSGlenn Hammond 
2087d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
20882fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2089fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2090fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2091fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2092d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2093d851a50bSGlenn Hammond }
2094d851a50bSGlenn Hammond 
2095d851a50bSGlenn Hammond 
2096d851a50bSGlenn Hammond /*MC
2097d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2098d851a50bSGlenn Hammond 
2099d851a50bSGlenn Hammond    Level: advanced
2100d851a50bSGlenn Hammond 
2101d851a50bSGlenn Hammond    Options Database:
2102d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2103d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2104d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2105d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2106d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2107d851a50bSGlenn Hammond 
2108d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
2109d851a50bSGlenn Hammond 
2110f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2111aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2112d851a50bSGlenn Hammond            Also, only cell-centered variables.
2113d851a50bSGlenn Hammond 
2114d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2115d851a50bSGlenn Hammond M*/
2116d851a50bSGlenn Hammond 
2117d851a50bSGlenn Hammond #undef __FUNCT__
2118d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
21198cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2120d851a50bSGlenn Hammond {
2121d851a50bSGlenn Hammond   PetscErrorCode ierr;
2122d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2123d851a50bSGlenn Hammond 
2124d851a50bSGlenn Hammond   PetscFunctionBegin;
2125b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2126d851a50bSGlenn Hammond   pc->data = ex;
2127d851a50bSGlenn Hammond 
2128d851a50bSGlenn Hammond   ex->its            = 1;
2129d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2130d851a50bSGlenn Hammond   ex->relax_type     = 1;
2131d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2132d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2133d851a50bSGlenn Hammond 
2134d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2135d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2136d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2137d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2138d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2139d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
21402fa5cd67SKarl Rupp 
2141ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2142fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2143d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2144d851a50bSGlenn Hammond }
2145