xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 37096e45aa9753169c2f7861fc44754b85103e49)
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;
64ec64516dSEike Mueller   PetscInt  eu_level;   /* Number of levels for ILU(k) in Euclid */
65ec64516dSEike Mueller   double    eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */
66ec64516dSEike Mueller   PetscInt  eu_bj;      /* Defines use of Block Jacobi ILU in Euclid */
674ddd07fcSJed Brown   PetscInt  relaxtype[3];
6816d9e3a6SLisandro Dalcin   double    relaxweight;
6916d9e3a6SLisandro Dalcin   double    outerrelaxweight;
704ddd07fcSJed Brown   PetscInt  relaxorder;
7116d9e3a6SLisandro Dalcin   double    truncfactor;
72ace3abfcSBarry Smith   PetscBool applyrichardson;
734ddd07fcSJed Brown   PetscInt  pmax;
744ddd07fcSJed Brown   PetscInt  interptype;
754ddd07fcSJed Brown   PetscInt  agg_nl;
764ddd07fcSJed Brown   PetscInt  agg_num_paths;
774ddd07fcSJed Brown   PetscInt  nodal_coarsen;
78ace3abfcSBarry Smith   PetscBool nodal_relax;
794ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
804cb006feSStefano Zampini 
81863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
82863406b8SStefano Zampini   PetscInt  as_print;
83863406b8SStefano Zampini   PetscInt  as_max_iter;
84863406b8SStefano Zampini   PetscReal as_tol;
85863406b8SStefano Zampini   PetscInt  as_relax_type;
86863406b8SStefano Zampini   PetscInt  as_relax_times;
87863406b8SStefano Zampini   PetscReal as_relax_weight;
88863406b8SStefano Zampini   PetscReal as_omega;
89863406b8SStefano 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) */
90863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
91863406b8SStefano 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) */
92863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
934cb006feSStefano Zampini   PetscInt  ams_cycle_type;
94863406b8SStefano Zampini   PetscInt  ads_cycle_type;
954cb006feSStefano Zampini 
964cb006feSStefano Zampini   /* additional data */
974cb006feSStefano Zampini   HYPRE_IJVector coords[3];
984cb006feSStefano Zampini   HYPRE_IJVector constants[3];
994cb006feSStefano Zampini   HYPRE_IJMatrix G;
100863406b8SStefano Zampini   HYPRE_IJMatrix C;
1014cb006feSStefano Zampini   HYPRE_IJMatrix alpha_Poisson;
1024cb006feSStefano Zampini   HYPRE_IJMatrix beta_Poisson;
1034cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
10416d9e3a6SLisandro Dalcin } PC_HYPRE;
10516d9e3a6SLisandro Dalcin 
106d2128fa2SBarry Smith #undef __FUNCT__
107d2128fa2SBarry Smith #define __FUNCT__ "PCHYPREGetSolver"
108d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
109d2128fa2SBarry Smith {
110d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
111d2128fa2SBarry Smith 
112d2128fa2SBarry Smith   PetscFunctionBegin;
113d2128fa2SBarry Smith   *hsolver = jac->hsolver;
114d2128fa2SBarry Smith   PetscFunctionReturn(0);
115d2128fa2SBarry Smith }
11616d9e3a6SLisandro Dalcin 
11716d9e3a6SLisandro Dalcin #undef __FUNCT__
11816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE"
11916d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
12016d9e3a6SLisandro Dalcin {
12116d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
12216d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
12316d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
12416d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
12516d9e3a6SLisandro Dalcin   PetscInt           bs;
12616d9e3a6SLisandro Dalcin 
12716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
12816d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
12902a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
13016d9e3a6SLisandro Dalcin   }
1315f5c5b43SBarry Smith 
1325f5c5b43SBarry Smith   if (pc->setupcalled) {
1335f5c5b43SBarry Smith     /* always destroy the old matrix and create a new memory;
1345f5c5b43SBarry Smith        hope this does not churn the memory too much. The problem
1355f5c5b43SBarry Smith        is I do not know if it is possible to put the matrix back to
1365f5c5b43SBarry Smith        its initial state so that we can directly copy the values
1375f5c5b43SBarry Smith        the second time through. */
138fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
1395f5c5b43SBarry Smith     jac->ij = 0;
14016d9e3a6SLisandro Dalcin   }
1415f5c5b43SBarry Smith 
14216d9e3a6SLisandro Dalcin   if (!jac->ij) { /* create the matrix the first time through */
14316d9e3a6SLisandro Dalcin     ierr = MatHYPRE_IJMatrixCreate(pc->pmat,&jac->ij);CHKERRQ(ierr);
14416d9e3a6SLisandro Dalcin   }
14516d9e3a6SLisandro Dalcin   if (!jac->b) { /* create the vectors the first time through */
14616d9e3a6SLisandro Dalcin     Vec x,b;
1472a7a6963SBarry Smith     ierr = MatCreateVecs(pc->pmat,&x,&b);CHKERRQ(ierr);
14816d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(x,&jac->x);CHKERRQ(ierr);
14916d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(b,&jac->b);CHKERRQ(ierr);
1506bf464f9SBarry Smith     ierr = VecDestroy(&x);CHKERRQ(ierr);
1516bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
15216d9e3a6SLisandro Dalcin   }
1535f5c5b43SBarry Smith 
15416d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
15516d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
15616d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1572fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
1584cb006feSStefano Zampini   }
159863406b8SStefano Zampini 
1604cb006feSStefano Zampini   /* special case for AMS */
1614cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
1624cb006feSStefano 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()");
1634cb006feSStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
1644cb006feSStefano Zampini   }
165863406b8SStefano Zampini   /* special case for ADS */
166863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
167*37096e45SBarry Smith     if (!jac->coords[0]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs coordinate vectors via PCSetCoordinates()");
168*37096e45SBarry Smith     else if (!jac->coords[1] || !jac->coords[2]) 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");
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 
4871810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
4881810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
4891810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
4901810e44eSEike Mueller     jac->eu_level = indx;
4911810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
4921810e44eSEike Mueller   }
4931810e44eSEike Mueller 
4941810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
4951810e44eSEike Mueller   double droptolerance;
4961810e44eSEike Mueller   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
4971810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
4981810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
4991810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
5001810e44eSEike Mueller   }
5011810e44eSEike Mueller 
5021810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
5031810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5041810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
5051810e44eSEike Mueller     jac->eu_bj = tmp_truth;
506493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
5071810e44eSEike Mueller   }
5081810e44eSEike Mueller 
50916d9e3a6SLisandro Dalcin   /* Relax type */
510a669f990SJed 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);
51116d9e3a6SLisandro Dalcin   if (flg) {
5120f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
513fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
5140f1074feSSatish Balay     /* by default, coarse type set to 9 */
5150f1074feSSatish Balay     jac->relaxtype[2] = 9;
5160f1074feSSatish Balay 
51716d9e3a6SLisandro Dalcin   }
518a669f990SJed 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);
51916d9e3a6SLisandro Dalcin   if (flg) {
52016d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
521fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
52216d9e3a6SLisandro Dalcin   }
523a669f990SJed 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);
52416d9e3a6SLisandro Dalcin   if (flg) {
5250f1074feSSatish Balay     jac->relaxtype[1] = indx;
526fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
52716d9e3a6SLisandro Dalcin   }
528a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
52916d9e3a6SLisandro Dalcin   if (flg) {
5300f1074feSSatish Balay     jac->relaxtype[2] = indx;
531fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
53216d9e3a6SLisandro Dalcin   }
53316d9e3a6SLisandro Dalcin 
53416d9e3a6SLisandro Dalcin   /* Relaxation Weight */
53516d9e3a6SLisandro 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);
53616d9e3a6SLisandro Dalcin   if (flg) {
537fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
53816d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
53916d9e3a6SLisandro Dalcin   }
54016d9e3a6SLisandro Dalcin 
54116d9e3a6SLisandro Dalcin   n         = 2;
54216d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
54316d9e3a6SLisandro 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);
54416d9e3a6SLisandro Dalcin   if (flg) {
54516d9e3a6SLisandro Dalcin     if (n == 2) {
54616d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
547fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
548ce94432eSBarry 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);
54916d9e3a6SLisandro Dalcin   }
55016d9e3a6SLisandro Dalcin 
55116d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
55216d9e3a6SLisandro 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);
55316d9e3a6SLisandro Dalcin   if (flg) {
554fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
55516d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
55616d9e3a6SLisandro Dalcin   }
55716d9e3a6SLisandro Dalcin 
55816d9e3a6SLisandro Dalcin   n         = 2;
55916d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
56016d9e3a6SLisandro 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);
56116d9e3a6SLisandro Dalcin   if (flg) {
56216d9e3a6SLisandro Dalcin     if (n == 2) {
56316d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
564fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
565ce94432eSBarry 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);
56616d9e3a6SLisandro Dalcin   }
56716d9e3a6SLisandro Dalcin 
56816d9e3a6SLisandro Dalcin   /* the Relax Order */
569acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
57016d9e3a6SLisandro Dalcin 
5718afaa268SBarry Smith   if (flg && tmp_truth) {
57216d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
573fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
57416d9e3a6SLisandro Dalcin   }
575a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
57616d9e3a6SLisandro Dalcin   if (flg) {
57716d9e3a6SLisandro Dalcin     jac->measuretype = indx;
578fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
57916d9e3a6SLisandro Dalcin   }
5800f1074feSSatish Balay   /* update list length 3/07 */
581a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
58216d9e3a6SLisandro Dalcin   if (flg) {
58316d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
584fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
58516d9e3a6SLisandro Dalcin   }
5860f1074feSSatish Balay 
5870f1074feSSatish Balay   /* new 3/07 */
588a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
5890f1074feSSatish Balay   if (flg) {
5900f1074feSSatish Balay     jac->interptype = indx;
591fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
5920f1074feSSatish Balay   }
5930f1074feSSatish Balay 
594b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
59516d9e3a6SLisandro Dalcin   if (flg) {
596b96a4a96SBarry Smith     level = 3;
5970298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
5982fa5cd67SKarl Rupp 
599b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
600fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
6012ae77aedSBarry Smith   }
6022ae77aedSBarry Smith 
603b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
6042ae77aedSBarry Smith   if (flg) {
605b96a4a96SBarry Smith     level = 3;
6060298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
6072fa5cd67SKarl Rupp 
608b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
609fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
61016d9e3a6SLisandro Dalcin   }
6118f87f92bSBarry Smith 
6128afaa268SBarry Smith   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_coarsen", "HYPRE_BoomerAMGSetNodal()", "None", jac->nodal_coarsen ? PETSC_TRUE : PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
6138f87f92bSBarry Smith   if (flg && tmp_truth) {
6148f87f92bSBarry Smith     jac->nodal_coarsen = 1;
615fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,1));
6168f87f92bSBarry Smith   }
6178f87f92bSBarry Smith 
618acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
6198f87f92bSBarry Smith   if (flg && tmp_truth) {
6208f87f92bSBarry Smith     PetscInt tmp_int;
6218f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
6228f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
623fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
624fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
625fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
626fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
6278f87f92bSBarry Smith   }
6288f87f92bSBarry Smith 
62916d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
63016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
63116d9e3a6SLisandro Dalcin }
63216d9e3a6SLisandro Dalcin 
63316d9e3a6SLisandro Dalcin #undef __FUNCT__
63416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG"
635ace3abfcSBarry 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)
63616d9e3a6SLisandro Dalcin {
63716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
63816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
6394ddd07fcSJed Brown   PetscInt       oits;
64016d9e3a6SLisandro Dalcin 
64116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
642dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
643fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
644fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
64516d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
64616d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
64716d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
6488b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
6494d0a8057SBarry Smith   *outits = oits;
6504d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
6514d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
652fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
653fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
65416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
65516d9e3a6SLisandro Dalcin }
65616d9e3a6SLisandro Dalcin 
65716d9e3a6SLisandro Dalcin 
65816d9e3a6SLisandro Dalcin #undef __FUNCT__
65916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG"
66016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
66116d9e3a6SLisandro Dalcin {
66216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
66316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
664ace3abfcSBarry Smith   PetscBool      iascii;
66516d9e3a6SLisandro Dalcin 
66616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
667251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
66816d9e3a6SLisandro Dalcin   if (iascii) {
66916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
67016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
67116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
67216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
67357622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
67457622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
67557622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
6760f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
6770f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
6780f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
6790f1074feSSatish Balay 
68057622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
68116d9e3a6SLisandro Dalcin 
6820f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
6830f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
6840f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
68516d9e3a6SLisandro Dalcin 
6860f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
6870f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
6880f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
68916d9e3a6SLisandro Dalcin 
69057622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
69157622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
69216d9e3a6SLisandro Dalcin 
69316d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
69416d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr);
69516d9e3a6SLisandro Dalcin     } else {
69616d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr);
69716d9e3a6SLisandro Dalcin     }
6986a251517SEike Mueller     if (jac->smoothtype!=-1) {
6996a251517SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
7008131ecf7SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Smooth num levels    %d\n",jac->smoothnumlevels);CHKERRQ(ierr);
7017e352d70SEike Mueller     } else {
7027e352d70SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using more complex smoothers.\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
7031810e44eSEike Mueller     }
7041810e44eSEike Mueller     if (jac->smoothtype==3) {
7051810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU(k) levels %d\n",jac->eu_level);CHKERRQ(ierr);
7061810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU(k) drop tolerance %g\n",jac->eu_droptolerance);CHKERRQ(ierr);
7071810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU use Block-Jacobi? %d\n",jac->eu_bj);CHKERRQ(ierr);
7086a251517SEike Mueller     }
70916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
71016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
7110f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
7128f87f92bSBarry Smith     if (jac->nodal_coarsen) {
7138f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal())\n");CHKERRQ(ierr);
7148f87f92bSBarry Smith     }
7158f87f92bSBarry Smith     if (jac->nodal_relax) {
7168f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
7178f87f92bSBarry Smith     }
71816d9e3a6SLisandro Dalcin   }
71916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
72016d9e3a6SLisandro Dalcin }
72116d9e3a6SLisandro Dalcin 
72216d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
72316d9e3a6SLisandro Dalcin #undef __FUNCT__
72416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails"
7258c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptions *PetscOptionsObject,PC pc)
72616d9e3a6SLisandro Dalcin {
72716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
72816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
7294ddd07fcSJed Brown   PetscInt       indx;
730ace3abfcSBarry Smith   PetscBool      flag;
73116d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
73216d9e3a6SLisandro Dalcin 
73316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
734e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
73516d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
73616d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
7372fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
73816d9e3a6SLisandro Dalcin 
73916d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
7402fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
74116d9e3a6SLisandro Dalcin 
74216d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
7432fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
74416d9e3a6SLisandro Dalcin 
745acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
7462fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
74716d9e3a6SLisandro Dalcin 
748acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
7492fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
75016d9e3a6SLisandro Dalcin 
751a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
75216d9e3a6SLisandro Dalcin   if (flag) {
75316d9e3a6SLisandro Dalcin     jac->symt = indx;
754fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
75516d9e3a6SLisandro Dalcin   }
75616d9e3a6SLisandro Dalcin 
75716d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
75816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
75916d9e3a6SLisandro Dalcin }
76016d9e3a6SLisandro Dalcin 
76116d9e3a6SLisandro Dalcin #undef __FUNCT__
76216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails"
76316d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
76416d9e3a6SLisandro Dalcin {
76516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
76616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
767ace3abfcSBarry Smith   PetscBool      iascii;
76816d9e3a6SLisandro Dalcin   const char     *symt = 0;;
76916d9e3a6SLisandro Dalcin 
77016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
771251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
77216d9e3a6SLisandro Dalcin   if (iascii) {
77316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
77416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
77557622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
77657622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: filter %g\n",(double)jac->filter);CHKERRQ(ierr);
77757622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
778ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
779ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
7802fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
7812fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
7822fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
783ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
78416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr);
78516d9e3a6SLisandro Dalcin   }
78616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
78716d9e3a6SLisandro Dalcin }
7884cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
7894cb006feSStefano Zampini #undef __FUNCT__
7904cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS"
7919fa463a7SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptions *PetscOptionsObject,PC pc)
7924cb006feSStefano Zampini {
7934cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
7944cb006feSStefano Zampini   PetscErrorCode ierr;
7954cb006feSStefano Zampini   PetscInt       n;
7964cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
7974cb006feSStefano Zampini 
7984cb006feSStefano Zampini   PetscFunctionBegin;
7999fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
800863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
801863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
802863406b8SStefano 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);
803863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
8044cb006feSStefano 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);
8054cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
806863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
807863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
808863406b8SStefano 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);
809863406b8SStefano 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);
810863406b8SStefano 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);
811863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
8124cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
813863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
814863406b8SStefano Zampini                                                                       jac->as_relax_times,
815863406b8SStefano Zampini                                                                       jac->as_relax_weight,
816863406b8SStefano Zampini                                                                       jac->as_omega));
8174cb006feSStefano Zampini   }
818863406b8SStefano 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);
8194cb006feSStefano Zampini   n = 5;
820863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
8214cb006feSStefano Zampini   if (flag || flag2) {
822863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
823863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
824863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
825863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
826863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
827863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
8284cb006feSStefano Zampini   }
829863406b8SStefano 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);
8304cb006feSStefano Zampini   n = 5;
831863406b8SStefano 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);
8324cb006feSStefano Zampini   if (flag || flag2) {
833863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
834863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
835863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
836863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
837863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
838863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
8394cb006feSStefano Zampini   }
8404cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
8414cb006feSStefano Zampini   PetscFunctionReturn(0);
8424cb006feSStefano Zampini }
8434cb006feSStefano Zampini 
8444cb006feSStefano Zampini #undef __FUNCT__
8454cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS"
8464cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
8474cb006feSStefano Zampini {
8484cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
8494cb006feSStefano Zampini   PetscErrorCode ierr;
8504cb006feSStefano Zampini   PetscBool      iascii;
8514cb006feSStefano Zampini 
8524cb006feSStefano Zampini   PetscFunctionBegin;
8534cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
8544cb006feSStefano Zampini   if (iascii) {
8554cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
856863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
8574cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
858863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
859863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
860863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
861863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
862863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
8634cb006feSStefano Zampini     if (jac->alpha_Poisson) {
8644cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8654cb006feSStefano Zampini     } else {
8664cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr);
8674cb006feSStefano Zampini     }
868863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
869863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
870863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
871863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
872863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
873863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
8744cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
8754cb006feSStefano Zampini       if (jac->beta_Poisson) {
8764cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8774cb006feSStefano Zampini       } else {
8784cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr);
8794cb006feSStefano Zampini       }
880863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
881863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
882863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
883863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
884863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
885863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
8864cb006feSStefano Zampini     }
8874cb006feSStefano Zampini   }
8884cb006feSStefano Zampini   PetscFunctionReturn(0);
8894cb006feSStefano Zampini }
8904cb006feSStefano Zampini 
8914cb006feSStefano Zampini #undef __FUNCT__
892863406b8SStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_ADS"
893863406b8SStefano Zampini static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptions *PetscOptionsObject,PC pc)
894863406b8SStefano Zampini {
895863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
896863406b8SStefano Zampini   PetscErrorCode ierr;
897863406b8SStefano Zampini   PetscInt       n;
898863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
899863406b8SStefano Zampini 
900863406b8SStefano Zampini   PetscFunctionBegin;
901863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
902863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
903863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
904863406b8SStefano 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);
905863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
906863406b8SStefano 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);
907863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
908863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
909863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
910863406b8SStefano 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);
911863406b8SStefano 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);
912863406b8SStefano 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);
913863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
914863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
915863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
916863406b8SStefano Zampini                                                                       jac->as_relax_times,
917863406b8SStefano Zampini                                                                       jac->as_relax_weight,
918863406b8SStefano Zampini                                                                       jac->as_omega));
919863406b8SStefano Zampini   }
920863406b8SStefano 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);
921863406b8SStefano Zampini   n = 5;
922863406b8SStefano 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);
923863406b8SStefano 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);
924863406b8SStefano Zampini   if (flag || flag2 || flag3) {
925863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
926863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
927863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
928863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
929863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
930863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
931863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
932863406b8SStefano Zampini   }
933863406b8SStefano 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);
934863406b8SStefano Zampini   n = 5;
935863406b8SStefano 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);
936863406b8SStefano Zampini   if (flag || flag2) {
937863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
938863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
939863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
940863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
941863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
942863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
943863406b8SStefano Zampini   }
944863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
945863406b8SStefano Zampini   PetscFunctionReturn(0);
946863406b8SStefano Zampini }
947863406b8SStefano Zampini 
948863406b8SStefano Zampini #undef __FUNCT__
949863406b8SStefano Zampini #define __FUNCT__ "PCView_HYPRE_ADS"
950863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
951863406b8SStefano Zampini {
952863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
953863406b8SStefano Zampini   PetscErrorCode ierr;
954863406b8SStefano Zampini   PetscBool      iascii;
955863406b8SStefano Zampini 
956863406b8SStefano Zampini   PetscFunctionBegin;
957863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
958863406b8SStefano Zampini   if (iascii) {
959863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
960863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
961863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
962863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
963863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
964863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
965863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
966863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
967863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: AMS solver\n");CHKERRQ(ierr);
968863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
969863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
970863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
971863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
972863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
973863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
974863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
975863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: vector Poisson solver\n");CHKERRQ(ierr);
976863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
977863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
978863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
979863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
980863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
981863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
982863406b8SStefano Zampini   }
983863406b8SStefano Zampini   PetscFunctionReturn(0);
984863406b8SStefano Zampini }
985863406b8SStefano Zampini 
986863406b8SStefano Zampini #undef __FUNCT__
987863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE"
988863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
9894cb006feSStefano Zampini {
9904cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
9914cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_G;
9924cb006feSStefano Zampini   PetscErrorCode     ierr;
9934cb006feSStefano Zampini 
9944cb006feSStefano Zampini   PetscFunctionBegin;
9954cb006feSStefano Zampini   /* throw away any discrete gradient if already set */
9964cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
9974cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(G,&jac->G);CHKERRQ(ierr);
9984cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(G,jac->G);CHKERRQ(ierr);
9994cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->G,(void**)(&parcsr_G)));
1000863406b8SStefano Zampini   PetscStackCall("Hypre set gradient",ierr = (*jac->setdgrad)(jac->hsolver,parcsr_G);CHKERRQ(ierr););
10014cb006feSStefano Zampini   PetscFunctionReturn(0);
10024cb006feSStefano Zampini }
10034cb006feSStefano Zampini 
10044cb006feSStefano Zampini #undef __FUNCT__
10054cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient"
10064cb006feSStefano Zampini /*@
10074cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
10084cb006feSStefano Zampini 
10094cb006feSStefano Zampini    Collective on PC
10104cb006feSStefano Zampini 
10114cb006feSStefano Zampini    Input Parameters:
10124cb006feSStefano Zampini +  pc - the preconditioning context
10134cb006feSStefano Zampini -  G - the discrete gradient
10144cb006feSStefano Zampini 
10154cb006feSStefano Zampini    Level: intermediate
10164cb006feSStefano Zampini 
10174cb006feSStefano 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
1018863406b8SStefano 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
10194cb006feSStefano Zampini 
10204cb006feSStefano Zampini .seealso:
10214cb006feSStefano Zampini @*/
10224cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
10234cb006feSStefano Zampini {
10244cb006feSStefano Zampini   PetscErrorCode ierr;
10254cb006feSStefano Zampini 
10264cb006feSStefano Zampini   PetscFunctionBegin;
10274cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
10284cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
10294cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
10304cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
10314cb006feSStefano Zampini   PetscFunctionReturn(0);
10324cb006feSStefano Zampini }
10334cb006feSStefano Zampini 
10344cb006feSStefano Zampini #undef __FUNCT__
1035863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl_HYPRE"
1036863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1037863406b8SStefano Zampini {
1038863406b8SStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
1039863406b8SStefano Zampini   HYPRE_ParCSRMatrix parcsr_C;
1040863406b8SStefano Zampini   PetscErrorCode     ierr;
1041863406b8SStefano Zampini 
1042863406b8SStefano Zampini   PetscFunctionBegin;
1043863406b8SStefano Zampini   /* throw away any discrete curl if already set */
1044863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
1045863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(C,&jac->C);CHKERRQ(ierr);
1046863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(C,jac->C);CHKERRQ(ierr);
1047863406b8SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->C,(void**)(&parcsr_C)));
1048863406b8SStefano Zampini   PetscStackCall("Hypre set curl",ierr = (*jac->setdcurl)(jac->hsolver,parcsr_C);CHKERRQ(ierr););
1049863406b8SStefano Zampini   PetscFunctionReturn(0);
1050863406b8SStefano Zampini }
1051863406b8SStefano Zampini 
1052863406b8SStefano Zampini #undef __FUNCT__
1053863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl"
1054863406b8SStefano Zampini /*@
1055863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1056863406b8SStefano Zampini 
1057863406b8SStefano Zampini    Collective on PC
1058863406b8SStefano Zampini 
1059863406b8SStefano Zampini    Input Parameters:
1060863406b8SStefano Zampini +  pc - the preconditioning context
1061863406b8SStefano Zampini -  C - the discrete curl
1062863406b8SStefano Zampini 
1063863406b8SStefano Zampini    Level: intermediate
1064863406b8SStefano Zampini 
1065863406b8SStefano 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
1066863406b8SStefano 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
1067863406b8SStefano Zampini 
1068863406b8SStefano Zampini .seealso:
1069863406b8SStefano Zampini @*/
1070863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1071863406b8SStefano Zampini {
1072863406b8SStefano Zampini   PetscErrorCode ierr;
1073863406b8SStefano Zampini 
1074863406b8SStefano Zampini   PetscFunctionBegin;
1075863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1076863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1077863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1078863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1079863406b8SStefano Zampini   PetscFunctionReturn(0);
1080863406b8SStefano Zampini }
1081863406b8SStefano Zampini 
1082863406b8SStefano Zampini #undef __FUNCT__
10834cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS"
10844cb006feSStefano Zampini static PetscErrorCode PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
10854cb006feSStefano Zampini {
10864cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
10874cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_alpha_Poisson;
10884cb006feSStefano Zampini   PetscErrorCode     ierr;
10894cb006feSStefano Zampini 
10904cb006feSStefano Zampini   PetscFunctionBegin;
10914cb006feSStefano Zampini   /* throw away any matrix if already set */
10924cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
10934cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->alpha_Poisson);CHKERRQ(ierr);
10944cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->alpha_Poisson);CHKERRQ(ierr);
10954cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->alpha_Poisson,(void**)(&parcsr_alpha_Poisson)));
10964cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr_alpha_Poisson));
10974cb006feSStefano Zampini   PetscFunctionReturn(0);
10984cb006feSStefano Zampini }
10994cb006feSStefano Zampini 
11004cb006feSStefano Zampini #undef __FUNCT__
11014cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix"
11024cb006feSStefano Zampini /*@
11034cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
11044cb006feSStefano Zampini 
11054cb006feSStefano Zampini    Collective on PC
11064cb006feSStefano Zampini 
11074cb006feSStefano Zampini    Input Parameters:
11084cb006feSStefano Zampini +  pc - the preconditioning context
11094cb006feSStefano Zampini -  A - the matrix
11104cb006feSStefano Zampini 
11114cb006feSStefano Zampini    Level: intermediate
11124cb006feSStefano Zampini 
11134cb006feSStefano Zampini    Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
11144cb006feSStefano Zampini 
11154cb006feSStefano Zampini .seealso:
11164cb006feSStefano Zampini @*/
11174cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
11184cb006feSStefano Zampini {
11194cb006feSStefano Zampini   PetscErrorCode ierr;
11204cb006feSStefano Zampini 
11214cb006feSStefano Zampini   PetscFunctionBegin;
11224cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11234cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
11244cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
11254cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetAlphaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
11264cb006feSStefano Zampini   PetscFunctionReturn(0);
11274cb006feSStefano Zampini }
11284cb006feSStefano Zampini 
11294cb006feSStefano Zampini #undef __FUNCT__
11304cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix_HYPRE_AMS"
11314cb006feSStefano Zampini static PetscErrorCode PCHYPRESetBetaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
11324cb006feSStefano Zampini {
11334cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11344cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_beta_Poisson;
11354cb006feSStefano Zampini   PetscErrorCode     ierr;
11364cb006feSStefano Zampini 
11374cb006feSStefano Zampini   PetscFunctionBegin;
11384cb006feSStefano Zampini   if (!A) {
11394cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_TRUE;
11404cb006feSStefano Zampini     PetscFunctionReturn(0);
11414cb006feSStefano Zampini   }
11424cb006feSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
11434cb006feSStefano Zampini   /* throw away any matrix if already set */
11444cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
11454cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->beta_Poisson);CHKERRQ(ierr);
11464cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->beta_Poisson);CHKERRQ(ierr);
11474cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->beta_Poisson,(void**)(&parcsr_beta_Poisson)));
11484cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr_beta_Poisson));
11494cb006feSStefano Zampini   PetscFunctionReturn(0);
11504cb006feSStefano Zampini }
11514cb006feSStefano Zampini 
11524cb006feSStefano Zampini #undef __FUNCT__
11534cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix"
11544cb006feSStefano Zampini /*@
11554cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
11564cb006feSStefano Zampini 
11574cb006feSStefano Zampini    Collective on PC
11584cb006feSStefano Zampini 
11594cb006feSStefano Zampini    Input Parameters:
11604cb006feSStefano Zampini +  pc - the preconditioning context
11614cb006feSStefano Zampini -  A - the matrix
11624cb006feSStefano Zampini 
11634cb006feSStefano Zampini    Level: intermediate
11644cb006feSStefano Zampini 
11654cb006feSStefano Zampini    Notes: A should be obtained by discretizing the Poisson problem with linear finite elements.
11664cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
11674cb006feSStefano Zampini 
11684cb006feSStefano Zampini .seealso:
11694cb006feSStefano Zampini @*/
11704cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
11714cb006feSStefano Zampini {
11724cb006feSStefano Zampini   PetscErrorCode ierr;
11734cb006feSStefano Zampini 
11744cb006feSStefano Zampini   PetscFunctionBegin;
11754cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11764cb006feSStefano Zampini   if (A) {
11774cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
11784cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
11794cb006feSStefano Zampini   }
11804cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetBetaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
11814cb006feSStefano Zampini   PetscFunctionReturn(0);
11824cb006feSStefano Zampini }
11834cb006feSStefano Zampini 
11844cb006feSStefano Zampini #undef __FUNCT__
11854cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE_AMS"
11864cb006feSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE_AMS(PC pc,Vec ozz, Vec zoz, Vec zzo)
11874cb006feSStefano Zampini {
11884cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11894cb006feSStefano Zampini   HYPRE_ParVector    par_ozz,par_zoz,par_zzo;
119012ddd1b6SStefano Zampini   PetscInt           dim;
11914cb006feSStefano Zampini   PetscErrorCode     ierr;
11924cb006feSStefano Zampini 
11934cb006feSStefano Zampini   PetscFunctionBegin;
11944cb006feSStefano Zampini   /* throw away any vector if already set */
11954cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
11964cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
11974cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
11984cb006feSStefano Zampini   jac->constants[0] = NULL;
11994cb006feSStefano Zampini   jac->constants[1] = NULL;
12004cb006feSStefano Zampini   jac->constants[2] = NULL;
12014cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
12024cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
12034cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&par_ozz)));
12044cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
12054cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
12064cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&par_zoz)));
120712ddd1b6SStefano Zampini   dim = 2;
12084cb006feSStefano Zampini   if (zzo) {
12094cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
12104cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
12114cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&par_zzo)));
121212ddd1b6SStefano Zampini     dim++;
12134cb006feSStefano Zampini   }
12144cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,par_ozz,par_zoz,par_zzo));
121512ddd1b6SStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim));
12164cb006feSStefano Zampini   PetscFunctionReturn(0);
12174cb006feSStefano Zampini }
12184cb006feSStefano Zampini 
12194cb006feSStefano Zampini #undef __FUNCT__
12204cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors"
12214cb006feSStefano Zampini /*@
12224cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
12234cb006feSStefano Zampini 
12244cb006feSStefano Zampini    Collective on PC
12254cb006feSStefano Zampini 
12264cb006feSStefano Zampini    Input Parameters:
12274cb006feSStefano Zampini +  pc - the preconditioning context
12284cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
12294cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
12304cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
12314cb006feSStefano Zampini 
12324cb006feSStefano Zampini    Level: intermediate
12334cb006feSStefano Zampini 
12344cb006feSStefano Zampini    Notes:
12354cb006feSStefano Zampini 
12364cb006feSStefano Zampini .seealso:
12374cb006feSStefano Zampini @*/
12384cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
12394cb006feSStefano Zampini {
12404cb006feSStefano Zampini   PetscErrorCode ierr;
12414cb006feSStefano Zampini 
12424cb006feSStefano Zampini   PetscFunctionBegin;
12434cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12444cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
12454cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
12464cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
12474cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
12484cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
12494cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
12504cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
12514cb006feSStefano Zampini   PetscFunctionReturn(0);
12524cb006feSStefano Zampini }
12534cb006feSStefano Zampini 
12544cb006feSStefano Zampini #undef __FUNCT__
1255863406b8SStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE"
1256863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
12574cb006feSStefano Zampini {
12584cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
12594cb006feSStefano Zampini   Vec             tv;
12604cb006feSStefano Zampini   HYPRE_ParVector par_coords[3];
12614cb006feSStefano Zampini   PetscInt        i;
12624cb006feSStefano Zampini   PetscErrorCode  ierr;
12634cb006feSStefano Zampini 
12644cb006feSStefano Zampini   PetscFunctionBegin;
12654cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
12664cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
12674cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
12684cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
12694cb006feSStefano Zampini   /* set problem's dimension */
1270863406b8SStefano Zampini   if (jac->setdim) {
1271863406b8SStefano Zampini     PetscStackCall("Hypre set dim",ierr = (*jac->setdim)(jac->hsolver,dim);CHKERRQ(ierr););
1272863406b8SStefano Zampini   }
12734cb006feSStefano Zampini   /* compute IJ vector for coordinates */
12744cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
12754cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
12764cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
12774cb006feSStefano Zampini   for (i=0;i<dim;i++) {
12784cb006feSStefano Zampini     PetscScalar *array;
12794cb006feSStefano Zampini     PetscInt    j;
12804cb006feSStefano Zampini 
12814cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
12824cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
12834cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
12844cb006feSStefano Zampini       array[j] = coords[j*dim+i];
12854cb006feSStefano Zampini     }
12864cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
12874cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
12884cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
12894cb006feSStefano Zampini   }
12904cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
12914cb006feSStefano Zampini   /* pass parCSR vectors to AMS solver */
12924cb006feSStefano Zampini   par_coords[0] = NULL;
12934cb006feSStefano Zampini   par_coords[1] = NULL;
12944cb006feSStefano Zampini   par_coords[2] = NULL;
12954cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&par_coords[0])));
12964cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&par_coords[1])));
12974cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&par_coords[2])));
1298863406b8SStefano Zampini   PetscStackCall("Hypre set coords",ierr = (*jac->setcoord)(jac->hsolver,par_coords[0],par_coords[1],par_coords[2]);CHKERRQ(ierr););
12994cb006feSStefano Zampini   PetscFunctionReturn(0);
13004cb006feSStefano Zampini }
13014cb006feSStefano Zampini 
130216d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
130316d9e3a6SLisandro Dalcin 
130416d9e3a6SLisandro Dalcin #undef __FUNCT__
130516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
1306f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
130716d9e3a6SLisandro Dalcin {
130816d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
130916d9e3a6SLisandro Dalcin 
131016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
131116d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
131216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
131316d9e3a6SLisandro Dalcin }
131416d9e3a6SLisandro Dalcin 
131516d9e3a6SLisandro Dalcin #undef __FUNCT__
131616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
1317f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
131816d9e3a6SLisandro Dalcin {
131916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
132016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1321ace3abfcSBarry Smith   PetscBool      flag;
132216d9e3a6SLisandro Dalcin 
132316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
132416d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
132516d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1326ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
132716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
132816d9e3a6SLisandro Dalcin   } else {
132916d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
133016d9e3a6SLisandro Dalcin   }
133116d9e3a6SLisandro Dalcin 
133216d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
133316d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
133416d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
133516d9e3a6SLisandro Dalcin 
133616d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
133716d9e3a6SLisandro Dalcin   if (flag) {
1338fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
133916d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
134016d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
134116d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
134216d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
134316d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
134416d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
134516d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
134616d9e3a6SLisandro Dalcin   }
134716d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
134816d9e3a6SLisandro Dalcin   if (flag) {
1349fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
135016d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
135116d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
135216d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
135316d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
135416d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
135516d9e3a6SLisandro Dalcin     /* initialize */
135616d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
135716d9e3a6SLisandro Dalcin     jac->threshhold = .1;
135816d9e3a6SLisandro Dalcin     jac->filter     = .1;
135916d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
13602fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
13612fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
13622fa5cd67SKarl Rupp 
136316d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
136416d9e3a6SLisandro Dalcin     jac->symt = 0;
1365fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1366fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1367fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1368fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1369fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1370fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
137116d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
137216d9e3a6SLisandro Dalcin   }
137316d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
137416d9e3a6SLisandro Dalcin   if (flag) {
137516d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
137616d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
137716d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
137816d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
137916d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
138016d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
138116d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
138216d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
138316d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
138416d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
138516d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
138616d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
138716d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
13888f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
138916d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
139016d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
139116d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
139216d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
139316d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
13940f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
13956a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1396b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
13971810e44eSEike Mueller     jac->eu_level         = 0;
13981810e44eSEike Mueller     jac->eu_droptolerance = 0;
13991810e44eSEike Mueller     jac->eu_bj            = 0;
14008f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
14010f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
140216d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
140316d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
140416d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
14050f1074feSSatish Balay     jac->interptype       = 0;
14060f1074feSSatish Balay     jac->agg_nl           = 0;
14070f1074feSSatish Balay     jac->pmax             = 0;
14080f1074feSSatish Balay     jac->truncfactor      = 0.0;
14090f1074feSSatish Balay     jac->agg_num_paths    = 1;
14108f87f92bSBarry Smith 
14118f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
14128f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
14138f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1414fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1415fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1416fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1417fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1418fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1419fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1420fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1421fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1422fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1423fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1424fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1425fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1426fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1427fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1428fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1429fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
143016d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
143116d9e3a6SLisandro Dalcin   }
14324cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
14334cb006feSStefano Zampini   if (flag) {
14344cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
14354cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
14364cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
14374cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
14384cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
14394cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
1440863406b8SStefano Zampini     jac->setdgrad            = HYPRE_AMSSetDiscreteGradient;
1441863406b8SStefano Zampini     jac->setcoord            = HYPRE_AMSSetCoordinateVectors;
1442863406b8SStefano Zampini     jac->setdim              = HYPRE_AMSSetDimension;
14434cb006feSStefano Zampini     jac->coords[0]           = NULL;
14444cb006feSStefano Zampini     jac->coords[1]           = NULL;
14454cb006feSStefano Zampini     jac->coords[2]           = NULL;
14464cb006feSStefano Zampini     jac->G                   = NULL;
14474cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1448863406b8SStefano Zampini     jac->as_print           = 0;
1449863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1450863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
14514cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
14524cb006feSStefano Zampini     /* Smoothing options */
1453863406b8SStefano Zampini     jac->as_relax_type      = 2;
1454863406b8SStefano Zampini     jac->as_relax_times     = 1;
1455863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1456863406b8SStefano Zampini     jac->as_omega           = 1.0;
14574cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1458863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1459863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1460863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 8;
1461863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1462863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1463863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
14644cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
14654cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_FALSE;
1466863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1467863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1468863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 8;
1469863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1470863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1471863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1472863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1473863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
14744cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1475863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1476863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1477863406b8SStefano Zampini                                                                       jac->as_relax_times,
1478863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1479863406b8SStefano Zampini                                                                       jac->as_omega));
1480863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1481863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1482863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1483863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1484863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1485863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1486863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1487863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1488863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1489863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1490863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1491863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1492863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1493863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
14944cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE_AMS);CHKERRQ(ierr);
14954cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
14964cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",PCHYPRESetBetaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
14974cb006feSStefano Zampini     PetscFunctionReturn(0);
14984cb006feSStefano Zampini   }
1499863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1500863406b8SStefano Zampini   if (flag) {
1501863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1502863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1503863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1504863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1505863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1506863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1507863406b8SStefano Zampini     jac->setdgrad            = HYPRE_ADSSetDiscreteGradient;
1508863406b8SStefano Zampini     jac->setdcurl            = HYPRE_ADSSetDiscreteCurl;
1509863406b8SStefano Zampini     jac->setcoord            = HYPRE_ADSSetCoordinateVectors;
1510863406b8SStefano Zampini     jac->coords[0]           = NULL;
1511863406b8SStefano Zampini     jac->coords[1]           = NULL;
1512863406b8SStefano Zampini     jac->coords[2]           = NULL;
1513863406b8SStefano Zampini     jac->G                   = NULL;
1514863406b8SStefano Zampini     jac->C                   = NULL;
1515863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1516863406b8SStefano Zampini     jac->as_print           = 0;
1517863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1518863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1519863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1520863406b8SStefano Zampini     /* Smoothing options */
1521863406b8SStefano Zampini     jac->as_relax_type      = 2;
1522863406b8SStefano Zampini     jac->as_relax_times     = 1;
1523863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1524863406b8SStefano Zampini     jac->as_omega           = 1.0;
1525863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1526863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1527863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1528863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1529863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1530863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1531863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1532863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1533863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1534863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1535863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1536863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1537863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1538863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1539863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1540863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1541863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1542863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1543863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1544863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1545863406b8SStefano Zampini                                                                       jac->as_relax_times,
1546863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1547863406b8SStefano Zampini                                                                       jac->as_omega));
1548863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1549863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1550863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1551863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1552863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1553863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1554863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1555863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1556863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1557863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1558863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1559863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1560863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1561863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1562863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
1563863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
1564863406b8SStefano Zampini     PetscFunctionReturn(0);
1565863406b8SStefano Zampini   }
1566503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
15672fa5cd67SKarl Rupp 
15680298fd71SBarry Smith   jac->hypre_type = NULL;
156933263987SBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, boomeramg, ams",name);
157016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
157116d9e3a6SLisandro Dalcin }
157216d9e3a6SLisandro Dalcin 
157316d9e3a6SLisandro Dalcin /*
157416d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
157516d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
157616d9e3a6SLisandro Dalcin */
157716d9e3a6SLisandro Dalcin #undef __FUNCT__
157816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
15798c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptions *PetscOptionsObject,PC pc)
158016d9e3a6SLisandro Dalcin {
158116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
15824ddd07fcSJed Brown   PetscInt       indx;
1583863406b8SStefano Zampini   const char     *type[] = {"pilut","parasails","boomeramg","ams","ads"};
1584ace3abfcSBarry Smith   PetscBool      flg;
158516d9e3a6SLisandro Dalcin 
158616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
15879fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
15889c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
158916d9e3a6SLisandro Dalcin   if (flg) {
159016d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
159102a17cd4SBarry Smith   } else {
159202a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
159316d9e3a6SLisandro Dalcin   }
159416d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
15953931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
159616d9e3a6SLisandro Dalcin   }
159716d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
159816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
159916d9e3a6SLisandro Dalcin }
160016d9e3a6SLisandro Dalcin 
160116d9e3a6SLisandro Dalcin #undef __FUNCT__
160216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
160316d9e3a6SLisandro Dalcin /*@C
160416d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
160516d9e3a6SLisandro Dalcin 
160616d9e3a6SLisandro Dalcin    Input Parameters:
160716d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1608863406b8SStefano Zampini -     name - either  pilut, parasails, boomeramg, ams, ads
160916d9e3a6SLisandro Dalcin 
161016d9e3a6SLisandro Dalcin    Options Database Keys:
1611863406b8SStefano Zampini    -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
161216d9e3a6SLisandro Dalcin 
161316d9e3a6SLisandro Dalcin    Level: intermediate
161416d9e3a6SLisandro Dalcin 
161516d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
161616d9e3a6SLisandro Dalcin            PCHYPRE
161716d9e3a6SLisandro Dalcin 
161816d9e3a6SLisandro Dalcin @*/
16197087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
162016d9e3a6SLisandro Dalcin {
16214ac538c5SBarry Smith   PetscErrorCode ierr;
162216d9e3a6SLisandro Dalcin 
162316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16240700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
162516d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
16264ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
162716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
162816d9e3a6SLisandro Dalcin }
162916d9e3a6SLisandro Dalcin 
163016d9e3a6SLisandro Dalcin #undef __FUNCT__
163116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
163216d9e3a6SLisandro Dalcin /*@C
163316d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
163416d9e3a6SLisandro Dalcin 
163516d9e3a6SLisandro Dalcin    Input Parameter:
163616d9e3a6SLisandro Dalcin .     pc - the preconditioner context
163716d9e3a6SLisandro Dalcin 
163816d9e3a6SLisandro Dalcin    Output Parameter:
1639863406b8SStefano Zampini .     name - either  pilut, parasails, boomeramg, ams, ads
164016d9e3a6SLisandro Dalcin 
164116d9e3a6SLisandro Dalcin    Level: intermediate
164216d9e3a6SLisandro Dalcin 
164316d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
164416d9e3a6SLisandro Dalcin            PCHYPRE
164516d9e3a6SLisandro Dalcin 
164616d9e3a6SLisandro Dalcin @*/
16477087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
164816d9e3a6SLisandro Dalcin {
16494ac538c5SBarry Smith   PetscErrorCode ierr;
165016d9e3a6SLisandro Dalcin 
165116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16520700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
165316d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
16544ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
165516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
165616d9e3a6SLisandro Dalcin }
165716d9e3a6SLisandro Dalcin 
165816d9e3a6SLisandro Dalcin /*MC
165916d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
166016d9e3a6SLisandro Dalcin 
166116d9e3a6SLisandro Dalcin    Options Database Keys:
1662863406b8SStefano Zampini +   -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
166316d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
166416d9e3a6SLisandro Dalcin           preconditioner
166516d9e3a6SLisandro Dalcin 
166616d9e3a6SLisandro Dalcin    Level: intermediate
166716d9e3a6SLisandro Dalcin 
166816d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
166916d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
167016d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
167116d9e3a6SLisandro Dalcin 
167216d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
16730f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
16740f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
16750f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
16768f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
16770f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
16780f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
167916d9e3a6SLisandro Dalcin 
16800f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
16810f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
16820f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
168316d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
168416d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
168516d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
168616d9e3a6SLisandro Dalcin 
168716d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
168816d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
168916d9e3a6SLisandro Dalcin 
16909e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
16919e5bc791SBarry Smith 
169216d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
16939e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
169416d9e3a6SLisandro Dalcin 
169516d9e3a6SLisandro Dalcin M*/
169616d9e3a6SLisandro Dalcin 
169716d9e3a6SLisandro Dalcin #undef __FUNCT__
169816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
16998cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
170016d9e3a6SLisandro Dalcin {
170116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
170216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
170316d9e3a6SLisandro Dalcin 
170416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1705b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
17062fa5cd67SKarl Rupp 
170716d9e3a6SLisandro Dalcin   pc->data                = jac;
170816d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
170916d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
171016d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
171116d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
171216d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
17130298fd71SBarry Smith   jac->hypre_type         = NULL;
17144cb006feSStefano Zampini   jac->coords[0]          = NULL;
17154cb006feSStefano Zampini   jac->coords[1]          = NULL;
17164cb006feSStefano Zampini   jac->coords[2]          = NULL;
17174cb006feSStefano Zampini   jac->constants[0]       = NULL;
17184cb006feSStefano Zampini   jac->constants[1]       = NULL;
17194cb006feSStefano Zampini   jac->constants[2]       = NULL;
1720863406b8SStefano Zampini   jac->G                  = NULL;
1721863406b8SStefano Zampini   jac->C                  = NULL;
1722863406b8SStefano Zampini   jac->alpha_Poisson      = NULL;
1723863406b8SStefano Zampini   jac->beta_Poisson       = NULL;
1724fd444223SStefano Zampini   jac->setdim             = NULL;
172516d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1726ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1727bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1728bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
172916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
173016d9e3a6SLisandro Dalcin }
1731ebc551c0SBarry Smith 
1732f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1733f91d8e95SBarry Smith 
1734b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1735af0996ceSBarry Smith #include <petsc/private/matimpl.h>
1736ebc551c0SBarry Smith 
1737ebc551c0SBarry Smith typedef struct {
173868326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1739f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
17409e5bc791SBarry Smith 
17419e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
17424ddd07fcSJed Brown   PetscInt its;
17439e5bc791SBarry Smith   double   tol;
17444ddd07fcSJed Brown   PetscInt relax_type;
17454ddd07fcSJed Brown   PetscInt rap_type;
17464ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
17474ddd07fcSJed Brown   PetscInt max_levels;
1748ebc551c0SBarry Smith } PC_PFMG;
1749ebc551c0SBarry Smith 
1750ebc551c0SBarry Smith #undef __FUNCT__
1751ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1752ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1753ebc551c0SBarry Smith {
1754ebc551c0SBarry Smith   PetscErrorCode ierr;
1755f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1756ebc551c0SBarry Smith 
1757ebc551c0SBarry Smith   PetscFunctionBegin;
17582fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1759f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1760c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1761ebc551c0SBarry Smith   PetscFunctionReturn(0);
1762ebc551c0SBarry Smith }
1763ebc551c0SBarry Smith 
17649e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
17659e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
17669e5bc791SBarry Smith 
1767ebc551c0SBarry Smith #undef __FUNCT__
1768ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1769ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1770ebc551c0SBarry Smith {
1771ebc551c0SBarry Smith   PetscErrorCode ierr;
1772ace3abfcSBarry Smith   PetscBool      iascii;
1773f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1774ebc551c0SBarry Smith 
1775ebc551c0SBarry Smith   PetscFunctionBegin;
1776251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
17779e5bc791SBarry Smith   if (iascii) {
17789e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
17799e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
17809e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
17819e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
17829e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
17839e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
17843b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
17859e5bc791SBarry Smith   }
1786ebc551c0SBarry Smith   PetscFunctionReturn(0);
1787ebc551c0SBarry Smith }
1788ebc551c0SBarry Smith 
17899e5bc791SBarry Smith 
1790ebc551c0SBarry Smith #undef __FUNCT__
1791ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
17928c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptions *PetscOptionsObject,PC pc)
1793ebc551c0SBarry Smith {
1794ebc551c0SBarry Smith   PetscErrorCode ierr;
1795f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1796ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1797ebc551c0SBarry Smith 
1798ebc551c0SBarry Smith   PetscFunctionBegin;
1799e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
18000298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
180168326731SBarry Smith   if (flg) {
1802a0324ebeSBarry Smith     int level=3;
1803fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
180468326731SBarry Smith   }
18050298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1806fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
18070298fd71SBarry 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);
1808fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
18090298fd71SBarry 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);
1810fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
18119e5bc791SBarry Smith 
18120298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
1813fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
18143b46a515SGlenn Hammond 
18150298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1816fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
18170298fd71SBarry 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);
1818fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
18190298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
1820fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1821ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1822ebc551c0SBarry Smith   PetscFunctionReturn(0);
1823ebc551c0SBarry Smith }
1824ebc551c0SBarry Smith 
1825f91d8e95SBarry Smith #undef __FUNCT__
1826f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1827f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1828f91d8e95SBarry Smith {
1829f91d8e95SBarry Smith   PetscErrorCode    ierr;
1830f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
1831d9ca1df4SBarry Smith   PetscScalar       *yy;
1832d9ca1df4SBarry Smith   const PetscScalar *xx;
18334ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
183468326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1835f91d8e95SBarry Smith 
1836f91d8e95SBarry Smith   PetscFunctionBegin;
1837dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1838aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1839f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1840f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1841f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1842f91d8e95SBarry Smith 
1843f91d8e95SBarry Smith   /* copy x values over to hypre */
1844fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1845d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1846d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
1847d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1848fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
1849fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1850f91d8e95SBarry Smith 
1851f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1852f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
18538b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
1854f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1855f91d8e95SBarry Smith   PetscFunctionReturn(0);
1856f91d8e95SBarry Smith }
1857f91d8e95SBarry Smith 
18589e5bc791SBarry Smith #undef __FUNCT__
18599e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1860ace3abfcSBarry 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)
18619e5bc791SBarry Smith {
18629e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
18639e5bc791SBarry Smith   PetscErrorCode ierr;
18644ddd07fcSJed Brown   PetscInt       oits;
18659e5bc791SBarry Smith 
18669e5bc791SBarry Smith   PetscFunctionBegin;
1867dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1868fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1869fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
18709e5bc791SBarry Smith 
18719e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
18728b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
18739e5bc791SBarry Smith   *outits = oits;
18749e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
18759e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1876fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1877fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
18789e5bc791SBarry Smith   PetscFunctionReturn(0);
18799e5bc791SBarry Smith }
18809e5bc791SBarry Smith 
18819e5bc791SBarry Smith 
18823a32d3dbSGlenn Hammond #undef __FUNCT__
18833a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
18843a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
18853a32d3dbSGlenn Hammond {
18863a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
18873a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
18883a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1889ace3abfcSBarry Smith   PetscBool       flg;
18903a32d3dbSGlenn Hammond 
18913a32d3dbSGlenn Hammond   PetscFunctionBegin;
1892251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1893ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
18943a32d3dbSGlenn Hammond 
18953a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
18962fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1897fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1898fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1899fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
19003a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
19013a32d3dbSGlenn Hammond }
19023a32d3dbSGlenn Hammond 
1903ebc551c0SBarry Smith 
1904ebc551c0SBarry Smith /*MC
1905ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1906ebc551c0SBarry Smith 
1907ebc551c0SBarry Smith    Level: advanced
1908ebc551c0SBarry Smith 
19099e5bc791SBarry Smith    Options Database:
19109e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
19119e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
19129e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
19139e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
19149e5bc791SBarry 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
19159e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
1916f91d8e95SBarry Smith 
19179e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
19189e5bc791SBarry Smith 
19198e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
1920aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
19219e5bc791SBarry Smith 
19229e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
1923ebc551c0SBarry Smith M*/
1924ebc551c0SBarry Smith 
1925ebc551c0SBarry Smith #undef __FUNCT__
1926ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
19278cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
1928ebc551c0SBarry Smith {
1929ebc551c0SBarry Smith   PetscErrorCode ierr;
1930ebc551c0SBarry Smith   PC_PFMG        *ex;
1931ebc551c0SBarry Smith 
1932ebc551c0SBarry Smith   PetscFunctionBegin;
1933b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
193468326731SBarry Smith   pc->data = ex;
1935ebc551c0SBarry Smith 
19369e5bc791SBarry Smith   ex->its            = 1;
19379e5bc791SBarry Smith   ex->tol            = 1.e-8;
19389e5bc791SBarry Smith   ex->relax_type     = 1;
19399e5bc791SBarry Smith   ex->rap_type       = 0;
19409e5bc791SBarry Smith   ex->num_pre_relax  = 1;
19419e5bc791SBarry Smith   ex->num_post_relax = 1;
19423b46a515SGlenn Hammond   ex->max_levels     = 0;
19439e5bc791SBarry Smith 
1944ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
1945ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
1946ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
1947f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
19489e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
194968326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
19502fa5cd67SKarl Rupp 
1951ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
1952fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1953ebc551c0SBarry Smith   PetscFunctionReturn(0);
1954ebc551c0SBarry Smith }
1955d851a50bSGlenn Hammond 
1956325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
1957325fc9f4SBarry Smith 
1958d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
1959d851a50bSGlenn Hammond typedef struct {
1960d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
1961d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
1962d851a50bSGlenn Hammond 
1963d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
19644ddd07fcSJed Brown   PetscInt its;
1965d851a50bSGlenn Hammond   double   tol;
19664ddd07fcSJed Brown   PetscInt relax_type;
19674ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
1968d851a50bSGlenn Hammond } PC_SysPFMG;
1969d851a50bSGlenn Hammond 
1970d851a50bSGlenn Hammond #undef __FUNCT__
1971d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
1972d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
1973d851a50bSGlenn Hammond {
1974d851a50bSGlenn Hammond   PetscErrorCode ierr;
1975d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1976d851a50bSGlenn Hammond 
1977d851a50bSGlenn Hammond   PetscFunctionBegin;
19782fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1979d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1980c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1981d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1982d851a50bSGlenn Hammond }
1983d851a50bSGlenn Hammond 
1984d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
1985d851a50bSGlenn Hammond 
1986d851a50bSGlenn Hammond #undef __FUNCT__
1987d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
1988d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
1989d851a50bSGlenn Hammond {
1990d851a50bSGlenn Hammond   PetscErrorCode ierr;
1991ace3abfcSBarry Smith   PetscBool      iascii;
1992d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1993d851a50bSGlenn Hammond 
1994d851a50bSGlenn Hammond   PetscFunctionBegin;
1995251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1996d851a50bSGlenn Hammond   if (iascii) {
1997d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
1998d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
1999d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
2000d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2001d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2002d851a50bSGlenn Hammond   }
2003d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2004d851a50bSGlenn Hammond }
2005d851a50bSGlenn Hammond 
2006d851a50bSGlenn Hammond 
2007d851a50bSGlenn Hammond #undef __FUNCT__
2008d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
20098c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptions *PetscOptionsObject,PC pc)
2010d851a50bSGlenn Hammond {
2011d851a50bSGlenn Hammond   PetscErrorCode ierr;
2012d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2013ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2014d851a50bSGlenn Hammond 
2015d851a50bSGlenn Hammond   PetscFunctionBegin;
2016e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
20170298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2018d851a50bSGlenn Hammond   if (flg) {
2019d851a50bSGlenn Hammond     int level=3;
2020fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
2021d851a50bSGlenn Hammond   }
20220298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2023fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
20240298fd71SBarry 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);
2025fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
20260298fd71SBarry 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);
2027fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2028d851a50bSGlenn Hammond 
20290298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2030fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
20310298fd71SBarry 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);
2032fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2033d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2034d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2035d851a50bSGlenn Hammond }
2036d851a50bSGlenn Hammond 
2037d851a50bSGlenn Hammond #undef __FUNCT__
2038d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
2039d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2040d851a50bSGlenn Hammond {
2041d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2042d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2043d9ca1df4SBarry Smith   PetscScalar       *yy;
2044d9ca1df4SBarry Smith   const PetscScalar *xx;
20454ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
2046d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
20474ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
20484ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
20494ddd07fcSJed Brown   PetscInt          part    = 0;
20504ddd07fcSJed Brown   PetscInt          size;
20514ddd07fcSJed Brown   PetscInt          i;
2052d851a50bSGlenn Hammond 
2053d851a50bSGlenn Hammond   PetscFunctionBegin;
2054dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2055aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2056d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2057d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2058d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2059d851a50bSGlenn Hammond 
2060d851a50bSGlenn Hammond   size = 1;
20612fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
20622fa5cd67SKarl Rupp 
2063d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2064d851a50bSGlenn Hammond   if (ordering) {
2065fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2066d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2067d9ca1df4SBarry 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)));
2068d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2069fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2070fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2071fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2072d851a50bSGlenn Hammond 
2073d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2074d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
20758b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2076d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2077a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2078d851a50bSGlenn Hammond     PetscScalar *z;
20794ddd07fcSJed Brown     PetscInt    j, k;
2080d851a50bSGlenn Hammond 
2081785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2082fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2083d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2084d851a50bSGlenn Hammond 
2085d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2086d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2087d851a50bSGlenn Hammond       k= i*nvars;
20882fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2089d851a50bSGlenn Hammond     }
20908b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2091d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2092fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2093fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2094d851a50bSGlenn Hammond 
2095d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2096d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
20978b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2098d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2099d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2100d851a50bSGlenn Hammond       k= i*nvars;
21012fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2102d851a50bSGlenn Hammond     }
2103d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2104d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2105d851a50bSGlenn Hammond   }
2106d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2107d851a50bSGlenn Hammond }
2108d851a50bSGlenn Hammond 
2109d851a50bSGlenn Hammond #undef __FUNCT__
2110d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
2111ace3abfcSBarry 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)
2112d851a50bSGlenn Hammond {
2113d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2114d851a50bSGlenn Hammond   PetscErrorCode ierr;
21154ddd07fcSJed Brown   PetscInt       oits;
2116d851a50bSGlenn Hammond 
2117d851a50bSGlenn Hammond   PetscFunctionBegin;
2118dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2119fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2120fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2121d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
21228b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2123d851a50bSGlenn Hammond   *outits = oits;
2124d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2125d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2126fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2127fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2128d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2129d851a50bSGlenn Hammond }
2130d851a50bSGlenn Hammond 
2131d851a50bSGlenn Hammond 
2132d851a50bSGlenn Hammond #undef __FUNCT__
2133d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
2134d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2135d851a50bSGlenn Hammond {
2136d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2137d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2138d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2139ace3abfcSBarry Smith   PetscBool        flg;
2140d851a50bSGlenn Hammond 
2141d851a50bSGlenn Hammond   PetscFunctionBegin;
2142251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2143ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2144d851a50bSGlenn Hammond 
2145d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
21462fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2147fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2148fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2149fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2150d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2151d851a50bSGlenn Hammond }
2152d851a50bSGlenn Hammond 
2153d851a50bSGlenn Hammond 
2154d851a50bSGlenn Hammond /*MC
2155d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2156d851a50bSGlenn Hammond 
2157d851a50bSGlenn Hammond    Level: advanced
2158d851a50bSGlenn Hammond 
2159d851a50bSGlenn Hammond    Options Database:
2160d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2161d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2162d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2163d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2164d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2165d851a50bSGlenn Hammond 
2166d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
2167d851a50bSGlenn Hammond 
2168f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2169aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2170d851a50bSGlenn Hammond            Also, only cell-centered variables.
2171d851a50bSGlenn Hammond 
2172d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2173d851a50bSGlenn Hammond M*/
2174d851a50bSGlenn Hammond 
2175d851a50bSGlenn Hammond #undef __FUNCT__
2176d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
21778cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2178d851a50bSGlenn Hammond {
2179d851a50bSGlenn Hammond   PetscErrorCode ierr;
2180d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2181d851a50bSGlenn Hammond 
2182d851a50bSGlenn Hammond   PetscFunctionBegin;
2183b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2184d851a50bSGlenn Hammond   pc->data = ex;
2185d851a50bSGlenn Hammond 
2186d851a50bSGlenn Hammond   ex->its            = 1;
2187d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2188d851a50bSGlenn Hammond   ex->relax_type     = 1;
2189d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2190d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2191d851a50bSGlenn Hammond 
2192d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2193d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2194d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2195d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2196d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2197d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
21982fa5cd67SKarl Rupp 
2199ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2200fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2201d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2202d851a50bSGlenn Hammond }
2203