xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 728274352f3a62e7198a15da1837cf5ce653057d)
116d9e3a6SLisandro Dalcin 
216d9e3a6SLisandro Dalcin /*
316d9e3a6SLisandro Dalcin    Provides an interface to the LLNL package hypre
416d9e3a6SLisandro Dalcin */
50f1074feSSatish Balay 
60f1074feSSatish Balay /* Must use hypre 2.0.0 or more recent. */
70f1074feSSatish Balay 
8af0996ceSBarry Smith #include <petsc/private/pcimpl.h>          /*I "petscpc.h" I*/
9c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h>
104cb006feSStefano Zampini #include <_hypre_parcsr_ls.h>
1116d9e3a6SLisandro Dalcin 
12dff31646SBarry Smith static PetscBool cite = PETSC_FALSE;
131f817a21SBarry Smith static const char hypreCitation[] = "@manual{hypre-web-page,\n  title  = {{\\sl hypre}: High Performance Preconditioners},\n  organization = {Lawrence Livermore National Laboratory},\n  note  = {\\url{http://www.llnl.gov/CASC/hypre/}}\n}\n";
141f817a21SBarry Smith 
1516d9e3a6SLisandro Dalcin /*
1616d9e3a6SLisandro Dalcin    Private context (data structure) for the  preconditioner.
1716d9e3a6SLisandro Dalcin */
1816d9e3a6SLisandro Dalcin typedef struct {
1916d9e3a6SLisandro Dalcin   HYPRE_Solver   hsolver;
2016d9e3a6SLisandro Dalcin   HYPRE_IJMatrix ij;
2116d9e3a6SLisandro Dalcin   HYPRE_IJVector b,x;
2216d9e3a6SLisandro Dalcin 
234ddd07fcSJed Brown   HYPRE_Int (*destroy)(HYPRE_Solver);
244ddd07fcSJed Brown   HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
254ddd07fcSJed Brown   HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
26863406b8SStefano Zampini   HYPRE_Int (*setdgrad)(HYPRE_Solver,HYPRE_ParCSRMatrix);
27863406b8SStefano Zampini   HYPRE_Int (*setdcurl)(HYPRE_Solver,HYPRE_ParCSRMatrix);
28863406b8SStefano Zampini   HYPRE_Int (*setcoord)(HYPRE_Solver,HYPRE_ParVector,HYPRE_ParVector,HYPRE_ParVector);
29863406b8SStefano Zampini   HYPRE_Int (*setdim)(HYPRE_Solver,HYPRE_Int);
3016d9e3a6SLisandro Dalcin 
3116d9e3a6SLisandro Dalcin   MPI_Comm comm_hypre;
3216d9e3a6SLisandro Dalcin   char     *hypre_type;
3316d9e3a6SLisandro Dalcin 
3416d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
354ddd07fcSJed Brown   PetscInt maxiter;
3616d9e3a6SLisandro Dalcin   double   tol;
3716d9e3a6SLisandro Dalcin 
3816d9e3a6SLisandro Dalcin   /* options for Pilut */
394ddd07fcSJed Brown   PetscInt factorrowsize;
4016d9e3a6SLisandro Dalcin 
4116d9e3a6SLisandro Dalcin   /* options for ParaSails */
424ddd07fcSJed Brown   PetscInt nlevels;
4316d9e3a6SLisandro Dalcin   double   threshhold;
4416d9e3a6SLisandro Dalcin   double   filter;
454ddd07fcSJed Brown   PetscInt sym;
4616d9e3a6SLisandro Dalcin   double   loadbal;
474ddd07fcSJed Brown   PetscInt logging;
484ddd07fcSJed Brown   PetscInt ruse;
494ddd07fcSJed Brown   PetscInt symt;
5016d9e3a6SLisandro Dalcin 
5122b6d1caSBarry Smith   /* options for BoomerAMG */
52ace3abfcSBarry Smith   PetscBool printstatistics;
5316d9e3a6SLisandro Dalcin 
5416d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
554ddd07fcSJed Brown   PetscInt  cycletype;
564ddd07fcSJed Brown   PetscInt  maxlevels;
5716d9e3a6SLisandro Dalcin   double    strongthreshold;
5816d9e3a6SLisandro Dalcin   double    maxrowsum;
594ddd07fcSJed Brown   PetscInt  gridsweeps[3];
604ddd07fcSJed Brown   PetscInt  coarsentype;
614ddd07fcSJed Brown   PetscInt  measuretype;
626a251517SEike Mueller   PetscInt  smoothtype;
638131ecf7SEike Mueller   PetscInt  smoothnumlevels;
64ec64516dSEike Mueller   PetscInt  eu_level;   /* Number of levels for ILU(k) in Euclid */
65ec64516dSEike Mueller   double    eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */
66ec64516dSEike Mueller   PetscInt  eu_bj;      /* Defines use of Block Jacobi ILU in Euclid */
674ddd07fcSJed Brown   PetscInt  relaxtype[3];
6816d9e3a6SLisandro Dalcin   double    relaxweight;
6916d9e3a6SLisandro Dalcin   double    outerrelaxweight;
704ddd07fcSJed Brown   PetscInt  relaxorder;
7116d9e3a6SLisandro Dalcin   double    truncfactor;
72ace3abfcSBarry Smith   PetscBool applyrichardson;
734ddd07fcSJed Brown   PetscInt  pmax;
744ddd07fcSJed Brown   PetscInt  interptype;
754ddd07fcSJed Brown   PetscInt  agg_nl;
764ddd07fcSJed Brown   PetscInt  agg_num_paths;
774ddd07fcSJed Brown   PetscInt  nodal_coarsen;
78ace3abfcSBarry Smith   PetscBool nodal_relax;
794ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
804cb006feSStefano Zampini 
815272c319SBarry Smith   PetscInt  nodal_coarsening;
825272c319SBarry Smith   PetscInt  vec_interp_variant;
835272c319SBarry Smith   HYPRE_IJVector  *hmnull;
845272c319SBarry Smith   HYPRE_ParVector *phmnull;  /* near null space passed to hypre */
855272c319SBarry Smith   PetscInt        n_hmnull;
865272c319SBarry Smith   Vec             hmnull_constant;
87*72827435SBarry Smith   PetscScalar     **hmnull_hypre_data_array;   /* this is the space in hmnull that was allocated by hypre, it is restored to hypre just before freeing the phmnull vectors */
885272c319SBarry Smith 
89863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
90863406b8SStefano Zampini   PetscInt  as_print;
91863406b8SStefano Zampini   PetscInt  as_max_iter;
92863406b8SStefano Zampini   PetscReal as_tol;
93863406b8SStefano Zampini   PetscInt  as_relax_type;
94863406b8SStefano Zampini   PetscInt  as_relax_times;
95863406b8SStefano Zampini   PetscReal as_relax_weight;
96863406b8SStefano Zampini   PetscReal as_omega;
97863406b8SStefano 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) */
98863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
99863406b8SStefano 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) */
100863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
1014cb006feSStefano Zampini   PetscInt  ams_cycle_type;
102863406b8SStefano Zampini   PetscInt  ads_cycle_type;
1034cb006feSStefano Zampini 
1044cb006feSStefano Zampini   /* additional data */
1054cb006feSStefano Zampini   HYPRE_IJVector coords[3];
1064cb006feSStefano Zampini   HYPRE_IJVector constants[3];
1074cb006feSStefano Zampini   HYPRE_IJMatrix G;
108863406b8SStefano Zampini   HYPRE_IJMatrix C;
1094cb006feSStefano Zampini   HYPRE_IJMatrix alpha_Poisson;
1104cb006feSStefano Zampini   HYPRE_IJMatrix beta_Poisson;
1114cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
11216d9e3a6SLisandro Dalcin } PC_HYPRE;
11316d9e3a6SLisandro Dalcin 
114d2128fa2SBarry Smith #undef __FUNCT__
115d2128fa2SBarry Smith #define __FUNCT__ "PCHYPREGetSolver"
116d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
117d2128fa2SBarry Smith {
118d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
119d2128fa2SBarry Smith 
120d2128fa2SBarry Smith   PetscFunctionBegin;
121d2128fa2SBarry Smith   *hsolver = jac->hsolver;
122d2128fa2SBarry Smith   PetscFunctionReturn(0);
123d2128fa2SBarry Smith }
12416d9e3a6SLisandro Dalcin 
125*72827435SBarry Smith /*
126*72827435SBarry Smith     Replaces the address where the HYPRE vector points to its data with the address of
127*72827435SBarry Smith   PETSc's data. Saves the old address so it can be reset when we are finished with it.
128*72827435SBarry Smith   Allows use to get the data into a HYPRE vector without the cost of memcopies
129*72827435SBarry Smith */
130*72827435SBarry Smith #define HYPREReplacePointer(b,newvalue,savedvalue) { \
131*72827435SBarry Smith     hypre_ParVector *par_vector   = (hypre_ParVector*)hypre_IJVectorObject(((hypre_IJVector*)b)); \
132*72827435SBarry Smith     hypre_Vector    *local_vector = hypre_ParVectorLocalVector(par_vector); \
133*72827435SBarry Smith     savedvalue         = local_vector->data; \
134*72827435SBarry Smith     local_vector->data = newvalue;          \
135*72827435SBarry Smith }
136*72827435SBarry Smith 
13716d9e3a6SLisandro Dalcin #undef __FUNCT__
13816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE"
13916d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
14016d9e3a6SLisandro Dalcin {
14116d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
14216d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
14316d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
14416d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
14516d9e3a6SLisandro Dalcin   PetscInt           bs;
14616d9e3a6SLisandro Dalcin 
14716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
14816d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
14902a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
15016d9e3a6SLisandro Dalcin   }
1515f5c5b43SBarry Smith 
1525f5c5b43SBarry Smith   if (pc->setupcalled) {
1535f5c5b43SBarry Smith     /* always destroy the old matrix and create a new memory;
1545f5c5b43SBarry Smith        hope this does not churn the memory too much. The problem
1555f5c5b43SBarry Smith        is I do not know if it is possible to put the matrix back to
1565f5c5b43SBarry Smith        its initial state so that we can directly copy the values
1575f5c5b43SBarry Smith        the second time through. */
158fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
1595f5c5b43SBarry Smith     jac->ij = 0;
16016d9e3a6SLisandro Dalcin   }
1615f5c5b43SBarry Smith 
16216d9e3a6SLisandro Dalcin   if (!jac->ij) { /* create the matrix the first time through */
16316d9e3a6SLisandro Dalcin     ierr = MatHYPRE_IJMatrixCreate(pc->pmat,&jac->ij);CHKERRQ(ierr);
16416d9e3a6SLisandro Dalcin   }
16516d9e3a6SLisandro Dalcin   if (!jac->b) { /* create the vectors the first time through */
16616d9e3a6SLisandro Dalcin     Vec x,b;
1672a7a6963SBarry Smith     ierr = MatCreateVecs(pc->pmat,&x,&b);CHKERRQ(ierr);
16816d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(x,&jac->x);CHKERRQ(ierr);
16916d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(b,&jac->b);CHKERRQ(ierr);
1706bf464f9SBarry Smith     ierr = VecDestroy(&x);CHKERRQ(ierr);
1716bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
17216d9e3a6SLisandro Dalcin   }
1735f5c5b43SBarry Smith 
17416d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
17516d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
1765272c319SBarry Smith     MatNullSpace    mnull;
1775272c319SBarry Smith     PetscBool       has_const;
1785272c319SBarry Smith     PetscInt        nvec,i;
1795272c319SBarry Smith     const Vec       *vecs;
180*72827435SBarry Smith     PetscScalar     *petscvecarray;
1815272c319SBarry Smith 
18216d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1832fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
1845272c319SBarry Smith     ierr = MatGetNearNullSpace(pc->mat, &mnull);CHKERRQ(ierr);
1855272c319SBarry Smith     if (mnull) {
1865272c319SBarry Smith       ierr = MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs);CHKERRQ(ierr);
1875272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull);CHKERRQ(ierr);
188*72827435SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull_hypre_data_array);CHKERRQ(ierr);
1895272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->phmnull);CHKERRQ(ierr);
1905272c319SBarry Smith       for (i=0; i<nvec; i++) {
1915272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(vecs[i],&jac->hmnull[i]);CHKERRQ(ierr);
192*72827435SBarry Smith         ierr = VecGetArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
193*72827435SBarry Smith         HYPREReplacePointer(jac->hmnull[i],petscvecarray,jac->hmnull_hypre_data_array[i]);
194*72827435SBarry Smith         ierr = VecRestoreArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
1955272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[i],(void**)&jac->phmnull[i]));
1965272c319SBarry Smith       }
1975272c319SBarry Smith       if (has_const) {
1985272c319SBarry Smith         ierr = MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL);CHKERRQ(ierr);
1995272c319SBarry Smith         ierr = VecSet(jac->hmnull_constant,1);CHKERRQ(ierr);
2005272c319SBarry Smith         ierr = VecNormalize(jac->hmnull_constant,NULL);
2015272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(jac->hmnull_constant,&jac->hmnull[nvec]);CHKERRQ(ierr);
202*72827435SBarry Smith         ierr = VecGetArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
203*72827435SBarry Smith         HYPREReplacePointer(jac->hmnull[nvec],petscvecarray,jac->hmnull_hypre_data_array[nvec]);
204*72827435SBarry Smith         ierr = VecRestoreArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
2055272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[nvec],(void**)&jac->phmnull[nvec]));
2065272c319SBarry Smith         nvec++;
2075272c319SBarry Smith       }
2085272c319SBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVectors,(jac->hsolver,nvec,jac->phmnull));
2095272c319SBarry Smith       jac->n_hmnull = nvec;
2105272c319SBarry Smith     }
2114cb006feSStefano Zampini   }
212863406b8SStefano Zampini 
2134cb006feSStefano Zampini   /* special case for AMS */
2144cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
2154cb006feSStefano 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()");
2164cb006feSStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
2174cb006feSStefano Zampini   }
218863406b8SStefano Zampini   /* special case for ADS */
219863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
22037096e45SBarry Smith     if (!jac->coords[0]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs coordinate vectors via PCSetCoordinates()");
22137096e45SBarry Smith     else if (!jac->coords[1] || !jac->coords[2]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner has been designed for three dimensional problems! For two dimensional problems, use HYPRE AMS instead");
222863406b8SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
223863406b8SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete curl operator via PCHYPRESetDiscreteGradient");
224863406b8SStefano Zampini   }
22516d9e3a6SLisandro Dalcin   ierr = MatHYPRE_IJMatrixCopy(pc->pmat,jac->ij);CHKERRQ(ierr);
226fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
227fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&bv));
228fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&xv));
229fd3f9acdSBarry Smith   PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr););
23016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
23116d9e3a6SLisandro Dalcin }
23216d9e3a6SLisandro Dalcin 
23316d9e3a6SLisandro Dalcin #undef __FUNCT__
23416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE"
23516d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
23616d9e3a6SLisandro Dalcin {
23716d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
23816d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
23916d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
240d9ca1df4SBarry Smith   PetscScalar        *xv;
241d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
24216d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
243d9ca1df4SBarry Smith   PetscScalar        *sxv;
2444ddd07fcSJed Brown   PetscInt           hierr;
24516d9e3a6SLisandro Dalcin 
24616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
247dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
24816d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
249d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
25016d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
251d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
25216d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
25316d9e3a6SLisandro Dalcin 
254fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
255fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
256fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
257fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
25865e19b50SBarry Smith                                if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
259fd3f9acdSBarry Smith                                if (hierr) hypre__global_error = 0;);
26016d9e3a6SLisandro Dalcin 
261d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)sbv,bv);
26216d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
26316d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
264d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
26516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
26616d9e3a6SLisandro Dalcin }
26716d9e3a6SLisandro Dalcin 
26816d9e3a6SLisandro Dalcin #undef __FUNCT__
26916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE"
27016d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
27116d9e3a6SLisandro Dalcin {
27216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
27316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
274*72827435SBarry Smith   PetscScalar    *petscvecarray;
27516d9e3a6SLisandro Dalcin 
27616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
277fd3f9acdSBarry Smith   if (jac->ij) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
278fd3f9acdSBarry Smith   if (jac->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->b));
279fd3f9acdSBarry Smith   if (jac->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->x));
2804cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
2814cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
2824cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
2834cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
2844cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
2854cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
2864cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
287863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
2884cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
2894cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
2905272c319SBarry Smith   if (jac->n_hmnull) {
2915272c319SBarry Smith     PetscInt i;
2925272c319SBarry Smith 
2935272c319SBarry Smith     for (i=0; i<jac->n_hmnull; i++) {
294*72827435SBarry Smith       HYPREReplacePointer(jac->hmnull[i],jac->hmnull_hypre_data_array[i],petscvecarray);
2955272c319SBarry Smith       PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->hmnull[i]));
2965272c319SBarry Smith     }
2975272c319SBarry Smith     ierr = PetscFree(jac->hmnull);CHKERRQ(ierr);
298*72827435SBarry Smith     ierr = PetscFree(jac->hmnull_hypre_data_array);CHKERRQ(ierr);
2995272c319SBarry Smith     ierr = PetscFree(jac->phmnull);CHKERRQ(ierr);
3005272c319SBarry Smith     ierr = VecDestroy(&jac->hmnull_constant);CHKERRQ(ierr);
3015272c319SBarry Smith   }
302226b0620SJed Brown   if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr););
303503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
30416d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
305c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
30616d9e3a6SLisandro Dalcin 
30716d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
308bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
309bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
3104cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
3114cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
312863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
3134cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
3144cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",NULL);CHKERRQ(ierr);
3154cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",NULL);CHKERRQ(ierr);
31616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
31716d9e3a6SLisandro Dalcin }
31816d9e3a6SLisandro Dalcin 
31916d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
32016d9e3a6SLisandro Dalcin #undef __FUNCT__
32116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut"
3228c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptions *PetscOptionsObject,PC pc)
32316d9e3a6SLisandro Dalcin {
32416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
32516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
326ace3abfcSBarry Smith   PetscBool      flag;
32716d9e3a6SLisandro Dalcin 
32816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
329e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
33016d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
331fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
33216d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
333fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
33416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
335fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
33616d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
33716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
33816d9e3a6SLisandro Dalcin }
33916d9e3a6SLisandro Dalcin 
34016d9e3a6SLisandro Dalcin #undef __FUNCT__
34116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut"
34216d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
34316d9e3a6SLisandro Dalcin {
34416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
34516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
346ace3abfcSBarry Smith   PetscBool      iascii;
34716d9e3a6SLisandro Dalcin 
34816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
349251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
35016d9e3a6SLisandro Dalcin   if (iascii) {
35116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
35216d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
35316d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
35416d9e3a6SLisandro Dalcin     } else {
35516d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr);
35616d9e3a6SLisandro Dalcin     }
35716d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
35857622a8eSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
35916d9e3a6SLisandro Dalcin     } else {
36016d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr);
36116d9e3a6SLisandro Dalcin     }
36216d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
36316d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
36416d9e3a6SLisandro Dalcin     } else {
36516d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default factor row size \n");CHKERRQ(ierr);
36616d9e3a6SLisandro Dalcin     }
36716d9e3a6SLisandro Dalcin   }
36816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
36916d9e3a6SLisandro Dalcin }
37016d9e3a6SLisandro Dalcin 
37116d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
37216d9e3a6SLisandro Dalcin 
37316d9e3a6SLisandro Dalcin #undef __FUNCT__
37416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG"
37516d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
37616d9e3a6SLisandro Dalcin {
37716d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
37816d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
37916d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
380d9ca1df4SBarry Smith   PetscScalar        *xv;
381d9ca1df4SBarry Smith   const PetscScalar  *bv;
38216d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
38316d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
3844ddd07fcSJed Brown   PetscInt           hierr;
38516d9e3a6SLisandro Dalcin 
38616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
387dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
38816d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
389d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
39016d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
391d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
39216d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
39316d9e3a6SLisandro Dalcin 
394fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
395fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
396fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
39716d9e3a6SLisandro Dalcin 
39816d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
39916d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
400e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
40116d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
40216d9e3a6SLisandro Dalcin 
40316d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
40416d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
40516d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
406d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
40716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
40816d9e3a6SLisandro Dalcin }
40916d9e3a6SLisandro Dalcin 
410a669f990SJed Brown /* static array length */
411a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
412a669f990SJed Brown 
41316d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
4140f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
41516d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
41665de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
4176a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]   = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
41865de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
41965de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
42065de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
42165de4495SJed Brown                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */,
42265de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
4230f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
4240f1074feSSatish Balay                                                   "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"};
42516d9e3a6SLisandro Dalcin #undef __FUNCT__
42616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG"
4278c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptions *PetscOptionsObject,PC pc)
42816d9e3a6SLisandro Dalcin {
42916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
43016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
4314ddd07fcSJed Brown   PetscInt       n,indx,level;
432ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
43316d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
43416d9e3a6SLisandro Dalcin 
43516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
436e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
4374336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
43816d9e3a6SLisandro Dalcin   if (flg) {
4394336a9eeSBarry Smith     jac->cycletype = indx+1;
440fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
44116d9e3a6SLisandro Dalcin   }
44216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
44316d9e3a6SLisandro Dalcin   if (flg) {
444ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
445fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
44616d9e3a6SLisandro Dalcin   }
44716d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
44816d9e3a6SLisandro Dalcin   if (flg) {
449ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
450fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
45116d9e3a6SLisandro Dalcin   }
4520f1074feSSatish 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);
45316d9e3a6SLisandro Dalcin   if (flg) {
45457622a8eSBarry 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);
455fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
45616d9e3a6SLisandro Dalcin   }
45716d9e3a6SLisandro Dalcin 
4580f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
45916d9e3a6SLisandro Dalcin   if (flg) {
46057622a8eSBarry 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);
461fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
46216d9e3a6SLisandro Dalcin   }
46316d9e3a6SLisandro Dalcin 
4640f1074feSSatish 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);
4650f1074feSSatish Balay   if (flg) {
46657622a8eSBarry 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);
467fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
4680f1074feSSatish Balay   }
4690f1074feSSatish Balay 
4700f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
4710f1074feSSatish Balay   if (flg) {
47257622a8eSBarry 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);
4730f1074feSSatish Balay 
474fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
4750f1074feSSatish Balay   }
4760f1074feSSatish Balay 
4770f1074feSSatish Balay 
4780f1074feSSatish 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);
4790f1074feSSatish Balay   if (flg) {
48057622a8eSBarry 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);
4810f1074feSSatish Balay 
482fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
4830f1074feSSatish Balay   }
4840f1074feSSatish Balay 
4850f1074feSSatish Balay 
48616d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
48716d9e3a6SLisandro Dalcin   if (flg) {
48857622a8eSBarry 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);
489fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
49016d9e3a6SLisandro Dalcin   }
49116d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
49216d9e3a6SLisandro Dalcin   if (flg) {
49357622a8eSBarry 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);
49457622a8eSBarry 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);
495fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
49616d9e3a6SLisandro Dalcin   }
49716d9e3a6SLisandro Dalcin 
49816d9e3a6SLisandro Dalcin   /* Grid sweeps */
4990f1074feSSatish 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);
50016d9e3a6SLisandro Dalcin   if (flg) {
501fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
50216d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
50316d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
5040f1074feSSatish Balay     jac->gridsweeps[1] = indx;
5050f1074feSSatish Balay     /*defaults coarse to 1 */
5060f1074feSSatish Balay     jac->gridsweeps[2] = 1;
50716d9e3a6SLisandro Dalcin   }
5080f1074feSSatish Balay 
5095272c319SBarry 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);
5105272c319SBarry Smith   if (flg) {
5115272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,jac->nodal_coarsening));
5125272c319SBarry Smith   }
5135272c319SBarry Smith 
514cbc39033SBarry Smith   ierr = PetscOptionsInt("-pc_hypre_boomeramg_vec_interp_variant","Variant of algorithm 1-3","HYPRE_BoomerAMGSetInterpVecVariant",jac->vec_interp_variant, &jac->vec_interp_variant,&flg);CHKERRQ(ierr);
5155272c319SBarry Smith   if (flg) {
5165272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,(jac->hsolver,jac->vec_interp_variant));
5175272c319SBarry Smith   }
5185272c319SBarry Smith 
5190f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
52016d9e3a6SLisandro Dalcin   if (flg) {
521fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
5220f1074feSSatish Balay     jac->gridsweeps[0] = indx;
52316d9e3a6SLisandro Dalcin   }
52416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
52516d9e3a6SLisandro Dalcin   if (flg) {
526fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
5270f1074feSSatish Balay     jac->gridsweeps[1] = indx;
52816d9e3a6SLisandro Dalcin   }
5290f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
53016d9e3a6SLisandro Dalcin   if (flg) {
531fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
5320f1074feSSatish Balay     jac->gridsweeps[2] = indx;
53316d9e3a6SLisandro Dalcin   }
53416d9e3a6SLisandro Dalcin 
5356a251517SEike Mueller   /* Smooth type */
5366a251517SEike Mueller   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);
5376a251517SEike Mueller   if (flg) {
5386a251517SEike Mueller     jac->smoothtype = indx;
5396a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
5408131ecf7SEike Mueller     jac->smoothnumlevels = 25;
5418131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
5428131ecf7SEike Mueller   }
5438131ecf7SEike Mueller 
5448131ecf7SEike Mueller   /* Number of smoothing levels */
5458131ecf7SEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_smooth_num_levels","Number of levels on which more complex smoothers are used","None",25,&indx,&flg);CHKERRQ(ierr);
5468131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
5478131ecf7SEike Mueller     jac->smoothnumlevels = indx;
5488131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
5496a251517SEike Mueller   }
5506a251517SEike Mueller 
5511810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
5521810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
5531810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
5541810e44eSEike Mueller     jac->eu_level = indx;
5551810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
5561810e44eSEike Mueller   }
5571810e44eSEike Mueller 
5581810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
5591810e44eSEike Mueller   double droptolerance;
5601810e44eSEike Mueller   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
5611810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
5621810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
5631810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
5641810e44eSEike Mueller   }
5651810e44eSEike Mueller 
5661810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
5671810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5681810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
5691810e44eSEike Mueller     jac->eu_bj = tmp_truth;
570493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
5711810e44eSEike Mueller   }
5721810e44eSEike Mueller 
57316d9e3a6SLisandro Dalcin   /* Relax type */
574a669f990SJed 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);
57516d9e3a6SLisandro Dalcin   if (flg) {
5760f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
577fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
5780f1074feSSatish Balay     /* by default, coarse type set to 9 */
5790f1074feSSatish Balay     jac->relaxtype[2] = 9;
5800f1074feSSatish Balay 
58116d9e3a6SLisandro Dalcin   }
582a669f990SJed 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);
58316d9e3a6SLisandro Dalcin   if (flg) {
58416d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
585fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
58616d9e3a6SLisandro Dalcin   }
587a669f990SJed 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);
58816d9e3a6SLisandro Dalcin   if (flg) {
5890f1074feSSatish Balay     jac->relaxtype[1] = indx;
590fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
59116d9e3a6SLisandro Dalcin   }
592a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
59316d9e3a6SLisandro Dalcin   if (flg) {
5940f1074feSSatish Balay     jac->relaxtype[2] = indx;
595fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
59616d9e3a6SLisandro Dalcin   }
59716d9e3a6SLisandro Dalcin 
59816d9e3a6SLisandro Dalcin   /* Relaxation Weight */
59916d9e3a6SLisandro 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);
60016d9e3a6SLisandro Dalcin   if (flg) {
601fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
60216d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
60316d9e3a6SLisandro Dalcin   }
60416d9e3a6SLisandro Dalcin 
60516d9e3a6SLisandro Dalcin   n         = 2;
60616d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
60716d9e3a6SLisandro 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);
60816d9e3a6SLisandro Dalcin   if (flg) {
60916d9e3a6SLisandro Dalcin     if (n == 2) {
61016d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
611fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
612ce94432eSBarry 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);
61316d9e3a6SLisandro Dalcin   }
61416d9e3a6SLisandro Dalcin 
61516d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
61616d9e3a6SLisandro 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);
61716d9e3a6SLisandro Dalcin   if (flg) {
618fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
61916d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
62016d9e3a6SLisandro Dalcin   }
62116d9e3a6SLisandro Dalcin 
62216d9e3a6SLisandro Dalcin   n         = 2;
62316d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
62416d9e3a6SLisandro 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);
62516d9e3a6SLisandro Dalcin   if (flg) {
62616d9e3a6SLisandro Dalcin     if (n == 2) {
62716d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
628fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
629ce94432eSBarry 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);
63016d9e3a6SLisandro Dalcin   }
63116d9e3a6SLisandro Dalcin 
63216d9e3a6SLisandro Dalcin   /* the Relax Order */
633acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
63416d9e3a6SLisandro Dalcin 
6358afaa268SBarry Smith   if (flg && tmp_truth) {
63616d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
637fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
63816d9e3a6SLisandro Dalcin   }
639a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
64016d9e3a6SLisandro Dalcin   if (flg) {
64116d9e3a6SLisandro Dalcin     jac->measuretype = indx;
642fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
64316d9e3a6SLisandro Dalcin   }
6440f1074feSSatish Balay   /* update list length 3/07 */
645a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
64616d9e3a6SLisandro Dalcin   if (flg) {
64716d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
648fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
64916d9e3a6SLisandro Dalcin   }
6500f1074feSSatish Balay 
6510f1074feSSatish Balay   /* new 3/07 */
652a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
6530f1074feSSatish Balay   if (flg) {
6540f1074feSSatish Balay     jac->interptype = indx;
655fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
6560f1074feSSatish Balay   }
6570f1074feSSatish Balay 
658b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
65916d9e3a6SLisandro Dalcin   if (flg) {
660b96a4a96SBarry Smith     level = 3;
6610298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
6622fa5cd67SKarl Rupp 
663b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
664fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
6652ae77aedSBarry Smith   }
6662ae77aedSBarry Smith 
667b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
6682ae77aedSBarry Smith   if (flg) {
669b96a4a96SBarry Smith     level = 3;
6700298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
6712fa5cd67SKarl Rupp 
672b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
673fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
67416d9e3a6SLisandro Dalcin   }
6758f87f92bSBarry Smith 
676acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
6778f87f92bSBarry Smith   if (flg && tmp_truth) {
6788f87f92bSBarry Smith     PetscInt tmp_int;
6798f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
6808f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
681fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
682fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
683fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
684fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
6858f87f92bSBarry Smith   }
6868f87f92bSBarry Smith 
68716d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
68816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
68916d9e3a6SLisandro Dalcin }
69016d9e3a6SLisandro Dalcin 
69116d9e3a6SLisandro Dalcin #undef __FUNCT__
69216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG"
693ace3abfcSBarry 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)
69416d9e3a6SLisandro Dalcin {
69516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
69616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
6974ddd07fcSJed Brown   PetscInt       oits;
69816d9e3a6SLisandro Dalcin 
69916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
700dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
701fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
702fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
70316d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
70416d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
70516d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
7068b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
7074d0a8057SBarry Smith   *outits = oits;
7084d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
7094d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
710fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
711fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
71216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
71316d9e3a6SLisandro Dalcin }
71416d9e3a6SLisandro Dalcin 
71516d9e3a6SLisandro Dalcin 
71616d9e3a6SLisandro Dalcin #undef __FUNCT__
71716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG"
71816d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
71916d9e3a6SLisandro Dalcin {
72016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
72116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
722ace3abfcSBarry Smith   PetscBool      iascii;
72316d9e3a6SLisandro Dalcin 
72416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
725251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
72616d9e3a6SLisandro Dalcin   if (iascii) {
72716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
72816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
72916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
73016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
73157622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
73257622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
73357622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
7340f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
7350f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
7360f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
7370f1074feSSatish Balay 
73857622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
73916d9e3a6SLisandro Dalcin 
7400f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
7410f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
7420f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
74316d9e3a6SLisandro Dalcin 
7440f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
7450f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
7460f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
74716d9e3a6SLisandro Dalcin 
74857622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
74957622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
75016d9e3a6SLisandro Dalcin 
75116d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
75216d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr);
75316d9e3a6SLisandro Dalcin     } else {
75416d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr);
75516d9e3a6SLisandro Dalcin     }
7566a251517SEike Mueller     if (jac->smoothtype!=-1) {
7576a251517SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
7588131ecf7SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Smooth num levels    %d\n",jac->smoothnumlevels);CHKERRQ(ierr);
7597e352d70SEike Mueller     } else {
760c2bc9be0SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using more complex smoothers.\n");CHKERRQ(ierr);
7611810e44eSEike Mueller     }
7621810e44eSEike Mueller     if (jac->smoothtype==3) {
7631810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU(k) levels %d\n",jac->eu_level);CHKERRQ(ierr);
7641810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU(k) drop tolerance %g\n",jac->eu_droptolerance);CHKERRQ(ierr);
7651810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU use Block-Jacobi? %d\n",jac->eu_bj);CHKERRQ(ierr);
7666a251517SEike Mueller     }
76716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
76816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
7690f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
7705272c319SBarry Smith     if (jac->nodal_coarsening) {
7715272c319SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
7725272c319SBarry Smith     }
7735272c319SBarry Smith     if (jac->vec_interp_variant) {
7745272c319SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
7758f87f92bSBarry Smith     }
7768f87f92bSBarry Smith     if (jac->nodal_relax) {
7778f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
7788f87f92bSBarry Smith     }
77916d9e3a6SLisandro Dalcin   }
78016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
78116d9e3a6SLisandro Dalcin }
78216d9e3a6SLisandro Dalcin 
78316d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
78416d9e3a6SLisandro Dalcin #undef __FUNCT__
78516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails"
7868c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptions *PetscOptionsObject,PC pc)
78716d9e3a6SLisandro Dalcin {
78816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
78916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
7904ddd07fcSJed Brown   PetscInt       indx;
791ace3abfcSBarry Smith   PetscBool      flag;
79216d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
79316d9e3a6SLisandro Dalcin 
79416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
795e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
79616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
79716d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
7982fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
79916d9e3a6SLisandro Dalcin 
80016d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
8012fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
80216d9e3a6SLisandro Dalcin 
80316d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
8042fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
80516d9e3a6SLisandro Dalcin 
806acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
8072fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
80816d9e3a6SLisandro Dalcin 
809acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
8102fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
81116d9e3a6SLisandro Dalcin 
812a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
81316d9e3a6SLisandro Dalcin   if (flag) {
81416d9e3a6SLisandro Dalcin     jac->symt = indx;
815fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
81616d9e3a6SLisandro Dalcin   }
81716d9e3a6SLisandro Dalcin 
81816d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
81916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
82016d9e3a6SLisandro Dalcin }
82116d9e3a6SLisandro Dalcin 
82216d9e3a6SLisandro Dalcin #undef __FUNCT__
82316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails"
82416d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
82516d9e3a6SLisandro Dalcin {
82616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
82716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
828ace3abfcSBarry Smith   PetscBool      iascii;
82916d9e3a6SLisandro Dalcin   const char     *symt = 0;;
83016d9e3a6SLisandro Dalcin 
83116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
832251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
83316d9e3a6SLisandro Dalcin   if (iascii) {
83416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
83516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
83657622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
83757622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: filter %g\n",(double)jac->filter);CHKERRQ(ierr);
83857622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
839ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
840ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
8412fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
8422fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
8432fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
844ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
84516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr);
84616d9e3a6SLisandro Dalcin   }
84716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
84816d9e3a6SLisandro Dalcin }
8494cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
8504cb006feSStefano Zampini #undef __FUNCT__
8514cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS"
8529fa463a7SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptions *PetscOptionsObject,PC pc)
8534cb006feSStefano Zampini {
8544cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
8554cb006feSStefano Zampini   PetscErrorCode ierr;
8564cb006feSStefano Zampini   PetscInt       n;
8574cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
8584cb006feSStefano Zampini 
8594cb006feSStefano Zampini   PetscFunctionBegin;
8609fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
861863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
862863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
863863406b8SStefano 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);
864863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
8654cb006feSStefano 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);
8664cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
867863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
868863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
869863406b8SStefano 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);
870863406b8SStefano 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);
871863406b8SStefano 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);
872863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
8734cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
874863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
875863406b8SStefano Zampini                                                                       jac->as_relax_times,
876863406b8SStefano Zampini                                                                       jac->as_relax_weight,
877863406b8SStefano Zampini                                                                       jac->as_omega));
8784cb006feSStefano Zampini   }
879863406b8SStefano 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);
8804cb006feSStefano Zampini   n = 5;
881863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
8824cb006feSStefano Zampini   if (flag || flag2) {
883863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
884863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
885863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
886863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
887863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
888863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
8894cb006feSStefano Zampini   }
890863406b8SStefano 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);
8914cb006feSStefano Zampini   n = 5;
892863406b8SStefano 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);
8934cb006feSStefano Zampini   if (flag || flag2) {
894863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
895863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
896863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
897863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
898863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
899863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
9004cb006feSStefano Zampini   }
9014cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
9024cb006feSStefano Zampini   PetscFunctionReturn(0);
9034cb006feSStefano Zampini }
9044cb006feSStefano Zampini 
9054cb006feSStefano Zampini #undef __FUNCT__
9064cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS"
9074cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
9084cb006feSStefano Zampini {
9094cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
9104cb006feSStefano Zampini   PetscErrorCode ierr;
9114cb006feSStefano Zampini   PetscBool      iascii;
9124cb006feSStefano Zampini 
9134cb006feSStefano Zampini   PetscFunctionBegin;
9144cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
9154cb006feSStefano Zampini   if (iascii) {
9164cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
917863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
9184cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
919863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
920863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
921863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
922863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
923863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
9244cb006feSStefano Zampini     if (jac->alpha_Poisson) {
9254cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
9264cb006feSStefano Zampini     } else {
9274cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr);
9284cb006feSStefano Zampini     }
929863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
930863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
931863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
932863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
933863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
934863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
9354cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
9364cb006feSStefano Zampini       if (jac->beta_Poisson) {
9374cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
9384cb006feSStefano Zampini       } else {
9394cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr);
9404cb006feSStefano Zampini       }
941863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
942863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
943863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
944863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
945863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
946863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
9474cb006feSStefano Zampini     }
9484cb006feSStefano Zampini   }
9494cb006feSStefano Zampini   PetscFunctionReturn(0);
9504cb006feSStefano Zampini }
9514cb006feSStefano Zampini 
9524cb006feSStefano Zampini #undef __FUNCT__
953863406b8SStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_ADS"
954863406b8SStefano Zampini static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptions *PetscOptionsObject,PC pc)
955863406b8SStefano Zampini {
956863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
957863406b8SStefano Zampini   PetscErrorCode ierr;
958863406b8SStefano Zampini   PetscInt       n;
959863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
960863406b8SStefano Zampini 
961863406b8SStefano Zampini   PetscFunctionBegin;
962863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
963863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
964863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
965863406b8SStefano 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);
966863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
967863406b8SStefano 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);
968863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
969863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
970863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
971863406b8SStefano 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);
972863406b8SStefano 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);
973863406b8SStefano 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);
974863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
975863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
976863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
977863406b8SStefano Zampini                                                                       jac->as_relax_times,
978863406b8SStefano Zampini                                                                       jac->as_relax_weight,
979863406b8SStefano Zampini                                                                       jac->as_omega));
980863406b8SStefano Zampini   }
981863406b8SStefano 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);
982863406b8SStefano Zampini   n = 5;
983863406b8SStefano 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);
984863406b8SStefano 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);
985863406b8SStefano Zampini   if (flag || flag2 || flag3) {
986863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
987863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
988863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
989863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
990863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
991863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
992863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
993863406b8SStefano Zampini   }
994863406b8SStefano 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);
995863406b8SStefano Zampini   n = 5;
996863406b8SStefano 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);
997863406b8SStefano Zampini   if (flag || flag2) {
998863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
999863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1000863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1001863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1002863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1003863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1004863406b8SStefano Zampini   }
1005863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
1006863406b8SStefano Zampini   PetscFunctionReturn(0);
1007863406b8SStefano Zampini }
1008863406b8SStefano Zampini 
1009863406b8SStefano Zampini #undef __FUNCT__
1010863406b8SStefano Zampini #define __FUNCT__ "PCView_HYPRE_ADS"
1011863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1012863406b8SStefano Zampini {
1013863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1014863406b8SStefano Zampini   PetscErrorCode ierr;
1015863406b8SStefano Zampini   PetscBool      iascii;
1016863406b8SStefano Zampini 
1017863406b8SStefano Zampini   PetscFunctionBegin;
1018863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1019863406b8SStefano Zampini   if (iascii) {
1020863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
1021863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1022863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
1023863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1024863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1025863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1026863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1027863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
1028863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: AMS solver\n");CHKERRQ(ierr);
1029863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1030863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1031863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1032863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1033863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1034863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1035863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
1036863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: vector Poisson solver\n");CHKERRQ(ierr);
1037863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1038863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1039863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1040863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1041863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1042863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
1043863406b8SStefano Zampini   }
1044863406b8SStefano Zampini   PetscFunctionReturn(0);
1045863406b8SStefano Zampini }
1046863406b8SStefano Zampini 
1047863406b8SStefano Zampini #undef __FUNCT__
1048863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE"
1049863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
10504cb006feSStefano Zampini {
10514cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
10524cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_G;
10534cb006feSStefano Zampini   PetscErrorCode     ierr;
10544cb006feSStefano Zampini 
10554cb006feSStefano Zampini   PetscFunctionBegin;
10564cb006feSStefano Zampini   /* throw away any discrete gradient if already set */
10574cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
10584cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(G,&jac->G);CHKERRQ(ierr);
10594cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(G,jac->G);CHKERRQ(ierr);
10604cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->G,(void**)(&parcsr_G)));
1061863406b8SStefano Zampini   PetscStackCall("Hypre set gradient",ierr = (*jac->setdgrad)(jac->hsolver,parcsr_G);CHKERRQ(ierr););
10624cb006feSStefano Zampini   PetscFunctionReturn(0);
10634cb006feSStefano Zampini }
10644cb006feSStefano Zampini 
10654cb006feSStefano Zampini #undef __FUNCT__
10664cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient"
10674cb006feSStefano Zampini /*@
10684cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
10694cb006feSStefano Zampini 
10704cb006feSStefano Zampini    Collective on PC
10714cb006feSStefano Zampini 
10724cb006feSStefano Zampini    Input Parameters:
10734cb006feSStefano Zampini +  pc - the preconditioning context
10744cb006feSStefano Zampini -  G - the discrete gradient
10754cb006feSStefano Zampini 
10764cb006feSStefano Zampini    Level: intermediate
10774cb006feSStefano Zampini 
10784cb006feSStefano 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
1079863406b8SStefano 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
10804cb006feSStefano Zampini 
10814cb006feSStefano Zampini .seealso:
10824cb006feSStefano Zampini @*/
10834cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
10844cb006feSStefano Zampini {
10854cb006feSStefano Zampini   PetscErrorCode ierr;
10864cb006feSStefano Zampini 
10874cb006feSStefano Zampini   PetscFunctionBegin;
10884cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
10894cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
10904cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
10914cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
10924cb006feSStefano Zampini   PetscFunctionReturn(0);
10934cb006feSStefano Zampini }
10944cb006feSStefano Zampini 
10954cb006feSStefano Zampini #undef __FUNCT__
1096863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl_HYPRE"
1097863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1098863406b8SStefano Zampini {
1099863406b8SStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
1100863406b8SStefano Zampini   HYPRE_ParCSRMatrix parcsr_C;
1101863406b8SStefano Zampini   PetscErrorCode     ierr;
1102863406b8SStefano Zampini 
1103863406b8SStefano Zampini   PetscFunctionBegin;
1104863406b8SStefano Zampini   /* throw away any discrete curl if already set */
1105863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
1106863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(C,&jac->C);CHKERRQ(ierr);
1107863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(C,jac->C);CHKERRQ(ierr);
1108863406b8SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->C,(void**)(&parcsr_C)));
1109863406b8SStefano Zampini   PetscStackCall("Hypre set curl",ierr = (*jac->setdcurl)(jac->hsolver,parcsr_C);CHKERRQ(ierr););
1110863406b8SStefano Zampini   PetscFunctionReturn(0);
1111863406b8SStefano Zampini }
1112863406b8SStefano Zampini 
1113863406b8SStefano Zampini #undef __FUNCT__
1114863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl"
1115863406b8SStefano Zampini /*@
1116863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1117863406b8SStefano Zampini 
1118863406b8SStefano Zampini    Collective on PC
1119863406b8SStefano Zampini 
1120863406b8SStefano Zampini    Input Parameters:
1121863406b8SStefano Zampini +  pc - the preconditioning context
1122863406b8SStefano Zampini -  C - the discrete curl
1123863406b8SStefano Zampini 
1124863406b8SStefano Zampini    Level: intermediate
1125863406b8SStefano Zampini 
1126863406b8SStefano 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
1127863406b8SStefano 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
1128863406b8SStefano Zampini 
1129863406b8SStefano Zampini .seealso:
1130863406b8SStefano Zampini @*/
1131863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1132863406b8SStefano Zampini {
1133863406b8SStefano Zampini   PetscErrorCode ierr;
1134863406b8SStefano Zampini 
1135863406b8SStefano Zampini   PetscFunctionBegin;
1136863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1137863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1138863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1139863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1140863406b8SStefano Zampini   PetscFunctionReturn(0);
1141863406b8SStefano Zampini }
1142863406b8SStefano Zampini 
1143863406b8SStefano Zampini #undef __FUNCT__
11444cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS"
11454cb006feSStefano Zampini static PetscErrorCode PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
11464cb006feSStefano Zampini {
11474cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11484cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_alpha_Poisson;
11494cb006feSStefano Zampini   PetscErrorCode     ierr;
11504cb006feSStefano Zampini 
11514cb006feSStefano Zampini   PetscFunctionBegin;
11524cb006feSStefano Zampini   /* throw away any matrix if already set */
11534cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
11544cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->alpha_Poisson);CHKERRQ(ierr);
11554cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->alpha_Poisson);CHKERRQ(ierr);
11564cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->alpha_Poisson,(void**)(&parcsr_alpha_Poisson)));
11574cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr_alpha_Poisson));
11584cb006feSStefano Zampini   PetscFunctionReturn(0);
11594cb006feSStefano Zampini }
11604cb006feSStefano Zampini 
11614cb006feSStefano Zampini #undef __FUNCT__
11624cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix"
11634cb006feSStefano Zampini /*@
11644cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
11654cb006feSStefano Zampini 
11664cb006feSStefano Zampini    Collective on PC
11674cb006feSStefano Zampini 
11684cb006feSStefano Zampini    Input Parameters:
11694cb006feSStefano Zampini +  pc - the preconditioning context
11704cb006feSStefano Zampini -  A - the matrix
11714cb006feSStefano Zampini 
11724cb006feSStefano Zampini    Level: intermediate
11734cb006feSStefano Zampini 
11744cb006feSStefano Zampini    Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
11754cb006feSStefano Zampini 
11764cb006feSStefano Zampini .seealso:
11774cb006feSStefano Zampini @*/
11784cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
11794cb006feSStefano Zampini {
11804cb006feSStefano Zampini   PetscErrorCode ierr;
11814cb006feSStefano Zampini 
11824cb006feSStefano Zampini   PetscFunctionBegin;
11834cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11844cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
11854cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
11864cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetAlphaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
11874cb006feSStefano Zampini   PetscFunctionReturn(0);
11884cb006feSStefano Zampini }
11894cb006feSStefano Zampini 
11904cb006feSStefano Zampini #undef __FUNCT__
11914cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix_HYPRE_AMS"
11924cb006feSStefano Zampini static PetscErrorCode PCHYPRESetBetaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
11934cb006feSStefano Zampini {
11944cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11954cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_beta_Poisson;
11964cb006feSStefano Zampini   PetscErrorCode     ierr;
11974cb006feSStefano Zampini 
11984cb006feSStefano Zampini   PetscFunctionBegin;
11994cb006feSStefano Zampini   if (!A) {
1200484796dcSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
12014cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_TRUE;
12024cb006feSStefano Zampini     PetscFunctionReturn(0);
12034cb006feSStefano Zampini   }
12044cb006feSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
12054cb006feSStefano Zampini   /* throw away any matrix if already set */
12064cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
12074cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->beta_Poisson);CHKERRQ(ierr);
12084cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->beta_Poisson);CHKERRQ(ierr);
12094cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->beta_Poisson,(void**)(&parcsr_beta_Poisson)));
12104cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr_beta_Poisson));
12114cb006feSStefano Zampini   PetscFunctionReturn(0);
12124cb006feSStefano Zampini }
12134cb006feSStefano Zampini 
12144cb006feSStefano Zampini #undef __FUNCT__
12154cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix"
12164cb006feSStefano Zampini /*@
12174cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
12184cb006feSStefano Zampini 
12194cb006feSStefano Zampini    Collective on PC
12204cb006feSStefano Zampini 
12214cb006feSStefano Zampini    Input Parameters:
12224cb006feSStefano Zampini +  pc - the preconditioning context
12234cb006feSStefano Zampini -  A - the matrix
12244cb006feSStefano Zampini 
12254cb006feSStefano Zampini    Level: intermediate
12264cb006feSStefano Zampini 
12274cb006feSStefano Zampini    Notes: A should be obtained by discretizing the Poisson problem with linear finite elements.
12284cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
12294cb006feSStefano Zampini 
12304cb006feSStefano Zampini .seealso:
12314cb006feSStefano Zampini @*/
12324cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
12334cb006feSStefano Zampini {
12344cb006feSStefano Zampini   PetscErrorCode ierr;
12354cb006feSStefano Zampini 
12364cb006feSStefano Zampini   PetscFunctionBegin;
12374cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12384cb006feSStefano Zampini   if (A) {
12394cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
12404cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
12414cb006feSStefano Zampini   }
12424cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetBetaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
12434cb006feSStefano Zampini   PetscFunctionReturn(0);
12444cb006feSStefano Zampini }
12454cb006feSStefano Zampini 
12464cb006feSStefano Zampini #undef __FUNCT__
12474cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE_AMS"
12484cb006feSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE_AMS(PC pc,Vec ozz, Vec zoz, Vec zzo)
12494cb006feSStefano Zampini {
12504cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
12514cb006feSStefano Zampini   HYPRE_ParVector    par_ozz,par_zoz,par_zzo;
125212ddd1b6SStefano Zampini   PetscInt           dim;
12534cb006feSStefano Zampini   PetscErrorCode     ierr;
12544cb006feSStefano Zampini 
12554cb006feSStefano Zampini   PetscFunctionBegin;
12564cb006feSStefano Zampini   /* throw away any vector if already set */
12574cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
12584cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
12594cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
12604cb006feSStefano Zampini   jac->constants[0] = NULL;
12614cb006feSStefano Zampini   jac->constants[1] = NULL;
12624cb006feSStefano Zampini   jac->constants[2] = NULL;
12634cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
12644cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
12654cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&par_ozz)));
12664cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
12674cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
12684cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&par_zoz)));
126912ddd1b6SStefano Zampini   dim = 2;
12704cb006feSStefano Zampini   if (zzo) {
12714cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
12724cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
12734cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&par_zzo)));
127412ddd1b6SStefano Zampini     dim++;
12754cb006feSStefano Zampini   }
12764cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,par_ozz,par_zoz,par_zzo));
127712ddd1b6SStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim));
12784cb006feSStefano Zampini   PetscFunctionReturn(0);
12794cb006feSStefano Zampini }
12804cb006feSStefano Zampini 
12814cb006feSStefano Zampini #undef __FUNCT__
12824cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors"
12834cb006feSStefano Zampini /*@
12844cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
12854cb006feSStefano Zampini 
12864cb006feSStefano Zampini    Collective on PC
12874cb006feSStefano Zampini 
12884cb006feSStefano Zampini    Input Parameters:
12894cb006feSStefano Zampini +  pc - the preconditioning context
12904cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
12914cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
12924cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
12934cb006feSStefano Zampini 
12944cb006feSStefano Zampini    Level: intermediate
12954cb006feSStefano Zampini 
12964cb006feSStefano Zampini    Notes:
12974cb006feSStefano Zampini 
12984cb006feSStefano Zampini .seealso:
12994cb006feSStefano Zampini @*/
13004cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
13014cb006feSStefano Zampini {
13024cb006feSStefano Zampini   PetscErrorCode ierr;
13034cb006feSStefano Zampini 
13044cb006feSStefano Zampini   PetscFunctionBegin;
13054cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
13064cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
13074cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
13084cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
13094cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
13104cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
13114cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
13124cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
13134cb006feSStefano Zampini   PetscFunctionReturn(0);
13144cb006feSStefano Zampini }
13154cb006feSStefano Zampini 
13164cb006feSStefano Zampini #undef __FUNCT__
1317863406b8SStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE"
1318863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
13194cb006feSStefano Zampini {
13204cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
13214cb006feSStefano Zampini   Vec             tv;
13224cb006feSStefano Zampini   HYPRE_ParVector par_coords[3];
13234cb006feSStefano Zampini   PetscInt        i;
13244cb006feSStefano Zampini   PetscErrorCode  ierr;
13254cb006feSStefano Zampini 
13264cb006feSStefano Zampini   PetscFunctionBegin;
13274cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
13284cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
13294cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
13304cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
13314cb006feSStefano Zampini   /* set problem's dimension */
1332863406b8SStefano Zampini   if (jac->setdim) {
1333863406b8SStefano Zampini     PetscStackCall("Hypre set dim",ierr = (*jac->setdim)(jac->hsolver,dim);CHKERRQ(ierr););
1334863406b8SStefano Zampini   }
13354cb006feSStefano Zampini   /* compute IJ vector for coordinates */
13364cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
13374cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
13384cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
13394cb006feSStefano Zampini   for (i=0;i<dim;i++) {
13404cb006feSStefano Zampini     PetscScalar *array;
13414cb006feSStefano Zampini     PetscInt    j;
13424cb006feSStefano Zampini 
13434cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
13444cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
13454cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
13464cb006feSStefano Zampini       array[j] = coords[j*dim+i];
13474cb006feSStefano Zampini     }
13484cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
13494cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
13504cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
13514cb006feSStefano Zampini   }
13524cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
13534cb006feSStefano Zampini   /* pass parCSR vectors to AMS solver */
13544cb006feSStefano Zampini   par_coords[0] = NULL;
13554cb006feSStefano Zampini   par_coords[1] = NULL;
13564cb006feSStefano Zampini   par_coords[2] = NULL;
13574cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&par_coords[0])));
13584cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&par_coords[1])));
13594cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&par_coords[2])));
1360863406b8SStefano Zampini   PetscStackCall("Hypre set coords",ierr = (*jac->setcoord)(jac->hsolver,par_coords[0],par_coords[1],par_coords[2]);CHKERRQ(ierr););
13614cb006feSStefano Zampini   PetscFunctionReturn(0);
13624cb006feSStefano Zampini }
13634cb006feSStefano Zampini 
136416d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
136516d9e3a6SLisandro Dalcin 
136616d9e3a6SLisandro Dalcin #undef __FUNCT__
136716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
1368f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
136916d9e3a6SLisandro Dalcin {
137016d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
137116d9e3a6SLisandro Dalcin 
137216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
137316d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
137416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
137516d9e3a6SLisandro Dalcin }
137616d9e3a6SLisandro Dalcin 
137716d9e3a6SLisandro Dalcin #undef __FUNCT__
137816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
1379f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
138016d9e3a6SLisandro Dalcin {
138116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
138216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1383ace3abfcSBarry Smith   PetscBool      flag;
138416d9e3a6SLisandro Dalcin 
138516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
138616d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
138716d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1388ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
138916d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
139016d9e3a6SLisandro Dalcin   } else {
139116d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
139216d9e3a6SLisandro Dalcin   }
139316d9e3a6SLisandro Dalcin 
139416d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
139516d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
139616d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
139716d9e3a6SLisandro Dalcin 
139816d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
139916d9e3a6SLisandro Dalcin   if (flag) {
1400fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
140116d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
140216d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
140316d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
140416d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
140516d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
140616d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
140716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
140816d9e3a6SLisandro Dalcin   }
140916d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
141016d9e3a6SLisandro Dalcin   if (flag) {
1411fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
141216d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
141316d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
141416d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
141516d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
141616d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
141716d9e3a6SLisandro Dalcin     /* initialize */
141816d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
141916d9e3a6SLisandro Dalcin     jac->threshhold = .1;
142016d9e3a6SLisandro Dalcin     jac->filter     = .1;
142116d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
14222fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
14232fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
14242fa5cd67SKarl Rupp 
142516d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
142616d9e3a6SLisandro Dalcin     jac->symt = 0;
1427fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1428fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1429fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1430fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1431fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1432fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
143316d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
143416d9e3a6SLisandro Dalcin   }
143516d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
143616d9e3a6SLisandro Dalcin   if (flag) {
143716d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
143816d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
143916d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
144016d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
144116d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
144216d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
144316d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
144416d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
144516d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
144616d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
144716d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
144816d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
144916d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
14508f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
145116d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
145216d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
145316d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
145416d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
145516d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
14560f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
14576a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1458b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
14591810e44eSEike Mueller     jac->eu_level         = 0;
14601810e44eSEike Mueller     jac->eu_droptolerance = 0;
14611810e44eSEike Mueller     jac->eu_bj            = 0;
14628f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
14630f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
146416d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
146516d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
146616d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
14670f1074feSSatish Balay     jac->interptype       = 0;
14680f1074feSSatish Balay     jac->agg_nl           = 0;
14690f1074feSSatish Balay     jac->pmax             = 0;
14700f1074feSSatish Balay     jac->truncfactor      = 0.0;
14710f1074feSSatish Balay     jac->agg_num_paths    = 1;
14728f87f92bSBarry Smith 
14738f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
14748f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
14758f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1476fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1477fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1478fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1479fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1480fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1481fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1482fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1483fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1484fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1485fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1486fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1487fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1488fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1489fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1490fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1491fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
149216d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
149316d9e3a6SLisandro Dalcin   }
14944cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
14954cb006feSStefano Zampini   if (flag) {
14964cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
14974cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
14984cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
14994cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
15004cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
15014cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
1502863406b8SStefano Zampini     jac->setdgrad            = HYPRE_AMSSetDiscreteGradient;
1503863406b8SStefano Zampini     jac->setcoord            = HYPRE_AMSSetCoordinateVectors;
1504863406b8SStefano Zampini     jac->setdim              = HYPRE_AMSSetDimension;
15054cb006feSStefano Zampini     jac->coords[0]           = NULL;
15064cb006feSStefano Zampini     jac->coords[1]           = NULL;
15074cb006feSStefano Zampini     jac->coords[2]           = NULL;
15084cb006feSStefano Zampini     jac->G                   = NULL;
15094cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1510863406b8SStefano Zampini     jac->as_print           = 0;
1511863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1512863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
15134cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
15144cb006feSStefano Zampini     /* Smoothing options */
1515863406b8SStefano Zampini     jac->as_relax_type      = 2;
1516863406b8SStefano Zampini     jac->as_relax_times     = 1;
1517863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1518863406b8SStefano Zampini     jac->as_omega           = 1.0;
15194cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1520863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1521863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
15220bdd8552SBarry Smith     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;
15264cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
15274cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_FALSE;
1528863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1529863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
15300bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1531863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1532863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1533863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1534863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1535863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
15364cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1537863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1538863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1539863406b8SStefano Zampini                                                                       jac->as_relax_times,
1540863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1541863406b8SStefano Zampini                                                                       jac->as_omega));
1542863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,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_AMSSetBetaAMGOptions,(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);
15564cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE_AMS);CHKERRQ(ierr);
15574cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
15584cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",PCHYPRESetBetaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
15594cb006feSStefano Zampini     PetscFunctionReturn(0);
15604cb006feSStefano Zampini   }
1561863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1562863406b8SStefano Zampini   if (flag) {
1563863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1564863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1565863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1566863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1567863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1568863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1569863406b8SStefano Zampini     jac->setdgrad            = HYPRE_ADSSetDiscreteGradient;
1570863406b8SStefano Zampini     jac->setdcurl            = HYPRE_ADSSetDiscreteCurl;
1571863406b8SStefano Zampini     jac->setcoord            = HYPRE_ADSSetCoordinateVectors;
1572863406b8SStefano Zampini     jac->coords[0]           = NULL;
1573863406b8SStefano Zampini     jac->coords[1]           = NULL;
1574863406b8SStefano Zampini     jac->coords[2]           = NULL;
1575863406b8SStefano Zampini     jac->G                   = NULL;
1576863406b8SStefano Zampini     jac->C                   = NULL;
1577863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1578863406b8SStefano Zampini     jac->as_print           = 0;
1579863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1580863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1581863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1582863406b8SStefano Zampini     /* Smoothing options */
1583863406b8SStefano Zampini     jac->as_relax_type      = 2;
1584863406b8SStefano Zampini     jac->as_relax_times     = 1;
1585863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1586863406b8SStefano Zampini     jac->as_omega           = 1.0;
1587863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1588863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1589863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1590863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1591863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1592863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1593863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1594863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1595863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1596863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1597863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1598863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1599863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1600863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1601863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1602863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1603863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1604863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1605863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1606863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1607863406b8SStefano Zampini                                                                       jac->as_relax_times,
1608863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1609863406b8SStefano Zampini                                                                       jac->as_omega));
1610863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1611863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1612863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1613863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1614863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1615863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1616863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1617863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1618863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1619863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1620863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1621863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1622863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1623863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1624863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
1625863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
1626863406b8SStefano Zampini     PetscFunctionReturn(0);
1627863406b8SStefano Zampini   }
1628503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
16292fa5cd67SKarl Rupp 
16300298fd71SBarry Smith   jac->hypre_type = NULL;
163133263987SBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, boomeramg, ams",name);
163216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
163316d9e3a6SLisandro Dalcin }
163416d9e3a6SLisandro Dalcin 
163516d9e3a6SLisandro Dalcin /*
163616d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
163716d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
163816d9e3a6SLisandro Dalcin */
163916d9e3a6SLisandro Dalcin #undef __FUNCT__
164016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
16418c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptions *PetscOptionsObject,PC pc)
164216d9e3a6SLisandro Dalcin {
164316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
16444ddd07fcSJed Brown   PetscInt       indx;
1645863406b8SStefano Zampini   const char     *type[] = {"pilut","parasails","boomeramg","ams","ads"};
1646ace3abfcSBarry Smith   PetscBool      flg;
164716d9e3a6SLisandro Dalcin 
164816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16499fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
16509c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
165116d9e3a6SLisandro Dalcin   if (flg) {
165216d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
165302a17cd4SBarry Smith   } else {
165402a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
165516d9e3a6SLisandro Dalcin   }
165616d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
16573931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
165816d9e3a6SLisandro Dalcin   }
165916d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
166016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
166116d9e3a6SLisandro Dalcin }
166216d9e3a6SLisandro Dalcin 
166316d9e3a6SLisandro Dalcin #undef __FUNCT__
166416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
166516d9e3a6SLisandro Dalcin /*@C
166616d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
166716d9e3a6SLisandro Dalcin 
166816d9e3a6SLisandro Dalcin    Input Parameters:
166916d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1670863406b8SStefano Zampini -     name - either  pilut, parasails, boomeramg, ams, ads
167116d9e3a6SLisandro Dalcin 
167216d9e3a6SLisandro Dalcin    Options Database Keys:
1673863406b8SStefano Zampini    -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
167416d9e3a6SLisandro Dalcin 
167516d9e3a6SLisandro Dalcin    Level: intermediate
167616d9e3a6SLisandro Dalcin 
167716d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
167816d9e3a6SLisandro Dalcin            PCHYPRE
167916d9e3a6SLisandro Dalcin 
168016d9e3a6SLisandro Dalcin @*/
16817087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
168216d9e3a6SLisandro Dalcin {
16834ac538c5SBarry Smith   PetscErrorCode ierr;
168416d9e3a6SLisandro Dalcin 
168516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16860700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
168716d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
16884ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
168916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
169016d9e3a6SLisandro Dalcin }
169116d9e3a6SLisandro Dalcin 
169216d9e3a6SLisandro Dalcin #undef __FUNCT__
169316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
169416d9e3a6SLisandro Dalcin /*@C
169516d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
169616d9e3a6SLisandro Dalcin 
169716d9e3a6SLisandro Dalcin    Input Parameter:
169816d9e3a6SLisandro Dalcin .     pc - the preconditioner context
169916d9e3a6SLisandro Dalcin 
170016d9e3a6SLisandro Dalcin    Output Parameter:
1701863406b8SStefano Zampini .     name - either  pilut, parasails, boomeramg, ams, ads
170216d9e3a6SLisandro Dalcin 
170316d9e3a6SLisandro Dalcin    Level: intermediate
170416d9e3a6SLisandro Dalcin 
170516d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
170616d9e3a6SLisandro Dalcin            PCHYPRE
170716d9e3a6SLisandro Dalcin 
170816d9e3a6SLisandro Dalcin @*/
17097087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
171016d9e3a6SLisandro Dalcin {
17114ac538c5SBarry Smith   PetscErrorCode ierr;
171216d9e3a6SLisandro Dalcin 
171316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
17140700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
171516d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
17164ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
171716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
171816d9e3a6SLisandro Dalcin }
171916d9e3a6SLisandro Dalcin 
172016d9e3a6SLisandro Dalcin /*MC
172116d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
172216d9e3a6SLisandro Dalcin 
172316d9e3a6SLisandro Dalcin    Options Database Keys:
1724863406b8SStefano Zampini +   -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
172516d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
172616d9e3a6SLisandro Dalcin           preconditioner
172716d9e3a6SLisandro Dalcin 
172816d9e3a6SLisandro Dalcin    Level: intermediate
172916d9e3a6SLisandro Dalcin 
173016d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
173116d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
173216d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
173316d9e3a6SLisandro Dalcin 
173416d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
17350f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
17360f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
17370f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
17388f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
17390f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
17400f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
174116d9e3a6SLisandro Dalcin 
17420f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
17430f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
17440f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
174516d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
174616d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
174716d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
174816d9e3a6SLisandro Dalcin 
174916d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
175016d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
175116d9e3a6SLisandro Dalcin 
17525272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
17535272c319SBarry Smith           the two options:
17545272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
1755cbc39033SBarry Smith -   -pc_hypre_boomeramg_vec_interp_variant <v> where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
17565272c319SBarry Smith 
17575272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
17585272c319SBarry Smith 
17599e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
17609e5bc791SBarry Smith 
176116d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
17629e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
176316d9e3a6SLisandro Dalcin 
176416d9e3a6SLisandro Dalcin M*/
176516d9e3a6SLisandro Dalcin 
176616d9e3a6SLisandro Dalcin #undef __FUNCT__
176716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
17688cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
176916d9e3a6SLisandro Dalcin {
177016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
177116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
177216d9e3a6SLisandro Dalcin 
177316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1774b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
17752fa5cd67SKarl Rupp 
177616d9e3a6SLisandro Dalcin   pc->data                = jac;
177716d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
177816d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
177916d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
178016d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
178116d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
17820298fd71SBarry Smith   jac->hypre_type         = NULL;
17834cb006feSStefano Zampini   jac->coords[0]          = NULL;
17844cb006feSStefano Zampini   jac->coords[1]          = NULL;
17854cb006feSStefano Zampini   jac->coords[2]          = NULL;
17864cb006feSStefano Zampini   jac->constants[0]       = NULL;
17874cb006feSStefano Zampini   jac->constants[1]       = NULL;
17884cb006feSStefano Zampini   jac->constants[2]       = NULL;
1789863406b8SStefano Zampini   jac->G                  = NULL;
1790863406b8SStefano Zampini   jac->C                  = NULL;
1791863406b8SStefano Zampini   jac->alpha_Poisson      = NULL;
1792863406b8SStefano Zampini   jac->beta_Poisson       = NULL;
1793fd444223SStefano Zampini   jac->setdim             = NULL;
17945272c319SBarry Smith   jac->hmnull             = NULL;
17955272c319SBarry Smith   jac->n_hmnull           = 0;
179616d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1797ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1798bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1799bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
180016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
180116d9e3a6SLisandro Dalcin }
1802ebc551c0SBarry Smith 
1803f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1804f91d8e95SBarry Smith 
1805b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1806af0996ceSBarry Smith #include <petsc/private/matimpl.h>
1807ebc551c0SBarry Smith 
1808ebc551c0SBarry Smith typedef struct {
180968326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1810f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
18119e5bc791SBarry Smith 
18129e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
18134ddd07fcSJed Brown   PetscInt its;
18149e5bc791SBarry Smith   double   tol;
18154ddd07fcSJed Brown   PetscInt relax_type;
18164ddd07fcSJed Brown   PetscInt rap_type;
18174ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
18184ddd07fcSJed Brown   PetscInt max_levels;
1819ebc551c0SBarry Smith } PC_PFMG;
1820ebc551c0SBarry Smith 
1821ebc551c0SBarry Smith #undef __FUNCT__
1822ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1823ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1824ebc551c0SBarry Smith {
1825ebc551c0SBarry Smith   PetscErrorCode ierr;
1826f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1827ebc551c0SBarry Smith 
1828ebc551c0SBarry Smith   PetscFunctionBegin;
18292fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1830f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1831c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1832ebc551c0SBarry Smith   PetscFunctionReturn(0);
1833ebc551c0SBarry Smith }
1834ebc551c0SBarry Smith 
18359e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
18369e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
18379e5bc791SBarry Smith 
1838ebc551c0SBarry Smith #undef __FUNCT__
1839ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1840ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1841ebc551c0SBarry Smith {
1842ebc551c0SBarry Smith   PetscErrorCode ierr;
1843ace3abfcSBarry Smith   PetscBool      iascii;
1844f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1845ebc551c0SBarry Smith 
1846ebc551c0SBarry Smith   PetscFunctionBegin;
1847251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
18489e5bc791SBarry Smith   if (iascii) {
18499e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
18509e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
18519e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
18529e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
18539e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
18549e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
18553b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
18569e5bc791SBarry Smith   }
1857ebc551c0SBarry Smith   PetscFunctionReturn(0);
1858ebc551c0SBarry Smith }
1859ebc551c0SBarry Smith 
18609e5bc791SBarry Smith 
1861ebc551c0SBarry Smith #undef __FUNCT__
1862ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
18638c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptions *PetscOptionsObject,PC pc)
1864ebc551c0SBarry Smith {
1865ebc551c0SBarry Smith   PetscErrorCode ierr;
1866f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1867ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1868ebc551c0SBarry Smith 
1869ebc551c0SBarry Smith   PetscFunctionBegin;
1870e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
18710298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
187268326731SBarry Smith   if (flg) {
1873a0324ebeSBarry Smith     int level=3;
1874fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
187568326731SBarry Smith   }
18760298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1877fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
18780298fd71SBarry 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);
1879fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
18800298fd71SBarry 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);
1881fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
18829e5bc791SBarry Smith 
18830298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
1884fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
18853b46a515SGlenn Hammond 
18860298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1887fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
18880298fd71SBarry 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);
1889fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
18900298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
1891fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1892ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1893ebc551c0SBarry Smith   PetscFunctionReturn(0);
1894ebc551c0SBarry Smith }
1895ebc551c0SBarry Smith 
1896f91d8e95SBarry Smith #undef __FUNCT__
1897f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1898f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1899f91d8e95SBarry Smith {
1900f91d8e95SBarry Smith   PetscErrorCode    ierr;
1901f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
1902d9ca1df4SBarry Smith   PetscScalar       *yy;
1903d9ca1df4SBarry Smith   const PetscScalar *xx;
19044ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
190568326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1906f91d8e95SBarry Smith 
1907f91d8e95SBarry Smith   PetscFunctionBegin;
1908dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1909aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1910f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1911f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1912f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1913f91d8e95SBarry Smith 
1914f91d8e95SBarry Smith   /* copy x values over to hypre */
1915fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1916d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1917d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
1918d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1919fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
1920fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1921f91d8e95SBarry Smith 
1922f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1923f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
19248b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
1925f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1926f91d8e95SBarry Smith   PetscFunctionReturn(0);
1927f91d8e95SBarry Smith }
1928f91d8e95SBarry Smith 
19299e5bc791SBarry Smith #undef __FUNCT__
19309e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1931ace3abfcSBarry 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)
19329e5bc791SBarry Smith {
19339e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
19349e5bc791SBarry Smith   PetscErrorCode ierr;
19354ddd07fcSJed Brown   PetscInt       oits;
19369e5bc791SBarry Smith 
19379e5bc791SBarry Smith   PetscFunctionBegin;
1938dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1939fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1940fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
19419e5bc791SBarry Smith 
19429e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
19438b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
19449e5bc791SBarry Smith   *outits = oits;
19459e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
19469e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1947fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1948fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
19499e5bc791SBarry Smith   PetscFunctionReturn(0);
19509e5bc791SBarry Smith }
19519e5bc791SBarry Smith 
19529e5bc791SBarry Smith 
19533a32d3dbSGlenn Hammond #undef __FUNCT__
19543a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
19553a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
19563a32d3dbSGlenn Hammond {
19573a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
19583a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
19593a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1960ace3abfcSBarry Smith   PetscBool       flg;
19613a32d3dbSGlenn Hammond 
19623a32d3dbSGlenn Hammond   PetscFunctionBegin;
1963251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1964ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
19653a32d3dbSGlenn Hammond 
19663a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
19672fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1968fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1969fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1970fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
19713a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
19723a32d3dbSGlenn Hammond }
19733a32d3dbSGlenn Hammond 
1974ebc551c0SBarry Smith 
1975ebc551c0SBarry Smith /*MC
1976ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1977ebc551c0SBarry Smith 
1978ebc551c0SBarry Smith    Level: advanced
1979ebc551c0SBarry Smith 
19809e5bc791SBarry Smith    Options Database:
19819e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
19829e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
19839e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
19849e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
19859e5bc791SBarry 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
19869e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
1987f91d8e95SBarry Smith 
19889e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
19899e5bc791SBarry Smith 
19908e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
1991aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
19929e5bc791SBarry Smith 
19939e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
1994ebc551c0SBarry Smith M*/
1995ebc551c0SBarry Smith 
1996ebc551c0SBarry Smith #undef __FUNCT__
1997ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
19988cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
1999ebc551c0SBarry Smith {
2000ebc551c0SBarry Smith   PetscErrorCode ierr;
2001ebc551c0SBarry Smith   PC_PFMG        *ex;
2002ebc551c0SBarry Smith 
2003ebc551c0SBarry Smith   PetscFunctionBegin;
2004b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
200568326731SBarry Smith   pc->data = ex;
2006ebc551c0SBarry Smith 
20079e5bc791SBarry Smith   ex->its            = 1;
20089e5bc791SBarry Smith   ex->tol            = 1.e-8;
20099e5bc791SBarry Smith   ex->relax_type     = 1;
20109e5bc791SBarry Smith   ex->rap_type       = 0;
20119e5bc791SBarry Smith   ex->num_pre_relax  = 1;
20129e5bc791SBarry Smith   ex->num_post_relax = 1;
20133b46a515SGlenn Hammond   ex->max_levels     = 0;
20149e5bc791SBarry Smith 
2015ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2016ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2017ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2018f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
20199e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
202068326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
20212fa5cd67SKarl Rupp 
2022ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2023fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2024ebc551c0SBarry Smith   PetscFunctionReturn(0);
2025ebc551c0SBarry Smith }
2026d851a50bSGlenn Hammond 
2027325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2028325fc9f4SBarry Smith 
2029d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2030d851a50bSGlenn Hammond typedef struct {
2031d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2032d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2033d851a50bSGlenn Hammond 
2034d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
20354ddd07fcSJed Brown   PetscInt its;
2036d851a50bSGlenn Hammond   double   tol;
20374ddd07fcSJed Brown   PetscInt relax_type;
20384ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2039d851a50bSGlenn Hammond } PC_SysPFMG;
2040d851a50bSGlenn Hammond 
2041d851a50bSGlenn Hammond #undef __FUNCT__
2042d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
2043d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2044d851a50bSGlenn Hammond {
2045d851a50bSGlenn Hammond   PetscErrorCode ierr;
2046d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2047d851a50bSGlenn Hammond 
2048d851a50bSGlenn Hammond   PetscFunctionBegin;
20492fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2050d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2051c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2052d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2053d851a50bSGlenn Hammond }
2054d851a50bSGlenn Hammond 
2055d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2056d851a50bSGlenn Hammond 
2057d851a50bSGlenn Hammond #undef __FUNCT__
2058d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
2059d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2060d851a50bSGlenn Hammond {
2061d851a50bSGlenn Hammond   PetscErrorCode ierr;
2062ace3abfcSBarry Smith   PetscBool      iascii;
2063d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2064d851a50bSGlenn Hammond 
2065d851a50bSGlenn Hammond   PetscFunctionBegin;
2066251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2067d851a50bSGlenn Hammond   if (iascii) {
2068d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2069d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
2070d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
2071d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2072d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2073d851a50bSGlenn Hammond   }
2074d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2075d851a50bSGlenn Hammond }
2076d851a50bSGlenn Hammond 
2077d851a50bSGlenn Hammond 
2078d851a50bSGlenn Hammond #undef __FUNCT__
2079d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
20808c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptions *PetscOptionsObject,PC pc)
2081d851a50bSGlenn Hammond {
2082d851a50bSGlenn Hammond   PetscErrorCode ierr;
2083d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2084ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2085d851a50bSGlenn Hammond 
2086d851a50bSGlenn Hammond   PetscFunctionBegin;
2087e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
20880298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2089d851a50bSGlenn Hammond   if (flg) {
2090d851a50bSGlenn Hammond     int level=3;
2091fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
2092d851a50bSGlenn Hammond   }
20930298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2094fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
20950298fd71SBarry 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);
2096fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
20970298fd71SBarry 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);
2098fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2099d851a50bSGlenn Hammond 
21000298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2101fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
21020298fd71SBarry 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);
2103fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2104d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2105d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2106d851a50bSGlenn Hammond }
2107d851a50bSGlenn Hammond 
2108d851a50bSGlenn Hammond #undef __FUNCT__
2109d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
2110d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2111d851a50bSGlenn Hammond {
2112d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2113d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2114d9ca1df4SBarry Smith   PetscScalar       *yy;
2115d9ca1df4SBarry Smith   const PetscScalar *xx;
21164ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
2117d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
21184ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
21194ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
21204ddd07fcSJed Brown   PetscInt          part    = 0;
21214ddd07fcSJed Brown   PetscInt          size;
21224ddd07fcSJed Brown   PetscInt          i;
2123d851a50bSGlenn Hammond 
2124d851a50bSGlenn Hammond   PetscFunctionBegin;
2125dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2126aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2127d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2128d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2129d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2130d851a50bSGlenn Hammond 
2131d851a50bSGlenn Hammond   size = 1;
21322fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
21332fa5cd67SKarl Rupp 
2134d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2135d851a50bSGlenn Hammond   if (ordering) {
2136fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2137d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2138d9ca1df4SBarry 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)));
2139d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2140fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2141fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2142fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2143d851a50bSGlenn Hammond 
2144d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2145d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
21468b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2147d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2148a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2149d851a50bSGlenn Hammond     PetscScalar *z;
21504ddd07fcSJed Brown     PetscInt    j, k;
2151d851a50bSGlenn Hammond 
2152785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2153fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2154d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2155d851a50bSGlenn Hammond 
2156d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2157d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2158d851a50bSGlenn Hammond       k= i*nvars;
21592fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2160d851a50bSGlenn Hammond     }
21618b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2162d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2163fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2164fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2165d851a50bSGlenn Hammond 
2166d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2167d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
21688b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2169d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2170d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2171d851a50bSGlenn Hammond       k= i*nvars;
21722fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2173d851a50bSGlenn Hammond     }
2174d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2175d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2176d851a50bSGlenn Hammond   }
2177d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2178d851a50bSGlenn Hammond }
2179d851a50bSGlenn Hammond 
2180d851a50bSGlenn Hammond #undef __FUNCT__
2181d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
2182ace3abfcSBarry 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)
2183d851a50bSGlenn Hammond {
2184d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2185d851a50bSGlenn Hammond   PetscErrorCode ierr;
21864ddd07fcSJed Brown   PetscInt       oits;
2187d851a50bSGlenn Hammond 
2188d851a50bSGlenn Hammond   PetscFunctionBegin;
2189dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2190fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2191fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2192d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
21938b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2194d851a50bSGlenn Hammond   *outits = oits;
2195d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2196d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2197fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2198fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2199d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2200d851a50bSGlenn Hammond }
2201d851a50bSGlenn Hammond 
2202d851a50bSGlenn Hammond 
2203d851a50bSGlenn Hammond #undef __FUNCT__
2204d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
2205d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2206d851a50bSGlenn Hammond {
2207d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2208d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2209d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2210ace3abfcSBarry Smith   PetscBool        flg;
2211d851a50bSGlenn Hammond 
2212d851a50bSGlenn Hammond   PetscFunctionBegin;
2213251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2214ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2215d851a50bSGlenn Hammond 
2216d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
22172fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2218fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2219fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2220fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2221d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2222d851a50bSGlenn Hammond }
2223d851a50bSGlenn Hammond 
2224d851a50bSGlenn Hammond 
2225d851a50bSGlenn Hammond /*MC
2226d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2227d851a50bSGlenn Hammond 
2228d851a50bSGlenn Hammond    Level: advanced
2229d851a50bSGlenn Hammond 
2230d851a50bSGlenn Hammond    Options Database:
2231d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2232d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2233d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2234d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2235d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2236d851a50bSGlenn Hammond 
2237d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
2238d851a50bSGlenn Hammond 
2239f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2240aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2241d851a50bSGlenn Hammond            Also, only cell-centered variables.
2242d851a50bSGlenn Hammond 
2243d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2244d851a50bSGlenn Hammond M*/
2245d851a50bSGlenn Hammond 
2246d851a50bSGlenn Hammond #undef __FUNCT__
2247d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
22488cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2249d851a50bSGlenn Hammond {
2250d851a50bSGlenn Hammond   PetscErrorCode ierr;
2251d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2252d851a50bSGlenn Hammond 
2253d851a50bSGlenn Hammond   PetscFunctionBegin;
2254b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2255d851a50bSGlenn Hammond   pc->data = ex;
2256d851a50bSGlenn Hammond 
2257d851a50bSGlenn Hammond   ex->its            = 1;
2258d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2259d851a50bSGlenn Hammond   ex->relax_type     = 1;
2260d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2261d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2262d851a50bSGlenn Hammond 
2263d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2264d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2265d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2266d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2267d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2268d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
22692fa5cd67SKarl Rupp 
2270ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2271fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2272d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2273d851a50bSGlenn Hammond }
2274