xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision b9eb5777a7c3dae85dcab316f30cc8cf214aaa6f)
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 
8af0996ceSBarry Smith #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);
26863406b8SStefano Zampini   HYPRE_Int (*setdgrad)(HYPRE_Solver,HYPRE_ParCSRMatrix);
27863406b8SStefano Zampini   HYPRE_Int (*setdcurl)(HYPRE_Solver,HYPRE_ParCSRMatrix);
28863406b8SStefano Zampini   HYPRE_Int (*setcoord)(HYPRE_Solver,HYPRE_ParVector,HYPRE_ParVector,HYPRE_ParVector);
29863406b8SStefano 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;
626a251517SEike Mueller   PetscInt  smoothtype;
638131ecf7SEike Mueller   PetscInt  smoothnumlevels;
644ddd07fcSJed Brown   PetscInt  relaxtype[3];
6516d9e3a6SLisandro Dalcin   double    relaxweight;
6616d9e3a6SLisandro Dalcin   double    outerrelaxweight;
674ddd07fcSJed Brown   PetscInt  relaxorder;
6816d9e3a6SLisandro Dalcin   double    truncfactor;
69ace3abfcSBarry Smith   PetscBool applyrichardson;
704ddd07fcSJed Brown   PetscInt  pmax;
714ddd07fcSJed Brown   PetscInt  interptype;
724ddd07fcSJed Brown   PetscInt  agg_nl;
734ddd07fcSJed Brown   PetscInt  agg_num_paths;
744ddd07fcSJed Brown   PetscInt  nodal_coarsen;
75ace3abfcSBarry Smith   PetscBool nodal_relax;
764ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
774cb006feSStefano Zampini 
78863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
79863406b8SStefano Zampini   PetscInt  as_print;
80863406b8SStefano Zampini   PetscInt  as_max_iter;
81863406b8SStefano Zampini   PetscReal as_tol;
82863406b8SStefano Zampini   PetscInt  as_relax_type;
83863406b8SStefano Zampini   PetscInt  as_relax_times;
84863406b8SStefano Zampini   PetscReal as_relax_weight;
85863406b8SStefano Zampini   PetscReal as_omega;
86863406b8SStefano 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) */
87863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
88863406b8SStefano 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) */
89863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
904cb006feSStefano Zampini   PetscInt  ams_cycle_type;
91863406b8SStefano Zampini   PetscInt  ads_cycle_type;
924cb006feSStefano Zampini 
934cb006feSStefano Zampini   /* additional data */
944cb006feSStefano Zampini   HYPRE_IJVector coords[3];
954cb006feSStefano Zampini   HYPRE_IJVector constants[3];
964cb006feSStefano Zampini   HYPRE_IJMatrix G;
97863406b8SStefano Zampini   HYPRE_IJMatrix C;
984cb006feSStefano Zampini   HYPRE_IJMatrix alpha_Poisson;
994cb006feSStefano Zampini   HYPRE_IJMatrix beta_Poisson;
1004cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
10116d9e3a6SLisandro Dalcin } PC_HYPRE;
10216d9e3a6SLisandro Dalcin 
103d2128fa2SBarry Smith #undef __FUNCT__
104d2128fa2SBarry Smith #define __FUNCT__ "PCHYPREGetSolver"
105d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
106d2128fa2SBarry Smith {
107d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
108d2128fa2SBarry Smith 
109d2128fa2SBarry Smith   PetscFunctionBegin;
110d2128fa2SBarry Smith   *hsolver = jac->hsolver;
111d2128fa2SBarry Smith   PetscFunctionReturn(0);
112d2128fa2SBarry Smith }
11316d9e3a6SLisandro Dalcin 
11416d9e3a6SLisandro Dalcin #undef __FUNCT__
11516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE"
11616d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
11716d9e3a6SLisandro Dalcin {
11816d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11916d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
12016d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
12116d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
12216d9e3a6SLisandro Dalcin   PetscInt           bs;
12316d9e3a6SLisandro Dalcin 
12416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
12516d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
12602a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
12716d9e3a6SLisandro Dalcin   }
1285f5c5b43SBarry Smith 
1295f5c5b43SBarry Smith   if (pc->setupcalled) {
1305f5c5b43SBarry Smith     /* always destroy the old matrix and create a new memory;
1315f5c5b43SBarry Smith        hope this does not churn the memory too much. The problem
1325f5c5b43SBarry Smith        is I do not know if it is possible to put the matrix back to
1335f5c5b43SBarry Smith        its initial state so that we can directly copy the values
1345f5c5b43SBarry Smith        the second time through. */
135fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
1365f5c5b43SBarry Smith     jac->ij = 0;
13716d9e3a6SLisandro Dalcin   }
1385f5c5b43SBarry Smith 
13916d9e3a6SLisandro Dalcin   if (!jac->ij) { /* create the matrix the first time through */
14016d9e3a6SLisandro Dalcin     ierr = MatHYPRE_IJMatrixCreate(pc->pmat,&jac->ij);CHKERRQ(ierr);
14116d9e3a6SLisandro Dalcin   }
14216d9e3a6SLisandro Dalcin   if (!jac->b) { /* create the vectors the first time through */
14316d9e3a6SLisandro Dalcin     Vec x,b;
1442a7a6963SBarry Smith     ierr = MatCreateVecs(pc->pmat,&x,&b);CHKERRQ(ierr);
14516d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(x,&jac->x);CHKERRQ(ierr);
14616d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(b,&jac->b);CHKERRQ(ierr);
1476bf464f9SBarry Smith     ierr = VecDestroy(&x);CHKERRQ(ierr);
1486bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
14916d9e3a6SLisandro Dalcin   }
1505f5c5b43SBarry Smith 
15116d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
15216d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
15316d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1542fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
1554cb006feSStefano Zampini   }
156863406b8SStefano Zampini 
1574cb006feSStefano Zampini   /* special case for AMS */
1584cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
1594cb006feSStefano 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()");
1604cb006feSStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
1614cb006feSStefano Zampini   }
162863406b8SStefano Zampini   /* special case for ADS */
163863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
164863406b8SStefano Zampini     if (!jac->coords[0]) {
165863406b8SStefano Zampini       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs coordinate vectors via PCSetCoordinates()");
166fd444223SStefano Zampini     } else if (!jac->coords[1] || !jac->coords[2]) {
167fd444223SStefano Zampini       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner has been designed for three dimensional problems! For two dimensional problems, use HYPRE AMS instead");
168863406b8SStefano Zampini     }
169863406b8SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
170863406b8SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete curl operator via PCHYPRESetDiscreteGradient");
171863406b8SStefano Zampini   }
17216d9e3a6SLisandro Dalcin   ierr = MatHYPRE_IJMatrixCopy(pc->pmat,jac->ij);CHKERRQ(ierr);
173fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
174fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&bv));
175fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&xv));
176fd3f9acdSBarry Smith   PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr););
17716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
17816d9e3a6SLisandro Dalcin }
17916d9e3a6SLisandro Dalcin 
18016d9e3a6SLisandro Dalcin /*
18116d9e3a6SLisandro Dalcin     Replaces the address where the HYPRE vector points to its data with the address of
18216d9e3a6SLisandro Dalcin   PETSc's data. Saves the old address so it can be reset when we are finished with it.
18316d9e3a6SLisandro Dalcin   Allows use to get the data into a HYPRE vector without the cost of memcopies
18416d9e3a6SLisandro Dalcin */
18516d9e3a6SLisandro Dalcin #define HYPREReplacePointer(b,newvalue,savedvalue) { \
18616d9e3a6SLisandro Dalcin     hypre_ParVector *par_vector   = (hypre_ParVector*)hypre_IJVectorObject(((hypre_IJVector*)b)); \
18716d9e3a6SLisandro Dalcin     hypre_Vector    *local_vector = hypre_ParVectorLocalVector(par_vector); \
18816d9e3a6SLisandro Dalcin     savedvalue         = local_vector->data; \
1890ad7597dSKarl Rupp     local_vector->data = newvalue;          \
1900ad7597dSKarl Rupp }
19116d9e3a6SLisandro Dalcin 
19216d9e3a6SLisandro Dalcin #undef __FUNCT__
19316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE"
19416d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
19516d9e3a6SLisandro Dalcin {
19616d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
19716d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
19816d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
199d9ca1df4SBarry Smith   PetscScalar        *xv;
200d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
20116d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
202d9ca1df4SBarry Smith   PetscScalar        *sxv;
2034ddd07fcSJed Brown   PetscInt           hierr;
20416d9e3a6SLisandro Dalcin 
20516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
206dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
20716d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
208d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
20916d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
210d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
21116d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
21216d9e3a6SLisandro Dalcin 
213fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
214fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
215fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
216fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
21765e19b50SBarry Smith                                if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
218fd3f9acdSBarry Smith                                if (hierr) hypre__global_error = 0;);
21916d9e3a6SLisandro Dalcin 
220d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)sbv,bv);
22116d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
22216d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
223d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
22416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
22516d9e3a6SLisandro Dalcin }
22616d9e3a6SLisandro Dalcin 
22716d9e3a6SLisandro Dalcin #undef __FUNCT__
22816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE"
22916d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
23016d9e3a6SLisandro Dalcin {
23116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
23216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
23316d9e3a6SLisandro Dalcin 
23416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
235fd3f9acdSBarry Smith   if (jac->ij) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
236fd3f9acdSBarry Smith   if (jac->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->b));
237fd3f9acdSBarry Smith   if (jac->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->x));
2384cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
2394cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
2404cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
2414cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
2424cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
2434cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
2444cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
245863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
2464cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
2474cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
248226b0620SJed Brown   if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr););
249503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
25016d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
251c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
25216d9e3a6SLisandro Dalcin 
25316d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
254bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
255bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
2564cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
2574cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
258863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
2594cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
2604cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",NULL);CHKERRQ(ierr);
2614cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",NULL);CHKERRQ(ierr);
26216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
26316d9e3a6SLisandro Dalcin }
26416d9e3a6SLisandro Dalcin 
26516d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
26616d9e3a6SLisandro Dalcin #undef __FUNCT__
26716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut"
2688c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptions *PetscOptionsObject,PC pc)
26916d9e3a6SLisandro Dalcin {
27016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
27116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
272ace3abfcSBarry Smith   PetscBool      flag;
27316d9e3a6SLisandro Dalcin 
27416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
275e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
27616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
277fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
27816d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
279fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
28016d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
281fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
28216d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
28316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
28416d9e3a6SLisandro Dalcin }
28516d9e3a6SLisandro Dalcin 
28616d9e3a6SLisandro Dalcin #undef __FUNCT__
28716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut"
28816d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
28916d9e3a6SLisandro Dalcin {
29016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
29116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
292ace3abfcSBarry Smith   PetscBool      iascii;
29316d9e3a6SLisandro Dalcin 
29416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
295251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
29616d9e3a6SLisandro Dalcin   if (iascii) {
29716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
29816d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
29916d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
30016d9e3a6SLisandro Dalcin     } else {
30116d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr);
30216d9e3a6SLisandro Dalcin     }
30316d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
30457622a8eSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
30516d9e3a6SLisandro Dalcin     } else {
30616d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr);
30716d9e3a6SLisandro Dalcin     }
30816d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
30916d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
31016d9e3a6SLisandro Dalcin     } else {
31116d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default factor row size \n");CHKERRQ(ierr);
31216d9e3a6SLisandro Dalcin     }
31316d9e3a6SLisandro Dalcin   }
31416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
31516d9e3a6SLisandro Dalcin }
31616d9e3a6SLisandro Dalcin 
31716d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
31816d9e3a6SLisandro Dalcin 
31916d9e3a6SLisandro Dalcin #undef __FUNCT__
32016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG"
32116d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
32216d9e3a6SLisandro Dalcin {
32316d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
32416d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
32516d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
326d9ca1df4SBarry Smith   PetscScalar        *xv;
327d9ca1df4SBarry Smith   const PetscScalar  *bv;
32816d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
32916d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
3304ddd07fcSJed Brown   PetscInt           hierr;
33116d9e3a6SLisandro Dalcin 
33216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
333dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
33416d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
335d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
33616d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
337d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
33816d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
33916d9e3a6SLisandro Dalcin 
340fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
341fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
342fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
34316d9e3a6SLisandro Dalcin 
34416d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
34516d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
346e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
34716d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
34816d9e3a6SLisandro Dalcin 
34916d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
35016d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
35116d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
352d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
35316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
35416d9e3a6SLisandro Dalcin }
35516d9e3a6SLisandro Dalcin 
356a669f990SJed Brown /* static array length */
357a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
358a669f990SJed Brown 
35916d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
3600f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
36116d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
36265de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
3636a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]   = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
36465de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
36565de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
36665de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
36765de4495SJed Brown                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */,
36865de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
3690f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
3700f1074feSSatish Balay                                                   "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"};
37116d9e3a6SLisandro Dalcin #undef __FUNCT__
37216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG"
3738c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptions *PetscOptionsObject,PC pc)
37416d9e3a6SLisandro Dalcin {
37516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
37616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
3774ddd07fcSJed Brown   PetscInt       n,indx,level;
378ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
37916d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
38016d9e3a6SLisandro Dalcin 
38116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
382e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
3834336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
38416d9e3a6SLisandro Dalcin   if (flg) {
3854336a9eeSBarry Smith     jac->cycletype = indx+1;
386fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
38716d9e3a6SLisandro Dalcin   }
38816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
38916d9e3a6SLisandro Dalcin   if (flg) {
390ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
391fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
39216d9e3a6SLisandro Dalcin   }
39316d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
39416d9e3a6SLisandro Dalcin   if (flg) {
395ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
396fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
39716d9e3a6SLisandro Dalcin   }
3980f1074feSSatish 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);
39916d9e3a6SLisandro Dalcin   if (flg) {
40057622a8eSBarry 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);
401fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
40216d9e3a6SLisandro Dalcin   }
40316d9e3a6SLisandro Dalcin 
4040f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
40516d9e3a6SLisandro Dalcin   if (flg) {
40657622a8eSBarry 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);
407fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
40816d9e3a6SLisandro Dalcin   }
40916d9e3a6SLisandro Dalcin 
4100f1074feSSatish 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);
4110f1074feSSatish Balay   if (flg) {
41257622a8eSBarry 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);
413fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
4140f1074feSSatish Balay   }
4150f1074feSSatish Balay 
4160f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
4170f1074feSSatish Balay   if (flg) {
41857622a8eSBarry 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);
4190f1074feSSatish Balay 
420fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
4210f1074feSSatish Balay   }
4220f1074feSSatish Balay 
4230f1074feSSatish Balay 
4240f1074feSSatish 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);
4250f1074feSSatish Balay   if (flg) {
42657622a8eSBarry 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);
4270f1074feSSatish Balay 
428fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
4290f1074feSSatish Balay   }
4300f1074feSSatish Balay 
4310f1074feSSatish Balay 
43216d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
43316d9e3a6SLisandro Dalcin   if (flg) {
43457622a8eSBarry 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);
435fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
43616d9e3a6SLisandro Dalcin   }
43716d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
43816d9e3a6SLisandro Dalcin   if (flg) {
43957622a8eSBarry 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);
44057622a8eSBarry 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);
441fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
44216d9e3a6SLisandro Dalcin   }
44316d9e3a6SLisandro Dalcin 
44416d9e3a6SLisandro Dalcin   /* Grid sweeps */
4450f1074feSSatish 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);
44616d9e3a6SLisandro Dalcin   if (flg) {
447fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
44816d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
44916d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
4500f1074feSSatish Balay     jac->gridsweeps[1] = indx;
4510f1074feSSatish Balay     /*defaults coarse to 1 */
4520f1074feSSatish Balay     jac->gridsweeps[2] = 1;
45316d9e3a6SLisandro Dalcin   }
4540f1074feSSatish Balay 
4550f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
45616d9e3a6SLisandro Dalcin   if (flg) {
457fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
4580f1074feSSatish Balay     jac->gridsweeps[0] = indx;
45916d9e3a6SLisandro Dalcin   }
46016d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
46116d9e3a6SLisandro Dalcin   if (flg) {
462fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
4630f1074feSSatish Balay     jac->gridsweeps[1] = indx;
46416d9e3a6SLisandro Dalcin   }
4650f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
46616d9e3a6SLisandro Dalcin   if (flg) {
467fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
4680f1074feSSatish Balay     jac->gridsweeps[2] = indx;
46916d9e3a6SLisandro Dalcin   }
47016d9e3a6SLisandro Dalcin 
4716a251517SEike Mueller   /* Smooth type */
4726a251517SEike Mueller   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);
4736a251517SEike Mueller   if (flg) {
4746a251517SEike Mueller     jac->smoothtype = indx;
4756a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
4768131ecf7SEike Mueller     jac->smoothnumlevels = 25;
4778131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
4788131ecf7SEike Mueller   }
4798131ecf7SEike Mueller 
4808131ecf7SEike Mueller   /* Number of smoothing levels */
4818131ecf7SEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_smooth_num_levels","Number of levels on which more complex smoothers are used","None",25,&indx,&flg);CHKERRQ(ierr);
4828131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
4838131ecf7SEike Mueller     jac->smoothnumlevels = indx;
4848131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
4856a251517SEike Mueller   }
4866a251517SEike Mueller 
48716d9e3a6SLisandro Dalcin   /* Relax type */
488a669f990SJed 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);
48916d9e3a6SLisandro Dalcin   if (flg) {
4900f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
491fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
4920f1074feSSatish Balay     /* by default, coarse type set to 9 */
4930f1074feSSatish Balay     jac->relaxtype[2] = 9;
4940f1074feSSatish Balay 
49516d9e3a6SLisandro Dalcin   }
496a669f990SJed 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);
49716d9e3a6SLisandro Dalcin   if (flg) {
49816d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
499fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
50016d9e3a6SLisandro Dalcin   }
501a669f990SJed 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);
50216d9e3a6SLisandro Dalcin   if (flg) {
5030f1074feSSatish Balay     jac->relaxtype[1] = indx;
504fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
50516d9e3a6SLisandro Dalcin   }
506a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
50716d9e3a6SLisandro Dalcin   if (flg) {
5080f1074feSSatish Balay     jac->relaxtype[2] = indx;
509fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
51016d9e3a6SLisandro Dalcin   }
51116d9e3a6SLisandro Dalcin 
51216d9e3a6SLisandro Dalcin   /* Relaxation Weight */
51316d9e3a6SLisandro 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);
51416d9e3a6SLisandro Dalcin   if (flg) {
515fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
51616d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
51716d9e3a6SLisandro Dalcin   }
51816d9e3a6SLisandro Dalcin 
51916d9e3a6SLisandro Dalcin   n         = 2;
52016d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
52116d9e3a6SLisandro 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);
52216d9e3a6SLisandro Dalcin   if (flg) {
52316d9e3a6SLisandro Dalcin     if (n == 2) {
52416d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
525fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
526ce94432eSBarry 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);
52716d9e3a6SLisandro Dalcin   }
52816d9e3a6SLisandro Dalcin 
52916d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
53016d9e3a6SLisandro 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);
53116d9e3a6SLisandro Dalcin   if (flg) {
532fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
53316d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
53416d9e3a6SLisandro Dalcin   }
53516d9e3a6SLisandro Dalcin 
53616d9e3a6SLisandro Dalcin   n         = 2;
53716d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
53816d9e3a6SLisandro 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);
53916d9e3a6SLisandro Dalcin   if (flg) {
54016d9e3a6SLisandro Dalcin     if (n == 2) {
54116d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
542fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
543ce94432eSBarry 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);
54416d9e3a6SLisandro Dalcin   }
54516d9e3a6SLisandro Dalcin 
54616d9e3a6SLisandro Dalcin   /* the Relax Order */
547acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
54816d9e3a6SLisandro Dalcin 
5498afaa268SBarry Smith   if (flg && tmp_truth) {
55016d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
551fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
55216d9e3a6SLisandro Dalcin   }
553a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
55416d9e3a6SLisandro Dalcin   if (flg) {
55516d9e3a6SLisandro Dalcin     jac->measuretype = indx;
556fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
55716d9e3a6SLisandro Dalcin   }
5580f1074feSSatish Balay   /* update list length 3/07 */
559a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
56016d9e3a6SLisandro Dalcin   if (flg) {
56116d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
562fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
56316d9e3a6SLisandro Dalcin   }
5640f1074feSSatish Balay 
5650f1074feSSatish Balay   /* new 3/07 */
566a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
5670f1074feSSatish Balay   if (flg) {
5680f1074feSSatish Balay     jac->interptype = indx;
569fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
5700f1074feSSatish Balay   }
5710f1074feSSatish Balay 
572b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
57316d9e3a6SLisandro Dalcin   if (flg) {
574b96a4a96SBarry Smith     level = 3;
5750298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
5762fa5cd67SKarl Rupp 
577b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
578fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
5792ae77aedSBarry Smith   }
5802ae77aedSBarry Smith 
581b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
5822ae77aedSBarry Smith   if (flg) {
583b96a4a96SBarry Smith     level = 3;
5840298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
5852fa5cd67SKarl Rupp 
586b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
587fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
58816d9e3a6SLisandro Dalcin   }
5898f87f92bSBarry Smith 
5908afaa268SBarry Smith   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_coarsen", "HYPRE_BoomerAMGSetNodal()", "None", jac->nodal_coarsen ? PETSC_TRUE : PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5918f87f92bSBarry Smith   if (flg && tmp_truth) {
5928f87f92bSBarry Smith     jac->nodal_coarsen = 1;
593fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,1));
5948f87f92bSBarry Smith   }
5958f87f92bSBarry Smith 
596acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5978f87f92bSBarry Smith   if (flg && tmp_truth) {
5988f87f92bSBarry Smith     PetscInt tmp_int;
5998f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
6008f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
601fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
602fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
603fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
604fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
6058f87f92bSBarry Smith   }
6068f87f92bSBarry Smith 
60716d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
60816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
60916d9e3a6SLisandro Dalcin }
61016d9e3a6SLisandro Dalcin 
61116d9e3a6SLisandro Dalcin #undef __FUNCT__
61216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG"
613ace3abfcSBarry 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)
61416d9e3a6SLisandro Dalcin {
61516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
61616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
6174ddd07fcSJed Brown   PetscInt       oits;
61816d9e3a6SLisandro Dalcin 
61916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
620dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
621fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
622fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
62316d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
62416d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
62516d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
6268b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
6274d0a8057SBarry Smith   *outits = oits;
6284d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
6294d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
630fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
631fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
63216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
63316d9e3a6SLisandro Dalcin }
63416d9e3a6SLisandro Dalcin 
63516d9e3a6SLisandro Dalcin 
63616d9e3a6SLisandro Dalcin #undef __FUNCT__
63716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG"
63816d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
63916d9e3a6SLisandro Dalcin {
64016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
64116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
642ace3abfcSBarry Smith   PetscBool      iascii;
64316d9e3a6SLisandro Dalcin 
64416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
645251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
64616d9e3a6SLisandro Dalcin   if (iascii) {
64716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
64816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
64916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
65016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
65157622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
65257622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
65357622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
6540f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
6550f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
6560f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
6570f1074feSSatish Balay 
65857622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
65916d9e3a6SLisandro Dalcin 
6600f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
6610f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
6620f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
66316d9e3a6SLisandro Dalcin 
6640f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
6650f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
6660f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
66716d9e3a6SLisandro Dalcin 
66857622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
66957622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
67016d9e3a6SLisandro Dalcin 
67116d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
67216d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr);
67316d9e3a6SLisandro Dalcin     } else {
67416d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr);
67516d9e3a6SLisandro Dalcin     }
6766a251517SEike Mueller     if (jac->smoothtype!=-1) {
6776a251517SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Smooth type         %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
6788131ecf7SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Smooth num levels   %d\n",jac->smoothnumlevels);CHKERRQ(ierr);
6796a251517SEike Mueller     } else {
6806a251517SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using more complex smoothers.\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
6816a251517SEike Mueller     }
68216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
68316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
6840f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
6858f87f92bSBarry Smith     if (jac->nodal_coarsen) {
6868f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal())\n");CHKERRQ(ierr);
6878f87f92bSBarry Smith     }
6888f87f92bSBarry Smith     if (jac->nodal_relax) {
6898f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
6908f87f92bSBarry Smith     }
69116d9e3a6SLisandro Dalcin   }
69216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
69316d9e3a6SLisandro Dalcin }
69416d9e3a6SLisandro Dalcin 
69516d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
69616d9e3a6SLisandro Dalcin #undef __FUNCT__
69716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails"
6988c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptions *PetscOptionsObject,PC pc)
69916d9e3a6SLisandro Dalcin {
70016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
70116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
7024ddd07fcSJed Brown   PetscInt       indx;
703ace3abfcSBarry Smith   PetscBool      flag;
70416d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
70516d9e3a6SLisandro Dalcin 
70616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
707e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
70816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
70916d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
7102fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
71116d9e3a6SLisandro Dalcin 
71216d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
7132fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
71416d9e3a6SLisandro Dalcin 
71516d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
7162fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
71716d9e3a6SLisandro Dalcin 
718acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
7192fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
72016d9e3a6SLisandro Dalcin 
721acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
7222fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
72316d9e3a6SLisandro Dalcin 
724a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
72516d9e3a6SLisandro Dalcin   if (flag) {
72616d9e3a6SLisandro Dalcin     jac->symt = indx;
727fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
72816d9e3a6SLisandro Dalcin   }
72916d9e3a6SLisandro Dalcin 
73016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
73116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
73216d9e3a6SLisandro Dalcin }
73316d9e3a6SLisandro Dalcin 
73416d9e3a6SLisandro Dalcin #undef __FUNCT__
73516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails"
73616d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
73716d9e3a6SLisandro Dalcin {
73816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
73916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
740ace3abfcSBarry Smith   PetscBool      iascii;
74116d9e3a6SLisandro Dalcin   const char     *symt = 0;;
74216d9e3a6SLisandro Dalcin 
74316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
744251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
74516d9e3a6SLisandro Dalcin   if (iascii) {
74616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
74716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
74857622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
74957622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: filter %g\n",(double)jac->filter);CHKERRQ(ierr);
75057622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
751ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
752ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
7532fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
7542fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
7552fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
756ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
75716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr);
75816d9e3a6SLisandro Dalcin   }
75916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
76016d9e3a6SLisandro Dalcin }
7614cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
7624cb006feSStefano Zampini #undef __FUNCT__
7634cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS"
7649fa463a7SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptions *PetscOptionsObject,PC pc)
7654cb006feSStefano Zampini {
7664cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
7674cb006feSStefano Zampini   PetscErrorCode ierr;
7684cb006feSStefano Zampini   PetscInt       n;
7694cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
7704cb006feSStefano Zampini 
7714cb006feSStefano Zampini   PetscFunctionBegin;
7729fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
773863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
774863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
775863406b8SStefano 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);
776863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
7774cb006feSStefano 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);
7784cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
779863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
780863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
781863406b8SStefano 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);
782863406b8SStefano 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);
783863406b8SStefano 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);
784863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
7854cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
786863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
787863406b8SStefano Zampini                                                                       jac->as_relax_times,
788863406b8SStefano Zampini                                                                       jac->as_relax_weight,
789863406b8SStefano Zampini                                                                       jac->as_omega));
7904cb006feSStefano Zampini   }
791863406b8SStefano 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);
7924cb006feSStefano Zampini   n = 5;
793863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
7944cb006feSStefano Zampini   if (flag || flag2) {
795863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
796863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
797863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
798863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
799863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
800863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
8014cb006feSStefano Zampini   }
802863406b8SStefano 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);
8034cb006feSStefano Zampini   n = 5;
804863406b8SStefano 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);
8054cb006feSStefano Zampini   if (flag || flag2) {
806863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
807863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
808863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
809863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
810863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
811863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
8124cb006feSStefano Zampini   }
8134cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
8144cb006feSStefano Zampini   PetscFunctionReturn(0);
8154cb006feSStefano Zampini }
8164cb006feSStefano Zampini 
8174cb006feSStefano Zampini #undef __FUNCT__
8184cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS"
8194cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
8204cb006feSStefano Zampini {
8214cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
8224cb006feSStefano Zampini   PetscErrorCode ierr;
8234cb006feSStefano Zampini   PetscBool      iascii;
8244cb006feSStefano Zampini 
8254cb006feSStefano Zampini   PetscFunctionBegin;
8264cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
8274cb006feSStefano Zampini   if (iascii) {
8284cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
829863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
8304cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
831863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
832863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
833863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
834863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
835863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
8364cb006feSStefano Zampini     if (jac->alpha_Poisson) {
8374cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8384cb006feSStefano Zampini     } else {
8394cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr);
8404cb006feSStefano Zampini     }
841863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
842863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
843863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
844863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
845863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
846863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
8474cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
8484cb006feSStefano Zampini       if (jac->beta_Poisson) {
8494cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8504cb006feSStefano Zampini       } else {
8514cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr);
8524cb006feSStefano Zampini       }
853863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
854863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
855863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
856863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
857863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
858863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
8594cb006feSStefano Zampini     }
8604cb006feSStefano Zampini   }
8614cb006feSStefano Zampini   PetscFunctionReturn(0);
8624cb006feSStefano Zampini }
8634cb006feSStefano Zampini 
8644cb006feSStefano Zampini #undef __FUNCT__
865863406b8SStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_ADS"
866863406b8SStefano Zampini static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptions *PetscOptionsObject,PC pc)
867863406b8SStefano Zampini {
868863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
869863406b8SStefano Zampini   PetscErrorCode ierr;
870863406b8SStefano Zampini   PetscInt       n;
871863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
872863406b8SStefano Zampini 
873863406b8SStefano Zampini   PetscFunctionBegin;
874863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
875863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
876863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
877863406b8SStefano 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);
878863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
879863406b8SStefano 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);
880863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
881863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
882863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
883863406b8SStefano 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);
884863406b8SStefano 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);
885863406b8SStefano 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);
886863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
887863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
888863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
889863406b8SStefano Zampini                                                                       jac->as_relax_times,
890863406b8SStefano Zampini                                                                       jac->as_relax_weight,
891863406b8SStefano Zampini                                                                       jac->as_omega));
892863406b8SStefano Zampini   }
893863406b8SStefano 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);
894863406b8SStefano Zampini   n = 5;
895863406b8SStefano 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);
896863406b8SStefano 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);
897863406b8SStefano Zampini   if (flag || flag2 || flag3) {
898863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
899863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
900863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
901863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
902863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
903863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
904863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
905863406b8SStefano Zampini   }
906863406b8SStefano 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);
907863406b8SStefano Zampini   n = 5;
908863406b8SStefano 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);
909863406b8SStefano Zampini   if (flag || flag2) {
910863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
911863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
912863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
913863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
914863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
915863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
916863406b8SStefano Zampini   }
917863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
918863406b8SStefano Zampini   PetscFunctionReturn(0);
919863406b8SStefano Zampini }
920863406b8SStefano Zampini 
921863406b8SStefano Zampini #undef __FUNCT__
922863406b8SStefano Zampini #define __FUNCT__ "PCView_HYPRE_ADS"
923863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
924863406b8SStefano Zampini {
925863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
926863406b8SStefano Zampini   PetscErrorCode ierr;
927863406b8SStefano Zampini   PetscBool      iascii;
928863406b8SStefano Zampini 
929863406b8SStefano Zampini   PetscFunctionBegin;
930863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
931863406b8SStefano Zampini   if (iascii) {
932863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
933863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
934863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
935863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
936863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
937863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
938863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
939863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
940863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: AMS solver\n");CHKERRQ(ierr);
941863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
942863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
943863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
944863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
945863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
946863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
947863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
948863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: vector Poisson solver\n");CHKERRQ(ierr);
949863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
950863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
951863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
952863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
953863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
954863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
955863406b8SStefano Zampini   }
956863406b8SStefano Zampini   PetscFunctionReturn(0);
957863406b8SStefano Zampini }
958863406b8SStefano Zampini 
959863406b8SStefano Zampini #undef __FUNCT__
960863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE"
961863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
9624cb006feSStefano Zampini {
9634cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
9644cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_G;
9654cb006feSStefano Zampini   PetscErrorCode     ierr;
9664cb006feSStefano Zampini 
9674cb006feSStefano Zampini   PetscFunctionBegin;
9684cb006feSStefano Zampini   /* throw away any discrete gradient if already set */
9694cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
9704cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(G,&jac->G);CHKERRQ(ierr);
9714cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(G,jac->G);CHKERRQ(ierr);
9724cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->G,(void**)(&parcsr_G)));
973863406b8SStefano Zampini   PetscStackCall("Hypre set gradient",ierr = (*jac->setdgrad)(jac->hsolver,parcsr_G);CHKERRQ(ierr););
9744cb006feSStefano Zampini   PetscFunctionReturn(0);
9754cb006feSStefano Zampini }
9764cb006feSStefano Zampini 
9774cb006feSStefano Zampini #undef __FUNCT__
9784cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient"
9794cb006feSStefano Zampini /*@
9804cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
9814cb006feSStefano Zampini 
9824cb006feSStefano Zampini    Collective on PC
9834cb006feSStefano Zampini 
9844cb006feSStefano Zampini    Input Parameters:
9854cb006feSStefano Zampini +  pc - the preconditioning context
9864cb006feSStefano Zampini -  G - the discrete gradient
9874cb006feSStefano Zampini 
9884cb006feSStefano Zampini    Level: intermediate
9894cb006feSStefano Zampini 
9904cb006feSStefano 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
991863406b8SStefano 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
9924cb006feSStefano Zampini 
9934cb006feSStefano Zampini .seealso:
9944cb006feSStefano Zampini @*/
9954cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
9964cb006feSStefano Zampini {
9974cb006feSStefano Zampini   PetscErrorCode ierr;
9984cb006feSStefano Zampini 
9994cb006feSStefano Zampini   PetscFunctionBegin;
10004cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
10014cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
10024cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
10034cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
10044cb006feSStefano Zampini   PetscFunctionReturn(0);
10054cb006feSStefano Zampini }
10064cb006feSStefano Zampini 
10074cb006feSStefano Zampini #undef __FUNCT__
1008863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl_HYPRE"
1009863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1010863406b8SStefano Zampini {
1011863406b8SStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
1012863406b8SStefano Zampini   HYPRE_ParCSRMatrix parcsr_C;
1013863406b8SStefano Zampini   PetscErrorCode     ierr;
1014863406b8SStefano Zampini 
1015863406b8SStefano Zampini   PetscFunctionBegin;
1016863406b8SStefano Zampini   /* throw away any discrete curl if already set */
1017863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
1018863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(C,&jac->C);CHKERRQ(ierr);
1019863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(C,jac->C);CHKERRQ(ierr);
1020863406b8SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->C,(void**)(&parcsr_C)));
1021863406b8SStefano Zampini   PetscStackCall("Hypre set curl",ierr = (*jac->setdcurl)(jac->hsolver,parcsr_C);CHKERRQ(ierr););
1022863406b8SStefano Zampini   PetscFunctionReturn(0);
1023863406b8SStefano Zampini }
1024863406b8SStefano Zampini 
1025863406b8SStefano Zampini #undef __FUNCT__
1026863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl"
1027863406b8SStefano Zampini /*@
1028863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1029863406b8SStefano Zampini 
1030863406b8SStefano Zampini    Collective on PC
1031863406b8SStefano Zampini 
1032863406b8SStefano Zampini    Input Parameters:
1033863406b8SStefano Zampini +  pc - the preconditioning context
1034863406b8SStefano Zampini -  C - the discrete curl
1035863406b8SStefano Zampini 
1036863406b8SStefano Zampini    Level: intermediate
1037863406b8SStefano Zampini 
1038863406b8SStefano 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
1039863406b8SStefano 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
1040863406b8SStefano Zampini 
1041863406b8SStefano Zampini .seealso:
1042863406b8SStefano Zampini @*/
1043863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1044863406b8SStefano Zampini {
1045863406b8SStefano Zampini   PetscErrorCode ierr;
1046863406b8SStefano Zampini 
1047863406b8SStefano Zampini   PetscFunctionBegin;
1048863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1049863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1050863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1051863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1052863406b8SStefano Zampini   PetscFunctionReturn(0);
1053863406b8SStefano Zampini }
1054863406b8SStefano Zampini 
1055863406b8SStefano Zampini #undef __FUNCT__
10564cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS"
10574cb006feSStefano Zampini static PetscErrorCode PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
10584cb006feSStefano Zampini {
10594cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
10604cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_alpha_Poisson;
10614cb006feSStefano Zampini   PetscErrorCode     ierr;
10624cb006feSStefano Zampini 
10634cb006feSStefano Zampini   PetscFunctionBegin;
10644cb006feSStefano Zampini   /* throw away any matrix if already set */
10654cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
10664cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->alpha_Poisson);CHKERRQ(ierr);
10674cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->alpha_Poisson);CHKERRQ(ierr);
10684cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->alpha_Poisson,(void**)(&parcsr_alpha_Poisson)));
10694cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr_alpha_Poisson));
10704cb006feSStefano Zampini   PetscFunctionReturn(0);
10714cb006feSStefano Zampini }
10724cb006feSStefano Zampini 
10734cb006feSStefano Zampini #undef __FUNCT__
10744cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix"
10754cb006feSStefano Zampini /*@
10764cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
10774cb006feSStefano Zampini 
10784cb006feSStefano Zampini    Collective on PC
10794cb006feSStefano Zampini 
10804cb006feSStefano Zampini    Input Parameters:
10814cb006feSStefano Zampini +  pc - the preconditioning context
10824cb006feSStefano Zampini -  A - the matrix
10834cb006feSStefano Zampini 
10844cb006feSStefano Zampini    Level: intermediate
10854cb006feSStefano Zampini 
10864cb006feSStefano Zampini    Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
10874cb006feSStefano Zampini 
10884cb006feSStefano Zampini .seealso:
10894cb006feSStefano Zampini @*/
10904cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
10914cb006feSStefano Zampini {
10924cb006feSStefano Zampini   PetscErrorCode ierr;
10934cb006feSStefano Zampini 
10944cb006feSStefano Zampini   PetscFunctionBegin;
10954cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
10964cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
10974cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
10984cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetAlphaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
10994cb006feSStefano Zampini   PetscFunctionReturn(0);
11004cb006feSStefano Zampini }
11014cb006feSStefano Zampini 
11024cb006feSStefano Zampini #undef __FUNCT__
11034cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix_HYPRE_AMS"
11044cb006feSStefano Zampini static PetscErrorCode PCHYPRESetBetaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
11054cb006feSStefano Zampini {
11064cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11074cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_beta_Poisson;
11084cb006feSStefano Zampini   PetscErrorCode     ierr;
11094cb006feSStefano Zampini 
11104cb006feSStefano Zampini   PetscFunctionBegin;
11114cb006feSStefano Zampini   if (!A) {
11124cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_TRUE;
11134cb006feSStefano Zampini     PetscFunctionReturn(0);
11144cb006feSStefano Zampini   }
11154cb006feSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
11164cb006feSStefano Zampini   /* throw away any matrix if already set */
11174cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
11184cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->beta_Poisson);CHKERRQ(ierr);
11194cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->beta_Poisson);CHKERRQ(ierr);
11204cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->beta_Poisson,(void**)(&parcsr_beta_Poisson)));
11214cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr_beta_Poisson));
11224cb006feSStefano Zampini   PetscFunctionReturn(0);
11234cb006feSStefano Zampini }
11244cb006feSStefano Zampini 
11254cb006feSStefano Zampini #undef __FUNCT__
11264cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix"
11274cb006feSStefano Zampini /*@
11284cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
11294cb006feSStefano Zampini 
11304cb006feSStefano Zampini    Collective on PC
11314cb006feSStefano Zampini 
11324cb006feSStefano Zampini    Input Parameters:
11334cb006feSStefano Zampini +  pc - the preconditioning context
11344cb006feSStefano Zampini -  A - the matrix
11354cb006feSStefano Zampini 
11364cb006feSStefano Zampini    Level: intermediate
11374cb006feSStefano Zampini 
11384cb006feSStefano Zampini    Notes: A should be obtained by discretizing the Poisson problem with linear finite elements.
11394cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
11404cb006feSStefano Zampini 
11414cb006feSStefano Zampini .seealso:
11424cb006feSStefano Zampini @*/
11434cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
11444cb006feSStefano Zampini {
11454cb006feSStefano Zampini   PetscErrorCode ierr;
11464cb006feSStefano Zampini 
11474cb006feSStefano Zampini   PetscFunctionBegin;
11484cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11494cb006feSStefano Zampini   if (A) {
11504cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
11514cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
11524cb006feSStefano Zampini   }
11534cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetBetaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
11544cb006feSStefano Zampini   PetscFunctionReturn(0);
11554cb006feSStefano Zampini }
11564cb006feSStefano Zampini 
11574cb006feSStefano Zampini #undef __FUNCT__
11584cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE_AMS"
11594cb006feSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE_AMS(PC pc,Vec ozz, Vec zoz, Vec zzo)
11604cb006feSStefano Zampini {
11614cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11624cb006feSStefano Zampini   HYPRE_ParVector    par_ozz,par_zoz,par_zzo;
116312ddd1b6SStefano Zampini   PetscInt           dim;
11644cb006feSStefano Zampini   PetscErrorCode     ierr;
11654cb006feSStefano Zampini 
11664cb006feSStefano Zampini   PetscFunctionBegin;
11674cb006feSStefano Zampini   /* throw away any vector if already set */
11684cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
11694cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
11704cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
11714cb006feSStefano Zampini   jac->constants[0] = NULL;
11724cb006feSStefano Zampini   jac->constants[1] = NULL;
11734cb006feSStefano Zampini   jac->constants[2] = NULL;
11744cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
11754cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
11764cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&par_ozz)));
11774cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
11784cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
11794cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&par_zoz)));
118012ddd1b6SStefano Zampini   dim = 2;
11814cb006feSStefano Zampini   if (zzo) {
11824cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
11834cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
11844cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&par_zzo)));
118512ddd1b6SStefano Zampini     dim++;
11864cb006feSStefano Zampini   }
11874cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,par_ozz,par_zoz,par_zzo));
118812ddd1b6SStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim));
11894cb006feSStefano Zampini   PetscFunctionReturn(0);
11904cb006feSStefano Zampini }
11914cb006feSStefano Zampini 
11924cb006feSStefano Zampini #undef __FUNCT__
11934cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors"
11944cb006feSStefano Zampini /*@
11954cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
11964cb006feSStefano Zampini 
11974cb006feSStefano Zampini    Collective on PC
11984cb006feSStefano Zampini 
11994cb006feSStefano Zampini    Input Parameters:
12004cb006feSStefano Zampini +  pc - the preconditioning context
12014cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
12024cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
12034cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
12044cb006feSStefano Zampini 
12054cb006feSStefano Zampini    Level: intermediate
12064cb006feSStefano Zampini 
12074cb006feSStefano Zampini    Notes:
12084cb006feSStefano Zampini 
12094cb006feSStefano Zampini .seealso:
12104cb006feSStefano Zampini @*/
12114cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
12124cb006feSStefano Zampini {
12134cb006feSStefano Zampini   PetscErrorCode ierr;
12144cb006feSStefano Zampini 
12154cb006feSStefano Zampini   PetscFunctionBegin;
12164cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12174cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
12184cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
12194cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
12204cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
12214cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
12224cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
12234cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
12244cb006feSStefano Zampini   PetscFunctionReturn(0);
12254cb006feSStefano Zampini }
12264cb006feSStefano Zampini 
12274cb006feSStefano Zampini #undef __FUNCT__
1228863406b8SStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE"
1229863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
12304cb006feSStefano Zampini {
12314cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
12324cb006feSStefano Zampini   Vec             tv;
12334cb006feSStefano Zampini   HYPRE_ParVector par_coords[3];
12344cb006feSStefano Zampini   PetscInt        i;
12354cb006feSStefano Zampini   PetscErrorCode  ierr;
12364cb006feSStefano Zampini 
12374cb006feSStefano Zampini   PetscFunctionBegin;
12384cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
12394cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
12404cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
12414cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
12424cb006feSStefano Zampini   /* set problem's dimension */
1243863406b8SStefano Zampini   if (jac->setdim) {
1244863406b8SStefano Zampini     PetscStackCall("Hypre set dim",ierr = (*jac->setdim)(jac->hsolver,dim);CHKERRQ(ierr););
1245863406b8SStefano Zampini   }
12464cb006feSStefano Zampini   /* compute IJ vector for coordinates */
12474cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
12484cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
12494cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
12504cb006feSStefano Zampini   for (i=0;i<dim;i++) {
12514cb006feSStefano Zampini     PetscScalar *array;
12524cb006feSStefano Zampini     PetscInt    j;
12534cb006feSStefano Zampini 
12544cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
12554cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
12564cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
12574cb006feSStefano Zampini       array[j] = coords[j*dim+i];
12584cb006feSStefano Zampini     }
12594cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
12604cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
12614cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
12624cb006feSStefano Zampini   }
12634cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
12644cb006feSStefano Zampini   /* pass parCSR vectors to AMS solver */
12654cb006feSStefano Zampini   par_coords[0] = NULL;
12664cb006feSStefano Zampini   par_coords[1] = NULL;
12674cb006feSStefano Zampini   par_coords[2] = NULL;
12684cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&par_coords[0])));
12694cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&par_coords[1])));
12704cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&par_coords[2])));
1271863406b8SStefano Zampini   PetscStackCall("Hypre set coords",ierr = (*jac->setcoord)(jac->hsolver,par_coords[0],par_coords[1],par_coords[2]);CHKERRQ(ierr););
12724cb006feSStefano Zampini   PetscFunctionReturn(0);
12734cb006feSStefano Zampini }
12744cb006feSStefano Zampini 
127516d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
127616d9e3a6SLisandro Dalcin 
127716d9e3a6SLisandro Dalcin #undef __FUNCT__
127816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
1279f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
128016d9e3a6SLisandro Dalcin {
128116d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
128216d9e3a6SLisandro Dalcin 
128316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
128416d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
128516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
128616d9e3a6SLisandro Dalcin }
128716d9e3a6SLisandro Dalcin 
128816d9e3a6SLisandro Dalcin #undef __FUNCT__
128916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
1290f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
129116d9e3a6SLisandro Dalcin {
129216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
129316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1294ace3abfcSBarry Smith   PetscBool      flag;
129516d9e3a6SLisandro Dalcin 
129616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
129716d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
129816d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1299ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
130016d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
130116d9e3a6SLisandro Dalcin   } else {
130216d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
130316d9e3a6SLisandro Dalcin   }
130416d9e3a6SLisandro Dalcin 
130516d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
130616d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
130716d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
130816d9e3a6SLisandro Dalcin 
130916d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
131016d9e3a6SLisandro Dalcin   if (flag) {
1311fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
131216d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
131316d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
131416d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
131516d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
131616d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
131716d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
131816d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
131916d9e3a6SLisandro Dalcin   }
132016d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
132116d9e3a6SLisandro Dalcin   if (flag) {
1322fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
132316d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
132416d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
132516d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
132616d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
132716d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
132816d9e3a6SLisandro Dalcin     /* initialize */
132916d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
133016d9e3a6SLisandro Dalcin     jac->threshhold = .1;
133116d9e3a6SLisandro Dalcin     jac->filter     = .1;
133216d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
13332fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
13342fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
13352fa5cd67SKarl Rupp 
133616d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
133716d9e3a6SLisandro Dalcin     jac->symt = 0;
1338fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1339fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1340fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1341fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1342fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1343fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
134416d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
134516d9e3a6SLisandro Dalcin   }
134616d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
134716d9e3a6SLisandro Dalcin   if (flag) {
134816d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
134916d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
135016d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
135116d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
135216d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
135316d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
135416d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
135516d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
135616d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
135716d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
135816d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
135916d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
136016d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
13618f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
136216d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
136316d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
136416d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
136516d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
136616d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
13670f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
13686a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1369*b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
13708f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
13710f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
137216d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
137316d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
137416d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
13750f1074feSSatish Balay     jac->interptype       = 0;
13760f1074feSSatish Balay     jac->agg_nl           = 0;
13770f1074feSSatish Balay     jac->pmax             = 0;
13780f1074feSSatish Balay     jac->truncfactor      = 0.0;
13790f1074feSSatish Balay     jac->agg_num_paths    = 1;
13808f87f92bSBarry Smith 
13818f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
13828f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
13838f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1384fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1385fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1386fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1387fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1388fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1389fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1390fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1391fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1392fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1393fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1394fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1395fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1396fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1397fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1398fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1399fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
140016d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
140116d9e3a6SLisandro Dalcin   }
14024cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
14034cb006feSStefano Zampini   if (flag) {
14044cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
14054cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
14064cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
14074cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
14084cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
14094cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
1410863406b8SStefano Zampini     jac->setdgrad            = HYPRE_AMSSetDiscreteGradient;
1411863406b8SStefano Zampini     jac->setcoord            = HYPRE_AMSSetCoordinateVectors;
1412863406b8SStefano Zampini     jac->setdim              = HYPRE_AMSSetDimension;
14134cb006feSStefano Zampini     jac->coords[0]           = NULL;
14144cb006feSStefano Zampini     jac->coords[1]           = NULL;
14154cb006feSStefano Zampini     jac->coords[2]           = NULL;
14164cb006feSStefano Zampini     jac->G                   = NULL;
14174cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1418863406b8SStefano Zampini     jac->as_print           = 0;
1419863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1420863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
14214cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
14224cb006feSStefano Zampini     /* Smoothing options */
1423863406b8SStefano Zampini     jac->as_relax_type      = 2;
1424863406b8SStefano Zampini     jac->as_relax_times     = 1;
1425863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1426863406b8SStefano Zampini     jac->as_omega           = 1.0;
14274cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1428863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1429863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1430863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 8;
1431863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1432863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1433863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
14344cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
14354cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_FALSE;
1436863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1437863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1438863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 8;
1439863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1440863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1441863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1442863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1443863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
14444cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1445863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1446863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1447863406b8SStefano Zampini                                                                       jac->as_relax_times,
1448863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1449863406b8SStefano Zampini                                                                       jac->as_omega));
1450863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1451863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1452863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1453863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1454863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1455863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1456863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1457863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1458863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1459863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1460863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1461863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1462863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1463863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
14644cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE_AMS);CHKERRQ(ierr);
14654cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
14664cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",PCHYPRESetBetaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
14674cb006feSStefano Zampini     PetscFunctionReturn(0);
14684cb006feSStefano Zampini   }
1469863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1470863406b8SStefano Zampini   if (flag) {
1471863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1472863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1473863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1474863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1475863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1476863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1477863406b8SStefano Zampini     jac->setdgrad            = HYPRE_ADSSetDiscreteGradient;
1478863406b8SStefano Zampini     jac->setdcurl            = HYPRE_ADSSetDiscreteCurl;
1479863406b8SStefano Zampini     jac->setcoord            = HYPRE_ADSSetCoordinateVectors;
1480863406b8SStefano Zampini     jac->coords[0]           = NULL;
1481863406b8SStefano Zampini     jac->coords[1]           = NULL;
1482863406b8SStefano Zampini     jac->coords[2]           = NULL;
1483863406b8SStefano Zampini     jac->G                   = NULL;
1484863406b8SStefano Zampini     jac->C                   = NULL;
1485863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1486863406b8SStefano Zampini     jac->as_print           = 0;
1487863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1488863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1489863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1490863406b8SStefano Zampini     /* Smoothing options */
1491863406b8SStefano Zampini     jac->as_relax_type      = 2;
1492863406b8SStefano Zampini     jac->as_relax_times     = 1;
1493863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1494863406b8SStefano Zampini     jac->as_omega           = 1.0;
1495863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1496863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1497863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1498863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1499863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1500863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1501863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1502863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1503863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1504863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1505863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1506863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1507863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1508863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1509863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1510863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1511863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1512863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1513863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1514863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1515863406b8SStefano Zampini                                                                       jac->as_relax_times,
1516863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1517863406b8SStefano Zampini                                                                       jac->as_omega));
1518863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1519863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1520863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1521863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1522863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1523863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1524863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1525863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1526863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1527863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1528863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1529863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1530863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1531863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1532863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
1533863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
1534863406b8SStefano Zampini     PetscFunctionReturn(0);
1535863406b8SStefano Zampini   }
1536503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
15372fa5cd67SKarl Rupp 
15380298fd71SBarry Smith   jac->hypre_type = NULL;
153933263987SBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, boomeramg, ams",name);
154016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
154116d9e3a6SLisandro Dalcin }
154216d9e3a6SLisandro Dalcin 
154316d9e3a6SLisandro Dalcin /*
154416d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
154516d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
154616d9e3a6SLisandro Dalcin */
154716d9e3a6SLisandro Dalcin #undef __FUNCT__
154816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
15498c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptions *PetscOptionsObject,PC pc)
155016d9e3a6SLisandro Dalcin {
155116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
15524ddd07fcSJed Brown   PetscInt       indx;
1553863406b8SStefano Zampini   const char     *type[] = {"pilut","parasails","boomeramg","ams","ads"};
1554ace3abfcSBarry Smith   PetscBool      flg;
155516d9e3a6SLisandro Dalcin 
155616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
15579fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
15589c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
155916d9e3a6SLisandro Dalcin   if (flg) {
156016d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
156102a17cd4SBarry Smith   } else {
156202a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
156316d9e3a6SLisandro Dalcin   }
156416d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
15653931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
156616d9e3a6SLisandro Dalcin   }
156716d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
156816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
156916d9e3a6SLisandro Dalcin }
157016d9e3a6SLisandro Dalcin 
157116d9e3a6SLisandro Dalcin #undef __FUNCT__
157216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
157316d9e3a6SLisandro Dalcin /*@C
157416d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
157516d9e3a6SLisandro Dalcin 
157616d9e3a6SLisandro Dalcin    Input Parameters:
157716d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1578863406b8SStefano Zampini -     name - either  pilut, parasails, boomeramg, ams, ads
157916d9e3a6SLisandro Dalcin 
158016d9e3a6SLisandro Dalcin    Options Database Keys:
1581863406b8SStefano Zampini    -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
158216d9e3a6SLisandro Dalcin 
158316d9e3a6SLisandro Dalcin    Level: intermediate
158416d9e3a6SLisandro Dalcin 
158516d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
158616d9e3a6SLisandro Dalcin            PCHYPRE
158716d9e3a6SLisandro Dalcin 
158816d9e3a6SLisandro Dalcin @*/
15897087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
159016d9e3a6SLisandro Dalcin {
15914ac538c5SBarry Smith   PetscErrorCode ierr;
159216d9e3a6SLisandro Dalcin 
159316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
15940700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
159516d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
15964ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
159716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
159816d9e3a6SLisandro Dalcin }
159916d9e3a6SLisandro Dalcin 
160016d9e3a6SLisandro Dalcin #undef __FUNCT__
160116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
160216d9e3a6SLisandro Dalcin /*@C
160316d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
160416d9e3a6SLisandro Dalcin 
160516d9e3a6SLisandro Dalcin    Input Parameter:
160616d9e3a6SLisandro Dalcin .     pc - the preconditioner context
160716d9e3a6SLisandro Dalcin 
160816d9e3a6SLisandro Dalcin    Output Parameter:
1609863406b8SStefano Zampini .     name - either  pilut, parasails, boomeramg, ams, ads
161016d9e3a6SLisandro Dalcin 
161116d9e3a6SLisandro Dalcin    Level: intermediate
161216d9e3a6SLisandro Dalcin 
161316d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
161416d9e3a6SLisandro Dalcin            PCHYPRE
161516d9e3a6SLisandro Dalcin 
161616d9e3a6SLisandro Dalcin @*/
16177087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
161816d9e3a6SLisandro Dalcin {
16194ac538c5SBarry Smith   PetscErrorCode ierr;
162016d9e3a6SLisandro Dalcin 
162116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16220700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
162316d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
16244ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
162516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
162616d9e3a6SLisandro Dalcin }
162716d9e3a6SLisandro Dalcin 
162816d9e3a6SLisandro Dalcin /*MC
162916d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
163016d9e3a6SLisandro Dalcin 
163116d9e3a6SLisandro Dalcin    Options Database Keys:
1632863406b8SStefano Zampini +   -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
163316d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
163416d9e3a6SLisandro Dalcin           preconditioner
163516d9e3a6SLisandro Dalcin 
163616d9e3a6SLisandro Dalcin    Level: intermediate
163716d9e3a6SLisandro Dalcin 
163816d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
163916d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
164016d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
164116d9e3a6SLisandro Dalcin 
164216d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
16430f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
16440f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
16450f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
16468f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
16470f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
16480f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
164916d9e3a6SLisandro Dalcin 
16500f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
16510f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
16520f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
165316d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
165416d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
165516d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
165616d9e3a6SLisandro Dalcin 
165716d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
165816d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
165916d9e3a6SLisandro Dalcin 
16609e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
16619e5bc791SBarry Smith 
166216d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
16639e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
166416d9e3a6SLisandro Dalcin 
166516d9e3a6SLisandro Dalcin M*/
166616d9e3a6SLisandro Dalcin 
166716d9e3a6SLisandro Dalcin #undef __FUNCT__
166816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
16698cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
167016d9e3a6SLisandro Dalcin {
167116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
167216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
167316d9e3a6SLisandro Dalcin 
167416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1675b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
16762fa5cd67SKarl Rupp 
167716d9e3a6SLisandro Dalcin   pc->data                = jac;
167816d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
167916d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
168016d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
168116d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
168216d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
16830298fd71SBarry Smith   jac->hypre_type         = NULL;
16844cb006feSStefano Zampini   jac->coords[0]          = NULL;
16854cb006feSStefano Zampini   jac->coords[1]          = NULL;
16864cb006feSStefano Zampini   jac->coords[2]          = NULL;
16874cb006feSStefano Zampini   jac->constants[0]       = NULL;
16884cb006feSStefano Zampini   jac->constants[1]       = NULL;
16894cb006feSStefano Zampini   jac->constants[2]       = NULL;
1690863406b8SStefano Zampini   jac->G                  = NULL;
1691863406b8SStefano Zampini   jac->C                  = NULL;
1692863406b8SStefano Zampini   jac->alpha_Poisson      = NULL;
1693863406b8SStefano Zampini   jac->beta_Poisson       = NULL;
1694fd444223SStefano Zampini   jac->setdim             = NULL;
169516d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1696ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1697bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1698bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
169916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
170016d9e3a6SLisandro Dalcin }
1701ebc551c0SBarry Smith 
1702f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1703f91d8e95SBarry Smith 
1704b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1705af0996ceSBarry Smith #include <petsc/private/matimpl.h>
1706ebc551c0SBarry Smith 
1707ebc551c0SBarry Smith typedef struct {
170868326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1709f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
17109e5bc791SBarry Smith 
17119e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
17124ddd07fcSJed Brown   PetscInt its;
17139e5bc791SBarry Smith   double   tol;
17144ddd07fcSJed Brown   PetscInt relax_type;
17154ddd07fcSJed Brown   PetscInt rap_type;
17164ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
17174ddd07fcSJed Brown   PetscInt max_levels;
1718ebc551c0SBarry Smith } PC_PFMG;
1719ebc551c0SBarry Smith 
1720ebc551c0SBarry Smith #undef __FUNCT__
1721ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1722ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1723ebc551c0SBarry Smith {
1724ebc551c0SBarry Smith   PetscErrorCode ierr;
1725f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1726ebc551c0SBarry Smith 
1727ebc551c0SBarry Smith   PetscFunctionBegin;
17282fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1729f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1730c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1731ebc551c0SBarry Smith   PetscFunctionReturn(0);
1732ebc551c0SBarry Smith }
1733ebc551c0SBarry Smith 
17349e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
17359e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
17369e5bc791SBarry Smith 
1737ebc551c0SBarry Smith #undef __FUNCT__
1738ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1739ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1740ebc551c0SBarry Smith {
1741ebc551c0SBarry Smith   PetscErrorCode ierr;
1742ace3abfcSBarry Smith   PetscBool      iascii;
1743f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1744ebc551c0SBarry Smith 
1745ebc551c0SBarry Smith   PetscFunctionBegin;
1746251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
17479e5bc791SBarry Smith   if (iascii) {
17489e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
17499e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
17509e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
17519e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
17529e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
17539e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
17543b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
17559e5bc791SBarry Smith   }
1756ebc551c0SBarry Smith   PetscFunctionReturn(0);
1757ebc551c0SBarry Smith }
1758ebc551c0SBarry Smith 
17599e5bc791SBarry Smith 
1760ebc551c0SBarry Smith #undef __FUNCT__
1761ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
17628c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptions *PetscOptionsObject,PC pc)
1763ebc551c0SBarry Smith {
1764ebc551c0SBarry Smith   PetscErrorCode ierr;
1765f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1766ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1767ebc551c0SBarry Smith 
1768ebc551c0SBarry Smith   PetscFunctionBegin;
1769e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
17700298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
177168326731SBarry Smith   if (flg) {
1772a0324ebeSBarry Smith     int level=3;
1773fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
177468326731SBarry Smith   }
17750298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1776fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
17770298fd71SBarry 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);
1778fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
17790298fd71SBarry 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);
1780fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
17819e5bc791SBarry Smith 
17820298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
1783fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
17843b46a515SGlenn Hammond 
17850298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1786fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
17870298fd71SBarry 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);
1788fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
17890298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
1790fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1791ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1792ebc551c0SBarry Smith   PetscFunctionReturn(0);
1793ebc551c0SBarry Smith }
1794ebc551c0SBarry Smith 
1795f91d8e95SBarry Smith #undef __FUNCT__
1796f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1797f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1798f91d8e95SBarry Smith {
1799f91d8e95SBarry Smith   PetscErrorCode    ierr;
1800f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
1801d9ca1df4SBarry Smith   PetscScalar       *yy;
1802d9ca1df4SBarry Smith   const PetscScalar *xx;
18034ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
180468326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1805f91d8e95SBarry Smith 
1806f91d8e95SBarry Smith   PetscFunctionBegin;
1807dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1808aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1809f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1810f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1811f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1812f91d8e95SBarry Smith 
1813f91d8e95SBarry Smith   /* copy x values over to hypre */
1814fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1815d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1816d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
1817d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1818fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
1819fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1820f91d8e95SBarry Smith 
1821f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1822f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
18238b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
1824f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1825f91d8e95SBarry Smith   PetscFunctionReturn(0);
1826f91d8e95SBarry Smith }
1827f91d8e95SBarry Smith 
18289e5bc791SBarry Smith #undef __FUNCT__
18299e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1830ace3abfcSBarry 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)
18319e5bc791SBarry Smith {
18329e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
18339e5bc791SBarry Smith   PetscErrorCode ierr;
18344ddd07fcSJed Brown   PetscInt       oits;
18359e5bc791SBarry Smith 
18369e5bc791SBarry Smith   PetscFunctionBegin;
1837dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1838fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1839fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
18409e5bc791SBarry Smith 
18419e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
18428b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
18439e5bc791SBarry Smith   *outits = oits;
18449e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
18459e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1846fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1847fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
18489e5bc791SBarry Smith   PetscFunctionReturn(0);
18499e5bc791SBarry Smith }
18509e5bc791SBarry Smith 
18519e5bc791SBarry Smith 
18523a32d3dbSGlenn Hammond #undef __FUNCT__
18533a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
18543a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
18553a32d3dbSGlenn Hammond {
18563a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
18573a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
18583a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1859ace3abfcSBarry Smith   PetscBool       flg;
18603a32d3dbSGlenn Hammond 
18613a32d3dbSGlenn Hammond   PetscFunctionBegin;
1862251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1863ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
18643a32d3dbSGlenn Hammond 
18653a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
18662fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1867fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1868fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1869fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
18703a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
18713a32d3dbSGlenn Hammond }
18723a32d3dbSGlenn Hammond 
1873ebc551c0SBarry Smith 
1874ebc551c0SBarry Smith /*MC
1875ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1876ebc551c0SBarry Smith 
1877ebc551c0SBarry Smith    Level: advanced
1878ebc551c0SBarry Smith 
18799e5bc791SBarry Smith    Options Database:
18809e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
18819e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
18829e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
18839e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
18849e5bc791SBarry 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
18859e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
1886f91d8e95SBarry Smith 
18879e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
18889e5bc791SBarry Smith 
18898e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
1890aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
18919e5bc791SBarry Smith 
18929e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
1893ebc551c0SBarry Smith M*/
1894ebc551c0SBarry Smith 
1895ebc551c0SBarry Smith #undef __FUNCT__
1896ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
18978cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
1898ebc551c0SBarry Smith {
1899ebc551c0SBarry Smith   PetscErrorCode ierr;
1900ebc551c0SBarry Smith   PC_PFMG        *ex;
1901ebc551c0SBarry Smith 
1902ebc551c0SBarry Smith   PetscFunctionBegin;
1903b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
190468326731SBarry Smith   pc->data = ex;
1905ebc551c0SBarry Smith 
19069e5bc791SBarry Smith   ex->its            = 1;
19079e5bc791SBarry Smith   ex->tol            = 1.e-8;
19089e5bc791SBarry Smith   ex->relax_type     = 1;
19099e5bc791SBarry Smith   ex->rap_type       = 0;
19109e5bc791SBarry Smith   ex->num_pre_relax  = 1;
19119e5bc791SBarry Smith   ex->num_post_relax = 1;
19123b46a515SGlenn Hammond   ex->max_levels     = 0;
19139e5bc791SBarry Smith 
1914ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
1915ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
1916ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
1917f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
19189e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
191968326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
19202fa5cd67SKarl Rupp 
1921ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
1922fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1923ebc551c0SBarry Smith   PetscFunctionReturn(0);
1924ebc551c0SBarry Smith }
1925d851a50bSGlenn Hammond 
1926325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
1927325fc9f4SBarry Smith 
1928d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
1929d851a50bSGlenn Hammond typedef struct {
1930d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
1931d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
1932d851a50bSGlenn Hammond 
1933d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
19344ddd07fcSJed Brown   PetscInt its;
1935d851a50bSGlenn Hammond   double   tol;
19364ddd07fcSJed Brown   PetscInt relax_type;
19374ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
1938d851a50bSGlenn Hammond } PC_SysPFMG;
1939d851a50bSGlenn Hammond 
1940d851a50bSGlenn Hammond #undef __FUNCT__
1941d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
1942d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
1943d851a50bSGlenn Hammond {
1944d851a50bSGlenn Hammond   PetscErrorCode ierr;
1945d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1946d851a50bSGlenn Hammond 
1947d851a50bSGlenn Hammond   PetscFunctionBegin;
19482fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1949d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1950c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1951d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1952d851a50bSGlenn Hammond }
1953d851a50bSGlenn Hammond 
1954d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
1955d851a50bSGlenn Hammond 
1956d851a50bSGlenn Hammond #undef __FUNCT__
1957d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
1958d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
1959d851a50bSGlenn Hammond {
1960d851a50bSGlenn Hammond   PetscErrorCode ierr;
1961ace3abfcSBarry Smith   PetscBool      iascii;
1962d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1963d851a50bSGlenn Hammond 
1964d851a50bSGlenn Hammond   PetscFunctionBegin;
1965251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1966d851a50bSGlenn Hammond   if (iascii) {
1967d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
1968d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
1969d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
1970d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
1971d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
1972d851a50bSGlenn Hammond   }
1973d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1974d851a50bSGlenn Hammond }
1975d851a50bSGlenn Hammond 
1976d851a50bSGlenn Hammond 
1977d851a50bSGlenn Hammond #undef __FUNCT__
1978d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
19798c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptions *PetscOptionsObject,PC pc)
1980d851a50bSGlenn Hammond {
1981d851a50bSGlenn Hammond   PetscErrorCode ierr;
1982d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1983ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1984d851a50bSGlenn Hammond 
1985d851a50bSGlenn Hammond   PetscFunctionBegin;
1986e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
19870298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
1988d851a50bSGlenn Hammond   if (flg) {
1989d851a50bSGlenn Hammond     int level=3;
1990fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
1991d851a50bSGlenn Hammond   }
19920298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1993fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
19940298fd71SBarry 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);
1995fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
19960298fd71SBarry 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);
1997fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
1998d851a50bSGlenn Hammond 
19990298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2000fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
20010298fd71SBarry 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);
2002fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2003d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2004d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2005d851a50bSGlenn Hammond }
2006d851a50bSGlenn Hammond 
2007d851a50bSGlenn Hammond #undef __FUNCT__
2008d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
2009d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2010d851a50bSGlenn Hammond {
2011d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2012d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2013d9ca1df4SBarry Smith   PetscScalar       *yy;
2014d9ca1df4SBarry Smith   const PetscScalar *xx;
20154ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
2016d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
20174ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
20184ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
20194ddd07fcSJed Brown   PetscInt          part    = 0;
20204ddd07fcSJed Brown   PetscInt          size;
20214ddd07fcSJed Brown   PetscInt          i;
2022d851a50bSGlenn Hammond 
2023d851a50bSGlenn Hammond   PetscFunctionBegin;
2024dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2025aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2026d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2027d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2028d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2029d851a50bSGlenn Hammond 
2030d851a50bSGlenn Hammond   size = 1;
20312fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
20322fa5cd67SKarl Rupp 
2033d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2034d851a50bSGlenn Hammond   if (ordering) {
2035fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2036d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2037d9ca1df4SBarry 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)));
2038d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2039fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2040fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2041fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2042d851a50bSGlenn Hammond 
2043d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2044d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
20458b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2046d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2047a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2048d851a50bSGlenn Hammond     PetscScalar *z;
20494ddd07fcSJed Brown     PetscInt    j, k;
2050d851a50bSGlenn Hammond 
2051785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2052fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2053d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2054d851a50bSGlenn Hammond 
2055d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2056d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2057d851a50bSGlenn Hammond       k= i*nvars;
20582fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2059d851a50bSGlenn Hammond     }
20608b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2061d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2062fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2063fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2064d851a50bSGlenn Hammond 
2065d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2066d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
20678b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2068d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2069d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2070d851a50bSGlenn Hammond       k= i*nvars;
20712fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2072d851a50bSGlenn Hammond     }
2073d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2074d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2075d851a50bSGlenn Hammond   }
2076d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2077d851a50bSGlenn Hammond }
2078d851a50bSGlenn Hammond 
2079d851a50bSGlenn Hammond #undef __FUNCT__
2080d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
2081ace3abfcSBarry 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)
2082d851a50bSGlenn Hammond {
2083d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2084d851a50bSGlenn Hammond   PetscErrorCode ierr;
20854ddd07fcSJed Brown   PetscInt       oits;
2086d851a50bSGlenn Hammond 
2087d851a50bSGlenn Hammond   PetscFunctionBegin;
2088dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2089fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2090fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2091d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
20928b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2093d851a50bSGlenn Hammond   *outits = oits;
2094d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2095d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2096fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2097fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2098d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2099d851a50bSGlenn Hammond }
2100d851a50bSGlenn Hammond 
2101d851a50bSGlenn Hammond 
2102d851a50bSGlenn Hammond #undef __FUNCT__
2103d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
2104d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2105d851a50bSGlenn Hammond {
2106d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2107d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2108d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2109ace3abfcSBarry Smith   PetscBool        flg;
2110d851a50bSGlenn Hammond 
2111d851a50bSGlenn Hammond   PetscFunctionBegin;
2112251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2113ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2114d851a50bSGlenn Hammond 
2115d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
21162fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2117fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2118fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2119fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2120d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2121d851a50bSGlenn Hammond }
2122d851a50bSGlenn Hammond 
2123d851a50bSGlenn Hammond 
2124d851a50bSGlenn Hammond /*MC
2125d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2126d851a50bSGlenn Hammond 
2127d851a50bSGlenn Hammond    Level: advanced
2128d851a50bSGlenn Hammond 
2129d851a50bSGlenn Hammond    Options Database:
2130d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2131d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2132d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2133d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2134d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2135d851a50bSGlenn Hammond 
2136d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
2137d851a50bSGlenn Hammond 
2138f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2139aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2140d851a50bSGlenn Hammond            Also, only cell-centered variables.
2141d851a50bSGlenn Hammond 
2142d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2143d851a50bSGlenn Hammond M*/
2144d851a50bSGlenn Hammond 
2145d851a50bSGlenn Hammond #undef __FUNCT__
2146d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
21478cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2148d851a50bSGlenn Hammond {
2149d851a50bSGlenn Hammond   PetscErrorCode ierr;
2150d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2151d851a50bSGlenn Hammond 
2152d851a50bSGlenn Hammond   PetscFunctionBegin;
2153b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2154d851a50bSGlenn Hammond   pc->data = ex;
2155d851a50bSGlenn Hammond 
2156d851a50bSGlenn Hammond   ex->its            = 1;
2157d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2158d851a50bSGlenn Hammond   ex->relax_type     = 1;
2159d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2160d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2161d851a50bSGlenn Hammond 
2162d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2163d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2164d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2165d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2166d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2167d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
21682fa5cd67SKarl Rupp 
2169ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2170fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2171d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2172d851a50bSGlenn Hammond }
2173