xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision ec64516dfc91c1dee9df3fd5de3ca08a62d34b45)
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;
64*ec64516dSEike Mueller   PetscInt  eu_level;   /* Number of levels for ILU(k) in Euclid */
65*ec64516dSEike Mueller   double    eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */
66*ec64516dSEike 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) {
167863406b8SStefano Zampini     if (!jac->coords[0]) {
168863406b8SStefano Zampini       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs coordinate vectors via PCSetCoordinates()");
169fd444223SStefano Zampini     } else if (!jac->coords[1] || !jac->coords[2]) {
170fd444223SStefano Zampini       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner has been designed for three dimensional problems! For two dimensional problems, use HYPRE AMS instead");
171863406b8SStefano Zampini     }
172863406b8SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
173863406b8SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete curl operator via PCHYPRESetDiscreteGradient");
174863406b8SStefano Zampini   }
17516d9e3a6SLisandro Dalcin   ierr = MatHYPRE_IJMatrixCopy(pc->pmat,jac->ij);CHKERRQ(ierr);
176fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
177fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&bv));
178fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&xv));
179fd3f9acdSBarry Smith   PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr););
18016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
18116d9e3a6SLisandro Dalcin }
18216d9e3a6SLisandro Dalcin 
18316d9e3a6SLisandro Dalcin /*
18416d9e3a6SLisandro Dalcin     Replaces the address where the HYPRE vector points to its data with the address of
18516d9e3a6SLisandro Dalcin   PETSc's data. Saves the old address so it can be reset when we are finished with it.
18616d9e3a6SLisandro Dalcin   Allows use to get the data into a HYPRE vector without the cost of memcopies
18716d9e3a6SLisandro Dalcin */
18816d9e3a6SLisandro Dalcin #define HYPREReplacePointer(b,newvalue,savedvalue) { \
18916d9e3a6SLisandro Dalcin     hypre_ParVector *par_vector   = (hypre_ParVector*)hypre_IJVectorObject(((hypre_IJVector*)b)); \
19016d9e3a6SLisandro Dalcin     hypre_Vector    *local_vector = hypre_ParVectorLocalVector(par_vector); \
19116d9e3a6SLisandro Dalcin     savedvalue         = local_vector->data; \
1920ad7597dSKarl Rupp     local_vector->data = newvalue;          \
1930ad7597dSKarl Rupp }
19416d9e3a6SLisandro Dalcin 
19516d9e3a6SLisandro Dalcin #undef __FUNCT__
19616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE"
19716d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
19816d9e3a6SLisandro Dalcin {
19916d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
20016d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
20116d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
202d9ca1df4SBarry Smith   PetscScalar        *xv;
203d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
20416d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
205d9ca1df4SBarry Smith   PetscScalar        *sxv;
2064ddd07fcSJed Brown   PetscInt           hierr;
20716d9e3a6SLisandro Dalcin 
20816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
209dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
21016d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
211d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
21216d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
213d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
21416d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
21516d9e3a6SLisandro Dalcin 
216fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
217fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
218fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
219fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
22065e19b50SBarry Smith                                if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
221fd3f9acdSBarry Smith                                if (hierr) hypre__global_error = 0;);
22216d9e3a6SLisandro Dalcin 
223d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)sbv,bv);
22416d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
22516d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
226d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
22716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
22816d9e3a6SLisandro Dalcin }
22916d9e3a6SLisandro Dalcin 
23016d9e3a6SLisandro Dalcin #undef __FUNCT__
23116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE"
23216d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
23316d9e3a6SLisandro Dalcin {
23416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
23516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
23616d9e3a6SLisandro Dalcin 
23716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
238fd3f9acdSBarry Smith   if (jac->ij) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
239fd3f9acdSBarry Smith   if (jac->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->b));
240fd3f9acdSBarry Smith   if (jac->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->x));
2414cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
2424cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
2434cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
2444cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
2454cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
2464cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
2474cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
248863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
2494cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
2504cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
251226b0620SJed Brown   if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr););
252503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
25316d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
254c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
25516d9e3a6SLisandro Dalcin 
25616d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
257bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
258bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
2594cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
2604cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
261863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
2624cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
2634cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",NULL);CHKERRQ(ierr);
2644cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",NULL);CHKERRQ(ierr);
26516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
26616d9e3a6SLisandro Dalcin }
26716d9e3a6SLisandro Dalcin 
26816d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
26916d9e3a6SLisandro Dalcin #undef __FUNCT__
27016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut"
2718c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptions *PetscOptionsObject,PC pc)
27216d9e3a6SLisandro Dalcin {
27316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
27416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
275ace3abfcSBarry Smith   PetscBool      flag;
27616d9e3a6SLisandro Dalcin 
27716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
278e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
27916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
280fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
28116d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
282fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
28316d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
284fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
28516d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
28616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
28716d9e3a6SLisandro Dalcin }
28816d9e3a6SLisandro Dalcin 
28916d9e3a6SLisandro Dalcin #undef __FUNCT__
29016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut"
29116d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
29216d9e3a6SLisandro Dalcin {
29316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
29416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
295ace3abfcSBarry Smith   PetscBool      iascii;
29616d9e3a6SLisandro Dalcin 
29716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
298251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
29916d9e3a6SLisandro Dalcin   if (iascii) {
30016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
30116d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
30216d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
30316d9e3a6SLisandro Dalcin     } else {
30416d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr);
30516d9e3a6SLisandro Dalcin     }
30616d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
30757622a8eSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
30816d9e3a6SLisandro Dalcin     } else {
30916d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr);
31016d9e3a6SLisandro Dalcin     }
31116d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
31216d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
31316d9e3a6SLisandro Dalcin     } else {
31416d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default factor row size \n");CHKERRQ(ierr);
31516d9e3a6SLisandro Dalcin     }
31616d9e3a6SLisandro Dalcin   }
31716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
31816d9e3a6SLisandro Dalcin }
31916d9e3a6SLisandro Dalcin 
32016d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
32116d9e3a6SLisandro Dalcin 
32216d9e3a6SLisandro Dalcin #undef __FUNCT__
32316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG"
32416d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
32516d9e3a6SLisandro Dalcin {
32616d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
32716d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
32816d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
329d9ca1df4SBarry Smith   PetscScalar        *xv;
330d9ca1df4SBarry Smith   const PetscScalar  *bv;
33116d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
33216d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
3334ddd07fcSJed Brown   PetscInt           hierr;
33416d9e3a6SLisandro Dalcin 
33516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
336dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
33716d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
338d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
33916d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
340d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
34116d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
34216d9e3a6SLisandro Dalcin 
343fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
344fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
345fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
34616d9e3a6SLisandro Dalcin 
34716d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
34816d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
349e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
35016d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
35116d9e3a6SLisandro Dalcin 
35216d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
35316d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
35416d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
355d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
35616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
35716d9e3a6SLisandro Dalcin }
35816d9e3a6SLisandro Dalcin 
359a669f990SJed Brown /* static array length */
360a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
361a669f990SJed Brown 
36216d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
3630f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
36416d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
36565de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
3666a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]   = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
36765de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
36865de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
36965de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
37065de4495SJed Brown                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */,
37165de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
3720f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
3730f1074feSSatish Balay                                                   "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"};
37416d9e3a6SLisandro Dalcin #undef __FUNCT__
37516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG"
3768c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptions *PetscOptionsObject,PC pc)
37716d9e3a6SLisandro Dalcin {
37816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
37916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
3804ddd07fcSJed Brown   PetscInt       n,indx,level;
381ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
38216d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
38316d9e3a6SLisandro Dalcin 
38416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
385e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
3864336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
38716d9e3a6SLisandro Dalcin   if (flg) {
3884336a9eeSBarry Smith     jac->cycletype = indx+1;
389fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
39016d9e3a6SLisandro Dalcin   }
39116d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
39216d9e3a6SLisandro Dalcin   if (flg) {
393ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
394fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
39516d9e3a6SLisandro Dalcin   }
39616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
39716d9e3a6SLisandro Dalcin   if (flg) {
398ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
399fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
40016d9e3a6SLisandro Dalcin   }
4010f1074feSSatish 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);
40216d9e3a6SLisandro Dalcin   if (flg) {
40357622a8eSBarry 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);
404fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
40516d9e3a6SLisandro Dalcin   }
40616d9e3a6SLisandro Dalcin 
4070f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
40816d9e3a6SLisandro Dalcin   if (flg) {
40957622a8eSBarry 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);
410fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
41116d9e3a6SLisandro Dalcin   }
41216d9e3a6SLisandro Dalcin 
4130f1074feSSatish 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);
4140f1074feSSatish Balay   if (flg) {
41557622a8eSBarry 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);
416fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
4170f1074feSSatish Balay   }
4180f1074feSSatish Balay 
4190f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
4200f1074feSSatish Balay   if (flg) {
42157622a8eSBarry 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);
4220f1074feSSatish Balay 
423fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
4240f1074feSSatish Balay   }
4250f1074feSSatish Balay 
4260f1074feSSatish Balay 
4270f1074feSSatish 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);
4280f1074feSSatish Balay   if (flg) {
42957622a8eSBarry 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);
4300f1074feSSatish Balay 
431fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
4320f1074feSSatish Balay   }
4330f1074feSSatish Balay 
4340f1074feSSatish Balay 
43516d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
43616d9e3a6SLisandro Dalcin   if (flg) {
43757622a8eSBarry 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);
438fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
43916d9e3a6SLisandro Dalcin   }
44016d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
44116d9e3a6SLisandro Dalcin   if (flg) {
44257622a8eSBarry 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);
44357622a8eSBarry 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);
444fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
44516d9e3a6SLisandro Dalcin   }
44616d9e3a6SLisandro Dalcin 
44716d9e3a6SLisandro Dalcin   /* Grid sweeps */
4480f1074feSSatish 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);
44916d9e3a6SLisandro Dalcin   if (flg) {
450fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
45116d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
45216d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
4530f1074feSSatish Balay     jac->gridsweeps[1] = indx;
4540f1074feSSatish Balay     /*defaults coarse to 1 */
4550f1074feSSatish Balay     jac->gridsweeps[2] = 1;
45616d9e3a6SLisandro Dalcin   }
4570f1074feSSatish Balay 
4580f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
45916d9e3a6SLisandro Dalcin   if (flg) {
460fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
4610f1074feSSatish Balay     jac->gridsweeps[0] = indx;
46216d9e3a6SLisandro Dalcin   }
46316d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
46416d9e3a6SLisandro Dalcin   if (flg) {
465fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
4660f1074feSSatish Balay     jac->gridsweeps[1] = indx;
46716d9e3a6SLisandro Dalcin   }
4680f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
46916d9e3a6SLisandro Dalcin   if (flg) {
470fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
4710f1074feSSatish Balay     jac->gridsweeps[2] = indx;
47216d9e3a6SLisandro Dalcin   }
47316d9e3a6SLisandro Dalcin 
4746a251517SEike Mueller   /* Smooth type */
4756a251517SEike Mueller   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);
4766a251517SEike Mueller   if (flg) {
4776a251517SEike Mueller     jac->smoothtype = indx;
4786a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
4798131ecf7SEike Mueller     jac->smoothnumlevels = 25;
4808131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
4818131ecf7SEike Mueller   }
4828131ecf7SEike Mueller 
4838131ecf7SEike Mueller   /* Number of smoothing levels */
4848131ecf7SEike 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);
4858131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
4868131ecf7SEike Mueller     jac->smoothnumlevels = indx;
4878131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
4886a251517SEike Mueller   }
4896a251517SEike Mueller 
4901810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
4911810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
4921810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
4931810e44eSEike Mueller     jac->eu_level = indx;
4941810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
4951810e44eSEike Mueller   }
4961810e44eSEike Mueller 
4971810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
4981810e44eSEike Mueller   double droptolerance;
4991810e44eSEike Mueller   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
5001810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
5011810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
5021810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
5031810e44eSEike Mueller   }
5041810e44eSEike Mueller 
5051810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
5061810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5071810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
5081810e44eSEike Mueller     jac->eu_bj = tmp_truth;
509493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
5101810e44eSEike Mueller   }
5111810e44eSEike Mueller 
51216d9e3a6SLisandro Dalcin   /* Relax type */
513a669f990SJed 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);
51416d9e3a6SLisandro Dalcin   if (flg) {
5150f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
516fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
5170f1074feSSatish Balay     /* by default, coarse type set to 9 */
5180f1074feSSatish Balay     jac->relaxtype[2] = 9;
5190f1074feSSatish Balay 
52016d9e3a6SLisandro Dalcin   }
521a669f990SJed 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);
52216d9e3a6SLisandro Dalcin   if (flg) {
52316d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
524fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
52516d9e3a6SLisandro Dalcin   }
526a669f990SJed 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);
52716d9e3a6SLisandro Dalcin   if (flg) {
5280f1074feSSatish Balay     jac->relaxtype[1] = indx;
529fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
53016d9e3a6SLisandro Dalcin   }
531a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
53216d9e3a6SLisandro Dalcin   if (flg) {
5330f1074feSSatish Balay     jac->relaxtype[2] = indx;
534fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
53516d9e3a6SLisandro Dalcin   }
53616d9e3a6SLisandro Dalcin 
53716d9e3a6SLisandro Dalcin   /* Relaxation Weight */
53816d9e3a6SLisandro 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);
53916d9e3a6SLisandro Dalcin   if (flg) {
540fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
54116d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
54216d9e3a6SLisandro Dalcin   }
54316d9e3a6SLisandro Dalcin 
54416d9e3a6SLisandro Dalcin   n         = 2;
54516d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
54616d9e3a6SLisandro 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);
54716d9e3a6SLisandro Dalcin   if (flg) {
54816d9e3a6SLisandro Dalcin     if (n == 2) {
54916d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
550fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
551ce94432eSBarry 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);
55216d9e3a6SLisandro Dalcin   }
55316d9e3a6SLisandro Dalcin 
55416d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
55516d9e3a6SLisandro 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);
55616d9e3a6SLisandro Dalcin   if (flg) {
557fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
55816d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
55916d9e3a6SLisandro Dalcin   }
56016d9e3a6SLisandro Dalcin 
56116d9e3a6SLisandro Dalcin   n         = 2;
56216d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
56316d9e3a6SLisandro 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);
56416d9e3a6SLisandro Dalcin   if (flg) {
56516d9e3a6SLisandro Dalcin     if (n == 2) {
56616d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
567fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
568ce94432eSBarry 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);
56916d9e3a6SLisandro Dalcin   }
57016d9e3a6SLisandro Dalcin 
57116d9e3a6SLisandro Dalcin   /* the Relax Order */
572acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
57316d9e3a6SLisandro Dalcin 
5748afaa268SBarry Smith   if (flg && tmp_truth) {
57516d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
576fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
57716d9e3a6SLisandro Dalcin   }
578a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
57916d9e3a6SLisandro Dalcin   if (flg) {
58016d9e3a6SLisandro Dalcin     jac->measuretype = indx;
581fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
58216d9e3a6SLisandro Dalcin   }
5830f1074feSSatish Balay   /* update list length 3/07 */
584a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
58516d9e3a6SLisandro Dalcin   if (flg) {
58616d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
587fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
58816d9e3a6SLisandro Dalcin   }
5890f1074feSSatish Balay 
5900f1074feSSatish Balay   /* new 3/07 */
591a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
5920f1074feSSatish Balay   if (flg) {
5930f1074feSSatish Balay     jac->interptype = indx;
594fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
5950f1074feSSatish Balay   }
5960f1074feSSatish Balay 
597b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
59816d9e3a6SLisandro Dalcin   if (flg) {
599b96a4a96SBarry Smith     level = 3;
6000298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
6012fa5cd67SKarl Rupp 
602b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
603fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
6042ae77aedSBarry Smith   }
6052ae77aedSBarry Smith 
606b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
6072ae77aedSBarry Smith   if (flg) {
608b96a4a96SBarry Smith     level = 3;
6090298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
6102fa5cd67SKarl Rupp 
611b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
612fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
61316d9e3a6SLisandro Dalcin   }
6148f87f92bSBarry Smith 
6158afaa268SBarry Smith   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_coarsen", "HYPRE_BoomerAMGSetNodal()", "None", jac->nodal_coarsen ? PETSC_TRUE : PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
6168f87f92bSBarry Smith   if (flg && tmp_truth) {
6178f87f92bSBarry Smith     jac->nodal_coarsen = 1;
618fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,1));
6198f87f92bSBarry Smith   }
6208f87f92bSBarry Smith 
621acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
6228f87f92bSBarry Smith   if (flg && tmp_truth) {
6238f87f92bSBarry Smith     PetscInt tmp_int;
6248f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
6258f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
626fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
627fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
628fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
629fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
6308f87f92bSBarry Smith   }
6318f87f92bSBarry Smith 
63216d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
63316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
63416d9e3a6SLisandro Dalcin }
63516d9e3a6SLisandro Dalcin 
63616d9e3a6SLisandro Dalcin #undef __FUNCT__
63716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG"
638ace3abfcSBarry 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)
63916d9e3a6SLisandro Dalcin {
64016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
64116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
6424ddd07fcSJed Brown   PetscInt       oits;
64316d9e3a6SLisandro Dalcin 
64416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
645dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
646fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
647fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
64816d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
64916d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
65016d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
6518b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
6524d0a8057SBarry Smith   *outits = oits;
6534d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
6544d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
655fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
656fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
65716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
65816d9e3a6SLisandro Dalcin }
65916d9e3a6SLisandro Dalcin 
66016d9e3a6SLisandro Dalcin 
66116d9e3a6SLisandro Dalcin #undef __FUNCT__
66216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG"
66316d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
66416d9e3a6SLisandro Dalcin {
66516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
66616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
667ace3abfcSBarry Smith   PetscBool      iascii;
66816d9e3a6SLisandro Dalcin 
66916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
670251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
67116d9e3a6SLisandro Dalcin   if (iascii) {
67216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
67316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
67416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
67516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
67657622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
67757622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
67857622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
6790f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
6800f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
6810f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
6820f1074feSSatish Balay 
68357622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
68416d9e3a6SLisandro Dalcin 
6850f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
6860f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
6870f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
68816d9e3a6SLisandro Dalcin 
6890f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
6900f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
6910f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
69216d9e3a6SLisandro Dalcin 
69357622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
69457622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
69516d9e3a6SLisandro Dalcin 
69616d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
69716d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr);
69816d9e3a6SLisandro Dalcin     } else {
69916d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr);
70016d9e3a6SLisandro Dalcin     }
7016a251517SEike Mueller     if (jac->smoothtype!=-1) {
7026a251517SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
7038131ecf7SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Smooth num levels    %d\n",jac->smoothnumlevels);CHKERRQ(ierr);
7041810e44eSEike Mueller     }
7051810e44eSEike Mueller     if (jac->smoothtype==3) {
7061810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU(k) levels %d\n",jac->eu_level);CHKERRQ(ierr);
7071810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU(k) drop tolerance %g\n",jac->eu_droptolerance);CHKERRQ(ierr);
7081810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU use Block-Jacobi? %d\n",jac->eu_bj);CHKERRQ(ierr);
7096a251517SEike Mueller     } else {
7106a251517SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using more complex smoothers.\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
7116a251517SEike Mueller     }
71216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
71316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
7140f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
7158f87f92bSBarry Smith     if (jac->nodal_coarsen) {
7168f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal())\n");CHKERRQ(ierr);
7178f87f92bSBarry Smith     }
7188f87f92bSBarry Smith     if (jac->nodal_relax) {
7198f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
7208f87f92bSBarry Smith     }
72116d9e3a6SLisandro Dalcin   }
72216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
72316d9e3a6SLisandro Dalcin }
72416d9e3a6SLisandro Dalcin 
72516d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
72616d9e3a6SLisandro Dalcin #undef __FUNCT__
72716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails"
7288c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptions *PetscOptionsObject,PC pc)
72916d9e3a6SLisandro Dalcin {
73016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
73116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
7324ddd07fcSJed Brown   PetscInt       indx;
733ace3abfcSBarry Smith   PetscBool      flag;
73416d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
73516d9e3a6SLisandro Dalcin 
73616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
737e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
73816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
73916d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
7402fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
74116d9e3a6SLisandro Dalcin 
74216d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
7432fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
74416d9e3a6SLisandro Dalcin 
74516d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
7462fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
74716d9e3a6SLisandro Dalcin 
748acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
7492fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
75016d9e3a6SLisandro Dalcin 
751acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
7522fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
75316d9e3a6SLisandro Dalcin 
754a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
75516d9e3a6SLisandro Dalcin   if (flag) {
75616d9e3a6SLisandro Dalcin     jac->symt = indx;
757fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
75816d9e3a6SLisandro Dalcin   }
75916d9e3a6SLisandro Dalcin 
76016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
76116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
76216d9e3a6SLisandro Dalcin }
76316d9e3a6SLisandro Dalcin 
76416d9e3a6SLisandro Dalcin #undef __FUNCT__
76516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails"
76616d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
76716d9e3a6SLisandro Dalcin {
76816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
76916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
770ace3abfcSBarry Smith   PetscBool      iascii;
77116d9e3a6SLisandro Dalcin   const char     *symt = 0;;
77216d9e3a6SLisandro Dalcin 
77316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
774251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
77516d9e3a6SLisandro Dalcin   if (iascii) {
77616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
77716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
77857622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
77957622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: filter %g\n",(double)jac->filter);CHKERRQ(ierr);
78057622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
781ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
782ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
7832fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
7842fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
7852fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
786ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
78716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr);
78816d9e3a6SLisandro Dalcin   }
78916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
79016d9e3a6SLisandro Dalcin }
7914cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
7924cb006feSStefano Zampini #undef __FUNCT__
7934cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS"
7949fa463a7SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptions *PetscOptionsObject,PC pc)
7954cb006feSStefano Zampini {
7964cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
7974cb006feSStefano Zampini   PetscErrorCode ierr;
7984cb006feSStefano Zampini   PetscInt       n;
7994cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
8004cb006feSStefano Zampini 
8014cb006feSStefano Zampini   PetscFunctionBegin;
8029fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
803863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
804863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
805863406b8SStefano 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);
806863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
8074cb006feSStefano 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);
8084cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
809863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
810863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
811863406b8SStefano 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);
812863406b8SStefano 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);
813863406b8SStefano 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);
814863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
8154cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
816863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
817863406b8SStefano Zampini                                                                       jac->as_relax_times,
818863406b8SStefano Zampini                                                                       jac->as_relax_weight,
819863406b8SStefano Zampini                                                                       jac->as_omega));
8204cb006feSStefano Zampini   }
821863406b8SStefano 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);
8224cb006feSStefano Zampini   n = 5;
823863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
8244cb006feSStefano Zampini   if (flag || flag2) {
825863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
826863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
827863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
828863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
829863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
830863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
8314cb006feSStefano Zampini   }
832863406b8SStefano 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);
8334cb006feSStefano Zampini   n = 5;
834863406b8SStefano 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);
8354cb006feSStefano Zampini   if (flag || flag2) {
836863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
837863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
838863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
839863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
840863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
841863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
8424cb006feSStefano Zampini   }
8434cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
8444cb006feSStefano Zampini   PetscFunctionReturn(0);
8454cb006feSStefano Zampini }
8464cb006feSStefano Zampini 
8474cb006feSStefano Zampini #undef __FUNCT__
8484cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS"
8494cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
8504cb006feSStefano Zampini {
8514cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
8524cb006feSStefano Zampini   PetscErrorCode ierr;
8534cb006feSStefano Zampini   PetscBool      iascii;
8544cb006feSStefano Zampini 
8554cb006feSStefano Zampini   PetscFunctionBegin;
8564cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
8574cb006feSStefano Zampini   if (iascii) {
8584cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
859863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
8604cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
861863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
862863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
863863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
864863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
865863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
8664cb006feSStefano Zampini     if (jac->alpha_Poisson) {
8674cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8684cb006feSStefano Zampini     } else {
8694cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr);
8704cb006feSStefano Zampini     }
871863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
872863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
873863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
874863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
875863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
876863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
8774cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
8784cb006feSStefano Zampini       if (jac->beta_Poisson) {
8794cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8804cb006feSStefano Zampini       } else {
8814cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr);
8824cb006feSStefano Zampini       }
883863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
884863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
885863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
886863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
887863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
888863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
8894cb006feSStefano Zampini     }
8904cb006feSStefano Zampini   }
8914cb006feSStefano Zampini   PetscFunctionReturn(0);
8924cb006feSStefano Zampini }
8934cb006feSStefano Zampini 
8944cb006feSStefano Zampini #undef __FUNCT__
895863406b8SStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_ADS"
896863406b8SStefano Zampini static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptions *PetscOptionsObject,PC pc)
897863406b8SStefano Zampini {
898863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
899863406b8SStefano Zampini   PetscErrorCode ierr;
900863406b8SStefano Zampini   PetscInt       n;
901863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
902863406b8SStefano Zampini 
903863406b8SStefano Zampini   PetscFunctionBegin;
904863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
905863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
906863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
907863406b8SStefano 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);
908863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
909863406b8SStefano 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);
910863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
911863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
912863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
913863406b8SStefano 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);
914863406b8SStefano 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);
915863406b8SStefano 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);
916863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
917863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
918863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
919863406b8SStefano Zampini                                                                       jac->as_relax_times,
920863406b8SStefano Zampini                                                                       jac->as_relax_weight,
921863406b8SStefano Zampini                                                                       jac->as_omega));
922863406b8SStefano Zampini   }
923863406b8SStefano 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);
924863406b8SStefano Zampini   n = 5;
925863406b8SStefano 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);
926863406b8SStefano 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);
927863406b8SStefano Zampini   if (flag || flag2 || flag3) {
928863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
929863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
930863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
931863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
932863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
933863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
934863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
935863406b8SStefano Zampini   }
936863406b8SStefano 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);
937863406b8SStefano Zampini   n = 5;
938863406b8SStefano 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);
939863406b8SStefano Zampini   if (flag || flag2) {
940863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
941863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
942863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
943863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
944863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
945863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
946863406b8SStefano Zampini   }
947863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
948863406b8SStefano Zampini   PetscFunctionReturn(0);
949863406b8SStefano Zampini }
950863406b8SStefano Zampini 
951863406b8SStefano Zampini #undef __FUNCT__
952863406b8SStefano Zampini #define __FUNCT__ "PCView_HYPRE_ADS"
953863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
954863406b8SStefano Zampini {
955863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
956863406b8SStefano Zampini   PetscErrorCode ierr;
957863406b8SStefano Zampini   PetscBool      iascii;
958863406b8SStefano Zampini 
959863406b8SStefano Zampini   PetscFunctionBegin;
960863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
961863406b8SStefano Zampini   if (iascii) {
962863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
963863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
964863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
965863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
966863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
967863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
968863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
969863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
970863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: AMS solver\n");CHKERRQ(ierr);
971863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
972863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
973863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
974863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
975863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
976863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
977863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
978863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: vector Poisson solver\n");CHKERRQ(ierr);
979863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
980863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
981863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
982863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
983863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
984863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
985863406b8SStefano Zampini   }
986863406b8SStefano Zampini   PetscFunctionReturn(0);
987863406b8SStefano Zampini }
988863406b8SStefano Zampini 
989863406b8SStefano Zampini #undef __FUNCT__
990863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE"
991863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
9924cb006feSStefano Zampini {
9934cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
9944cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_G;
9954cb006feSStefano Zampini   PetscErrorCode     ierr;
9964cb006feSStefano Zampini 
9974cb006feSStefano Zampini   PetscFunctionBegin;
9984cb006feSStefano Zampini   /* throw away any discrete gradient if already set */
9994cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
10004cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(G,&jac->G);CHKERRQ(ierr);
10014cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(G,jac->G);CHKERRQ(ierr);
10024cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->G,(void**)(&parcsr_G)));
1003863406b8SStefano Zampini   PetscStackCall("Hypre set gradient",ierr = (*jac->setdgrad)(jac->hsolver,parcsr_G);CHKERRQ(ierr););
10044cb006feSStefano Zampini   PetscFunctionReturn(0);
10054cb006feSStefano Zampini }
10064cb006feSStefano Zampini 
10074cb006feSStefano Zampini #undef __FUNCT__
10084cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient"
10094cb006feSStefano Zampini /*@
10104cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
10114cb006feSStefano Zampini 
10124cb006feSStefano Zampini    Collective on PC
10134cb006feSStefano Zampini 
10144cb006feSStefano Zampini    Input Parameters:
10154cb006feSStefano Zampini +  pc - the preconditioning context
10164cb006feSStefano Zampini -  G - the discrete gradient
10174cb006feSStefano Zampini 
10184cb006feSStefano Zampini    Level: intermediate
10194cb006feSStefano Zampini 
10204cb006feSStefano 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
1021863406b8SStefano 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
10224cb006feSStefano Zampini 
10234cb006feSStefano Zampini .seealso:
10244cb006feSStefano Zampini @*/
10254cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
10264cb006feSStefano Zampini {
10274cb006feSStefano Zampini   PetscErrorCode ierr;
10284cb006feSStefano Zampini 
10294cb006feSStefano Zampini   PetscFunctionBegin;
10304cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
10314cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
10324cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
10334cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
10344cb006feSStefano Zampini   PetscFunctionReturn(0);
10354cb006feSStefano Zampini }
10364cb006feSStefano Zampini 
10374cb006feSStefano Zampini #undef __FUNCT__
1038863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl_HYPRE"
1039863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1040863406b8SStefano Zampini {
1041863406b8SStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
1042863406b8SStefano Zampini   HYPRE_ParCSRMatrix parcsr_C;
1043863406b8SStefano Zampini   PetscErrorCode     ierr;
1044863406b8SStefano Zampini 
1045863406b8SStefano Zampini   PetscFunctionBegin;
1046863406b8SStefano Zampini   /* throw away any discrete curl if already set */
1047863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
1048863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(C,&jac->C);CHKERRQ(ierr);
1049863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(C,jac->C);CHKERRQ(ierr);
1050863406b8SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->C,(void**)(&parcsr_C)));
1051863406b8SStefano Zampini   PetscStackCall("Hypre set curl",ierr = (*jac->setdcurl)(jac->hsolver,parcsr_C);CHKERRQ(ierr););
1052863406b8SStefano Zampini   PetscFunctionReturn(0);
1053863406b8SStefano Zampini }
1054863406b8SStefano Zampini 
1055863406b8SStefano Zampini #undef __FUNCT__
1056863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl"
1057863406b8SStefano Zampini /*@
1058863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1059863406b8SStefano Zampini 
1060863406b8SStefano Zampini    Collective on PC
1061863406b8SStefano Zampini 
1062863406b8SStefano Zampini    Input Parameters:
1063863406b8SStefano Zampini +  pc - the preconditioning context
1064863406b8SStefano Zampini -  C - the discrete curl
1065863406b8SStefano Zampini 
1066863406b8SStefano Zampini    Level: intermediate
1067863406b8SStefano Zampini 
1068863406b8SStefano 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
1069863406b8SStefano 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
1070863406b8SStefano Zampini 
1071863406b8SStefano Zampini .seealso:
1072863406b8SStefano Zampini @*/
1073863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1074863406b8SStefano Zampini {
1075863406b8SStefano Zampini   PetscErrorCode ierr;
1076863406b8SStefano Zampini 
1077863406b8SStefano Zampini   PetscFunctionBegin;
1078863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1079863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1080863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1081863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1082863406b8SStefano Zampini   PetscFunctionReturn(0);
1083863406b8SStefano Zampini }
1084863406b8SStefano Zampini 
1085863406b8SStefano Zampini #undef __FUNCT__
10864cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS"
10874cb006feSStefano Zampini static PetscErrorCode PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
10884cb006feSStefano Zampini {
10894cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
10904cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_alpha_Poisson;
10914cb006feSStefano Zampini   PetscErrorCode     ierr;
10924cb006feSStefano Zampini 
10934cb006feSStefano Zampini   PetscFunctionBegin;
10944cb006feSStefano Zampini   /* throw away any matrix if already set */
10954cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
10964cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->alpha_Poisson);CHKERRQ(ierr);
10974cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->alpha_Poisson);CHKERRQ(ierr);
10984cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->alpha_Poisson,(void**)(&parcsr_alpha_Poisson)));
10994cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr_alpha_Poisson));
11004cb006feSStefano Zampini   PetscFunctionReturn(0);
11014cb006feSStefano Zampini }
11024cb006feSStefano Zampini 
11034cb006feSStefano Zampini #undef __FUNCT__
11044cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix"
11054cb006feSStefano Zampini /*@
11064cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
11074cb006feSStefano Zampini 
11084cb006feSStefano Zampini    Collective on PC
11094cb006feSStefano Zampini 
11104cb006feSStefano Zampini    Input Parameters:
11114cb006feSStefano Zampini +  pc - the preconditioning context
11124cb006feSStefano Zampini -  A - the matrix
11134cb006feSStefano Zampini 
11144cb006feSStefano Zampini    Level: intermediate
11154cb006feSStefano Zampini 
11164cb006feSStefano Zampini    Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
11174cb006feSStefano Zampini 
11184cb006feSStefano Zampini .seealso:
11194cb006feSStefano Zampini @*/
11204cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
11214cb006feSStefano Zampini {
11224cb006feSStefano Zampini   PetscErrorCode ierr;
11234cb006feSStefano Zampini 
11244cb006feSStefano Zampini   PetscFunctionBegin;
11254cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11264cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
11274cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
11284cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetAlphaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
11294cb006feSStefano Zampini   PetscFunctionReturn(0);
11304cb006feSStefano Zampini }
11314cb006feSStefano Zampini 
11324cb006feSStefano Zampini #undef __FUNCT__
11334cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix_HYPRE_AMS"
11344cb006feSStefano Zampini static PetscErrorCode PCHYPRESetBetaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
11354cb006feSStefano Zampini {
11364cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11374cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_beta_Poisson;
11384cb006feSStefano Zampini   PetscErrorCode     ierr;
11394cb006feSStefano Zampini 
11404cb006feSStefano Zampini   PetscFunctionBegin;
11414cb006feSStefano Zampini   if (!A) {
11424cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_TRUE;
11434cb006feSStefano Zampini     PetscFunctionReturn(0);
11444cb006feSStefano Zampini   }
11454cb006feSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
11464cb006feSStefano Zampini   /* throw away any matrix if already set */
11474cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
11484cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->beta_Poisson);CHKERRQ(ierr);
11494cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->beta_Poisson);CHKERRQ(ierr);
11504cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->beta_Poisson,(void**)(&parcsr_beta_Poisson)));
11514cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr_beta_Poisson));
11524cb006feSStefano Zampini   PetscFunctionReturn(0);
11534cb006feSStefano Zampini }
11544cb006feSStefano Zampini 
11554cb006feSStefano Zampini #undef __FUNCT__
11564cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix"
11574cb006feSStefano Zampini /*@
11584cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
11594cb006feSStefano Zampini 
11604cb006feSStefano Zampini    Collective on PC
11614cb006feSStefano Zampini 
11624cb006feSStefano Zampini    Input Parameters:
11634cb006feSStefano Zampini +  pc - the preconditioning context
11644cb006feSStefano Zampini -  A - the matrix
11654cb006feSStefano Zampini 
11664cb006feSStefano Zampini    Level: intermediate
11674cb006feSStefano Zampini 
11684cb006feSStefano Zampini    Notes: A should be obtained by discretizing the Poisson problem with linear finite elements.
11694cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
11704cb006feSStefano Zampini 
11714cb006feSStefano Zampini .seealso:
11724cb006feSStefano Zampini @*/
11734cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
11744cb006feSStefano Zampini {
11754cb006feSStefano Zampini   PetscErrorCode ierr;
11764cb006feSStefano Zampini 
11774cb006feSStefano Zampini   PetscFunctionBegin;
11784cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11794cb006feSStefano Zampini   if (A) {
11804cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
11814cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
11824cb006feSStefano Zampini   }
11834cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetBetaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
11844cb006feSStefano Zampini   PetscFunctionReturn(0);
11854cb006feSStefano Zampini }
11864cb006feSStefano Zampini 
11874cb006feSStefano Zampini #undef __FUNCT__
11884cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE_AMS"
11894cb006feSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE_AMS(PC pc,Vec ozz, Vec zoz, Vec zzo)
11904cb006feSStefano Zampini {
11914cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11924cb006feSStefano Zampini   HYPRE_ParVector    par_ozz,par_zoz,par_zzo;
119312ddd1b6SStefano Zampini   PetscInt           dim;
11944cb006feSStefano Zampini   PetscErrorCode     ierr;
11954cb006feSStefano Zampini 
11964cb006feSStefano Zampini   PetscFunctionBegin;
11974cb006feSStefano Zampini   /* throw away any vector if already set */
11984cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
11994cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
12004cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
12014cb006feSStefano Zampini   jac->constants[0] = NULL;
12024cb006feSStefano Zampini   jac->constants[1] = NULL;
12034cb006feSStefano Zampini   jac->constants[2] = NULL;
12044cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
12054cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
12064cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&par_ozz)));
12074cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
12084cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
12094cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&par_zoz)));
121012ddd1b6SStefano Zampini   dim = 2;
12114cb006feSStefano Zampini   if (zzo) {
12124cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
12134cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
12144cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&par_zzo)));
121512ddd1b6SStefano Zampini     dim++;
12164cb006feSStefano Zampini   }
12174cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,par_ozz,par_zoz,par_zzo));
121812ddd1b6SStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim));
12194cb006feSStefano Zampini   PetscFunctionReturn(0);
12204cb006feSStefano Zampini }
12214cb006feSStefano Zampini 
12224cb006feSStefano Zampini #undef __FUNCT__
12234cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors"
12244cb006feSStefano Zampini /*@
12254cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
12264cb006feSStefano Zampini 
12274cb006feSStefano Zampini    Collective on PC
12284cb006feSStefano Zampini 
12294cb006feSStefano Zampini    Input Parameters:
12304cb006feSStefano Zampini +  pc - the preconditioning context
12314cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
12324cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
12334cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
12344cb006feSStefano Zampini 
12354cb006feSStefano Zampini    Level: intermediate
12364cb006feSStefano Zampini 
12374cb006feSStefano Zampini    Notes:
12384cb006feSStefano Zampini 
12394cb006feSStefano Zampini .seealso:
12404cb006feSStefano Zampini @*/
12414cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
12424cb006feSStefano Zampini {
12434cb006feSStefano Zampini   PetscErrorCode ierr;
12444cb006feSStefano Zampini 
12454cb006feSStefano Zampini   PetscFunctionBegin;
12464cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12474cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
12484cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
12494cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
12504cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
12514cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
12524cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
12534cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
12544cb006feSStefano Zampini   PetscFunctionReturn(0);
12554cb006feSStefano Zampini }
12564cb006feSStefano Zampini 
12574cb006feSStefano Zampini #undef __FUNCT__
1258863406b8SStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE"
1259863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
12604cb006feSStefano Zampini {
12614cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
12624cb006feSStefano Zampini   Vec             tv;
12634cb006feSStefano Zampini   HYPRE_ParVector par_coords[3];
12644cb006feSStefano Zampini   PetscInt        i;
12654cb006feSStefano Zampini   PetscErrorCode  ierr;
12664cb006feSStefano Zampini 
12674cb006feSStefano Zampini   PetscFunctionBegin;
12684cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
12694cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
12704cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
12714cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
12724cb006feSStefano Zampini   /* set problem's dimension */
1273863406b8SStefano Zampini   if (jac->setdim) {
1274863406b8SStefano Zampini     PetscStackCall("Hypre set dim",ierr = (*jac->setdim)(jac->hsolver,dim);CHKERRQ(ierr););
1275863406b8SStefano Zampini   }
12764cb006feSStefano Zampini   /* compute IJ vector for coordinates */
12774cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
12784cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
12794cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
12804cb006feSStefano Zampini   for (i=0;i<dim;i++) {
12814cb006feSStefano Zampini     PetscScalar *array;
12824cb006feSStefano Zampini     PetscInt    j;
12834cb006feSStefano Zampini 
12844cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
12854cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
12864cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
12874cb006feSStefano Zampini       array[j] = coords[j*dim+i];
12884cb006feSStefano Zampini     }
12894cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
12904cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
12914cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
12924cb006feSStefano Zampini   }
12934cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
12944cb006feSStefano Zampini   /* pass parCSR vectors to AMS solver */
12954cb006feSStefano Zampini   par_coords[0] = NULL;
12964cb006feSStefano Zampini   par_coords[1] = NULL;
12974cb006feSStefano Zampini   par_coords[2] = NULL;
12984cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&par_coords[0])));
12994cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&par_coords[1])));
13004cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&par_coords[2])));
1301863406b8SStefano Zampini   PetscStackCall("Hypre set coords",ierr = (*jac->setcoord)(jac->hsolver,par_coords[0],par_coords[1],par_coords[2]);CHKERRQ(ierr););
13024cb006feSStefano Zampini   PetscFunctionReturn(0);
13034cb006feSStefano Zampini }
13044cb006feSStefano Zampini 
130516d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
130616d9e3a6SLisandro Dalcin 
130716d9e3a6SLisandro Dalcin #undef __FUNCT__
130816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
1309f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
131016d9e3a6SLisandro Dalcin {
131116d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
131216d9e3a6SLisandro Dalcin 
131316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
131416d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
131516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
131616d9e3a6SLisandro Dalcin }
131716d9e3a6SLisandro Dalcin 
131816d9e3a6SLisandro Dalcin #undef __FUNCT__
131916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
1320f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
132116d9e3a6SLisandro Dalcin {
132216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
132316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1324ace3abfcSBarry Smith   PetscBool      flag;
132516d9e3a6SLisandro Dalcin 
132616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
132716d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
132816d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1329ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
133016d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
133116d9e3a6SLisandro Dalcin   } else {
133216d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
133316d9e3a6SLisandro Dalcin   }
133416d9e3a6SLisandro Dalcin 
133516d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
133616d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
133716d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
133816d9e3a6SLisandro Dalcin 
133916d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
134016d9e3a6SLisandro Dalcin   if (flag) {
1341fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
134216d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
134316d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
134416d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
134516d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
134616d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
134716d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
134816d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
134916d9e3a6SLisandro Dalcin   }
135016d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
135116d9e3a6SLisandro Dalcin   if (flag) {
1352fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
135316d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
135416d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
135516d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
135616d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
135716d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
135816d9e3a6SLisandro Dalcin     /* initialize */
135916d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
136016d9e3a6SLisandro Dalcin     jac->threshhold = .1;
136116d9e3a6SLisandro Dalcin     jac->filter     = .1;
136216d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
13632fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
13642fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
13652fa5cd67SKarl Rupp 
136616d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
136716d9e3a6SLisandro Dalcin     jac->symt = 0;
1368fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1369fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1370fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1371fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1372fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1373fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
137416d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
137516d9e3a6SLisandro Dalcin   }
137616d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
137716d9e3a6SLisandro Dalcin   if (flag) {
137816d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
137916d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
138016d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
138116d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
138216d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
138316d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
138416d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
138516d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
138616d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
138716d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
138816d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
138916d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
139016d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
13918f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
139216d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
139316d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
139416d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
139516d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
139616d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
13970f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
13986a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1399b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
14001810e44eSEike Mueller     jac->eu_level         = 0;
14011810e44eSEike Mueller     jac->eu_droptolerance = 0;
14021810e44eSEike Mueller     jac->eu_bj            = 0;
14038f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
14040f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
140516d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
140616d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
140716d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
14080f1074feSSatish Balay     jac->interptype       = 0;
14090f1074feSSatish Balay     jac->agg_nl           = 0;
14100f1074feSSatish Balay     jac->pmax             = 0;
14110f1074feSSatish Balay     jac->truncfactor      = 0.0;
14120f1074feSSatish Balay     jac->agg_num_paths    = 1;
14138f87f92bSBarry Smith 
14148f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
14158f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
14168f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1417fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1418fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1419fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1420fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1421fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1422fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1423fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1424fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1425fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1426fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1427fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1428fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1429fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1430fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1431fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1432fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
143316d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
143416d9e3a6SLisandro Dalcin   }
14354cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
14364cb006feSStefano Zampini   if (flag) {
14374cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
14384cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
14394cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
14404cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
14414cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
14424cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
1443863406b8SStefano Zampini     jac->setdgrad            = HYPRE_AMSSetDiscreteGradient;
1444863406b8SStefano Zampini     jac->setcoord            = HYPRE_AMSSetCoordinateVectors;
1445863406b8SStefano Zampini     jac->setdim              = HYPRE_AMSSetDimension;
14464cb006feSStefano Zampini     jac->coords[0]           = NULL;
14474cb006feSStefano Zampini     jac->coords[1]           = NULL;
14484cb006feSStefano Zampini     jac->coords[2]           = NULL;
14494cb006feSStefano Zampini     jac->G                   = NULL;
14504cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1451863406b8SStefano Zampini     jac->as_print           = 0;
1452863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1453863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
14544cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
14554cb006feSStefano Zampini     /* Smoothing options */
1456863406b8SStefano Zampini     jac->as_relax_type      = 2;
1457863406b8SStefano Zampini     jac->as_relax_times     = 1;
1458863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1459863406b8SStefano Zampini     jac->as_omega           = 1.0;
14604cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1461863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1462863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1463863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 8;
1464863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1465863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1466863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
14674cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
14684cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_FALSE;
1469863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1470863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1471863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 8;
1472863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1473863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1474863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1475863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1476863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
14774cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1478863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1479863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1480863406b8SStefano Zampini                                                                       jac->as_relax_times,
1481863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1482863406b8SStefano Zampini                                                                       jac->as_omega));
1483863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1484863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1485863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1486863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1487863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1488863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1489863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1490863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1491863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1492863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1493863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1494863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1495863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1496863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
14974cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE_AMS);CHKERRQ(ierr);
14984cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
14994cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",PCHYPRESetBetaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
15004cb006feSStefano Zampini     PetscFunctionReturn(0);
15014cb006feSStefano Zampini   }
1502863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1503863406b8SStefano Zampini   if (flag) {
1504863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1505863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1506863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1507863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1508863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1509863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1510863406b8SStefano Zampini     jac->setdgrad            = HYPRE_ADSSetDiscreteGradient;
1511863406b8SStefano Zampini     jac->setdcurl            = HYPRE_ADSSetDiscreteCurl;
1512863406b8SStefano Zampini     jac->setcoord            = HYPRE_ADSSetCoordinateVectors;
1513863406b8SStefano Zampini     jac->coords[0]           = NULL;
1514863406b8SStefano Zampini     jac->coords[1]           = NULL;
1515863406b8SStefano Zampini     jac->coords[2]           = NULL;
1516863406b8SStefano Zampini     jac->G                   = NULL;
1517863406b8SStefano Zampini     jac->C                   = NULL;
1518863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1519863406b8SStefano Zampini     jac->as_print           = 0;
1520863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1521863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1522863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1523863406b8SStefano Zampini     /* Smoothing options */
1524863406b8SStefano Zampini     jac->as_relax_type      = 2;
1525863406b8SStefano Zampini     jac->as_relax_times     = 1;
1526863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1527863406b8SStefano Zampini     jac->as_omega           = 1.0;
1528863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1529863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1530863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1531863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1532863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1533863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1534863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1535863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1536863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1537863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1538863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1539863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1540863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1541863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1542863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1543863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1544863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1545863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1546863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1547863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1548863406b8SStefano Zampini                                                                       jac->as_relax_times,
1549863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1550863406b8SStefano Zampini                                                                       jac->as_omega));
1551863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1552863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1553863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1554863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1555863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1556863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1557863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1558863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1559863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1560863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1561863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1562863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1563863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1564863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1565863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
1566863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
1567863406b8SStefano Zampini     PetscFunctionReturn(0);
1568863406b8SStefano Zampini   }
1569503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
15702fa5cd67SKarl Rupp 
15710298fd71SBarry Smith   jac->hypre_type = NULL;
157233263987SBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, boomeramg, ams",name);
157316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
157416d9e3a6SLisandro Dalcin }
157516d9e3a6SLisandro Dalcin 
157616d9e3a6SLisandro Dalcin /*
157716d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
157816d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
157916d9e3a6SLisandro Dalcin */
158016d9e3a6SLisandro Dalcin #undef __FUNCT__
158116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
15828c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptions *PetscOptionsObject,PC pc)
158316d9e3a6SLisandro Dalcin {
158416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
15854ddd07fcSJed Brown   PetscInt       indx;
1586863406b8SStefano Zampini   const char     *type[] = {"pilut","parasails","boomeramg","ams","ads"};
1587ace3abfcSBarry Smith   PetscBool      flg;
158816d9e3a6SLisandro Dalcin 
158916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
15909fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
15919c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
159216d9e3a6SLisandro Dalcin   if (flg) {
159316d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
159402a17cd4SBarry Smith   } else {
159502a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
159616d9e3a6SLisandro Dalcin   }
159716d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
15983931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
159916d9e3a6SLisandro Dalcin   }
160016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
160116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
160216d9e3a6SLisandro Dalcin }
160316d9e3a6SLisandro Dalcin 
160416d9e3a6SLisandro Dalcin #undef __FUNCT__
160516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
160616d9e3a6SLisandro Dalcin /*@C
160716d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
160816d9e3a6SLisandro Dalcin 
160916d9e3a6SLisandro Dalcin    Input Parameters:
161016d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1611863406b8SStefano Zampini -     name - either  pilut, parasails, boomeramg, ams, ads
161216d9e3a6SLisandro Dalcin 
161316d9e3a6SLisandro Dalcin    Options Database Keys:
1614863406b8SStefano Zampini    -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
161516d9e3a6SLisandro Dalcin 
161616d9e3a6SLisandro Dalcin    Level: intermediate
161716d9e3a6SLisandro Dalcin 
161816d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
161916d9e3a6SLisandro Dalcin            PCHYPRE
162016d9e3a6SLisandro Dalcin 
162116d9e3a6SLisandro Dalcin @*/
16227087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
162316d9e3a6SLisandro Dalcin {
16244ac538c5SBarry Smith   PetscErrorCode ierr;
162516d9e3a6SLisandro Dalcin 
162616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16270700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
162816d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
16294ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
163016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
163116d9e3a6SLisandro Dalcin }
163216d9e3a6SLisandro Dalcin 
163316d9e3a6SLisandro Dalcin #undef __FUNCT__
163416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
163516d9e3a6SLisandro Dalcin /*@C
163616d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
163716d9e3a6SLisandro Dalcin 
163816d9e3a6SLisandro Dalcin    Input Parameter:
163916d9e3a6SLisandro Dalcin .     pc - the preconditioner context
164016d9e3a6SLisandro Dalcin 
164116d9e3a6SLisandro Dalcin    Output Parameter:
1642863406b8SStefano Zampini .     name - either  pilut, parasails, boomeramg, ams, ads
164316d9e3a6SLisandro Dalcin 
164416d9e3a6SLisandro Dalcin    Level: intermediate
164516d9e3a6SLisandro Dalcin 
164616d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
164716d9e3a6SLisandro Dalcin            PCHYPRE
164816d9e3a6SLisandro Dalcin 
164916d9e3a6SLisandro Dalcin @*/
16507087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
165116d9e3a6SLisandro Dalcin {
16524ac538c5SBarry Smith   PetscErrorCode ierr;
165316d9e3a6SLisandro Dalcin 
165416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16550700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
165616d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
16574ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
165816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
165916d9e3a6SLisandro Dalcin }
166016d9e3a6SLisandro Dalcin 
166116d9e3a6SLisandro Dalcin /*MC
166216d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
166316d9e3a6SLisandro Dalcin 
166416d9e3a6SLisandro Dalcin    Options Database Keys:
1665863406b8SStefano Zampini +   -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
166616d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
166716d9e3a6SLisandro Dalcin           preconditioner
166816d9e3a6SLisandro Dalcin 
166916d9e3a6SLisandro Dalcin    Level: intermediate
167016d9e3a6SLisandro Dalcin 
167116d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
167216d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
167316d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
167416d9e3a6SLisandro Dalcin 
167516d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
16760f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
16770f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
16780f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
16798f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
16800f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
16810f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
168216d9e3a6SLisandro Dalcin 
16830f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
16840f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
16850f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
168616d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
168716d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
168816d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
168916d9e3a6SLisandro Dalcin 
169016d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
169116d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
169216d9e3a6SLisandro Dalcin 
16939e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
16949e5bc791SBarry Smith 
169516d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
16969e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
169716d9e3a6SLisandro Dalcin 
169816d9e3a6SLisandro Dalcin M*/
169916d9e3a6SLisandro Dalcin 
170016d9e3a6SLisandro Dalcin #undef __FUNCT__
170116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
17028cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
170316d9e3a6SLisandro Dalcin {
170416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
170516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
170616d9e3a6SLisandro Dalcin 
170716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1708b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
17092fa5cd67SKarl Rupp 
171016d9e3a6SLisandro Dalcin   pc->data                = jac;
171116d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
171216d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
171316d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
171416d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
171516d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
17160298fd71SBarry Smith   jac->hypre_type         = NULL;
17174cb006feSStefano Zampini   jac->coords[0]          = NULL;
17184cb006feSStefano Zampini   jac->coords[1]          = NULL;
17194cb006feSStefano Zampini   jac->coords[2]          = NULL;
17204cb006feSStefano Zampini   jac->constants[0]       = NULL;
17214cb006feSStefano Zampini   jac->constants[1]       = NULL;
17224cb006feSStefano Zampini   jac->constants[2]       = NULL;
1723863406b8SStefano Zampini   jac->G                  = NULL;
1724863406b8SStefano Zampini   jac->C                  = NULL;
1725863406b8SStefano Zampini   jac->alpha_Poisson      = NULL;
1726863406b8SStefano Zampini   jac->beta_Poisson       = NULL;
1727fd444223SStefano Zampini   jac->setdim             = NULL;
172816d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1729ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1730bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1731bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
173216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
173316d9e3a6SLisandro Dalcin }
1734ebc551c0SBarry Smith 
1735f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1736f91d8e95SBarry Smith 
1737b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1738af0996ceSBarry Smith #include <petsc/private/matimpl.h>
1739ebc551c0SBarry Smith 
1740ebc551c0SBarry Smith typedef struct {
174168326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1742f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
17439e5bc791SBarry Smith 
17449e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
17454ddd07fcSJed Brown   PetscInt its;
17469e5bc791SBarry Smith   double   tol;
17474ddd07fcSJed Brown   PetscInt relax_type;
17484ddd07fcSJed Brown   PetscInt rap_type;
17494ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
17504ddd07fcSJed Brown   PetscInt max_levels;
1751ebc551c0SBarry Smith } PC_PFMG;
1752ebc551c0SBarry Smith 
1753ebc551c0SBarry Smith #undef __FUNCT__
1754ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1755ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1756ebc551c0SBarry Smith {
1757ebc551c0SBarry Smith   PetscErrorCode ierr;
1758f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1759ebc551c0SBarry Smith 
1760ebc551c0SBarry Smith   PetscFunctionBegin;
17612fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1762f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1763c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1764ebc551c0SBarry Smith   PetscFunctionReturn(0);
1765ebc551c0SBarry Smith }
1766ebc551c0SBarry Smith 
17679e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
17689e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
17699e5bc791SBarry Smith 
1770ebc551c0SBarry Smith #undef __FUNCT__
1771ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1772ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1773ebc551c0SBarry Smith {
1774ebc551c0SBarry Smith   PetscErrorCode ierr;
1775ace3abfcSBarry Smith   PetscBool      iascii;
1776f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1777ebc551c0SBarry Smith 
1778ebc551c0SBarry Smith   PetscFunctionBegin;
1779251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
17809e5bc791SBarry Smith   if (iascii) {
17819e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
17829e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
17839e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
17849e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
17859e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
17869e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
17873b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
17889e5bc791SBarry Smith   }
1789ebc551c0SBarry Smith   PetscFunctionReturn(0);
1790ebc551c0SBarry Smith }
1791ebc551c0SBarry Smith 
17929e5bc791SBarry Smith 
1793ebc551c0SBarry Smith #undef __FUNCT__
1794ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
17958c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptions *PetscOptionsObject,PC pc)
1796ebc551c0SBarry Smith {
1797ebc551c0SBarry Smith   PetscErrorCode ierr;
1798f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1799ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1800ebc551c0SBarry Smith 
1801ebc551c0SBarry Smith   PetscFunctionBegin;
1802e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
18030298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
180468326731SBarry Smith   if (flg) {
1805a0324ebeSBarry Smith     int level=3;
1806fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
180768326731SBarry Smith   }
18080298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1809fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
18100298fd71SBarry 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);
1811fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
18120298fd71SBarry 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);
1813fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
18149e5bc791SBarry Smith 
18150298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
1816fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
18173b46a515SGlenn Hammond 
18180298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1819fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
18200298fd71SBarry 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);
1821fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
18220298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
1823fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1824ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1825ebc551c0SBarry Smith   PetscFunctionReturn(0);
1826ebc551c0SBarry Smith }
1827ebc551c0SBarry Smith 
1828f91d8e95SBarry Smith #undef __FUNCT__
1829f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1830f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1831f91d8e95SBarry Smith {
1832f91d8e95SBarry Smith   PetscErrorCode    ierr;
1833f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
1834d9ca1df4SBarry Smith   PetscScalar       *yy;
1835d9ca1df4SBarry Smith   const PetscScalar *xx;
18364ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
183768326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1838f91d8e95SBarry Smith 
1839f91d8e95SBarry Smith   PetscFunctionBegin;
1840dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1841aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1842f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1843f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1844f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1845f91d8e95SBarry Smith 
1846f91d8e95SBarry Smith   /* copy x values over to hypre */
1847fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1848d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1849d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
1850d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1851fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
1852fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1853f91d8e95SBarry Smith 
1854f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1855f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
18568b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
1857f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1858f91d8e95SBarry Smith   PetscFunctionReturn(0);
1859f91d8e95SBarry Smith }
1860f91d8e95SBarry Smith 
18619e5bc791SBarry Smith #undef __FUNCT__
18629e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1863ace3abfcSBarry 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)
18649e5bc791SBarry Smith {
18659e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
18669e5bc791SBarry Smith   PetscErrorCode ierr;
18674ddd07fcSJed Brown   PetscInt       oits;
18689e5bc791SBarry Smith 
18699e5bc791SBarry Smith   PetscFunctionBegin;
1870dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1871fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1872fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
18739e5bc791SBarry Smith 
18749e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
18758b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
18769e5bc791SBarry Smith   *outits = oits;
18779e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
18789e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1879fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1880fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
18819e5bc791SBarry Smith   PetscFunctionReturn(0);
18829e5bc791SBarry Smith }
18839e5bc791SBarry Smith 
18849e5bc791SBarry Smith 
18853a32d3dbSGlenn Hammond #undef __FUNCT__
18863a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
18873a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
18883a32d3dbSGlenn Hammond {
18893a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
18903a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
18913a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1892ace3abfcSBarry Smith   PetscBool       flg;
18933a32d3dbSGlenn Hammond 
18943a32d3dbSGlenn Hammond   PetscFunctionBegin;
1895251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1896ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
18973a32d3dbSGlenn Hammond 
18983a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
18992fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1900fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1901fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1902fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
19033a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
19043a32d3dbSGlenn Hammond }
19053a32d3dbSGlenn Hammond 
1906ebc551c0SBarry Smith 
1907ebc551c0SBarry Smith /*MC
1908ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1909ebc551c0SBarry Smith 
1910ebc551c0SBarry Smith    Level: advanced
1911ebc551c0SBarry Smith 
19129e5bc791SBarry Smith    Options Database:
19139e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
19149e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
19159e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
19169e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
19179e5bc791SBarry 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
19189e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
1919f91d8e95SBarry Smith 
19209e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
19219e5bc791SBarry Smith 
19228e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
1923aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
19249e5bc791SBarry Smith 
19259e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
1926ebc551c0SBarry Smith M*/
1927ebc551c0SBarry Smith 
1928ebc551c0SBarry Smith #undef __FUNCT__
1929ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
19308cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
1931ebc551c0SBarry Smith {
1932ebc551c0SBarry Smith   PetscErrorCode ierr;
1933ebc551c0SBarry Smith   PC_PFMG        *ex;
1934ebc551c0SBarry Smith 
1935ebc551c0SBarry Smith   PetscFunctionBegin;
1936b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
193768326731SBarry Smith   pc->data = ex;
1938ebc551c0SBarry Smith 
19399e5bc791SBarry Smith   ex->its            = 1;
19409e5bc791SBarry Smith   ex->tol            = 1.e-8;
19419e5bc791SBarry Smith   ex->relax_type     = 1;
19429e5bc791SBarry Smith   ex->rap_type       = 0;
19439e5bc791SBarry Smith   ex->num_pre_relax  = 1;
19449e5bc791SBarry Smith   ex->num_post_relax = 1;
19453b46a515SGlenn Hammond   ex->max_levels     = 0;
19469e5bc791SBarry Smith 
1947ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
1948ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
1949ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
1950f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
19519e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
195268326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
19532fa5cd67SKarl Rupp 
1954ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
1955fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1956ebc551c0SBarry Smith   PetscFunctionReturn(0);
1957ebc551c0SBarry Smith }
1958d851a50bSGlenn Hammond 
1959325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
1960325fc9f4SBarry Smith 
1961d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
1962d851a50bSGlenn Hammond typedef struct {
1963d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
1964d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
1965d851a50bSGlenn Hammond 
1966d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
19674ddd07fcSJed Brown   PetscInt its;
1968d851a50bSGlenn Hammond   double   tol;
19694ddd07fcSJed Brown   PetscInt relax_type;
19704ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
1971d851a50bSGlenn Hammond } PC_SysPFMG;
1972d851a50bSGlenn Hammond 
1973d851a50bSGlenn Hammond #undef __FUNCT__
1974d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
1975d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
1976d851a50bSGlenn Hammond {
1977d851a50bSGlenn Hammond   PetscErrorCode ierr;
1978d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1979d851a50bSGlenn Hammond 
1980d851a50bSGlenn Hammond   PetscFunctionBegin;
19812fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1982d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1983c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1984d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1985d851a50bSGlenn Hammond }
1986d851a50bSGlenn Hammond 
1987d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
1988d851a50bSGlenn Hammond 
1989d851a50bSGlenn Hammond #undef __FUNCT__
1990d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
1991d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
1992d851a50bSGlenn Hammond {
1993d851a50bSGlenn Hammond   PetscErrorCode ierr;
1994ace3abfcSBarry Smith   PetscBool      iascii;
1995d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1996d851a50bSGlenn Hammond 
1997d851a50bSGlenn Hammond   PetscFunctionBegin;
1998251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1999d851a50bSGlenn Hammond   if (iascii) {
2000d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2001d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
2002d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
2003d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2004d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2005d851a50bSGlenn Hammond   }
2006d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2007d851a50bSGlenn Hammond }
2008d851a50bSGlenn Hammond 
2009d851a50bSGlenn Hammond 
2010d851a50bSGlenn Hammond #undef __FUNCT__
2011d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
20128c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptions *PetscOptionsObject,PC pc)
2013d851a50bSGlenn Hammond {
2014d851a50bSGlenn Hammond   PetscErrorCode ierr;
2015d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2016ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2017d851a50bSGlenn Hammond 
2018d851a50bSGlenn Hammond   PetscFunctionBegin;
2019e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
20200298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2021d851a50bSGlenn Hammond   if (flg) {
2022d851a50bSGlenn Hammond     int level=3;
2023fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
2024d851a50bSGlenn Hammond   }
20250298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2026fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
20270298fd71SBarry 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);
2028fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
20290298fd71SBarry 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);
2030fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2031d851a50bSGlenn Hammond 
20320298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2033fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
20340298fd71SBarry 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);
2035fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2036d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2037d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2038d851a50bSGlenn Hammond }
2039d851a50bSGlenn Hammond 
2040d851a50bSGlenn Hammond #undef __FUNCT__
2041d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
2042d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2043d851a50bSGlenn Hammond {
2044d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2045d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2046d9ca1df4SBarry Smith   PetscScalar       *yy;
2047d9ca1df4SBarry Smith   const PetscScalar *xx;
20484ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
2049d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
20504ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
20514ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
20524ddd07fcSJed Brown   PetscInt          part    = 0;
20534ddd07fcSJed Brown   PetscInt          size;
20544ddd07fcSJed Brown   PetscInt          i;
2055d851a50bSGlenn Hammond 
2056d851a50bSGlenn Hammond   PetscFunctionBegin;
2057dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2058aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2059d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2060d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2061d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2062d851a50bSGlenn Hammond 
2063d851a50bSGlenn Hammond   size = 1;
20642fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
20652fa5cd67SKarl Rupp 
2066d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2067d851a50bSGlenn Hammond   if (ordering) {
2068fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2069d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2070d9ca1df4SBarry 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)));
2071d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2072fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2073fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2074fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2075d851a50bSGlenn Hammond 
2076d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2077d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
20788b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2079d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2080a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2081d851a50bSGlenn Hammond     PetscScalar *z;
20824ddd07fcSJed Brown     PetscInt    j, k;
2083d851a50bSGlenn Hammond 
2084785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2085fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2086d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2087d851a50bSGlenn Hammond 
2088d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2089d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2090d851a50bSGlenn Hammond       k= i*nvars;
20912fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2092d851a50bSGlenn Hammond     }
20938b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2094d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2095fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2096fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2097d851a50bSGlenn Hammond 
2098d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2099d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
21008b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2101d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2102d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2103d851a50bSGlenn Hammond       k= i*nvars;
21042fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2105d851a50bSGlenn Hammond     }
2106d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2107d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2108d851a50bSGlenn Hammond   }
2109d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2110d851a50bSGlenn Hammond }
2111d851a50bSGlenn Hammond 
2112d851a50bSGlenn Hammond #undef __FUNCT__
2113d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
2114ace3abfcSBarry 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)
2115d851a50bSGlenn Hammond {
2116d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2117d851a50bSGlenn Hammond   PetscErrorCode ierr;
21184ddd07fcSJed Brown   PetscInt       oits;
2119d851a50bSGlenn Hammond 
2120d851a50bSGlenn Hammond   PetscFunctionBegin;
2121dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2122fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2123fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2124d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
21258b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2126d851a50bSGlenn Hammond   *outits = oits;
2127d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2128d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2129fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2130fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2131d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2132d851a50bSGlenn Hammond }
2133d851a50bSGlenn Hammond 
2134d851a50bSGlenn Hammond 
2135d851a50bSGlenn Hammond #undef __FUNCT__
2136d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
2137d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2138d851a50bSGlenn Hammond {
2139d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2140d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2141d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2142ace3abfcSBarry Smith   PetscBool        flg;
2143d851a50bSGlenn Hammond 
2144d851a50bSGlenn Hammond   PetscFunctionBegin;
2145251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2146ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2147d851a50bSGlenn Hammond 
2148d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
21492fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2150fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2151fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2152fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2153d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2154d851a50bSGlenn Hammond }
2155d851a50bSGlenn Hammond 
2156d851a50bSGlenn Hammond 
2157d851a50bSGlenn Hammond /*MC
2158d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2159d851a50bSGlenn Hammond 
2160d851a50bSGlenn Hammond    Level: advanced
2161d851a50bSGlenn Hammond 
2162d851a50bSGlenn Hammond    Options Database:
2163d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2164d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2165d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2166d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2167d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2168d851a50bSGlenn Hammond 
2169d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
2170d851a50bSGlenn Hammond 
2171f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2172aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2173d851a50bSGlenn Hammond            Also, only cell-centered variables.
2174d851a50bSGlenn Hammond 
2175d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2176d851a50bSGlenn Hammond M*/
2177d851a50bSGlenn Hammond 
2178d851a50bSGlenn Hammond #undef __FUNCT__
2179d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
21808cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2181d851a50bSGlenn Hammond {
2182d851a50bSGlenn Hammond   PetscErrorCode ierr;
2183d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2184d851a50bSGlenn Hammond 
2185d851a50bSGlenn Hammond   PetscFunctionBegin;
2186b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2187d851a50bSGlenn Hammond   pc->data = ex;
2188d851a50bSGlenn Hammond 
2189d851a50bSGlenn Hammond   ex->its            = 1;
2190d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2191d851a50bSGlenn Hammond   ex->relax_type     = 1;
2192d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2193d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2194d851a50bSGlenn Hammond 
2195d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2196d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2197d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2198d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2199d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2200d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
22012fa5cd67SKarl Rupp 
2202ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2203fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2204d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2205d851a50bSGlenn Hammond }
2206