xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 5272c31926308cd952f21eda4f777699f6b0911d)
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 
76*5272c319SBarry Smith   PetscInt  nodal_coarsening;
77*5272c319SBarry Smith   PetscInt  vec_interp_variant;
78*5272c319SBarry Smith   HYPRE_IJVector  *hmnull;
79*5272c319SBarry Smith   HYPRE_ParVector *phmnull;  /* near null space passed to hypre */
80*5272c319SBarry Smith   PetscInt        n_hmnull;
81*5272c319SBarry Smith   Vec             hmnull_constant;
82*5272c319SBarry Smith 
83863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
84863406b8SStefano Zampini   PetscInt  as_print;
85863406b8SStefano Zampini   PetscInt  as_max_iter;
86863406b8SStefano Zampini   PetscReal as_tol;
87863406b8SStefano Zampini   PetscInt  as_relax_type;
88863406b8SStefano Zampini   PetscInt  as_relax_times;
89863406b8SStefano Zampini   PetscReal as_relax_weight;
90863406b8SStefano Zampini   PetscReal as_omega;
91863406b8SStefano 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) */
92863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
93863406b8SStefano 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) */
94863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
954cb006feSStefano Zampini   PetscInt  ams_cycle_type;
96863406b8SStefano Zampini   PetscInt  ads_cycle_type;
974cb006feSStefano Zampini 
984cb006feSStefano Zampini   /* additional data */
994cb006feSStefano Zampini   HYPRE_IJVector coords[3];
1004cb006feSStefano Zampini   HYPRE_IJVector constants[3];
1014cb006feSStefano Zampini   HYPRE_IJMatrix G;
102863406b8SStefano Zampini   HYPRE_IJMatrix C;
1034cb006feSStefano Zampini   HYPRE_IJMatrix alpha_Poisson;
1044cb006feSStefano Zampini   HYPRE_IJMatrix beta_Poisson;
1054cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
10616d9e3a6SLisandro Dalcin } PC_HYPRE;
10716d9e3a6SLisandro Dalcin 
108d2128fa2SBarry Smith #undef __FUNCT__
109d2128fa2SBarry Smith #define __FUNCT__ "PCHYPREGetSolver"
110d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
111d2128fa2SBarry Smith {
112d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
113d2128fa2SBarry Smith 
114d2128fa2SBarry Smith   PetscFunctionBegin;
115d2128fa2SBarry Smith   *hsolver = jac->hsolver;
116d2128fa2SBarry Smith   PetscFunctionReturn(0);
117d2128fa2SBarry Smith }
11816d9e3a6SLisandro Dalcin 
11916d9e3a6SLisandro Dalcin #undef __FUNCT__
12016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE"
12116d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
12216d9e3a6SLisandro Dalcin {
12316d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
12416d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
12516d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
12616d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
12716d9e3a6SLisandro Dalcin   PetscInt           bs;
12816d9e3a6SLisandro Dalcin 
12916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
13016d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
13102a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
13216d9e3a6SLisandro Dalcin   }
1335f5c5b43SBarry Smith 
1345f5c5b43SBarry Smith   if (pc->setupcalled) {
1355f5c5b43SBarry Smith     /* always destroy the old matrix and create a new memory;
1365f5c5b43SBarry Smith        hope this does not churn the memory too much. The problem
1375f5c5b43SBarry Smith        is I do not know if it is possible to put the matrix back to
1385f5c5b43SBarry Smith        its initial state so that we can directly copy the values
1395f5c5b43SBarry Smith        the second time through. */
140fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
1415f5c5b43SBarry Smith     jac->ij = 0;
14216d9e3a6SLisandro Dalcin   }
1435f5c5b43SBarry Smith 
14416d9e3a6SLisandro Dalcin   if (!jac->ij) { /* create the matrix the first time through */
14516d9e3a6SLisandro Dalcin     ierr = MatHYPRE_IJMatrixCreate(pc->pmat,&jac->ij);CHKERRQ(ierr);
14616d9e3a6SLisandro Dalcin   }
14716d9e3a6SLisandro Dalcin   if (!jac->b) { /* create the vectors the first time through */
14816d9e3a6SLisandro Dalcin     Vec x,b;
1492a7a6963SBarry Smith     ierr = MatCreateVecs(pc->pmat,&x,&b);CHKERRQ(ierr);
15016d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(x,&jac->x);CHKERRQ(ierr);
15116d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(b,&jac->b);CHKERRQ(ierr);
1526bf464f9SBarry Smith     ierr = VecDestroy(&x);CHKERRQ(ierr);
1536bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
15416d9e3a6SLisandro Dalcin   }
1555f5c5b43SBarry Smith 
15616d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
15716d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
158*5272c319SBarry Smith     MatNullSpace    mnull;
159*5272c319SBarry Smith     PetscBool       has_const;
160*5272c319SBarry Smith     PetscInt        nvec,i;
161*5272c319SBarry Smith     const Vec       *vecs;
162*5272c319SBarry Smith 
16316d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1642fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
165*5272c319SBarry Smith     ierr = MatGetNearNullSpace(pc->mat, &mnull);CHKERRQ(ierr);
166*5272c319SBarry Smith     if (mnull) {
167*5272c319SBarry Smith       ierr = MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs);CHKERRQ(ierr);
168*5272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull);CHKERRQ(ierr);
169*5272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->phmnull);CHKERRQ(ierr);
170*5272c319SBarry Smith       for (i=0; i<nvec; i++) {
171*5272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(vecs[i],&jac->hmnull[i]);CHKERRQ(ierr);
172*5272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[i],(void**)&jac->phmnull[i]));
173*5272c319SBarry Smith       }
174*5272c319SBarry Smith       if (has_const) {
175*5272c319SBarry Smith         ierr = MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL);CHKERRQ(ierr);
176*5272c319SBarry Smith         ierr = VecSet(jac->hmnull_constant,1);CHKERRQ(ierr);
177*5272c319SBarry Smith         ierr = VecNormalize(jac->hmnull_constant,NULL);
178*5272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(jac->hmnull_constant,&jac->hmnull[nvec]);CHKERRQ(ierr);
179*5272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[nvec],(void**)&jac->phmnull[nvec]));
180*5272c319SBarry Smith         nvec++;
181*5272c319SBarry Smith       }
182*5272c319SBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVectors,(jac->hsolver,nvec,jac->phmnull));
183*5272c319SBarry Smith       jac->n_hmnull = nvec;
184*5272c319SBarry Smith     }
1854cb006feSStefano Zampini   }
186863406b8SStefano Zampini 
1874cb006feSStefano Zampini   /* special case for AMS */
1884cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
1894cb006feSStefano 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()");
1904cb006feSStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
1914cb006feSStefano Zampini   }
192863406b8SStefano Zampini   /* special case for ADS */
193863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
194863406b8SStefano Zampini     if (!jac->coords[0]) {
195863406b8SStefano Zampini       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs coordinate vectors via PCSetCoordinates()");
196fd444223SStefano Zampini     } else if (!jac->coords[1] || !jac->coords[2]) {
197fd444223SStefano 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");
198863406b8SStefano Zampini     }
199863406b8SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
200863406b8SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete curl operator via PCHYPRESetDiscreteGradient");
201863406b8SStefano Zampini   }
20216d9e3a6SLisandro Dalcin   ierr = MatHYPRE_IJMatrixCopy(pc->pmat,jac->ij);CHKERRQ(ierr);
203fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
204fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&bv));
205fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&xv));
206fd3f9acdSBarry Smith   PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr););
20716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
20816d9e3a6SLisandro Dalcin }
20916d9e3a6SLisandro Dalcin 
21016d9e3a6SLisandro Dalcin /*
21116d9e3a6SLisandro Dalcin     Replaces the address where the HYPRE vector points to its data with the address of
21216d9e3a6SLisandro Dalcin   PETSc's data. Saves the old address so it can be reset when we are finished with it.
21316d9e3a6SLisandro Dalcin   Allows use to get the data into a HYPRE vector without the cost of memcopies
21416d9e3a6SLisandro Dalcin */
21516d9e3a6SLisandro Dalcin #define HYPREReplacePointer(b,newvalue,savedvalue) { \
21616d9e3a6SLisandro Dalcin     hypre_ParVector *par_vector   = (hypre_ParVector*)hypre_IJVectorObject(((hypre_IJVector*)b)); \
21716d9e3a6SLisandro Dalcin     hypre_Vector    *local_vector = hypre_ParVectorLocalVector(par_vector); \
21816d9e3a6SLisandro Dalcin     savedvalue         = local_vector->data; \
2190ad7597dSKarl Rupp     local_vector->data = newvalue;          \
2200ad7597dSKarl Rupp }
22116d9e3a6SLisandro Dalcin 
22216d9e3a6SLisandro Dalcin #undef __FUNCT__
22316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE"
22416d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
22516d9e3a6SLisandro Dalcin {
22616d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
22716d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
22816d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
229d9ca1df4SBarry Smith   PetscScalar        *xv;
230d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
23116d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
232d9ca1df4SBarry Smith   PetscScalar        *sxv;
2334ddd07fcSJed Brown   PetscInt           hierr;
23416d9e3a6SLisandro Dalcin 
23516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
236dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
23716d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
238d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
23916d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
240d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
24116d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
24216d9e3a6SLisandro Dalcin 
243fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
244fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
245fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
246fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
24765e19b50SBarry Smith                                if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
248fd3f9acdSBarry Smith                                if (hierr) hypre__global_error = 0;);
24916d9e3a6SLisandro Dalcin 
250d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)sbv,bv);
25116d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
25216d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
253d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
25416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
25516d9e3a6SLisandro Dalcin }
25616d9e3a6SLisandro Dalcin 
25716d9e3a6SLisandro Dalcin #undef __FUNCT__
25816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE"
25916d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
26016d9e3a6SLisandro Dalcin {
26116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
26216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
26316d9e3a6SLisandro Dalcin 
26416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
265fd3f9acdSBarry Smith   if (jac->ij) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
266fd3f9acdSBarry Smith   if (jac->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->b));
267fd3f9acdSBarry Smith   if (jac->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->x));
2684cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
2694cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
2704cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
2714cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
2724cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
2734cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
2744cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
275863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
2764cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
2774cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
278*5272c319SBarry Smith   if (jac->n_hmnull) {
279*5272c319SBarry Smith     PetscInt i;
280*5272c319SBarry Smith 
281*5272c319SBarry Smith     for (i=0; i<jac->n_hmnull; i++) {
282*5272c319SBarry Smith       PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->hmnull[i]));
283*5272c319SBarry Smith     }
284*5272c319SBarry Smith     ierr = PetscFree(jac->hmnull);CHKERRQ(ierr);
285*5272c319SBarry Smith     ierr = PetscFree(jac->phmnull);CHKERRQ(ierr);
286*5272c319SBarry Smith     ierr = VecDestroy(&jac->hmnull_constant);CHKERRQ(ierr);
287*5272c319SBarry Smith   }
288226b0620SJed Brown   if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr););
289503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
29016d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
291c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
29216d9e3a6SLisandro Dalcin 
29316d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
294bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
295bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
2964cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
2974cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
298863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
2994cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
3004cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",NULL);CHKERRQ(ierr);
3014cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",NULL);CHKERRQ(ierr);
30216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
30316d9e3a6SLisandro Dalcin }
30416d9e3a6SLisandro Dalcin 
30516d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
30616d9e3a6SLisandro Dalcin #undef __FUNCT__
30716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut"
3088c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptions *PetscOptionsObject,PC pc)
30916d9e3a6SLisandro Dalcin {
31016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
31116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
312ace3abfcSBarry Smith   PetscBool      flag;
31316d9e3a6SLisandro Dalcin 
31416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
315e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
31616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
317fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
31816d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
319fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
32016d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
321fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
32216d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
32316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
32416d9e3a6SLisandro Dalcin }
32516d9e3a6SLisandro Dalcin 
32616d9e3a6SLisandro Dalcin #undef __FUNCT__
32716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut"
32816d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
32916d9e3a6SLisandro Dalcin {
33016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
33116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
332ace3abfcSBarry Smith   PetscBool      iascii;
33316d9e3a6SLisandro Dalcin 
33416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
335251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
33616d9e3a6SLisandro Dalcin   if (iascii) {
33716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
33816d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
33916d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
34016d9e3a6SLisandro Dalcin     } else {
34116d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr);
34216d9e3a6SLisandro Dalcin     }
34316d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
34457622a8eSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
34516d9e3a6SLisandro Dalcin     } else {
34616d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr);
34716d9e3a6SLisandro Dalcin     }
34816d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
34916d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
35016d9e3a6SLisandro Dalcin     } else {
35116d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default factor row size \n");CHKERRQ(ierr);
35216d9e3a6SLisandro Dalcin     }
35316d9e3a6SLisandro Dalcin   }
35416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
35516d9e3a6SLisandro Dalcin }
35616d9e3a6SLisandro Dalcin 
35716d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
35816d9e3a6SLisandro Dalcin 
35916d9e3a6SLisandro Dalcin #undef __FUNCT__
36016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG"
36116d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
36216d9e3a6SLisandro Dalcin {
36316d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
36416d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
36516d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
366d9ca1df4SBarry Smith   PetscScalar        *xv;
367d9ca1df4SBarry Smith   const PetscScalar  *bv;
36816d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
36916d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
3704ddd07fcSJed Brown   PetscInt           hierr;
37116d9e3a6SLisandro Dalcin 
37216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
373dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
37416d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
375d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
37616d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
377d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
37816d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
37916d9e3a6SLisandro Dalcin 
380fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
381fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
382fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
38316d9e3a6SLisandro Dalcin 
38416d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
38516d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
386e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
38716d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
38816d9e3a6SLisandro Dalcin 
38916d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
39016d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
39116d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
392d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
39316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
39416d9e3a6SLisandro Dalcin }
39516d9e3a6SLisandro Dalcin 
396a669f990SJed Brown /* static array length */
397a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
398a669f990SJed Brown 
39916d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
4000f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
40116d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
40265de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
40365de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
40465de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
40565de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
40665de4495SJed Brown                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */,
40765de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
4080f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
4090f1074feSSatish Balay                                                   "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"};
41016d9e3a6SLisandro Dalcin #undef __FUNCT__
41116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG"
4128c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptions *PetscOptionsObject,PC pc)
41316d9e3a6SLisandro Dalcin {
41416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
41516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
4164ddd07fcSJed Brown   PetscInt       n,indx,level;
417ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
41816d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
41916d9e3a6SLisandro Dalcin 
42016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
421e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
4224336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
42316d9e3a6SLisandro Dalcin   if (flg) {
4244336a9eeSBarry Smith     jac->cycletype = indx+1;
425fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
42616d9e3a6SLisandro Dalcin   }
42716d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
42816d9e3a6SLisandro Dalcin   if (flg) {
429ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
430fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
43116d9e3a6SLisandro Dalcin   }
43216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
43316d9e3a6SLisandro Dalcin   if (flg) {
434ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
435fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
43616d9e3a6SLisandro Dalcin   }
4370f1074feSSatish 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);
43816d9e3a6SLisandro Dalcin   if (flg) {
43957622a8eSBarry 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);
440fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
44116d9e3a6SLisandro Dalcin   }
44216d9e3a6SLisandro Dalcin 
4430f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
44416d9e3a6SLisandro Dalcin   if (flg) {
44557622a8eSBarry 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);
446fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
44716d9e3a6SLisandro Dalcin   }
44816d9e3a6SLisandro Dalcin 
4490f1074feSSatish 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);
4500f1074feSSatish Balay   if (flg) {
45157622a8eSBarry 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);
452fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
4530f1074feSSatish Balay   }
4540f1074feSSatish Balay 
4550f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
4560f1074feSSatish Balay   if (flg) {
45757622a8eSBarry 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);
4580f1074feSSatish Balay 
459fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
4600f1074feSSatish Balay   }
4610f1074feSSatish Balay 
4620f1074feSSatish Balay 
4630f1074feSSatish 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);
4640f1074feSSatish Balay   if (flg) {
46557622a8eSBarry 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);
4660f1074feSSatish Balay 
467fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
4680f1074feSSatish Balay   }
4690f1074feSSatish Balay 
4700f1074feSSatish Balay 
47116d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
47216d9e3a6SLisandro Dalcin   if (flg) {
47357622a8eSBarry 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);
474fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
47516d9e3a6SLisandro Dalcin   }
47616d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
47716d9e3a6SLisandro Dalcin   if (flg) {
47857622a8eSBarry 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);
47957622a8eSBarry 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);
480fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
48116d9e3a6SLisandro Dalcin   }
48216d9e3a6SLisandro Dalcin 
48316d9e3a6SLisandro Dalcin   /* Grid sweeps */
4840f1074feSSatish 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);
48516d9e3a6SLisandro Dalcin   if (flg) {
486fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
48716d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
48816d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
4890f1074feSSatish Balay     jac->gridsweeps[1] = indx;
4900f1074feSSatish Balay     /*defaults coarse to 1 */
4910f1074feSSatish Balay     jac->gridsweeps[2] = 1;
49216d9e3a6SLisandro Dalcin   }
4930f1074feSSatish Balay 
494*5272c319SBarry Smith   ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_coarsen","Use a nodal based coarsening 1-6","HYPRE_BoomerAMGSetNodal",jac->nodal_coarsening, &jac->nodal_coarsening,&flg);CHKERRQ(ierr);
495*5272c319SBarry Smith   if (flg) {
496*5272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,jac->nodal_coarsening));
497*5272c319SBarry Smith   }
498*5272c319SBarry Smith 
499*5272c319SBarry Smith   ierr = PetscOptionsInt("-pc_hypre_boomeramg_vec_interp_variant","Variant of algorithm 1-4","HYPRE_BoomerAMGSetInterpVecVariant",jac->vec_interp_variant, &jac->vec_interp_variant,&flg);CHKERRQ(ierr);
500*5272c319SBarry Smith   if (flg) {
501*5272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,(jac->hsolver,jac->vec_interp_variant));
502*5272c319SBarry Smith   }
503*5272c319SBarry Smith 
5040f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
50516d9e3a6SLisandro Dalcin   if (flg) {
506fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
5070f1074feSSatish Balay     jac->gridsweeps[0] = indx;
50816d9e3a6SLisandro Dalcin   }
50916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
51016d9e3a6SLisandro Dalcin   if (flg) {
511fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
5120f1074feSSatish Balay     jac->gridsweeps[1] = indx;
51316d9e3a6SLisandro Dalcin   }
5140f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
51516d9e3a6SLisandro Dalcin   if (flg) {
516fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
5170f1074feSSatish Balay     jac->gridsweeps[2] = indx;
51816d9e3a6SLisandro Dalcin   }
51916d9e3a6SLisandro Dalcin 
52016d9e3a6SLisandro Dalcin   /* Relax type */
521a669f990SJed 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);
52216d9e3a6SLisandro Dalcin   if (flg) {
5230f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
524fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
5250f1074feSSatish Balay     /* by default, coarse type set to 9 */
5260f1074feSSatish Balay     jac->relaxtype[2] = 9;
5270f1074feSSatish Balay 
52816d9e3a6SLisandro Dalcin   }
529a669f990SJed 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);
53016d9e3a6SLisandro Dalcin   if (flg) {
53116d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
532fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
53316d9e3a6SLisandro Dalcin   }
534a669f990SJed 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);
53516d9e3a6SLisandro Dalcin   if (flg) {
5360f1074feSSatish Balay     jac->relaxtype[1] = indx;
537fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
53816d9e3a6SLisandro Dalcin   }
539a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
54016d9e3a6SLisandro Dalcin   if (flg) {
5410f1074feSSatish Balay     jac->relaxtype[2] = indx;
542fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
54316d9e3a6SLisandro Dalcin   }
54416d9e3a6SLisandro Dalcin 
54516d9e3a6SLisandro Dalcin   /* Relaxation Weight */
54616d9e3a6SLisandro 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);
54716d9e3a6SLisandro Dalcin   if (flg) {
548fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
54916d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
55016d9e3a6SLisandro Dalcin   }
55116d9e3a6SLisandro Dalcin 
55216d9e3a6SLisandro Dalcin   n         = 2;
55316d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
55416d9e3a6SLisandro 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);
55516d9e3a6SLisandro Dalcin   if (flg) {
55616d9e3a6SLisandro Dalcin     if (n == 2) {
55716d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
558fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
559ce94432eSBarry 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);
56016d9e3a6SLisandro Dalcin   }
56116d9e3a6SLisandro Dalcin 
56216d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
56316d9e3a6SLisandro 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);
56416d9e3a6SLisandro Dalcin   if (flg) {
565fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
56616d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
56716d9e3a6SLisandro Dalcin   }
56816d9e3a6SLisandro Dalcin 
56916d9e3a6SLisandro Dalcin   n         = 2;
57016d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
57116d9e3a6SLisandro 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);
57216d9e3a6SLisandro Dalcin   if (flg) {
57316d9e3a6SLisandro Dalcin     if (n == 2) {
57416d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
575fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
576ce94432eSBarry 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);
57716d9e3a6SLisandro Dalcin   }
57816d9e3a6SLisandro Dalcin 
57916d9e3a6SLisandro Dalcin   /* the Relax Order */
580acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
58116d9e3a6SLisandro Dalcin 
5828afaa268SBarry Smith   if (flg && tmp_truth) {
58316d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
584fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
58516d9e3a6SLisandro Dalcin   }
586a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
58716d9e3a6SLisandro Dalcin   if (flg) {
58816d9e3a6SLisandro Dalcin     jac->measuretype = indx;
589fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
59016d9e3a6SLisandro Dalcin   }
5910f1074feSSatish Balay   /* update list length 3/07 */
592a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
59316d9e3a6SLisandro Dalcin   if (flg) {
59416d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
595fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
59616d9e3a6SLisandro Dalcin   }
5970f1074feSSatish Balay 
5980f1074feSSatish Balay   /* new 3/07 */
599a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
6000f1074feSSatish Balay   if (flg) {
6010f1074feSSatish Balay     jac->interptype = indx;
602fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
6030f1074feSSatish Balay   }
6040f1074feSSatish Balay 
605b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
60616d9e3a6SLisandro Dalcin   if (flg) {
607b96a4a96SBarry Smith     level = 3;
6080298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
6092fa5cd67SKarl Rupp 
610b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
611fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
6122ae77aedSBarry Smith   }
6132ae77aedSBarry Smith 
614b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
6152ae77aedSBarry Smith   if (flg) {
616b96a4a96SBarry Smith     level = 3;
6170298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
6182fa5cd67SKarl Rupp 
619b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
620fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
62116d9e3a6SLisandro Dalcin   }
6228f87f92bSBarry Smith 
623acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
6248f87f92bSBarry Smith   if (flg && tmp_truth) {
6258f87f92bSBarry Smith     PetscInt tmp_int;
6268f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
6278f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
628fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
629fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
630fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
631fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
6328f87f92bSBarry Smith   }
6338f87f92bSBarry Smith 
63416d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
63516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
63616d9e3a6SLisandro Dalcin }
63716d9e3a6SLisandro Dalcin 
63816d9e3a6SLisandro Dalcin #undef __FUNCT__
63916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG"
640ace3abfcSBarry 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)
64116d9e3a6SLisandro Dalcin {
64216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
64316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
6444ddd07fcSJed Brown   PetscInt       oits;
64516d9e3a6SLisandro Dalcin 
64616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
647dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
648fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
649fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
65016d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
65116d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
65216d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
6538b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
6544d0a8057SBarry Smith   *outits = oits;
6554d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
6564d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
657fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
658fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
65916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
66016d9e3a6SLisandro Dalcin }
66116d9e3a6SLisandro Dalcin 
66216d9e3a6SLisandro Dalcin 
66316d9e3a6SLisandro Dalcin #undef __FUNCT__
66416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG"
66516d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
66616d9e3a6SLisandro Dalcin {
66716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
66816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
669ace3abfcSBarry Smith   PetscBool      iascii;
67016d9e3a6SLisandro Dalcin 
67116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
672251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
67316d9e3a6SLisandro Dalcin   if (iascii) {
67416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
67516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
67616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
67716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
67857622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
67957622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
68057622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
6810f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
6820f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
6830f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
6840f1074feSSatish Balay 
68557622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
68616d9e3a6SLisandro Dalcin 
6870f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
6880f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
6890f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
69016d9e3a6SLisandro Dalcin 
6910f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
6920f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
6930f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
69416d9e3a6SLisandro Dalcin 
69557622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
69657622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
69716d9e3a6SLisandro Dalcin 
69816d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
69916d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr);
70016d9e3a6SLisandro Dalcin     } else {
70116d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr);
70216d9e3a6SLisandro Dalcin     }
70316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
70416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
7050f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
706*5272c319SBarry Smith     if (jac->nodal_coarsening) {
707*5272c319SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
708*5272c319SBarry Smith     }
709*5272c319SBarry Smith     if (jac->vec_interp_variant) {
710*5272c319SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
7118f87f92bSBarry Smith     }
7128f87f92bSBarry Smith     if (jac->nodal_relax) {
7138f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
7148f87f92bSBarry Smith     }
71516d9e3a6SLisandro Dalcin   }
71616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
71716d9e3a6SLisandro Dalcin }
71816d9e3a6SLisandro Dalcin 
71916d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
72016d9e3a6SLisandro Dalcin #undef __FUNCT__
72116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails"
7228c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptions *PetscOptionsObject,PC pc)
72316d9e3a6SLisandro Dalcin {
72416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
72516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
7264ddd07fcSJed Brown   PetscInt       indx;
727ace3abfcSBarry Smith   PetscBool      flag;
72816d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
72916d9e3a6SLisandro Dalcin 
73016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
731e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
73216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
73316d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
7342fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
73516d9e3a6SLisandro Dalcin 
73616d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
7372fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
73816d9e3a6SLisandro Dalcin 
73916d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
7402fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
74116d9e3a6SLisandro Dalcin 
742acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
7432fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
74416d9e3a6SLisandro Dalcin 
745acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
7462fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
74716d9e3a6SLisandro Dalcin 
748a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
74916d9e3a6SLisandro Dalcin   if (flag) {
75016d9e3a6SLisandro Dalcin     jac->symt = indx;
751fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
75216d9e3a6SLisandro Dalcin   }
75316d9e3a6SLisandro Dalcin 
75416d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
75516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
75616d9e3a6SLisandro Dalcin }
75716d9e3a6SLisandro Dalcin 
75816d9e3a6SLisandro Dalcin #undef __FUNCT__
75916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails"
76016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
76116d9e3a6SLisandro Dalcin {
76216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
76316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
764ace3abfcSBarry Smith   PetscBool      iascii;
76516d9e3a6SLisandro Dalcin   const char     *symt = 0;;
76616d9e3a6SLisandro Dalcin 
76716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
768251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
76916d9e3a6SLisandro Dalcin   if (iascii) {
77016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
77116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
77257622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
77357622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: filter %g\n",(double)jac->filter);CHKERRQ(ierr);
77457622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
775ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
776ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
7772fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
7782fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
7792fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
780ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
78116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr);
78216d9e3a6SLisandro Dalcin   }
78316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
78416d9e3a6SLisandro Dalcin }
7854cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
7864cb006feSStefano Zampini #undef __FUNCT__
7874cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS"
7889fa463a7SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptions *PetscOptionsObject,PC pc)
7894cb006feSStefano Zampini {
7904cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
7914cb006feSStefano Zampini   PetscErrorCode ierr;
7924cb006feSStefano Zampini   PetscInt       n;
7934cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
7944cb006feSStefano Zampini 
7954cb006feSStefano Zampini   PetscFunctionBegin;
7969fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
797863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
798863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
799863406b8SStefano 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);
800863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
8014cb006feSStefano 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);
8024cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
803863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
804863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
805863406b8SStefano 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);
806863406b8SStefano 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);
807863406b8SStefano 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);
808863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
8094cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
810863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
811863406b8SStefano Zampini                                                                       jac->as_relax_times,
812863406b8SStefano Zampini                                                                       jac->as_relax_weight,
813863406b8SStefano Zampini                                                                       jac->as_omega));
8144cb006feSStefano Zampini   }
815863406b8SStefano 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);
8164cb006feSStefano Zampini   n = 5;
817863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
8184cb006feSStefano Zampini   if (flag || flag2) {
819863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
820863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
821863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
822863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
823863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
824863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
8254cb006feSStefano Zampini   }
826863406b8SStefano 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);
8274cb006feSStefano Zampini   n = 5;
828863406b8SStefano 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);
8294cb006feSStefano Zampini   if (flag || flag2) {
830863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
831863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
832863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
833863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
834863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
835863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
8364cb006feSStefano Zampini   }
8374cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
8384cb006feSStefano Zampini   PetscFunctionReturn(0);
8394cb006feSStefano Zampini }
8404cb006feSStefano Zampini 
8414cb006feSStefano Zampini #undef __FUNCT__
8424cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS"
8434cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
8444cb006feSStefano Zampini {
8454cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
8464cb006feSStefano Zampini   PetscErrorCode ierr;
8474cb006feSStefano Zampini   PetscBool      iascii;
8484cb006feSStefano Zampini 
8494cb006feSStefano Zampini   PetscFunctionBegin;
8504cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
8514cb006feSStefano Zampini   if (iascii) {
8524cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
853863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
8544cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
855863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
856863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
857863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
858863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
859863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
8604cb006feSStefano Zampini     if (jac->alpha_Poisson) {
8614cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8624cb006feSStefano Zampini     } else {
8634cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr);
8644cb006feSStefano Zampini     }
865863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
866863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
867863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
868863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
869863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
870863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
8714cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
8724cb006feSStefano Zampini       if (jac->beta_Poisson) {
8734cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8744cb006feSStefano Zampini       } else {
8754cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr);
8764cb006feSStefano Zampini       }
877863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
878863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
879863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
880863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
881863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
882863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
8834cb006feSStefano Zampini     }
8844cb006feSStefano Zampini   }
8854cb006feSStefano Zampini   PetscFunctionReturn(0);
8864cb006feSStefano Zampini }
8874cb006feSStefano Zampini 
8884cb006feSStefano Zampini #undef __FUNCT__
889863406b8SStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_ADS"
890863406b8SStefano Zampini static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptions *PetscOptionsObject,PC pc)
891863406b8SStefano Zampini {
892863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
893863406b8SStefano Zampini   PetscErrorCode ierr;
894863406b8SStefano Zampini   PetscInt       n;
895863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
896863406b8SStefano Zampini 
897863406b8SStefano Zampini   PetscFunctionBegin;
898863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
899863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
900863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
901863406b8SStefano 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);
902863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
903863406b8SStefano 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);
904863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
905863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
906863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
907863406b8SStefano 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);
908863406b8SStefano 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);
909863406b8SStefano 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);
910863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
911863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
912863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
913863406b8SStefano Zampini                                                                       jac->as_relax_times,
914863406b8SStefano Zampini                                                                       jac->as_relax_weight,
915863406b8SStefano Zampini                                                                       jac->as_omega));
916863406b8SStefano Zampini   }
917863406b8SStefano 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);
918863406b8SStefano Zampini   n = 5;
919863406b8SStefano 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);
920863406b8SStefano 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);
921863406b8SStefano Zampini   if (flag || flag2 || flag3) {
922863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
923863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
924863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
925863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
926863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
927863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
928863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
929863406b8SStefano Zampini   }
930863406b8SStefano 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);
931863406b8SStefano Zampini   n = 5;
932863406b8SStefano 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);
933863406b8SStefano Zampini   if (flag || flag2) {
934863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
935863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
936863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
937863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
938863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
939863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
940863406b8SStefano Zampini   }
941863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
942863406b8SStefano Zampini   PetscFunctionReturn(0);
943863406b8SStefano Zampini }
944863406b8SStefano Zampini 
945863406b8SStefano Zampini #undef __FUNCT__
946863406b8SStefano Zampini #define __FUNCT__ "PCView_HYPRE_ADS"
947863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
948863406b8SStefano Zampini {
949863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
950863406b8SStefano Zampini   PetscErrorCode ierr;
951863406b8SStefano Zampini   PetscBool      iascii;
952863406b8SStefano Zampini 
953863406b8SStefano Zampini   PetscFunctionBegin;
954863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
955863406b8SStefano Zampini   if (iascii) {
956863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
957863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
958863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
959863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
960863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
961863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
962863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
963863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
964863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: AMS solver\n");CHKERRQ(ierr);
965863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
966863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
967863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
968863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
969863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
970863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
971863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
972863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: vector Poisson solver\n");CHKERRQ(ierr);
973863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
974863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
975863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
976863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
977863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
978863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
979863406b8SStefano Zampini   }
980863406b8SStefano Zampini   PetscFunctionReturn(0);
981863406b8SStefano Zampini }
982863406b8SStefano Zampini 
983863406b8SStefano Zampini #undef __FUNCT__
984863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE"
985863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
9864cb006feSStefano Zampini {
9874cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
9884cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_G;
9894cb006feSStefano Zampini   PetscErrorCode     ierr;
9904cb006feSStefano Zampini 
9914cb006feSStefano Zampini   PetscFunctionBegin;
9924cb006feSStefano Zampini   /* throw away any discrete gradient if already set */
9934cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
9944cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(G,&jac->G);CHKERRQ(ierr);
9954cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(G,jac->G);CHKERRQ(ierr);
9964cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->G,(void**)(&parcsr_G)));
997863406b8SStefano Zampini   PetscStackCall("Hypre set gradient",ierr = (*jac->setdgrad)(jac->hsolver,parcsr_G);CHKERRQ(ierr););
9984cb006feSStefano Zampini   PetscFunctionReturn(0);
9994cb006feSStefano Zampini }
10004cb006feSStefano Zampini 
10014cb006feSStefano Zampini #undef __FUNCT__
10024cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient"
10034cb006feSStefano Zampini /*@
10044cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
10054cb006feSStefano Zampini 
10064cb006feSStefano Zampini    Collective on PC
10074cb006feSStefano Zampini 
10084cb006feSStefano Zampini    Input Parameters:
10094cb006feSStefano Zampini +  pc - the preconditioning context
10104cb006feSStefano Zampini -  G - the discrete gradient
10114cb006feSStefano Zampini 
10124cb006feSStefano Zampini    Level: intermediate
10134cb006feSStefano Zampini 
10144cb006feSStefano 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
1015863406b8SStefano 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
10164cb006feSStefano Zampini 
10174cb006feSStefano Zampini .seealso:
10184cb006feSStefano Zampini @*/
10194cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
10204cb006feSStefano Zampini {
10214cb006feSStefano Zampini   PetscErrorCode ierr;
10224cb006feSStefano Zampini 
10234cb006feSStefano Zampini   PetscFunctionBegin;
10244cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
10254cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
10264cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
10274cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
10284cb006feSStefano Zampini   PetscFunctionReturn(0);
10294cb006feSStefano Zampini }
10304cb006feSStefano Zampini 
10314cb006feSStefano Zampini #undef __FUNCT__
1032863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl_HYPRE"
1033863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1034863406b8SStefano Zampini {
1035863406b8SStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
1036863406b8SStefano Zampini   HYPRE_ParCSRMatrix parcsr_C;
1037863406b8SStefano Zampini   PetscErrorCode     ierr;
1038863406b8SStefano Zampini 
1039863406b8SStefano Zampini   PetscFunctionBegin;
1040863406b8SStefano Zampini   /* throw away any discrete curl if already set */
1041863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
1042863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(C,&jac->C);CHKERRQ(ierr);
1043863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(C,jac->C);CHKERRQ(ierr);
1044863406b8SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->C,(void**)(&parcsr_C)));
1045863406b8SStefano Zampini   PetscStackCall("Hypre set curl",ierr = (*jac->setdcurl)(jac->hsolver,parcsr_C);CHKERRQ(ierr););
1046863406b8SStefano Zampini   PetscFunctionReturn(0);
1047863406b8SStefano Zampini }
1048863406b8SStefano Zampini 
1049863406b8SStefano Zampini #undef __FUNCT__
1050863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl"
1051863406b8SStefano Zampini /*@
1052863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1053863406b8SStefano Zampini 
1054863406b8SStefano Zampini    Collective on PC
1055863406b8SStefano Zampini 
1056863406b8SStefano Zampini    Input Parameters:
1057863406b8SStefano Zampini +  pc - the preconditioning context
1058863406b8SStefano Zampini -  C - the discrete curl
1059863406b8SStefano Zampini 
1060863406b8SStefano Zampini    Level: intermediate
1061863406b8SStefano Zampini 
1062863406b8SStefano 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
1063863406b8SStefano 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
1064863406b8SStefano Zampini 
1065863406b8SStefano Zampini .seealso:
1066863406b8SStefano Zampini @*/
1067863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1068863406b8SStefano Zampini {
1069863406b8SStefano Zampini   PetscErrorCode ierr;
1070863406b8SStefano Zampini 
1071863406b8SStefano Zampini   PetscFunctionBegin;
1072863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1073863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1074863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1075863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1076863406b8SStefano Zampini   PetscFunctionReturn(0);
1077863406b8SStefano Zampini }
1078863406b8SStefano Zampini 
1079863406b8SStefano Zampini #undef __FUNCT__
10804cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS"
10814cb006feSStefano Zampini static PetscErrorCode PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
10824cb006feSStefano Zampini {
10834cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
10844cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_alpha_Poisson;
10854cb006feSStefano Zampini   PetscErrorCode     ierr;
10864cb006feSStefano Zampini 
10874cb006feSStefano Zampini   PetscFunctionBegin;
10884cb006feSStefano Zampini   /* throw away any matrix if already set */
10894cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
10904cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->alpha_Poisson);CHKERRQ(ierr);
10914cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->alpha_Poisson);CHKERRQ(ierr);
10924cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->alpha_Poisson,(void**)(&parcsr_alpha_Poisson)));
10934cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr_alpha_Poisson));
10944cb006feSStefano Zampini   PetscFunctionReturn(0);
10954cb006feSStefano Zampini }
10964cb006feSStefano Zampini 
10974cb006feSStefano Zampini #undef __FUNCT__
10984cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix"
10994cb006feSStefano Zampini /*@
11004cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
11014cb006feSStefano Zampini 
11024cb006feSStefano Zampini    Collective on PC
11034cb006feSStefano Zampini 
11044cb006feSStefano Zampini    Input Parameters:
11054cb006feSStefano Zampini +  pc - the preconditioning context
11064cb006feSStefano Zampini -  A - the matrix
11074cb006feSStefano Zampini 
11084cb006feSStefano Zampini    Level: intermediate
11094cb006feSStefano Zampini 
11104cb006feSStefano Zampini    Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
11114cb006feSStefano Zampini 
11124cb006feSStefano Zampini .seealso:
11134cb006feSStefano Zampini @*/
11144cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
11154cb006feSStefano Zampini {
11164cb006feSStefano Zampini   PetscErrorCode ierr;
11174cb006feSStefano Zampini 
11184cb006feSStefano Zampini   PetscFunctionBegin;
11194cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11204cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
11214cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
11224cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetAlphaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
11234cb006feSStefano Zampini   PetscFunctionReturn(0);
11244cb006feSStefano Zampini }
11254cb006feSStefano Zampini 
11264cb006feSStefano Zampini #undef __FUNCT__
11274cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix_HYPRE_AMS"
11284cb006feSStefano Zampini static PetscErrorCode PCHYPRESetBetaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
11294cb006feSStefano Zampini {
11304cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11314cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_beta_Poisson;
11324cb006feSStefano Zampini   PetscErrorCode     ierr;
11334cb006feSStefano Zampini 
11344cb006feSStefano Zampini   PetscFunctionBegin;
11354cb006feSStefano Zampini   if (!A) {
1136484796dcSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
11374cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_TRUE;
11384cb006feSStefano Zampini     PetscFunctionReturn(0);
11394cb006feSStefano Zampini   }
11404cb006feSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
11414cb006feSStefano Zampini   /* throw away any matrix if already set */
11424cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
11434cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->beta_Poisson);CHKERRQ(ierr);
11444cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->beta_Poisson);CHKERRQ(ierr);
11454cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->beta_Poisson,(void**)(&parcsr_beta_Poisson)));
11464cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr_beta_Poisson));
11474cb006feSStefano Zampini   PetscFunctionReturn(0);
11484cb006feSStefano Zampini }
11494cb006feSStefano Zampini 
11504cb006feSStefano Zampini #undef __FUNCT__
11514cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix"
11524cb006feSStefano Zampini /*@
11534cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
11544cb006feSStefano Zampini 
11554cb006feSStefano Zampini    Collective on PC
11564cb006feSStefano Zampini 
11574cb006feSStefano Zampini    Input Parameters:
11584cb006feSStefano Zampini +  pc - the preconditioning context
11594cb006feSStefano Zampini -  A - the matrix
11604cb006feSStefano Zampini 
11614cb006feSStefano Zampini    Level: intermediate
11624cb006feSStefano Zampini 
11634cb006feSStefano Zampini    Notes: A should be obtained by discretizing the Poisson problem with linear finite elements.
11644cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
11654cb006feSStefano Zampini 
11664cb006feSStefano Zampini .seealso:
11674cb006feSStefano Zampini @*/
11684cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
11694cb006feSStefano Zampini {
11704cb006feSStefano Zampini   PetscErrorCode ierr;
11714cb006feSStefano Zampini 
11724cb006feSStefano Zampini   PetscFunctionBegin;
11734cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11744cb006feSStefano Zampini   if (A) {
11754cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
11764cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
11774cb006feSStefano Zampini   }
11784cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetBetaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
11794cb006feSStefano Zampini   PetscFunctionReturn(0);
11804cb006feSStefano Zampini }
11814cb006feSStefano Zampini 
11824cb006feSStefano Zampini #undef __FUNCT__
11834cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE_AMS"
11844cb006feSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE_AMS(PC pc,Vec ozz, Vec zoz, Vec zzo)
11854cb006feSStefano Zampini {
11864cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11874cb006feSStefano Zampini   HYPRE_ParVector    par_ozz,par_zoz,par_zzo;
118812ddd1b6SStefano Zampini   PetscInt           dim;
11894cb006feSStefano Zampini   PetscErrorCode     ierr;
11904cb006feSStefano Zampini 
11914cb006feSStefano Zampini   PetscFunctionBegin;
11924cb006feSStefano Zampini   /* throw away any vector if already set */
11934cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
11944cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
11954cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
11964cb006feSStefano Zampini   jac->constants[0] = NULL;
11974cb006feSStefano Zampini   jac->constants[1] = NULL;
11984cb006feSStefano Zampini   jac->constants[2] = NULL;
11994cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
12004cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
12014cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&par_ozz)));
12024cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
12034cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
12044cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&par_zoz)));
120512ddd1b6SStefano Zampini   dim = 2;
12064cb006feSStefano Zampini   if (zzo) {
12074cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
12084cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
12094cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&par_zzo)));
121012ddd1b6SStefano Zampini     dim++;
12114cb006feSStefano Zampini   }
12124cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,par_ozz,par_zoz,par_zzo));
121312ddd1b6SStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim));
12144cb006feSStefano Zampini   PetscFunctionReturn(0);
12154cb006feSStefano Zampini }
12164cb006feSStefano Zampini 
12174cb006feSStefano Zampini #undef __FUNCT__
12184cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors"
12194cb006feSStefano Zampini /*@
12204cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
12214cb006feSStefano Zampini 
12224cb006feSStefano Zampini    Collective on PC
12234cb006feSStefano Zampini 
12244cb006feSStefano Zampini    Input Parameters:
12254cb006feSStefano Zampini +  pc - the preconditioning context
12264cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
12274cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
12284cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
12294cb006feSStefano Zampini 
12304cb006feSStefano Zampini    Level: intermediate
12314cb006feSStefano Zampini 
12324cb006feSStefano Zampini    Notes:
12334cb006feSStefano Zampini 
12344cb006feSStefano Zampini .seealso:
12354cb006feSStefano Zampini @*/
12364cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
12374cb006feSStefano Zampini {
12384cb006feSStefano Zampini   PetscErrorCode ierr;
12394cb006feSStefano Zampini 
12404cb006feSStefano Zampini   PetscFunctionBegin;
12414cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12424cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
12434cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
12444cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
12454cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
12464cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
12474cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
12484cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
12494cb006feSStefano Zampini   PetscFunctionReturn(0);
12504cb006feSStefano Zampini }
12514cb006feSStefano Zampini 
12524cb006feSStefano Zampini #undef __FUNCT__
1253863406b8SStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE"
1254863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
12554cb006feSStefano Zampini {
12564cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
12574cb006feSStefano Zampini   Vec             tv;
12584cb006feSStefano Zampini   HYPRE_ParVector par_coords[3];
12594cb006feSStefano Zampini   PetscInt        i;
12604cb006feSStefano Zampini   PetscErrorCode  ierr;
12614cb006feSStefano Zampini 
12624cb006feSStefano Zampini   PetscFunctionBegin;
12634cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
12644cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
12654cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
12664cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
12674cb006feSStefano Zampini   /* set problem's dimension */
1268863406b8SStefano Zampini   if (jac->setdim) {
1269863406b8SStefano Zampini     PetscStackCall("Hypre set dim",ierr = (*jac->setdim)(jac->hsolver,dim);CHKERRQ(ierr););
1270863406b8SStefano Zampini   }
12714cb006feSStefano Zampini   /* compute IJ vector for coordinates */
12724cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
12734cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
12744cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
12754cb006feSStefano Zampini   for (i=0;i<dim;i++) {
12764cb006feSStefano Zampini     PetscScalar *array;
12774cb006feSStefano Zampini     PetscInt    j;
12784cb006feSStefano Zampini 
12794cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
12804cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
12814cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
12824cb006feSStefano Zampini       array[j] = coords[j*dim+i];
12834cb006feSStefano Zampini     }
12844cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
12854cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
12864cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
12874cb006feSStefano Zampini   }
12884cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
12894cb006feSStefano Zampini   /* pass parCSR vectors to AMS solver */
12904cb006feSStefano Zampini   par_coords[0] = NULL;
12914cb006feSStefano Zampini   par_coords[1] = NULL;
12924cb006feSStefano Zampini   par_coords[2] = NULL;
12934cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&par_coords[0])));
12944cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&par_coords[1])));
12954cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&par_coords[2])));
1296863406b8SStefano Zampini   PetscStackCall("Hypre set coords",ierr = (*jac->setcoord)(jac->hsolver,par_coords[0],par_coords[1],par_coords[2]);CHKERRQ(ierr););
12974cb006feSStefano Zampini   PetscFunctionReturn(0);
12984cb006feSStefano Zampini }
12994cb006feSStefano Zampini 
130016d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
130116d9e3a6SLisandro Dalcin 
130216d9e3a6SLisandro Dalcin #undef __FUNCT__
130316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
1304f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
130516d9e3a6SLisandro Dalcin {
130616d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
130716d9e3a6SLisandro Dalcin 
130816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
130916d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
131016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
131116d9e3a6SLisandro Dalcin }
131216d9e3a6SLisandro Dalcin 
131316d9e3a6SLisandro Dalcin #undef __FUNCT__
131416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
1315f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
131616d9e3a6SLisandro Dalcin {
131716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
131816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1319ace3abfcSBarry Smith   PetscBool      flag;
132016d9e3a6SLisandro Dalcin 
132116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
132216d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
132316d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1324ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
132516d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
132616d9e3a6SLisandro Dalcin   } else {
132716d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
132816d9e3a6SLisandro Dalcin   }
132916d9e3a6SLisandro Dalcin 
133016d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
133116d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
133216d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
133316d9e3a6SLisandro Dalcin 
133416d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
133516d9e3a6SLisandro Dalcin   if (flag) {
1336fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
133716d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
133816d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
133916d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
134016d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
134116d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
134216d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
134316d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
134416d9e3a6SLisandro Dalcin   }
134516d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
134616d9e3a6SLisandro Dalcin   if (flag) {
1347fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
134816d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
134916d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
135016d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
135116d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
135216d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
135316d9e3a6SLisandro Dalcin     /* initialize */
135416d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
135516d9e3a6SLisandro Dalcin     jac->threshhold = .1;
135616d9e3a6SLisandro Dalcin     jac->filter     = .1;
135716d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
13582fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
13592fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
13602fa5cd67SKarl Rupp 
136116d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
136216d9e3a6SLisandro Dalcin     jac->symt = 0;
1363fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1364fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1365fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1366fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1367fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1368fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
136916d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
137016d9e3a6SLisandro Dalcin   }
137116d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
137216d9e3a6SLisandro Dalcin   if (flag) {
137316d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
137416d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
137516d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
137616d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
137716d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
137816d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
137916d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
138016d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
138116d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
138216d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
138316d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
138416d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
138516d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
13868f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
138716d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
138816d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
138916d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
139016d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
139116d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
13920f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
13938f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
13940f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
139516d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
139616d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
139716d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
13980f1074feSSatish Balay     jac->interptype       = 0;
13990f1074feSSatish Balay     jac->agg_nl           = 0;
14000f1074feSSatish Balay     jac->pmax             = 0;
14010f1074feSSatish Balay     jac->truncfactor      = 0.0;
14020f1074feSSatish Balay     jac->agg_num_paths    = 1;
14038f87f92bSBarry Smith 
14048f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
14058f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
14068f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1407fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1408fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1409fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1410fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1411fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1412fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1413fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1414fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1415fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1416fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1417fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1418fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1419fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1420fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1421fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1422fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
142316d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
142416d9e3a6SLisandro Dalcin   }
14254cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
14264cb006feSStefano Zampini   if (flag) {
14274cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
14284cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
14294cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
14304cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
14314cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
14324cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
1433863406b8SStefano Zampini     jac->setdgrad            = HYPRE_AMSSetDiscreteGradient;
1434863406b8SStefano Zampini     jac->setcoord            = HYPRE_AMSSetCoordinateVectors;
1435863406b8SStefano Zampini     jac->setdim              = HYPRE_AMSSetDimension;
14364cb006feSStefano Zampini     jac->coords[0]           = NULL;
14374cb006feSStefano Zampini     jac->coords[1]           = NULL;
14384cb006feSStefano Zampini     jac->coords[2]           = NULL;
14394cb006feSStefano Zampini     jac->G                   = NULL;
14404cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1441863406b8SStefano Zampini     jac->as_print           = 0;
1442863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1443863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
14444cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
14454cb006feSStefano Zampini     /* Smoothing options */
1446863406b8SStefano Zampini     jac->as_relax_type      = 2;
1447863406b8SStefano Zampini     jac->as_relax_times     = 1;
1448863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1449863406b8SStefano Zampini     jac->as_omega           = 1.0;
14504cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1451863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1452863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
14530bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1454863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1455863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1456863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
14574cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
14584cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_FALSE;
1459863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1460863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
14610bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1462863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1463863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1464863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1465863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1466863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
14674cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1468863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1469863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1470863406b8SStefano Zampini                                                                       jac->as_relax_times,
1471863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1472863406b8SStefano Zampini                                                                       jac->as_omega));
1473863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1474863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1475863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1476863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1477863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1478863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1479863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1480863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1481863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1482863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1483863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1484863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1485863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1486863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
14874cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE_AMS);CHKERRQ(ierr);
14884cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
14894cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",PCHYPRESetBetaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
14904cb006feSStefano Zampini     PetscFunctionReturn(0);
14914cb006feSStefano Zampini   }
1492863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1493863406b8SStefano Zampini   if (flag) {
1494863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1495863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1496863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1497863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1498863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1499863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1500863406b8SStefano Zampini     jac->setdgrad            = HYPRE_ADSSetDiscreteGradient;
1501863406b8SStefano Zampini     jac->setdcurl            = HYPRE_ADSSetDiscreteCurl;
1502863406b8SStefano Zampini     jac->setcoord            = HYPRE_ADSSetCoordinateVectors;
1503863406b8SStefano Zampini     jac->coords[0]           = NULL;
1504863406b8SStefano Zampini     jac->coords[1]           = NULL;
1505863406b8SStefano Zampini     jac->coords[2]           = NULL;
1506863406b8SStefano Zampini     jac->G                   = NULL;
1507863406b8SStefano Zampini     jac->C                   = NULL;
1508863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1509863406b8SStefano Zampini     jac->as_print           = 0;
1510863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1511863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1512863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1513863406b8SStefano Zampini     /* Smoothing options */
1514863406b8SStefano Zampini     jac->as_relax_type      = 2;
1515863406b8SStefano Zampini     jac->as_relax_times     = 1;
1516863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1517863406b8SStefano Zampini     jac->as_omega           = 1.0;
1518863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1519863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1520863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1521863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1522863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1523863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1524863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1525863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1526863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1527863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1528863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1529863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1530863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1531863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1532863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1533863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1534863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1535863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1536863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1537863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1538863406b8SStefano Zampini                                                                       jac->as_relax_times,
1539863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1540863406b8SStefano Zampini                                                                       jac->as_omega));
1541863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1542863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1543863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1544863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1545863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1546863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1547863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1548863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1549863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1550863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1551863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1552863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1553863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1554863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1555863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
1556863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
1557863406b8SStefano Zampini     PetscFunctionReturn(0);
1558863406b8SStefano Zampini   }
1559503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
15602fa5cd67SKarl Rupp 
15610298fd71SBarry Smith   jac->hypre_type = NULL;
156233263987SBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, boomeramg, ams",name);
156316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
156416d9e3a6SLisandro Dalcin }
156516d9e3a6SLisandro Dalcin 
156616d9e3a6SLisandro Dalcin /*
156716d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
156816d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
156916d9e3a6SLisandro Dalcin */
157016d9e3a6SLisandro Dalcin #undef __FUNCT__
157116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
15728c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptions *PetscOptionsObject,PC pc)
157316d9e3a6SLisandro Dalcin {
157416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
15754ddd07fcSJed Brown   PetscInt       indx;
1576863406b8SStefano Zampini   const char     *type[] = {"pilut","parasails","boomeramg","ams","ads"};
1577ace3abfcSBarry Smith   PetscBool      flg;
157816d9e3a6SLisandro Dalcin 
157916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
15809fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
15819c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
158216d9e3a6SLisandro Dalcin   if (flg) {
158316d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
158402a17cd4SBarry Smith   } else {
158502a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
158616d9e3a6SLisandro Dalcin   }
158716d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
15883931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
158916d9e3a6SLisandro Dalcin   }
159016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
159116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
159216d9e3a6SLisandro Dalcin }
159316d9e3a6SLisandro Dalcin 
159416d9e3a6SLisandro Dalcin #undef __FUNCT__
159516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
159616d9e3a6SLisandro Dalcin /*@C
159716d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
159816d9e3a6SLisandro Dalcin 
159916d9e3a6SLisandro Dalcin    Input Parameters:
160016d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1601863406b8SStefano Zampini -     name - either  pilut, parasails, boomeramg, ams, ads
160216d9e3a6SLisandro Dalcin 
160316d9e3a6SLisandro Dalcin    Options Database Keys:
1604863406b8SStefano Zampini    -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
160516d9e3a6SLisandro Dalcin 
160616d9e3a6SLisandro Dalcin    Level: intermediate
160716d9e3a6SLisandro Dalcin 
160816d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
160916d9e3a6SLisandro Dalcin            PCHYPRE
161016d9e3a6SLisandro Dalcin 
161116d9e3a6SLisandro Dalcin @*/
16127087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
161316d9e3a6SLisandro Dalcin {
16144ac538c5SBarry Smith   PetscErrorCode ierr;
161516d9e3a6SLisandro Dalcin 
161616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16170700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
161816d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
16194ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
162016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
162116d9e3a6SLisandro Dalcin }
162216d9e3a6SLisandro Dalcin 
162316d9e3a6SLisandro Dalcin #undef __FUNCT__
162416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
162516d9e3a6SLisandro Dalcin /*@C
162616d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
162716d9e3a6SLisandro Dalcin 
162816d9e3a6SLisandro Dalcin    Input Parameter:
162916d9e3a6SLisandro Dalcin .     pc - the preconditioner context
163016d9e3a6SLisandro Dalcin 
163116d9e3a6SLisandro Dalcin    Output Parameter:
1632863406b8SStefano Zampini .     name - either  pilut, parasails, boomeramg, ams, ads
163316d9e3a6SLisandro Dalcin 
163416d9e3a6SLisandro Dalcin    Level: intermediate
163516d9e3a6SLisandro Dalcin 
163616d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
163716d9e3a6SLisandro Dalcin            PCHYPRE
163816d9e3a6SLisandro Dalcin 
163916d9e3a6SLisandro Dalcin @*/
16407087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
164116d9e3a6SLisandro Dalcin {
16424ac538c5SBarry Smith   PetscErrorCode ierr;
164316d9e3a6SLisandro Dalcin 
164416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16450700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
164616d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
16474ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
164816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
164916d9e3a6SLisandro Dalcin }
165016d9e3a6SLisandro Dalcin 
165116d9e3a6SLisandro Dalcin /*MC
165216d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
165316d9e3a6SLisandro Dalcin 
165416d9e3a6SLisandro Dalcin    Options Database Keys:
1655863406b8SStefano Zampini +   -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
165616d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
165716d9e3a6SLisandro Dalcin           preconditioner
165816d9e3a6SLisandro Dalcin 
165916d9e3a6SLisandro Dalcin    Level: intermediate
166016d9e3a6SLisandro Dalcin 
166116d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
166216d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
166316d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
166416d9e3a6SLisandro Dalcin 
166516d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
16660f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
16670f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
16680f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
16698f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
16700f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
16710f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
167216d9e3a6SLisandro Dalcin 
16730f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
16740f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
16750f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
167616d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
167716d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
167816d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
167916d9e3a6SLisandro Dalcin 
168016d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
168116d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
168216d9e3a6SLisandro Dalcin 
1683*5272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
1684*5272c319SBarry Smith           the two options:
1685*5272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
1686*5272c319SBarry Smith -   -pc_hypre_boomeramg_vec_interp_variant <v> where v is from 1 to 4 (see HYPRE_BoomerAMGSetInterpVecVariant())
1687*5272c319SBarry Smith 
1688*5272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
1689*5272c319SBarry Smith 
16909e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
16919e5bc791SBarry Smith 
169216d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
16939e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
169416d9e3a6SLisandro Dalcin 
169516d9e3a6SLisandro Dalcin M*/
169616d9e3a6SLisandro Dalcin 
169716d9e3a6SLisandro Dalcin #undef __FUNCT__
169816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
16998cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
170016d9e3a6SLisandro Dalcin {
170116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
170216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
170316d9e3a6SLisandro Dalcin 
170416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1705b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
17062fa5cd67SKarl Rupp 
170716d9e3a6SLisandro Dalcin   pc->data                = jac;
170816d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
170916d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
171016d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
171116d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
171216d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
17130298fd71SBarry Smith   jac->hypre_type         = NULL;
17144cb006feSStefano Zampini   jac->coords[0]          = NULL;
17154cb006feSStefano Zampini   jac->coords[1]          = NULL;
17164cb006feSStefano Zampini   jac->coords[2]          = NULL;
17174cb006feSStefano Zampini   jac->constants[0]       = NULL;
17184cb006feSStefano Zampini   jac->constants[1]       = NULL;
17194cb006feSStefano Zampini   jac->constants[2]       = NULL;
1720863406b8SStefano Zampini   jac->G                  = NULL;
1721863406b8SStefano Zampini   jac->C                  = NULL;
1722863406b8SStefano Zampini   jac->alpha_Poisson      = NULL;
1723863406b8SStefano Zampini   jac->beta_Poisson       = NULL;
1724fd444223SStefano Zampini   jac->setdim             = NULL;
1725*5272c319SBarry Smith   jac->hmnull             = NULL;
1726*5272c319SBarry Smith   jac->n_hmnull           = 0;
172716d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1728ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1729bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1730bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
173116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
173216d9e3a6SLisandro Dalcin }
1733ebc551c0SBarry Smith 
1734f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1735f91d8e95SBarry Smith 
1736b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1737af0996ceSBarry Smith #include <petsc/private/matimpl.h>
1738ebc551c0SBarry Smith 
1739ebc551c0SBarry Smith typedef struct {
174068326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1741f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
17429e5bc791SBarry Smith 
17439e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
17444ddd07fcSJed Brown   PetscInt its;
17459e5bc791SBarry Smith   double   tol;
17464ddd07fcSJed Brown   PetscInt relax_type;
17474ddd07fcSJed Brown   PetscInt rap_type;
17484ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
17494ddd07fcSJed Brown   PetscInt max_levels;
1750ebc551c0SBarry Smith } PC_PFMG;
1751ebc551c0SBarry Smith 
1752ebc551c0SBarry Smith #undef __FUNCT__
1753ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1754ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1755ebc551c0SBarry Smith {
1756ebc551c0SBarry Smith   PetscErrorCode ierr;
1757f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1758ebc551c0SBarry Smith 
1759ebc551c0SBarry Smith   PetscFunctionBegin;
17602fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1761f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1762c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1763ebc551c0SBarry Smith   PetscFunctionReturn(0);
1764ebc551c0SBarry Smith }
1765ebc551c0SBarry Smith 
17669e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
17679e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
17689e5bc791SBarry Smith 
1769ebc551c0SBarry Smith #undef __FUNCT__
1770ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1771ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1772ebc551c0SBarry Smith {
1773ebc551c0SBarry Smith   PetscErrorCode ierr;
1774ace3abfcSBarry Smith   PetscBool      iascii;
1775f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1776ebc551c0SBarry Smith 
1777ebc551c0SBarry Smith   PetscFunctionBegin;
1778251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
17799e5bc791SBarry Smith   if (iascii) {
17809e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
17819e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
17829e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
17839e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
17849e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
17859e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
17863b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
17879e5bc791SBarry Smith   }
1788ebc551c0SBarry Smith   PetscFunctionReturn(0);
1789ebc551c0SBarry Smith }
1790ebc551c0SBarry Smith 
17919e5bc791SBarry Smith 
1792ebc551c0SBarry Smith #undef __FUNCT__
1793ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
17948c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptions *PetscOptionsObject,PC pc)
1795ebc551c0SBarry Smith {
1796ebc551c0SBarry Smith   PetscErrorCode ierr;
1797f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1798ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1799ebc551c0SBarry Smith 
1800ebc551c0SBarry Smith   PetscFunctionBegin;
1801e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
18020298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
180368326731SBarry Smith   if (flg) {
1804a0324ebeSBarry Smith     int level=3;
1805fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
180668326731SBarry Smith   }
18070298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1808fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
18090298fd71SBarry 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);
1810fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
18110298fd71SBarry 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);
1812fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
18139e5bc791SBarry Smith 
18140298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
1815fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
18163b46a515SGlenn Hammond 
18170298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1818fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
18190298fd71SBarry 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);
1820fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
18210298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
1822fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1823ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1824ebc551c0SBarry Smith   PetscFunctionReturn(0);
1825ebc551c0SBarry Smith }
1826ebc551c0SBarry Smith 
1827f91d8e95SBarry Smith #undef __FUNCT__
1828f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1829f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1830f91d8e95SBarry Smith {
1831f91d8e95SBarry Smith   PetscErrorCode    ierr;
1832f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
1833d9ca1df4SBarry Smith   PetscScalar       *yy;
1834d9ca1df4SBarry Smith   const PetscScalar *xx;
18354ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
183668326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1837f91d8e95SBarry Smith 
1838f91d8e95SBarry Smith   PetscFunctionBegin;
1839dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1840aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1841f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1842f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1843f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1844f91d8e95SBarry Smith 
1845f91d8e95SBarry Smith   /* copy x values over to hypre */
1846fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1847d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1848d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
1849d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1850fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
1851fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1852f91d8e95SBarry Smith 
1853f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1854f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
18558b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
1856f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1857f91d8e95SBarry Smith   PetscFunctionReturn(0);
1858f91d8e95SBarry Smith }
1859f91d8e95SBarry Smith 
18609e5bc791SBarry Smith #undef __FUNCT__
18619e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1862ace3abfcSBarry 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)
18639e5bc791SBarry Smith {
18649e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
18659e5bc791SBarry Smith   PetscErrorCode ierr;
18664ddd07fcSJed Brown   PetscInt       oits;
18679e5bc791SBarry Smith 
18689e5bc791SBarry Smith   PetscFunctionBegin;
1869dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1870fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1871fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
18729e5bc791SBarry Smith 
18739e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
18748b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
18759e5bc791SBarry Smith   *outits = oits;
18769e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
18779e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1878fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1879fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
18809e5bc791SBarry Smith   PetscFunctionReturn(0);
18819e5bc791SBarry Smith }
18829e5bc791SBarry Smith 
18839e5bc791SBarry Smith 
18843a32d3dbSGlenn Hammond #undef __FUNCT__
18853a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
18863a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
18873a32d3dbSGlenn Hammond {
18883a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
18893a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
18903a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1891ace3abfcSBarry Smith   PetscBool       flg;
18923a32d3dbSGlenn Hammond 
18933a32d3dbSGlenn Hammond   PetscFunctionBegin;
1894251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1895ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
18963a32d3dbSGlenn Hammond 
18973a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
18982fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1899fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1900fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1901fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
19023a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
19033a32d3dbSGlenn Hammond }
19043a32d3dbSGlenn Hammond 
1905ebc551c0SBarry Smith 
1906ebc551c0SBarry Smith /*MC
1907ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1908ebc551c0SBarry Smith 
1909ebc551c0SBarry Smith    Level: advanced
1910ebc551c0SBarry Smith 
19119e5bc791SBarry Smith    Options Database:
19129e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
19139e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
19149e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
19159e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
19169e5bc791SBarry 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
19179e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
1918f91d8e95SBarry Smith 
19199e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
19209e5bc791SBarry Smith 
19218e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
1922aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
19239e5bc791SBarry Smith 
19249e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
1925ebc551c0SBarry Smith M*/
1926ebc551c0SBarry Smith 
1927ebc551c0SBarry Smith #undef __FUNCT__
1928ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
19298cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
1930ebc551c0SBarry Smith {
1931ebc551c0SBarry Smith   PetscErrorCode ierr;
1932ebc551c0SBarry Smith   PC_PFMG        *ex;
1933ebc551c0SBarry Smith 
1934ebc551c0SBarry Smith   PetscFunctionBegin;
1935b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
193668326731SBarry Smith   pc->data = ex;
1937ebc551c0SBarry Smith 
19389e5bc791SBarry Smith   ex->its            = 1;
19399e5bc791SBarry Smith   ex->tol            = 1.e-8;
19409e5bc791SBarry Smith   ex->relax_type     = 1;
19419e5bc791SBarry Smith   ex->rap_type       = 0;
19429e5bc791SBarry Smith   ex->num_pre_relax  = 1;
19439e5bc791SBarry Smith   ex->num_post_relax = 1;
19443b46a515SGlenn Hammond   ex->max_levels     = 0;
19459e5bc791SBarry Smith 
1946ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
1947ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
1948ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
1949f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
19509e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
195168326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
19522fa5cd67SKarl Rupp 
1953ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
1954fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1955ebc551c0SBarry Smith   PetscFunctionReturn(0);
1956ebc551c0SBarry Smith }
1957d851a50bSGlenn Hammond 
1958325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
1959325fc9f4SBarry Smith 
1960d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
1961d851a50bSGlenn Hammond typedef struct {
1962d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
1963d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
1964d851a50bSGlenn Hammond 
1965d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
19664ddd07fcSJed Brown   PetscInt its;
1967d851a50bSGlenn Hammond   double   tol;
19684ddd07fcSJed Brown   PetscInt relax_type;
19694ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
1970d851a50bSGlenn Hammond } PC_SysPFMG;
1971d851a50bSGlenn Hammond 
1972d851a50bSGlenn Hammond #undef __FUNCT__
1973d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
1974d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
1975d851a50bSGlenn Hammond {
1976d851a50bSGlenn Hammond   PetscErrorCode ierr;
1977d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1978d851a50bSGlenn Hammond 
1979d851a50bSGlenn Hammond   PetscFunctionBegin;
19802fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1981d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1982c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1983d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1984d851a50bSGlenn Hammond }
1985d851a50bSGlenn Hammond 
1986d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
1987d851a50bSGlenn Hammond 
1988d851a50bSGlenn Hammond #undef __FUNCT__
1989d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
1990d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
1991d851a50bSGlenn Hammond {
1992d851a50bSGlenn Hammond   PetscErrorCode ierr;
1993ace3abfcSBarry Smith   PetscBool      iascii;
1994d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1995d851a50bSGlenn Hammond 
1996d851a50bSGlenn Hammond   PetscFunctionBegin;
1997251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1998d851a50bSGlenn Hammond   if (iascii) {
1999d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2000d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
2001d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
2002d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2003d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2004d851a50bSGlenn Hammond   }
2005d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2006d851a50bSGlenn Hammond }
2007d851a50bSGlenn Hammond 
2008d851a50bSGlenn Hammond 
2009d851a50bSGlenn Hammond #undef __FUNCT__
2010d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
20118c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptions *PetscOptionsObject,PC pc)
2012d851a50bSGlenn Hammond {
2013d851a50bSGlenn Hammond   PetscErrorCode ierr;
2014d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2015ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2016d851a50bSGlenn Hammond 
2017d851a50bSGlenn Hammond   PetscFunctionBegin;
2018e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
20190298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2020d851a50bSGlenn Hammond   if (flg) {
2021d851a50bSGlenn Hammond     int level=3;
2022fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
2023d851a50bSGlenn Hammond   }
20240298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2025fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
20260298fd71SBarry 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);
2027fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
20280298fd71SBarry 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);
2029fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2030d851a50bSGlenn Hammond 
20310298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2032fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
20330298fd71SBarry 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);
2034fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2035d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2036d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2037d851a50bSGlenn Hammond }
2038d851a50bSGlenn Hammond 
2039d851a50bSGlenn Hammond #undef __FUNCT__
2040d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
2041d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2042d851a50bSGlenn Hammond {
2043d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2044d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2045d9ca1df4SBarry Smith   PetscScalar       *yy;
2046d9ca1df4SBarry Smith   const PetscScalar *xx;
20474ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
2048d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
20494ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
20504ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
20514ddd07fcSJed Brown   PetscInt          part    = 0;
20524ddd07fcSJed Brown   PetscInt          size;
20534ddd07fcSJed Brown   PetscInt          i;
2054d851a50bSGlenn Hammond 
2055d851a50bSGlenn Hammond   PetscFunctionBegin;
2056dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2057aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2058d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2059d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2060d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2061d851a50bSGlenn Hammond 
2062d851a50bSGlenn Hammond   size = 1;
20632fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
20642fa5cd67SKarl Rupp 
2065d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2066d851a50bSGlenn Hammond   if (ordering) {
2067fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2068d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2069d9ca1df4SBarry 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)));
2070d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2071fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2072fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2073fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2074d851a50bSGlenn Hammond 
2075d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2076d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
20778b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2078d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2079a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2080d851a50bSGlenn Hammond     PetscScalar *z;
20814ddd07fcSJed Brown     PetscInt    j, k;
2082d851a50bSGlenn Hammond 
2083785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2084fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2085d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2086d851a50bSGlenn Hammond 
2087d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2088d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2089d851a50bSGlenn Hammond       k= i*nvars;
20902fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2091d851a50bSGlenn Hammond     }
20928b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2093d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2094fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2095fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2096d851a50bSGlenn Hammond 
2097d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2098d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
20998b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2100d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2101d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2102d851a50bSGlenn Hammond       k= i*nvars;
21032fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2104d851a50bSGlenn Hammond     }
2105d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2106d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2107d851a50bSGlenn Hammond   }
2108d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2109d851a50bSGlenn Hammond }
2110d851a50bSGlenn Hammond 
2111d851a50bSGlenn Hammond #undef __FUNCT__
2112d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
2113ace3abfcSBarry 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)
2114d851a50bSGlenn Hammond {
2115d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2116d851a50bSGlenn Hammond   PetscErrorCode ierr;
21174ddd07fcSJed Brown   PetscInt       oits;
2118d851a50bSGlenn Hammond 
2119d851a50bSGlenn Hammond   PetscFunctionBegin;
2120dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2121fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2122fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2123d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
21248b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2125d851a50bSGlenn Hammond   *outits = oits;
2126d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2127d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2128fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2129fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2130d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2131d851a50bSGlenn Hammond }
2132d851a50bSGlenn Hammond 
2133d851a50bSGlenn Hammond 
2134d851a50bSGlenn Hammond #undef __FUNCT__
2135d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
2136d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2137d851a50bSGlenn Hammond {
2138d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2139d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2140d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2141ace3abfcSBarry Smith   PetscBool        flg;
2142d851a50bSGlenn Hammond 
2143d851a50bSGlenn Hammond   PetscFunctionBegin;
2144251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2145ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2146d851a50bSGlenn Hammond 
2147d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
21482fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2149fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2150fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2151fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2152d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2153d851a50bSGlenn Hammond }
2154d851a50bSGlenn Hammond 
2155d851a50bSGlenn Hammond 
2156d851a50bSGlenn Hammond /*MC
2157d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2158d851a50bSGlenn Hammond 
2159d851a50bSGlenn Hammond    Level: advanced
2160d851a50bSGlenn Hammond 
2161d851a50bSGlenn Hammond    Options Database:
2162d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2163d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2164d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2165d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2166d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2167d851a50bSGlenn Hammond 
2168d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
2169d851a50bSGlenn Hammond 
2170f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2171aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2172d851a50bSGlenn Hammond            Also, only cell-centered variables.
2173d851a50bSGlenn Hammond 
2174d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2175d851a50bSGlenn Hammond M*/
2176d851a50bSGlenn Hammond 
2177d851a50bSGlenn Hammond #undef __FUNCT__
2178d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
21798cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2180d851a50bSGlenn Hammond {
2181d851a50bSGlenn Hammond   PetscErrorCode ierr;
2182d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2183d851a50bSGlenn Hammond 
2184d851a50bSGlenn Hammond   PetscFunctionBegin;
2185b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2186d851a50bSGlenn Hammond   pc->data = ex;
2187d851a50bSGlenn Hammond 
2188d851a50bSGlenn Hammond   ex->its            = 1;
2189d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2190d851a50bSGlenn Hammond   ex->relax_type     = 1;
2191d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2192d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2193d851a50bSGlenn Hammond 
2194d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2195d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2196d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2197d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2198d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2199d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
22002fa5cd67SKarl Rupp 
2201ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2202fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2203d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2204d851a50bSGlenn Hammond }
2205