xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 8695de01ae8f598ce8b155b2ab3b26916fc80b56)
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;
624ddd07fcSJed Brown   PetscInt  relaxtype[3];
6316d9e3a6SLisandro Dalcin   double    relaxweight;
6416d9e3a6SLisandro Dalcin   double    outerrelaxweight;
654ddd07fcSJed Brown   PetscInt  relaxorder;
6616d9e3a6SLisandro Dalcin   double    truncfactor;
67ace3abfcSBarry Smith   PetscBool applyrichardson;
684ddd07fcSJed Brown   PetscInt  pmax;
694ddd07fcSJed Brown   PetscInt  interptype;
704ddd07fcSJed Brown   PetscInt  agg_nl;
714ddd07fcSJed Brown   PetscInt  agg_num_paths;
724ddd07fcSJed Brown   PetscInt  nodal_coarsen;
73ace3abfcSBarry Smith   PetscBool nodal_relax;
744ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
754cb006feSStefano Zampini 
76863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
77863406b8SStefano Zampini   PetscInt  as_print;
78863406b8SStefano Zampini   PetscInt  as_max_iter;
79863406b8SStefano Zampini   PetscReal as_tol;
80863406b8SStefano Zampini   PetscInt  as_relax_type;
81863406b8SStefano Zampini   PetscInt  as_relax_times;
82863406b8SStefano Zampini   PetscReal as_relax_weight;
83863406b8SStefano Zampini   PetscReal as_omega;
84863406b8SStefano 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) */
85863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
86863406b8SStefano 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) */
87863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
884cb006feSStefano Zampini   PetscInt  ams_cycle_type;
89863406b8SStefano Zampini   PetscInt  ads_cycle_type;
904cb006feSStefano Zampini 
914cb006feSStefano Zampini   /* additional data */
924cb006feSStefano Zampini   HYPRE_IJVector coords[3];
934cb006feSStefano Zampini   HYPRE_IJVector constants[3];
944cb006feSStefano Zampini   HYPRE_IJMatrix G;
95863406b8SStefano Zampini   HYPRE_IJMatrix C;
964cb006feSStefano Zampini   HYPRE_IJMatrix alpha_Poisson;
974cb006feSStefano Zampini   HYPRE_IJMatrix beta_Poisson;
984cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
9916d9e3a6SLisandro Dalcin } PC_HYPRE;
10016d9e3a6SLisandro Dalcin 
101d2128fa2SBarry Smith #undef __FUNCT__
102d2128fa2SBarry Smith #define __FUNCT__ "PCHYPREGetSolver"
103d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
104d2128fa2SBarry Smith {
105d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
106d2128fa2SBarry Smith 
107d2128fa2SBarry Smith   PetscFunctionBegin;
108d2128fa2SBarry Smith   *hsolver = jac->hsolver;
109d2128fa2SBarry Smith   PetscFunctionReturn(0);
110d2128fa2SBarry Smith }
11116d9e3a6SLisandro Dalcin 
11216d9e3a6SLisandro Dalcin #undef __FUNCT__
11316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE"
11416d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
11516d9e3a6SLisandro Dalcin {
11616d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11716d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
11816d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
11916d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
12016d9e3a6SLisandro Dalcin   PetscInt           bs;
12116d9e3a6SLisandro Dalcin 
12216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
12316d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
12402a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
12516d9e3a6SLisandro Dalcin   }
1265f5c5b43SBarry Smith 
1275f5c5b43SBarry Smith   if (pc->setupcalled) {
1285f5c5b43SBarry Smith     /* always destroy the old matrix and create a new memory;
1295f5c5b43SBarry Smith        hope this does not churn the memory too much. The problem
1305f5c5b43SBarry Smith        is I do not know if it is possible to put the matrix back to
1315f5c5b43SBarry Smith        its initial state so that we can directly copy the values
1325f5c5b43SBarry Smith        the second time through. */
133fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
1345f5c5b43SBarry Smith     jac->ij = 0;
13516d9e3a6SLisandro Dalcin   }
1365f5c5b43SBarry Smith 
13716d9e3a6SLisandro Dalcin   if (!jac->ij) { /* create the matrix the first time through */
13816d9e3a6SLisandro Dalcin     ierr = MatHYPRE_IJMatrixCreate(pc->pmat,&jac->ij);CHKERRQ(ierr);
13916d9e3a6SLisandro Dalcin   }
14016d9e3a6SLisandro Dalcin   if (!jac->b) { /* create the vectors the first time through */
14116d9e3a6SLisandro Dalcin     Vec x,b;
1422a7a6963SBarry Smith     ierr = MatCreateVecs(pc->pmat,&x,&b);CHKERRQ(ierr);
14316d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(x,&jac->x);CHKERRQ(ierr);
14416d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(b,&jac->b);CHKERRQ(ierr);
1456bf464f9SBarry Smith     ierr = VecDestroy(&x);CHKERRQ(ierr);
1466bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
14716d9e3a6SLisandro Dalcin   }
1485f5c5b43SBarry Smith 
14916d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
15016d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
15116d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1522fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
1534cb006feSStefano Zampini   }
154863406b8SStefano Zampini 
1554cb006feSStefano Zampini   /* special case for AMS */
1564cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
1574cb006feSStefano Zampini     if (!jac->coords[0] && !jac->constants[0]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs either coordinate vectors via PCSetCoordinates() or edge constant vectors via PCHYPRESetEdgeConstantVectors()");
1584cb006feSStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
1594cb006feSStefano Zampini   }
160863406b8SStefano Zampini   /* special case for ADS */
161863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
162863406b8SStefano Zampini     if (!jac->coords[0]) {
163863406b8SStefano Zampini       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs coordinate vectors via PCSetCoordinates()");
164fd444223SStefano Zampini     } else if (!jac->coords[1] || !jac->coords[2]) {
165fd444223SStefano 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");
166863406b8SStefano Zampini     }
167863406b8SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
168863406b8SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete curl operator via PCHYPRESetDiscreteGradient");
169863406b8SStefano Zampini   }
17016d9e3a6SLisandro Dalcin   ierr = MatHYPRE_IJMatrixCopy(pc->pmat,jac->ij);CHKERRQ(ierr);
171fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
172fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&bv));
173fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&xv));
174fd3f9acdSBarry Smith   PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr););
17516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
17616d9e3a6SLisandro Dalcin }
17716d9e3a6SLisandro Dalcin 
17816d9e3a6SLisandro Dalcin /*
17916d9e3a6SLisandro Dalcin     Replaces the address where the HYPRE vector points to its data with the address of
18016d9e3a6SLisandro Dalcin   PETSc's data. Saves the old address so it can be reset when we are finished with it.
18116d9e3a6SLisandro Dalcin   Allows use to get the data into a HYPRE vector without the cost of memcopies
18216d9e3a6SLisandro Dalcin */
18316d9e3a6SLisandro Dalcin #define HYPREReplacePointer(b,newvalue,savedvalue) { \
18416d9e3a6SLisandro Dalcin     hypre_ParVector *par_vector   = (hypre_ParVector*)hypre_IJVectorObject(((hypre_IJVector*)b)); \
18516d9e3a6SLisandro Dalcin     hypre_Vector    *local_vector = hypre_ParVectorLocalVector(par_vector); \
18616d9e3a6SLisandro Dalcin     savedvalue         = local_vector->data; \
1870ad7597dSKarl Rupp     local_vector->data = newvalue;          \
1880ad7597dSKarl Rupp }
18916d9e3a6SLisandro Dalcin 
19016d9e3a6SLisandro Dalcin #undef __FUNCT__
19116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE"
19216d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
19316d9e3a6SLisandro Dalcin {
19416d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
19516d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
19616d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
197d9ca1df4SBarry Smith   PetscScalar        *xv;
198d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
19916d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
200d9ca1df4SBarry Smith   PetscScalar        *sxv;
2014ddd07fcSJed Brown   PetscInt           hierr;
20216d9e3a6SLisandro Dalcin 
20316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
204dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
20516d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
206d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
20716d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
208d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
20916d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
21016d9e3a6SLisandro Dalcin 
211fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
212fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
213fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
214fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
21565e19b50SBarry Smith                                if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
216fd3f9acdSBarry Smith                                if (hierr) hypre__global_error = 0;);
21716d9e3a6SLisandro Dalcin 
218d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)sbv,bv);
21916d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
22016d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
221d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
22216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
22316d9e3a6SLisandro Dalcin }
22416d9e3a6SLisandro Dalcin 
22516d9e3a6SLisandro Dalcin #undef __FUNCT__
226*8695de01SBarry Smith #define __FUNCT__ "PCReset_HYPRE"
227*8695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc)
228*8695de01SBarry Smith {
229*8695de01SBarry Smith   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
230*8695de01SBarry Smith   PetscErrorCode ierr;
231*8695de01SBarry Smith 
232*8695de01SBarry Smith   PetscFunctionBegin;
233*8695de01SBarry Smith   if (jac->ij) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij)); jac->ij = NULL;
234*8695de01SBarry Smith   if (jac->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->b)); jac->b = NULL;
235*8695de01SBarry Smith   if (jac->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->x)); jac->x = NULL;
236*8695de01SBarry Smith   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); jac->coords[0] = NULL;
237*8695de01SBarry Smith   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); jac->coords[1] = NULL;
238*8695de01SBarry Smith   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); jac->coords[2] = NULL;
239*8695de01SBarry Smith   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); jac->constants[0] = NULL;
240*8695de01SBarry Smith   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); jac->constants[1] = NULL;
241*8695de01SBarry Smith   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); jac->constants[2] = NULL;
242*8695de01SBarry Smith   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G)); jac->G = NULL;
243*8695de01SBarry Smith   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C)); jac->C = NULL;
244*8695de01SBarry Smith   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson)); jac->alpha_Poisson = NULL;
245*8695de01SBarry Smith   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson)); jac->beta_Poisson = NULL;
246*8695de01SBarry Smith   PetscFunctionReturn(0);
247*8695de01SBarry Smith }
248*8695de01SBarry Smith 
249*8695de01SBarry Smith #undef __FUNCT__
25016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE"
25116d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
25216d9e3a6SLisandro Dalcin {
25316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
25416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
25516d9e3a6SLisandro Dalcin 
25616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
257*8695de01SBarry Smith   ierr = PCReset_HYPRE(pc);CHKERRQ(ierr);
258226b0620SJed Brown   if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr););
259503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
26016d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
261c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
26216d9e3a6SLisandro Dalcin 
26316d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
264bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
265bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
2664cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
2674cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
268863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
2694cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
2704cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",NULL);CHKERRQ(ierr);
2714cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",NULL);CHKERRQ(ierr);
27216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
27316d9e3a6SLisandro Dalcin }
27416d9e3a6SLisandro Dalcin 
27516d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
27616d9e3a6SLisandro Dalcin #undef __FUNCT__
27716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut"
2788c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptions *PetscOptionsObject,PC pc)
27916d9e3a6SLisandro Dalcin {
28016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
28116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
282ace3abfcSBarry Smith   PetscBool      flag;
28316d9e3a6SLisandro Dalcin 
28416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
285e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
28616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
287fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
28816d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
289fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
29016d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
291fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
29216d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
29316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
29416d9e3a6SLisandro Dalcin }
29516d9e3a6SLisandro Dalcin 
29616d9e3a6SLisandro Dalcin #undef __FUNCT__
29716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut"
29816d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
29916d9e3a6SLisandro Dalcin {
30016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
30116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
302ace3abfcSBarry Smith   PetscBool      iascii;
30316d9e3a6SLisandro Dalcin 
30416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
305251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
30616d9e3a6SLisandro Dalcin   if (iascii) {
30716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
30816d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
30916d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
31016d9e3a6SLisandro Dalcin     } else {
31116d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr);
31216d9e3a6SLisandro Dalcin     }
31316d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
31457622a8eSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
31516d9e3a6SLisandro Dalcin     } else {
31616d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr);
31716d9e3a6SLisandro Dalcin     }
31816d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
31916d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
32016d9e3a6SLisandro Dalcin     } else {
32116d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default factor row size \n");CHKERRQ(ierr);
32216d9e3a6SLisandro Dalcin     }
32316d9e3a6SLisandro Dalcin   }
32416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
32516d9e3a6SLisandro Dalcin }
32616d9e3a6SLisandro Dalcin 
32716d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
32816d9e3a6SLisandro Dalcin 
32916d9e3a6SLisandro Dalcin #undef __FUNCT__
33016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG"
33116d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
33216d9e3a6SLisandro Dalcin {
33316d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
33416d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
33516d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
336d9ca1df4SBarry Smith   PetscScalar        *xv;
337d9ca1df4SBarry Smith   const PetscScalar  *bv;
33816d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
33916d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
3404ddd07fcSJed Brown   PetscInt           hierr;
34116d9e3a6SLisandro Dalcin 
34216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
343dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
34416d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
345d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
34616d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
347d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
34816d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
34916d9e3a6SLisandro Dalcin 
350fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
351fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
352fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
35316d9e3a6SLisandro Dalcin 
35416d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
35516d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
356e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
35716d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
35816d9e3a6SLisandro Dalcin 
35916d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
36016d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
36116d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
362d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
36316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
36416d9e3a6SLisandro Dalcin }
36516d9e3a6SLisandro Dalcin 
366a669f990SJed Brown /* static array length */
367a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
368a669f990SJed Brown 
36916d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
3700f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
37116d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
37265de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
37365de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
37465de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
37565de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
37665de4495SJed Brown                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */,
37765de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
3780f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
3790f1074feSSatish Balay                                                   "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"};
38016d9e3a6SLisandro Dalcin #undef __FUNCT__
38116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG"
3828c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptions *PetscOptionsObject,PC pc)
38316d9e3a6SLisandro Dalcin {
38416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
38516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
3864ddd07fcSJed Brown   PetscInt       n,indx,level;
387ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
38816d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
38916d9e3a6SLisandro Dalcin 
39016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
391e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
3924336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
39316d9e3a6SLisandro Dalcin   if (flg) {
3944336a9eeSBarry Smith     jac->cycletype = indx+1;
395fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
39616d9e3a6SLisandro Dalcin   }
39716d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
39816d9e3a6SLisandro Dalcin   if (flg) {
399ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
400fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
40116d9e3a6SLisandro Dalcin   }
40216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
40316d9e3a6SLisandro Dalcin   if (flg) {
404ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
405fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
40616d9e3a6SLisandro Dalcin   }
4070f1074feSSatish 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);
40816d9e3a6SLisandro Dalcin   if (flg) {
40957622a8eSBarry 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);
410fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
41116d9e3a6SLisandro Dalcin   }
41216d9e3a6SLisandro Dalcin 
4130f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
41416d9e3a6SLisandro Dalcin   if (flg) {
41557622a8eSBarry 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);
416fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
41716d9e3a6SLisandro Dalcin   }
41816d9e3a6SLisandro Dalcin 
4190f1074feSSatish 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);
4200f1074feSSatish Balay   if (flg) {
42157622a8eSBarry 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);
422fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
4230f1074feSSatish Balay   }
4240f1074feSSatish Balay 
4250f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
4260f1074feSSatish Balay   if (flg) {
42757622a8eSBarry 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);
4280f1074feSSatish Balay 
429fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
4300f1074feSSatish Balay   }
4310f1074feSSatish Balay 
4320f1074feSSatish Balay 
4330f1074feSSatish 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);
4340f1074feSSatish Balay   if (flg) {
43557622a8eSBarry 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);
4360f1074feSSatish Balay 
437fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
4380f1074feSSatish Balay   }
4390f1074feSSatish Balay 
4400f1074feSSatish Balay 
44116d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
44216d9e3a6SLisandro Dalcin   if (flg) {
44357622a8eSBarry 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);
444fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
44516d9e3a6SLisandro Dalcin   }
44616d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
44716d9e3a6SLisandro Dalcin   if (flg) {
44857622a8eSBarry 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);
44957622a8eSBarry 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);
450fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
45116d9e3a6SLisandro Dalcin   }
45216d9e3a6SLisandro Dalcin 
45316d9e3a6SLisandro Dalcin   /* Grid sweeps */
4540f1074feSSatish 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);
45516d9e3a6SLisandro Dalcin   if (flg) {
456fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
45716d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
45816d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
4590f1074feSSatish Balay     jac->gridsweeps[1] = indx;
4600f1074feSSatish Balay     /*defaults coarse to 1 */
4610f1074feSSatish Balay     jac->gridsweeps[2] = 1;
46216d9e3a6SLisandro Dalcin   }
4630f1074feSSatish Balay 
4640f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
46516d9e3a6SLisandro Dalcin   if (flg) {
466fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
4670f1074feSSatish Balay     jac->gridsweeps[0] = indx;
46816d9e3a6SLisandro Dalcin   }
46916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
47016d9e3a6SLisandro Dalcin   if (flg) {
471fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
4720f1074feSSatish Balay     jac->gridsweeps[1] = indx;
47316d9e3a6SLisandro Dalcin   }
4740f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
47516d9e3a6SLisandro Dalcin   if (flg) {
476fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
4770f1074feSSatish Balay     jac->gridsweeps[2] = indx;
47816d9e3a6SLisandro Dalcin   }
47916d9e3a6SLisandro Dalcin 
48016d9e3a6SLisandro Dalcin   /* Relax type */
481a669f990SJed 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);
48216d9e3a6SLisandro Dalcin   if (flg) {
4830f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
484fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
4850f1074feSSatish Balay     /* by default, coarse type set to 9 */
4860f1074feSSatish Balay     jac->relaxtype[2] = 9;
4870f1074feSSatish Balay 
48816d9e3a6SLisandro Dalcin   }
489a669f990SJed 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);
49016d9e3a6SLisandro Dalcin   if (flg) {
49116d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
492fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
49316d9e3a6SLisandro Dalcin   }
494a669f990SJed 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);
49516d9e3a6SLisandro Dalcin   if (flg) {
4960f1074feSSatish Balay     jac->relaxtype[1] = indx;
497fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
49816d9e3a6SLisandro Dalcin   }
499a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
50016d9e3a6SLisandro Dalcin   if (flg) {
5010f1074feSSatish Balay     jac->relaxtype[2] = indx;
502fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
50316d9e3a6SLisandro Dalcin   }
50416d9e3a6SLisandro Dalcin 
50516d9e3a6SLisandro Dalcin   /* Relaxation Weight */
50616d9e3a6SLisandro 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);
50716d9e3a6SLisandro Dalcin   if (flg) {
508fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
50916d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
51016d9e3a6SLisandro Dalcin   }
51116d9e3a6SLisandro Dalcin 
51216d9e3a6SLisandro Dalcin   n         = 2;
51316d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
51416d9e3a6SLisandro 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);
51516d9e3a6SLisandro Dalcin   if (flg) {
51616d9e3a6SLisandro Dalcin     if (n == 2) {
51716d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
518fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
519ce94432eSBarry 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);
52016d9e3a6SLisandro Dalcin   }
52116d9e3a6SLisandro Dalcin 
52216d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
52316d9e3a6SLisandro 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);
52416d9e3a6SLisandro Dalcin   if (flg) {
525fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
52616d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
52716d9e3a6SLisandro Dalcin   }
52816d9e3a6SLisandro Dalcin 
52916d9e3a6SLisandro Dalcin   n         = 2;
53016d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
53116d9e3a6SLisandro 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);
53216d9e3a6SLisandro Dalcin   if (flg) {
53316d9e3a6SLisandro Dalcin     if (n == 2) {
53416d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
535fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
536ce94432eSBarry 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);
53716d9e3a6SLisandro Dalcin   }
53816d9e3a6SLisandro Dalcin 
53916d9e3a6SLisandro Dalcin   /* the Relax Order */
540acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
54116d9e3a6SLisandro Dalcin 
5428afaa268SBarry Smith   if (flg && tmp_truth) {
54316d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
544fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
54516d9e3a6SLisandro Dalcin   }
546a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
54716d9e3a6SLisandro Dalcin   if (flg) {
54816d9e3a6SLisandro Dalcin     jac->measuretype = indx;
549fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
55016d9e3a6SLisandro Dalcin   }
5510f1074feSSatish Balay   /* update list length 3/07 */
552a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
55316d9e3a6SLisandro Dalcin   if (flg) {
55416d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
555fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
55616d9e3a6SLisandro Dalcin   }
5570f1074feSSatish Balay 
5580f1074feSSatish Balay   /* new 3/07 */
559a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
5600f1074feSSatish Balay   if (flg) {
5610f1074feSSatish Balay     jac->interptype = indx;
562fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
5630f1074feSSatish Balay   }
5640f1074feSSatish Balay 
565b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
56616d9e3a6SLisandro Dalcin   if (flg) {
567b96a4a96SBarry Smith     level = 3;
5680298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
5692fa5cd67SKarl Rupp 
570b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
571fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
5722ae77aedSBarry Smith   }
5732ae77aedSBarry Smith 
574b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
5752ae77aedSBarry Smith   if (flg) {
576b96a4a96SBarry Smith     level = 3;
5770298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
5782fa5cd67SKarl Rupp 
579b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
580fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
58116d9e3a6SLisandro Dalcin   }
5828f87f92bSBarry Smith 
5838afaa268SBarry Smith   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_coarsen", "HYPRE_BoomerAMGSetNodal()", "None", jac->nodal_coarsen ? PETSC_TRUE : PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5848f87f92bSBarry Smith   if (flg && tmp_truth) {
5858f87f92bSBarry Smith     jac->nodal_coarsen = 1;
586fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,1));
5878f87f92bSBarry Smith   }
5888f87f92bSBarry Smith 
589acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5908f87f92bSBarry Smith   if (flg && tmp_truth) {
5918f87f92bSBarry Smith     PetscInt tmp_int;
5928f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
5938f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
594fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
595fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
596fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
597fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
5988f87f92bSBarry Smith   }
5998f87f92bSBarry Smith 
60016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
60116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
60216d9e3a6SLisandro Dalcin }
60316d9e3a6SLisandro Dalcin 
60416d9e3a6SLisandro Dalcin #undef __FUNCT__
60516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG"
606ace3abfcSBarry 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)
60716d9e3a6SLisandro Dalcin {
60816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
60916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
6104ddd07fcSJed Brown   PetscInt       oits;
61116d9e3a6SLisandro Dalcin 
61216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
613dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
614fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
615fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
61616d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
61716d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
61816d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
6198b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
6204d0a8057SBarry Smith   *outits = oits;
6214d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
6224d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
623fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
624fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
62516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
62616d9e3a6SLisandro Dalcin }
62716d9e3a6SLisandro Dalcin 
62816d9e3a6SLisandro Dalcin 
62916d9e3a6SLisandro Dalcin #undef __FUNCT__
63016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG"
63116d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
63216d9e3a6SLisandro Dalcin {
63316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
63416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
635ace3abfcSBarry Smith   PetscBool      iascii;
63616d9e3a6SLisandro Dalcin 
63716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
638251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
63916d9e3a6SLisandro Dalcin   if (iascii) {
64016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
64116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
64216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
64316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
64457622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
64557622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
64657622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
6470f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
6480f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
6490f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
6500f1074feSSatish Balay 
65157622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
65216d9e3a6SLisandro Dalcin 
6530f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
6540f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
6550f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
65616d9e3a6SLisandro Dalcin 
6570f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
6580f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
6590f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
66016d9e3a6SLisandro Dalcin 
66157622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
66257622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
66316d9e3a6SLisandro Dalcin 
66416d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
66516d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr);
66616d9e3a6SLisandro Dalcin     } else {
66716d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr);
66816d9e3a6SLisandro Dalcin     }
66916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
67016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
6710f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
6728f87f92bSBarry Smith     if (jac->nodal_coarsen) {
6738f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal())\n");CHKERRQ(ierr);
6748f87f92bSBarry Smith     }
6758f87f92bSBarry Smith     if (jac->nodal_relax) {
6768f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
6778f87f92bSBarry Smith     }
67816d9e3a6SLisandro Dalcin   }
67916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
68016d9e3a6SLisandro Dalcin }
68116d9e3a6SLisandro Dalcin 
68216d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
68316d9e3a6SLisandro Dalcin #undef __FUNCT__
68416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails"
6858c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptions *PetscOptionsObject,PC pc)
68616d9e3a6SLisandro Dalcin {
68716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
68816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
6894ddd07fcSJed Brown   PetscInt       indx;
690ace3abfcSBarry Smith   PetscBool      flag;
69116d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
69216d9e3a6SLisandro Dalcin 
69316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
694e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
69516d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
69616d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
6972fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
69816d9e3a6SLisandro Dalcin 
69916d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
7002fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
70116d9e3a6SLisandro Dalcin 
70216d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
7032fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
70416d9e3a6SLisandro Dalcin 
705acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
7062fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
70716d9e3a6SLisandro Dalcin 
708acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
7092fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
71016d9e3a6SLisandro Dalcin 
711a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
71216d9e3a6SLisandro Dalcin   if (flag) {
71316d9e3a6SLisandro Dalcin     jac->symt = indx;
714fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
71516d9e3a6SLisandro Dalcin   }
71616d9e3a6SLisandro Dalcin 
71716d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
71816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
71916d9e3a6SLisandro Dalcin }
72016d9e3a6SLisandro Dalcin 
72116d9e3a6SLisandro Dalcin #undef __FUNCT__
72216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails"
72316d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
72416d9e3a6SLisandro Dalcin {
72516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
72616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
727ace3abfcSBarry Smith   PetscBool      iascii;
72816d9e3a6SLisandro Dalcin   const char     *symt = 0;;
72916d9e3a6SLisandro Dalcin 
73016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
731251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
73216d9e3a6SLisandro Dalcin   if (iascii) {
73316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
73416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
73557622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
73657622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: filter %g\n",(double)jac->filter);CHKERRQ(ierr);
73757622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
738ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
739ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
7402fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
7412fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
7422fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
743ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
74416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr);
74516d9e3a6SLisandro Dalcin   }
74616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
74716d9e3a6SLisandro Dalcin }
7484cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
7494cb006feSStefano Zampini #undef __FUNCT__
7504cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS"
7519fa463a7SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptions *PetscOptionsObject,PC pc)
7524cb006feSStefano Zampini {
7534cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
7544cb006feSStefano Zampini   PetscErrorCode ierr;
7554cb006feSStefano Zampini   PetscInt       n;
7564cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
7574cb006feSStefano Zampini 
7584cb006feSStefano Zampini   PetscFunctionBegin;
7599fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
760863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
761863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
762863406b8SStefano 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);
763863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
7644cb006feSStefano 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);
7654cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
766863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
767863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
768863406b8SStefano 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);
769863406b8SStefano 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);
770863406b8SStefano 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);
771863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
7724cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
773863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
774863406b8SStefano Zampini                                                                       jac->as_relax_times,
775863406b8SStefano Zampini                                                                       jac->as_relax_weight,
776863406b8SStefano Zampini                                                                       jac->as_omega));
7774cb006feSStefano Zampini   }
778863406b8SStefano 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);
7794cb006feSStefano Zampini   n = 5;
780863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
7814cb006feSStefano Zampini   if (flag || flag2) {
782863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
783863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
784863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
785863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
786863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
787863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
7884cb006feSStefano Zampini   }
789863406b8SStefano 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);
7904cb006feSStefano Zampini   n = 5;
791863406b8SStefano 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);
7924cb006feSStefano Zampini   if (flag || flag2) {
793863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
794863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
795863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
796863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
797863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
798863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
7994cb006feSStefano Zampini   }
8004cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
8014cb006feSStefano Zampini   PetscFunctionReturn(0);
8024cb006feSStefano Zampini }
8034cb006feSStefano Zampini 
8044cb006feSStefano Zampini #undef __FUNCT__
8054cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS"
8064cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
8074cb006feSStefano Zampini {
8084cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
8094cb006feSStefano Zampini   PetscErrorCode ierr;
8104cb006feSStefano Zampini   PetscBool      iascii;
8114cb006feSStefano Zampini 
8124cb006feSStefano Zampini   PetscFunctionBegin;
8134cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
8144cb006feSStefano Zampini   if (iascii) {
8154cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
816863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
8174cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
818863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
819863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
820863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
821863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
822863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
8234cb006feSStefano Zampini     if (jac->alpha_Poisson) {
8244cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8254cb006feSStefano Zampini     } else {
8264cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr);
8274cb006feSStefano Zampini     }
828863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
829863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
830863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
831863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
832863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
833863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
8344cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
8354cb006feSStefano Zampini       if (jac->beta_Poisson) {
8364cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8374cb006feSStefano Zampini       } else {
8384cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr);
8394cb006feSStefano Zampini       }
840863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
841863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
842863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
843863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
844863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
845863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
8464cb006feSStefano Zampini     }
8474cb006feSStefano Zampini   }
8484cb006feSStefano Zampini   PetscFunctionReturn(0);
8494cb006feSStefano Zampini }
8504cb006feSStefano Zampini 
8514cb006feSStefano Zampini #undef __FUNCT__
852863406b8SStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_ADS"
853863406b8SStefano Zampini static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptions *PetscOptionsObject,PC pc)
854863406b8SStefano Zampini {
855863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
856863406b8SStefano Zampini   PetscErrorCode ierr;
857863406b8SStefano Zampini   PetscInt       n;
858863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
859863406b8SStefano Zampini 
860863406b8SStefano Zampini   PetscFunctionBegin;
861863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
862863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
863863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
864863406b8SStefano 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);
865863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
866863406b8SStefano 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);
867863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
868863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
869863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
870863406b8SStefano 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);
871863406b8SStefano 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);
872863406b8SStefano 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);
873863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
874863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
875863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
876863406b8SStefano Zampini                                                                       jac->as_relax_times,
877863406b8SStefano Zampini                                                                       jac->as_relax_weight,
878863406b8SStefano Zampini                                                                       jac->as_omega));
879863406b8SStefano Zampini   }
880863406b8SStefano 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);
881863406b8SStefano Zampini   n = 5;
882863406b8SStefano 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);
883863406b8SStefano 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);
884863406b8SStefano Zampini   if (flag || flag2 || flag3) {
885863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
886863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
887863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
888863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
889863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
890863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
891863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
892863406b8SStefano Zampini   }
893863406b8SStefano 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);
894863406b8SStefano Zampini   n = 5;
895863406b8SStefano 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);
896863406b8SStefano Zampini   if (flag || flag2) {
897863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
898863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
899863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
900863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
901863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
902863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
903863406b8SStefano Zampini   }
904863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
905863406b8SStefano Zampini   PetscFunctionReturn(0);
906863406b8SStefano Zampini }
907863406b8SStefano Zampini 
908863406b8SStefano Zampini #undef __FUNCT__
909863406b8SStefano Zampini #define __FUNCT__ "PCView_HYPRE_ADS"
910863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
911863406b8SStefano Zampini {
912863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
913863406b8SStefano Zampini   PetscErrorCode ierr;
914863406b8SStefano Zampini   PetscBool      iascii;
915863406b8SStefano Zampini 
916863406b8SStefano Zampini   PetscFunctionBegin;
917863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
918863406b8SStefano Zampini   if (iascii) {
919863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
920863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
921863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
922863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
923863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
924863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
925863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
926863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
927863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: AMS solver\n");CHKERRQ(ierr);
928863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
929863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
930863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
931863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
932863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
933863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
934863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
935863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: vector Poisson solver\n");CHKERRQ(ierr);
936863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
937863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
938863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
939863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
940863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
941863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
942863406b8SStefano Zampini   }
943863406b8SStefano Zampini   PetscFunctionReturn(0);
944863406b8SStefano Zampini }
945863406b8SStefano Zampini 
946863406b8SStefano Zampini #undef __FUNCT__
947863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE"
948863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
9494cb006feSStefano Zampini {
9504cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
9514cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_G;
9524cb006feSStefano Zampini   PetscErrorCode     ierr;
9534cb006feSStefano Zampini 
9544cb006feSStefano Zampini   PetscFunctionBegin;
9554cb006feSStefano Zampini   /* throw away any discrete gradient if already set */
9564cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
9574cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(G,&jac->G);CHKERRQ(ierr);
9584cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(G,jac->G);CHKERRQ(ierr);
9594cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->G,(void**)(&parcsr_G)));
960863406b8SStefano Zampini   PetscStackCall("Hypre set gradient",ierr = (*jac->setdgrad)(jac->hsolver,parcsr_G);CHKERRQ(ierr););
9614cb006feSStefano Zampini   PetscFunctionReturn(0);
9624cb006feSStefano Zampini }
9634cb006feSStefano Zampini 
9644cb006feSStefano Zampini #undef __FUNCT__
9654cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient"
9664cb006feSStefano Zampini /*@
9674cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
9684cb006feSStefano Zampini 
9694cb006feSStefano Zampini    Collective on PC
9704cb006feSStefano Zampini 
9714cb006feSStefano Zampini    Input Parameters:
9724cb006feSStefano Zampini +  pc - the preconditioning context
9734cb006feSStefano Zampini -  G - the discrete gradient
9744cb006feSStefano Zampini 
9754cb006feSStefano Zampini    Level: intermediate
9764cb006feSStefano Zampini 
9774cb006feSStefano 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
978863406b8SStefano 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
9794cb006feSStefano Zampini 
9804cb006feSStefano Zampini .seealso:
9814cb006feSStefano Zampini @*/
9824cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
9834cb006feSStefano Zampini {
9844cb006feSStefano Zampini   PetscErrorCode ierr;
9854cb006feSStefano Zampini 
9864cb006feSStefano Zampini   PetscFunctionBegin;
9874cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
9884cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
9894cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
9904cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
9914cb006feSStefano Zampini   PetscFunctionReturn(0);
9924cb006feSStefano Zampini }
9934cb006feSStefano Zampini 
9944cb006feSStefano Zampini #undef __FUNCT__
995863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl_HYPRE"
996863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
997863406b8SStefano Zampini {
998863406b8SStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
999863406b8SStefano Zampini   HYPRE_ParCSRMatrix parcsr_C;
1000863406b8SStefano Zampini   PetscErrorCode     ierr;
1001863406b8SStefano Zampini 
1002863406b8SStefano Zampini   PetscFunctionBegin;
1003863406b8SStefano Zampini   /* throw away any discrete curl if already set */
1004863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
1005863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(C,&jac->C);CHKERRQ(ierr);
1006863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(C,jac->C);CHKERRQ(ierr);
1007863406b8SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->C,(void**)(&parcsr_C)));
1008863406b8SStefano Zampini   PetscStackCall("Hypre set curl",ierr = (*jac->setdcurl)(jac->hsolver,parcsr_C);CHKERRQ(ierr););
1009863406b8SStefano Zampini   PetscFunctionReturn(0);
1010863406b8SStefano Zampini }
1011863406b8SStefano Zampini 
1012863406b8SStefano Zampini #undef __FUNCT__
1013863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl"
1014863406b8SStefano Zampini /*@
1015863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1016863406b8SStefano Zampini 
1017863406b8SStefano Zampini    Collective on PC
1018863406b8SStefano Zampini 
1019863406b8SStefano Zampini    Input Parameters:
1020863406b8SStefano Zampini +  pc - the preconditioning context
1021863406b8SStefano Zampini -  C - the discrete curl
1022863406b8SStefano Zampini 
1023863406b8SStefano Zampini    Level: intermediate
1024863406b8SStefano Zampini 
1025863406b8SStefano 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
1026863406b8SStefano 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
1027863406b8SStefano Zampini 
1028863406b8SStefano Zampini .seealso:
1029863406b8SStefano Zampini @*/
1030863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1031863406b8SStefano Zampini {
1032863406b8SStefano Zampini   PetscErrorCode ierr;
1033863406b8SStefano Zampini 
1034863406b8SStefano Zampini   PetscFunctionBegin;
1035863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1036863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1037863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1038863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1039863406b8SStefano Zampini   PetscFunctionReturn(0);
1040863406b8SStefano Zampini }
1041863406b8SStefano Zampini 
1042863406b8SStefano Zampini #undef __FUNCT__
10434cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS"
10444cb006feSStefano Zampini static PetscErrorCode PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
10454cb006feSStefano Zampini {
10464cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
10474cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_alpha_Poisson;
10484cb006feSStefano Zampini   PetscErrorCode     ierr;
10494cb006feSStefano Zampini 
10504cb006feSStefano Zampini   PetscFunctionBegin;
10514cb006feSStefano Zampini   /* throw away any matrix if already set */
10524cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
10534cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->alpha_Poisson);CHKERRQ(ierr);
10544cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->alpha_Poisson);CHKERRQ(ierr);
10554cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->alpha_Poisson,(void**)(&parcsr_alpha_Poisson)));
10564cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr_alpha_Poisson));
10574cb006feSStefano Zampini   PetscFunctionReturn(0);
10584cb006feSStefano Zampini }
10594cb006feSStefano Zampini 
10604cb006feSStefano Zampini #undef __FUNCT__
10614cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix"
10624cb006feSStefano Zampini /*@
10634cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
10644cb006feSStefano Zampini 
10654cb006feSStefano Zampini    Collective on PC
10664cb006feSStefano Zampini 
10674cb006feSStefano Zampini    Input Parameters:
10684cb006feSStefano Zampini +  pc - the preconditioning context
10694cb006feSStefano Zampini -  A - the matrix
10704cb006feSStefano Zampini 
10714cb006feSStefano Zampini    Level: intermediate
10724cb006feSStefano Zampini 
10734cb006feSStefano Zampini    Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
10744cb006feSStefano Zampini 
10754cb006feSStefano Zampini .seealso:
10764cb006feSStefano Zampini @*/
10774cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
10784cb006feSStefano Zampini {
10794cb006feSStefano Zampini   PetscErrorCode ierr;
10804cb006feSStefano Zampini 
10814cb006feSStefano Zampini   PetscFunctionBegin;
10824cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
10834cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
10844cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
10854cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetAlphaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
10864cb006feSStefano Zampini   PetscFunctionReturn(0);
10874cb006feSStefano Zampini }
10884cb006feSStefano Zampini 
10894cb006feSStefano Zampini #undef __FUNCT__
10904cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix_HYPRE_AMS"
10914cb006feSStefano Zampini static PetscErrorCode PCHYPRESetBetaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
10924cb006feSStefano Zampini {
10934cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
10944cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_beta_Poisson;
10954cb006feSStefano Zampini   PetscErrorCode     ierr;
10964cb006feSStefano Zampini 
10974cb006feSStefano Zampini   PetscFunctionBegin;
10984cb006feSStefano Zampini   if (!A) {
1099484796dcSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
11004cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_TRUE;
11014cb006feSStefano Zampini     PetscFunctionReturn(0);
11024cb006feSStefano Zampini   }
11034cb006feSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
11044cb006feSStefano Zampini   /* throw away any matrix if already set */
11054cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
11064cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->beta_Poisson);CHKERRQ(ierr);
11074cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->beta_Poisson);CHKERRQ(ierr);
11084cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->beta_Poisson,(void**)(&parcsr_beta_Poisson)));
11094cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr_beta_Poisson));
11104cb006feSStefano Zampini   PetscFunctionReturn(0);
11114cb006feSStefano Zampini }
11124cb006feSStefano Zampini 
11134cb006feSStefano Zampini #undef __FUNCT__
11144cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix"
11154cb006feSStefano Zampini /*@
11164cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
11174cb006feSStefano Zampini 
11184cb006feSStefano Zampini    Collective on PC
11194cb006feSStefano Zampini 
11204cb006feSStefano Zampini    Input Parameters:
11214cb006feSStefano Zampini +  pc - the preconditioning context
11224cb006feSStefano Zampini -  A - the matrix
11234cb006feSStefano Zampini 
11244cb006feSStefano Zampini    Level: intermediate
11254cb006feSStefano Zampini 
11264cb006feSStefano Zampini    Notes: A should be obtained by discretizing the Poisson problem with linear finite elements.
11274cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
11284cb006feSStefano Zampini 
11294cb006feSStefano Zampini .seealso:
11304cb006feSStefano Zampini @*/
11314cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
11324cb006feSStefano Zampini {
11334cb006feSStefano Zampini   PetscErrorCode ierr;
11344cb006feSStefano Zampini 
11354cb006feSStefano Zampini   PetscFunctionBegin;
11364cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11374cb006feSStefano Zampini   if (A) {
11384cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
11394cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
11404cb006feSStefano Zampini   }
11414cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetBetaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
11424cb006feSStefano Zampini   PetscFunctionReturn(0);
11434cb006feSStefano Zampini }
11444cb006feSStefano Zampini 
11454cb006feSStefano Zampini #undef __FUNCT__
11464cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE_AMS"
11474cb006feSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE_AMS(PC pc,Vec ozz, Vec zoz, Vec zzo)
11484cb006feSStefano Zampini {
11494cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11504cb006feSStefano Zampini   HYPRE_ParVector    par_ozz,par_zoz,par_zzo;
115112ddd1b6SStefano Zampini   PetscInt           dim;
11524cb006feSStefano Zampini   PetscErrorCode     ierr;
11534cb006feSStefano Zampini 
11544cb006feSStefano Zampini   PetscFunctionBegin;
11554cb006feSStefano Zampini   /* throw away any vector if already set */
11564cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
11574cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
11584cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
11594cb006feSStefano Zampini   jac->constants[0] = NULL;
11604cb006feSStefano Zampini   jac->constants[1] = NULL;
11614cb006feSStefano Zampini   jac->constants[2] = NULL;
11624cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
11634cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
11644cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&par_ozz)));
11654cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
11664cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
11674cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&par_zoz)));
116812ddd1b6SStefano Zampini   dim = 2;
11694cb006feSStefano Zampini   if (zzo) {
11704cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
11714cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
11724cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&par_zzo)));
117312ddd1b6SStefano Zampini     dim++;
11744cb006feSStefano Zampini   }
11754cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,par_ozz,par_zoz,par_zzo));
117612ddd1b6SStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim));
11774cb006feSStefano Zampini   PetscFunctionReturn(0);
11784cb006feSStefano Zampini }
11794cb006feSStefano Zampini 
11804cb006feSStefano Zampini #undef __FUNCT__
11814cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors"
11824cb006feSStefano Zampini /*@
11834cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
11844cb006feSStefano Zampini 
11854cb006feSStefano Zampini    Collective on PC
11864cb006feSStefano Zampini 
11874cb006feSStefano Zampini    Input Parameters:
11884cb006feSStefano Zampini +  pc - the preconditioning context
11894cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
11904cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
11914cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
11924cb006feSStefano Zampini 
11934cb006feSStefano Zampini    Level: intermediate
11944cb006feSStefano Zampini 
11954cb006feSStefano Zampini    Notes:
11964cb006feSStefano Zampini 
11974cb006feSStefano Zampini .seealso:
11984cb006feSStefano Zampini @*/
11994cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
12004cb006feSStefano Zampini {
12014cb006feSStefano Zampini   PetscErrorCode ierr;
12024cb006feSStefano Zampini 
12034cb006feSStefano Zampini   PetscFunctionBegin;
12044cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12054cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
12064cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
12074cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
12084cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
12094cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
12104cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
12114cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
12124cb006feSStefano Zampini   PetscFunctionReturn(0);
12134cb006feSStefano Zampini }
12144cb006feSStefano Zampini 
12154cb006feSStefano Zampini #undef __FUNCT__
1216863406b8SStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE"
1217863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
12184cb006feSStefano Zampini {
12194cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
12204cb006feSStefano Zampini   Vec             tv;
12214cb006feSStefano Zampini   HYPRE_ParVector par_coords[3];
12224cb006feSStefano Zampini   PetscInt        i;
12234cb006feSStefano Zampini   PetscErrorCode  ierr;
12244cb006feSStefano Zampini 
12254cb006feSStefano Zampini   PetscFunctionBegin;
12264cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
12274cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
12284cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
12294cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
12304cb006feSStefano Zampini   /* set problem's dimension */
1231863406b8SStefano Zampini   if (jac->setdim) {
1232863406b8SStefano Zampini     PetscStackCall("Hypre set dim",ierr = (*jac->setdim)(jac->hsolver,dim);CHKERRQ(ierr););
1233863406b8SStefano Zampini   }
12344cb006feSStefano Zampini   /* compute IJ vector for coordinates */
12354cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
12364cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
12374cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
12384cb006feSStefano Zampini   for (i=0;i<dim;i++) {
12394cb006feSStefano Zampini     PetscScalar *array;
12404cb006feSStefano Zampini     PetscInt    j;
12414cb006feSStefano Zampini 
12424cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
12434cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
12444cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
12454cb006feSStefano Zampini       array[j] = coords[j*dim+i];
12464cb006feSStefano Zampini     }
12474cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
12484cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
12494cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
12504cb006feSStefano Zampini   }
12514cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
12524cb006feSStefano Zampini   /* pass parCSR vectors to AMS solver */
12534cb006feSStefano Zampini   par_coords[0] = NULL;
12544cb006feSStefano Zampini   par_coords[1] = NULL;
12554cb006feSStefano Zampini   par_coords[2] = NULL;
12564cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&par_coords[0])));
12574cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&par_coords[1])));
12584cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&par_coords[2])));
1259863406b8SStefano Zampini   PetscStackCall("Hypre set coords",ierr = (*jac->setcoord)(jac->hsolver,par_coords[0],par_coords[1],par_coords[2]);CHKERRQ(ierr););
12604cb006feSStefano Zampini   PetscFunctionReturn(0);
12614cb006feSStefano Zampini }
12624cb006feSStefano Zampini 
126316d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
126416d9e3a6SLisandro Dalcin 
126516d9e3a6SLisandro Dalcin #undef __FUNCT__
126616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
1267f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
126816d9e3a6SLisandro Dalcin {
126916d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
127016d9e3a6SLisandro Dalcin 
127116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
127216d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
127316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
127416d9e3a6SLisandro Dalcin }
127516d9e3a6SLisandro Dalcin 
127616d9e3a6SLisandro Dalcin #undef __FUNCT__
127716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
1278f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
127916d9e3a6SLisandro Dalcin {
128016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
128116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1282ace3abfcSBarry Smith   PetscBool      flag;
128316d9e3a6SLisandro Dalcin 
128416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
128516d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
128616d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1287ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
128816d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
128916d9e3a6SLisandro Dalcin   } else {
129016d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
129116d9e3a6SLisandro Dalcin   }
129216d9e3a6SLisandro Dalcin 
129316d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
129416d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
129516d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
129616d9e3a6SLisandro Dalcin 
129716d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
129816d9e3a6SLisandro Dalcin   if (flag) {
1299fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
130016d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
130116d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
130216d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
130316d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
130416d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
130516d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
130616d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
130716d9e3a6SLisandro Dalcin   }
130816d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
130916d9e3a6SLisandro Dalcin   if (flag) {
1310fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
131116d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
131216d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
131316d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
131416d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
131516d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
131616d9e3a6SLisandro Dalcin     /* initialize */
131716d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
131816d9e3a6SLisandro Dalcin     jac->threshhold = .1;
131916d9e3a6SLisandro Dalcin     jac->filter     = .1;
132016d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
13212fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
13222fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
13232fa5cd67SKarl Rupp 
132416d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
132516d9e3a6SLisandro Dalcin     jac->symt = 0;
1326fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1327fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1328fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1329fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1330fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1331fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
133216d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
133316d9e3a6SLisandro Dalcin   }
133416d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
133516d9e3a6SLisandro Dalcin   if (flag) {
133616d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
133716d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
133816d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
133916d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
134016d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
134116d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
134216d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
134316d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
134416d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
134516d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
134616d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
134716d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
134816d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
13498f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
135016d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
135116d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
135216d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
135316d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
135416d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
13550f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
13568f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
13570f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
135816d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
135916d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
136016d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
13610f1074feSSatish Balay     jac->interptype       = 0;
13620f1074feSSatish Balay     jac->agg_nl           = 0;
13630f1074feSSatish Balay     jac->pmax             = 0;
13640f1074feSSatish Balay     jac->truncfactor      = 0.0;
13650f1074feSSatish Balay     jac->agg_num_paths    = 1;
13668f87f92bSBarry Smith 
13678f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
13688f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
13698f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1370fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1371fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1372fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1373fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1374fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1375fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1376fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1377fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1378fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1379fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1380fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1381fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1382fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1383fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1384fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1385fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
138616d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
138716d9e3a6SLisandro Dalcin   }
13884cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
13894cb006feSStefano Zampini   if (flag) {
13904cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
13914cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
13924cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
13934cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
13944cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
13954cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
1396863406b8SStefano Zampini     jac->setdgrad            = HYPRE_AMSSetDiscreteGradient;
1397863406b8SStefano Zampini     jac->setcoord            = HYPRE_AMSSetCoordinateVectors;
1398863406b8SStefano Zampini     jac->setdim              = HYPRE_AMSSetDimension;
13994cb006feSStefano Zampini     jac->coords[0]           = NULL;
14004cb006feSStefano Zampini     jac->coords[1]           = NULL;
14014cb006feSStefano Zampini     jac->coords[2]           = NULL;
14024cb006feSStefano Zampini     jac->G                   = NULL;
14034cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1404863406b8SStefano Zampini     jac->as_print           = 0;
1405863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1406863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
14074cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
14084cb006feSStefano Zampini     /* Smoothing options */
1409863406b8SStefano Zampini     jac->as_relax_type      = 2;
1410863406b8SStefano Zampini     jac->as_relax_times     = 1;
1411863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1412863406b8SStefano Zampini     jac->as_omega           = 1.0;
14134cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1414863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1415863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
14160bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1417863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1418863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1419863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
14204cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
14214cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_FALSE;
1422863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1423863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
14240bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1425863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1426863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1427863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1428863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1429863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
14304cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1431863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1432863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1433863406b8SStefano Zampini                                                                       jac->as_relax_times,
1434863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1435863406b8SStefano Zampini                                                                       jac->as_omega));
1436863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1437863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1438863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1439863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1440863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1441863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1442863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1443863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1444863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1445863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1446863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1447863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1448863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1449863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
14504cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE_AMS);CHKERRQ(ierr);
14514cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
14524cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",PCHYPRESetBetaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
14534cb006feSStefano Zampini     PetscFunctionReturn(0);
14544cb006feSStefano Zampini   }
1455863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1456863406b8SStefano Zampini   if (flag) {
1457863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1458863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1459863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1460863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1461863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1462863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1463863406b8SStefano Zampini     jac->setdgrad            = HYPRE_ADSSetDiscreteGradient;
1464863406b8SStefano Zampini     jac->setdcurl            = HYPRE_ADSSetDiscreteCurl;
1465863406b8SStefano Zampini     jac->setcoord            = HYPRE_ADSSetCoordinateVectors;
1466863406b8SStefano Zampini     jac->coords[0]           = NULL;
1467863406b8SStefano Zampini     jac->coords[1]           = NULL;
1468863406b8SStefano Zampini     jac->coords[2]           = NULL;
1469863406b8SStefano Zampini     jac->G                   = NULL;
1470863406b8SStefano Zampini     jac->C                   = NULL;
1471863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1472863406b8SStefano Zampini     jac->as_print           = 0;
1473863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1474863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1475863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1476863406b8SStefano Zampini     /* Smoothing options */
1477863406b8SStefano Zampini     jac->as_relax_type      = 2;
1478863406b8SStefano Zampini     jac->as_relax_times     = 1;
1479863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1480863406b8SStefano Zampini     jac->as_omega           = 1.0;
1481863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1482863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1483863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1484863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1485863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1486863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1487863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1488863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1489863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1490863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1491863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1492863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1493863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1494863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1495863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1496863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1497863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1498863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1499863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1500863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1501863406b8SStefano Zampini                                                                       jac->as_relax_times,
1502863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1503863406b8SStefano Zampini                                                                       jac->as_omega));
1504863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1505863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1506863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1507863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1508863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1509863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1510863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1511863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1512863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1513863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1514863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1515863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1516863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1517863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1518863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
1519863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
1520863406b8SStefano Zampini     PetscFunctionReturn(0);
1521863406b8SStefano Zampini   }
1522503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
15232fa5cd67SKarl Rupp 
15240298fd71SBarry Smith   jac->hypre_type = NULL;
152533263987SBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, boomeramg, ams",name);
152616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
152716d9e3a6SLisandro Dalcin }
152816d9e3a6SLisandro Dalcin 
152916d9e3a6SLisandro Dalcin /*
153016d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
153116d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
153216d9e3a6SLisandro Dalcin */
153316d9e3a6SLisandro Dalcin #undef __FUNCT__
153416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
15358c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptions *PetscOptionsObject,PC pc)
153616d9e3a6SLisandro Dalcin {
153716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
15384ddd07fcSJed Brown   PetscInt       indx;
1539863406b8SStefano Zampini   const char     *type[] = {"pilut","parasails","boomeramg","ams","ads"};
1540ace3abfcSBarry Smith   PetscBool      flg;
154116d9e3a6SLisandro Dalcin 
154216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
15439fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
15449c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
154516d9e3a6SLisandro Dalcin   if (flg) {
154616d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
154702a17cd4SBarry Smith   } else {
154802a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
154916d9e3a6SLisandro Dalcin   }
155016d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
15513931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
155216d9e3a6SLisandro Dalcin   }
155316d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
155416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
155516d9e3a6SLisandro Dalcin }
155616d9e3a6SLisandro Dalcin 
155716d9e3a6SLisandro Dalcin #undef __FUNCT__
155816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
155916d9e3a6SLisandro Dalcin /*@C
156016d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
156116d9e3a6SLisandro Dalcin 
156216d9e3a6SLisandro Dalcin    Input Parameters:
156316d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1564863406b8SStefano Zampini -     name - either  pilut, parasails, boomeramg, ams, ads
156516d9e3a6SLisandro Dalcin 
156616d9e3a6SLisandro Dalcin    Options Database Keys:
1567863406b8SStefano Zampini    -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
156816d9e3a6SLisandro Dalcin 
156916d9e3a6SLisandro Dalcin    Level: intermediate
157016d9e3a6SLisandro Dalcin 
157116d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
157216d9e3a6SLisandro Dalcin            PCHYPRE
157316d9e3a6SLisandro Dalcin 
157416d9e3a6SLisandro Dalcin @*/
15757087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
157616d9e3a6SLisandro Dalcin {
15774ac538c5SBarry Smith   PetscErrorCode ierr;
157816d9e3a6SLisandro Dalcin 
157916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
15800700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
158116d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
15824ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
158316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
158416d9e3a6SLisandro Dalcin }
158516d9e3a6SLisandro Dalcin 
158616d9e3a6SLisandro Dalcin #undef __FUNCT__
158716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
158816d9e3a6SLisandro Dalcin /*@C
158916d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
159016d9e3a6SLisandro Dalcin 
159116d9e3a6SLisandro Dalcin    Input Parameter:
159216d9e3a6SLisandro Dalcin .     pc - the preconditioner context
159316d9e3a6SLisandro Dalcin 
159416d9e3a6SLisandro Dalcin    Output Parameter:
1595863406b8SStefano Zampini .     name - either  pilut, parasails, boomeramg, ams, ads
159616d9e3a6SLisandro Dalcin 
159716d9e3a6SLisandro Dalcin    Level: intermediate
159816d9e3a6SLisandro Dalcin 
159916d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
160016d9e3a6SLisandro Dalcin            PCHYPRE
160116d9e3a6SLisandro Dalcin 
160216d9e3a6SLisandro Dalcin @*/
16037087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
160416d9e3a6SLisandro Dalcin {
16054ac538c5SBarry Smith   PetscErrorCode ierr;
160616d9e3a6SLisandro Dalcin 
160716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16080700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
160916d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
16104ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
161116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
161216d9e3a6SLisandro Dalcin }
161316d9e3a6SLisandro Dalcin 
161416d9e3a6SLisandro Dalcin /*MC
161516d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
161616d9e3a6SLisandro Dalcin 
161716d9e3a6SLisandro Dalcin    Options Database Keys:
1618863406b8SStefano Zampini +   -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
161916d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
162016d9e3a6SLisandro Dalcin           preconditioner
162116d9e3a6SLisandro Dalcin 
162216d9e3a6SLisandro Dalcin    Level: intermediate
162316d9e3a6SLisandro Dalcin 
162416d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
162516d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
162616d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
162716d9e3a6SLisandro Dalcin 
162816d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
16290f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
16300f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
16310f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
16328f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
16330f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
16340f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
163516d9e3a6SLisandro Dalcin 
16360f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
16370f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
16380f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
163916d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
164016d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
164116d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
164216d9e3a6SLisandro Dalcin 
164316d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
164416d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
164516d9e3a6SLisandro Dalcin 
16469e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
16479e5bc791SBarry Smith 
164816d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
16499e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
165016d9e3a6SLisandro Dalcin 
165116d9e3a6SLisandro Dalcin M*/
165216d9e3a6SLisandro Dalcin 
165316d9e3a6SLisandro Dalcin #undef __FUNCT__
165416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
16558cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
165616d9e3a6SLisandro Dalcin {
165716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
165816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
165916d9e3a6SLisandro Dalcin 
166016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1661b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
16622fa5cd67SKarl Rupp 
166316d9e3a6SLisandro Dalcin   pc->data                = jac;
1664*8695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
166516d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
166616d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
166716d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
166816d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
166916d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
16700298fd71SBarry Smith   jac->hypre_type         = NULL;
16714cb006feSStefano Zampini   jac->coords[0]          = NULL;
16724cb006feSStefano Zampini   jac->coords[1]          = NULL;
16734cb006feSStefano Zampini   jac->coords[2]          = NULL;
16744cb006feSStefano Zampini   jac->constants[0]       = NULL;
16754cb006feSStefano Zampini   jac->constants[1]       = NULL;
16764cb006feSStefano Zampini   jac->constants[2]       = NULL;
1677863406b8SStefano Zampini   jac->G                  = NULL;
1678863406b8SStefano Zampini   jac->C                  = NULL;
1679863406b8SStefano Zampini   jac->alpha_Poisson      = NULL;
1680863406b8SStefano Zampini   jac->beta_Poisson       = NULL;
1681fd444223SStefano Zampini   jac->setdim             = NULL;
168216d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1683ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1684bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1685bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
168616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
168716d9e3a6SLisandro Dalcin }
1688ebc551c0SBarry Smith 
1689f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1690f91d8e95SBarry Smith 
1691b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1692af0996ceSBarry Smith #include <petsc/private/matimpl.h>
1693ebc551c0SBarry Smith 
1694ebc551c0SBarry Smith typedef struct {
169568326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1696f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
16979e5bc791SBarry Smith 
16989e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
16994ddd07fcSJed Brown   PetscInt its;
17009e5bc791SBarry Smith   double   tol;
17014ddd07fcSJed Brown   PetscInt relax_type;
17024ddd07fcSJed Brown   PetscInt rap_type;
17034ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
17044ddd07fcSJed Brown   PetscInt max_levels;
1705ebc551c0SBarry Smith } PC_PFMG;
1706ebc551c0SBarry Smith 
1707ebc551c0SBarry Smith #undef __FUNCT__
1708ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1709ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1710ebc551c0SBarry Smith {
1711ebc551c0SBarry Smith   PetscErrorCode ierr;
1712f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1713ebc551c0SBarry Smith 
1714ebc551c0SBarry Smith   PetscFunctionBegin;
17152fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1716f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1717c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1718ebc551c0SBarry Smith   PetscFunctionReturn(0);
1719ebc551c0SBarry Smith }
1720ebc551c0SBarry Smith 
17219e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
17229e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
17239e5bc791SBarry Smith 
1724ebc551c0SBarry Smith #undef __FUNCT__
1725ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1726ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1727ebc551c0SBarry Smith {
1728ebc551c0SBarry Smith   PetscErrorCode ierr;
1729ace3abfcSBarry Smith   PetscBool      iascii;
1730f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1731ebc551c0SBarry Smith 
1732ebc551c0SBarry Smith   PetscFunctionBegin;
1733251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
17349e5bc791SBarry Smith   if (iascii) {
17359e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
17369e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
17379e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
17389e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
17399e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
17409e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
17413b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
17429e5bc791SBarry Smith   }
1743ebc551c0SBarry Smith   PetscFunctionReturn(0);
1744ebc551c0SBarry Smith }
1745ebc551c0SBarry Smith 
17469e5bc791SBarry Smith 
1747ebc551c0SBarry Smith #undef __FUNCT__
1748ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
17498c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptions *PetscOptionsObject,PC pc)
1750ebc551c0SBarry Smith {
1751ebc551c0SBarry Smith   PetscErrorCode ierr;
1752f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1753ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1754ebc551c0SBarry Smith 
1755ebc551c0SBarry Smith   PetscFunctionBegin;
1756e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
17570298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
175868326731SBarry Smith   if (flg) {
1759a0324ebeSBarry Smith     int level=3;
1760fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
176168326731SBarry Smith   }
17620298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1763fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
17640298fd71SBarry 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);
1765fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
17660298fd71SBarry 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);
1767fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
17689e5bc791SBarry Smith 
17690298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
1770fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
17713b46a515SGlenn Hammond 
17720298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1773fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
17740298fd71SBarry 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);
1775fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
17760298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
1777fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1778ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1779ebc551c0SBarry Smith   PetscFunctionReturn(0);
1780ebc551c0SBarry Smith }
1781ebc551c0SBarry Smith 
1782f91d8e95SBarry Smith #undef __FUNCT__
1783f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1784f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1785f91d8e95SBarry Smith {
1786f91d8e95SBarry Smith   PetscErrorCode    ierr;
1787f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
1788d9ca1df4SBarry Smith   PetscScalar       *yy;
1789d9ca1df4SBarry Smith   const PetscScalar *xx;
17904ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
179168326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1792f91d8e95SBarry Smith 
1793f91d8e95SBarry Smith   PetscFunctionBegin;
1794dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1795aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1796f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1797f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1798f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1799f91d8e95SBarry Smith 
1800f91d8e95SBarry Smith   /* copy x values over to hypre */
1801fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1802d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1803d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
1804d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1805fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
1806fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1807f91d8e95SBarry Smith 
1808f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1809f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
18108b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
1811f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1812f91d8e95SBarry Smith   PetscFunctionReturn(0);
1813f91d8e95SBarry Smith }
1814f91d8e95SBarry Smith 
18159e5bc791SBarry Smith #undef __FUNCT__
18169e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1817ace3abfcSBarry 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)
18189e5bc791SBarry Smith {
18199e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
18209e5bc791SBarry Smith   PetscErrorCode ierr;
18214ddd07fcSJed Brown   PetscInt       oits;
18229e5bc791SBarry Smith 
18239e5bc791SBarry Smith   PetscFunctionBegin;
1824dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1825fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1826fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
18279e5bc791SBarry Smith 
18289e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
18298b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
18309e5bc791SBarry Smith   *outits = oits;
18319e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
18329e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1833fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1834fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
18359e5bc791SBarry Smith   PetscFunctionReturn(0);
18369e5bc791SBarry Smith }
18379e5bc791SBarry Smith 
18389e5bc791SBarry Smith 
18393a32d3dbSGlenn Hammond #undef __FUNCT__
18403a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
18413a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
18423a32d3dbSGlenn Hammond {
18433a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
18443a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
18453a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1846ace3abfcSBarry Smith   PetscBool       flg;
18473a32d3dbSGlenn Hammond 
18483a32d3dbSGlenn Hammond   PetscFunctionBegin;
1849251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1850ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
18513a32d3dbSGlenn Hammond 
18523a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
18532fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1854fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1855fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1856fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
18573a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
18583a32d3dbSGlenn Hammond }
18593a32d3dbSGlenn Hammond 
1860ebc551c0SBarry Smith 
1861ebc551c0SBarry Smith /*MC
1862ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1863ebc551c0SBarry Smith 
1864ebc551c0SBarry Smith    Level: advanced
1865ebc551c0SBarry Smith 
18669e5bc791SBarry Smith    Options Database:
18679e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
18689e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
18699e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
18709e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
18719e5bc791SBarry 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
18729e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
1873f91d8e95SBarry Smith 
18749e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
18759e5bc791SBarry Smith 
18768e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
1877aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
18789e5bc791SBarry Smith 
18799e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
1880ebc551c0SBarry Smith M*/
1881ebc551c0SBarry Smith 
1882ebc551c0SBarry Smith #undef __FUNCT__
1883ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
18848cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
1885ebc551c0SBarry Smith {
1886ebc551c0SBarry Smith   PetscErrorCode ierr;
1887ebc551c0SBarry Smith   PC_PFMG        *ex;
1888ebc551c0SBarry Smith 
1889ebc551c0SBarry Smith   PetscFunctionBegin;
1890b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
189168326731SBarry Smith   pc->data = ex;
1892ebc551c0SBarry Smith 
18939e5bc791SBarry Smith   ex->its            = 1;
18949e5bc791SBarry Smith   ex->tol            = 1.e-8;
18959e5bc791SBarry Smith   ex->relax_type     = 1;
18969e5bc791SBarry Smith   ex->rap_type       = 0;
18979e5bc791SBarry Smith   ex->num_pre_relax  = 1;
18989e5bc791SBarry Smith   ex->num_post_relax = 1;
18993b46a515SGlenn Hammond   ex->max_levels     = 0;
19009e5bc791SBarry Smith 
1901ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
1902ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
1903ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
1904f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
19059e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
190668326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
19072fa5cd67SKarl Rupp 
1908ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
1909fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1910ebc551c0SBarry Smith   PetscFunctionReturn(0);
1911ebc551c0SBarry Smith }
1912d851a50bSGlenn Hammond 
1913325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
1914325fc9f4SBarry Smith 
1915d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
1916d851a50bSGlenn Hammond typedef struct {
1917d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
1918d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
1919d851a50bSGlenn Hammond 
1920d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
19214ddd07fcSJed Brown   PetscInt its;
1922d851a50bSGlenn Hammond   double   tol;
19234ddd07fcSJed Brown   PetscInt relax_type;
19244ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
1925d851a50bSGlenn Hammond } PC_SysPFMG;
1926d851a50bSGlenn Hammond 
1927d851a50bSGlenn Hammond #undef __FUNCT__
1928d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
1929d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
1930d851a50bSGlenn Hammond {
1931d851a50bSGlenn Hammond   PetscErrorCode ierr;
1932d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1933d851a50bSGlenn Hammond 
1934d851a50bSGlenn Hammond   PetscFunctionBegin;
19352fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1936d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1937c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1938d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1939d851a50bSGlenn Hammond }
1940d851a50bSGlenn Hammond 
1941d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
1942d851a50bSGlenn Hammond 
1943d851a50bSGlenn Hammond #undef __FUNCT__
1944d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
1945d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
1946d851a50bSGlenn Hammond {
1947d851a50bSGlenn Hammond   PetscErrorCode ierr;
1948ace3abfcSBarry Smith   PetscBool      iascii;
1949d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1950d851a50bSGlenn Hammond 
1951d851a50bSGlenn Hammond   PetscFunctionBegin;
1952251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1953d851a50bSGlenn Hammond   if (iascii) {
1954d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
1955d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
1956d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
1957d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
1958d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
1959d851a50bSGlenn Hammond   }
1960d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1961d851a50bSGlenn Hammond }
1962d851a50bSGlenn Hammond 
1963d851a50bSGlenn Hammond 
1964d851a50bSGlenn Hammond #undef __FUNCT__
1965d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
19668c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptions *PetscOptionsObject,PC pc)
1967d851a50bSGlenn Hammond {
1968d851a50bSGlenn Hammond   PetscErrorCode ierr;
1969d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1970ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1971d851a50bSGlenn Hammond 
1972d851a50bSGlenn Hammond   PetscFunctionBegin;
1973e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
19740298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
1975d851a50bSGlenn Hammond   if (flg) {
1976d851a50bSGlenn Hammond     int level=3;
1977fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
1978d851a50bSGlenn Hammond   }
19790298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1980fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
19810298fd71SBarry 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);
1982fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
19830298fd71SBarry 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);
1984fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
1985d851a50bSGlenn Hammond 
19860298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1987fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
19880298fd71SBarry 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);
1989fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
1990d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
1991d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1992d851a50bSGlenn Hammond }
1993d851a50bSGlenn Hammond 
1994d851a50bSGlenn Hammond #undef __FUNCT__
1995d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
1996d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
1997d851a50bSGlenn Hammond {
1998d851a50bSGlenn Hammond   PetscErrorCode    ierr;
1999d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2000d9ca1df4SBarry Smith   PetscScalar       *yy;
2001d9ca1df4SBarry Smith   const PetscScalar *xx;
20024ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
2003d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
20044ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
20054ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
20064ddd07fcSJed Brown   PetscInt          part    = 0;
20074ddd07fcSJed Brown   PetscInt          size;
20084ddd07fcSJed Brown   PetscInt          i;
2009d851a50bSGlenn Hammond 
2010d851a50bSGlenn Hammond   PetscFunctionBegin;
2011dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2012aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2013d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2014d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2015d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2016d851a50bSGlenn Hammond 
2017d851a50bSGlenn Hammond   size = 1;
20182fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
20192fa5cd67SKarl Rupp 
2020d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2021d851a50bSGlenn Hammond   if (ordering) {
2022fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2023d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2024d9ca1df4SBarry 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)));
2025d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2026fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2027fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2028fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2029d851a50bSGlenn Hammond 
2030d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2031d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
20328b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2033d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2034a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2035d851a50bSGlenn Hammond     PetscScalar *z;
20364ddd07fcSJed Brown     PetscInt    j, k;
2037d851a50bSGlenn Hammond 
2038785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2039fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2040d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2041d851a50bSGlenn Hammond 
2042d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2043d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2044d851a50bSGlenn Hammond       k= i*nvars;
20452fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2046d851a50bSGlenn Hammond     }
20478b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2048d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2049fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2050fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2051d851a50bSGlenn Hammond 
2052d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2053d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
20548b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2055d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2056d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2057d851a50bSGlenn Hammond       k= i*nvars;
20582fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2059d851a50bSGlenn Hammond     }
2060d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2061d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2062d851a50bSGlenn Hammond   }
2063d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2064d851a50bSGlenn Hammond }
2065d851a50bSGlenn Hammond 
2066d851a50bSGlenn Hammond #undef __FUNCT__
2067d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
2068ace3abfcSBarry 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)
2069d851a50bSGlenn Hammond {
2070d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2071d851a50bSGlenn Hammond   PetscErrorCode ierr;
20724ddd07fcSJed Brown   PetscInt       oits;
2073d851a50bSGlenn Hammond 
2074d851a50bSGlenn Hammond   PetscFunctionBegin;
2075dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2076fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2077fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2078d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
20798b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2080d851a50bSGlenn Hammond   *outits = oits;
2081d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2082d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2083fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2084fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2085d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2086d851a50bSGlenn Hammond }
2087d851a50bSGlenn Hammond 
2088d851a50bSGlenn Hammond 
2089d851a50bSGlenn Hammond #undef __FUNCT__
2090d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
2091d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2092d851a50bSGlenn Hammond {
2093d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2094d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2095d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2096ace3abfcSBarry Smith   PetscBool        flg;
2097d851a50bSGlenn Hammond 
2098d851a50bSGlenn Hammond   PetscFunctionBegin;
2099251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2100ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2101d851a50bSGlenn Hammond 
2102d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
21032fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2104fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2105fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2106fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2107d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2108d851a50bSGlenn Hammond }
2109d851a50bSGlenn Hammond 
2110d851a50bSGlenn Hammond 
2111d851a50bSGlenn Hammond /*MC
2112d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2113d851a50bSGlenn Hammond 
2114d851a50bSGlenn Hammond    Level: advanced
2115d851a50bSGlenn Hammond 
2116d851a50bSGlenn Hammond    Options Database:
2117d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2118d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2119d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2120d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2121d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2122d851a50bSGlenn Hammond 
2123d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
2124d851a50bSGlenn Hammond 
2125f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2126aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2127d851a50bSGlenn Hammond            Also, only cell-centered variables.
2128d851a50bSGlenn Hammond 
2129d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2130d851a50bSGlenn Hammond M*/
2131d851a50bSGlenn Hammond 
2132d851a50bSGlenn Hammond #undef __FUNCT__
2133d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
21348cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2135d851a50bSGlenn Hammond {
2136d851a50bSGlenn Hammond   PetscErrorCode ierr;
2137d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2138d851a50bSGlenn Hammond 
2139d851a50bSGlenn Hammond   PetscFunctionBegin;
2140b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2141d851a50bSGlenn Hammond   pc->data = ex;
2142d851a50bSGlenn Hammond 
2143d851a50bSGlenn Hammond   ex->its            = 1;
2144d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2145d851a50bSGlenn Hammond   ex->relax_type     = 1;
2146d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2147d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2148d851a50bSGlenn Hammond 
2149d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2150d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2151d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2152d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2153d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2154d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
21552fa5cd67SKarl Rupp 
2156ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2157fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2158d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2159d851a50bSGlenn Hammond }
2160