xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 49a781f5cee36db85e8d5b951eec29f10ac13593)
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*/
9*49a781f5SStefano Zampini /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
10*49a781f5SStefano Zampini #include <petsc/private/matimpl.h>
11*49a781f5SStefano Zampini #include <../src/mat/impls/hypre/mhypre.h>
12c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h>
134cb006feSStefano Zampini #include <_hypre_parcsr_ls.h>
1416d9e3a6SLisandro Dalcin 
15dff31646SBarry Smith static PetscBool cite = PETSC_FALSE;
161f817a21SBarry 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";
171f817a21SBarry Smith 
1816d9e3a6SLisandro Dalcin /*
1916d9e3a6SLisandro Dalcin    Private context (data structure) for the  preconditioner.
2016d9e3a6SLisandro Dalcin */
2116d9e3a6SLisandro Dalcin typedef struct {
2216d9e3a6SLisandro Dalcin   HYPRE_Solver   hsolver;
23*49a781f5SStefano Zampini   Mat            hpmat; /* MatHYPRE */
2416d9e3a6SLisandro Dalcin 
254ddd07fcSJed Brown   HYPRE_Int (*destroy)(HYPRE_Solver);
264ddd07fcSJed Brown   HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
274ddd07fcSJed Brown   HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
28863406b8SStefano Zampini   HYPRE_Int (*setdgrad)(HYPRE_Solver,HYPRE_ParCSRMatrix);
29863406b8SStefano Zampini   HYPRE_Int (*setdcurl)(HYPRE_Solver,HYPRE_ParCSRMatrix);
30863406b8SStefano Zampini   HYPRE_Int (*setcoord)(HYPRE_Solver,HYPRE_ParVector,HYPRE_ParVector,HYPRE_ParVector);
31863406b8SStefano Zampini   HYPRE_Int (*setdim)(HYPRE_Solver,HYPRE_Int);
3216d9e3a6SLisandro Dalcin 
3316d9e3a6SLisandro Dalcin   MPI_Comm comm_hypre;
3416d9e3a6SLisandro Dalcin   char     *hypre_type;
3516d9e3a6SLisandro Dalcin 
3616d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
374ddd07fcSJed Brown   PetscInt maxiter;
3816d9e3a6SLisandro Dalcin   double   tol;
3916d9e3a6SLisandro Dalcin 
4016d9e3a6SLisandro Dalcin   /* options for Pilut */
414ddd07fcSJed Brown   PetscInt factorrowsize;
4216d9e3a6SLisandro Dalcin 
4316d9e3a6SLisandro Dalcin   /* options for ParaSails */
444ddd07fcSJed Brown   PetscInt nlevels;
4516d9e3a6SLisandro Dalcin   double   threshhold;
4616d9e3a6SLisandro Dalcin   double   filter;
474ddd07fcSJed Brown   PetscInt sym;
4816d9e3a6SLisandro Dalcin   double   loadbal;
494ddd07fcSJed Brown   PetscInt logging;
504ddd07fcSJed Brown   PetscInt ruse;
514ddd07fcSJed Brown   PetscInt symt;
5216d9e3a6SLisandro Dalcin 
5322b6d1caSBarry Smith   /* options for BoomerAMG */
54ace3abfcSBarry Smith   PetscBool printstatistics;
5516d9e3a6SLisandro Dalcin 
5616d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
574ddd07fcSJed Brown   PetscInt  cycletype;
584ddd07fcSJed Brown   PetscInt  maxlevels;
5916d9e3a6SLisandro Dalcin   double    strongthreshold;
6016d9e3a6SLisandro Dalcin   double    maxrowsum;
614ddd07fcSJed Brown   PetscInt  gridsweeps[3];
624ddd07fcSJed Brown   PetscInt  coarsentype;
634ddd07fcSJed Brown   PetscInt  measuretype;
646a251517SEike Mueller   PetscInt  smoothtype;
658131ecf7SEike Mueller   PetscInt  smoothnumlevels;
66ec64516dSEike Mueller   PetscInt  eu_level;   /* Number of levels for ILU(k) in Euclid */
67ec64516dSEike Mueller   double    eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */
68ec64516dSEike Mueller   PetscInt  eu_bj;      /* Defines use of Block Jacobi ILU in Euclid */
694ddd07fcSJed Brown   PetscInt  relaxtype[3];
7016d9e3a6SLisandro Dalcin   double    relaxweight;
7116d9e3a6SLisandro Dalcin   double    outerrelaxweight;
724ddd07fcSJed Brown   PetscInt  relaxorder;
7316d9e3a6SLisandro Dalcin   double    truncfactor;
74ace3abfcSBarry Smith   PetscBool applyrichardson;
754ddd07fcSJed Brown   PetscInt  pmax;
764ddd07fcSJed Brown   PetscInt  interptype;
774ddd07fcSJed Brown   PetscInt  agg_nl;
784ddd07fcSJed Brown   PetscInt  agg_num_paths;
794ddd07fcSJed Brown   PetscInt  nodal_coarsen;
80ace3abfcSBarry Smith   PetscBool nodal_relax;
814ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
824cb006feSStefano Zampini 
835272c319SBarry Smith   PetscInt  nodal_coarsening;
845272c319SBarry Smith   PetscInt  vec_interp_variant;
855272c319SBarry Smith   HYPRE_IJVector  *hmnull;
865272c319SBarry Smith   HYPRE_ParVector *phmnull;  /* near null space passed to hypre */
875272c319SBarry Smith   PetscInt        n_hmnull;
885272c319SBarry Smith   Vec             hmnull_constant;
8972827435SBarry 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 */
905272c319SBarry Smith 
91863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
92863406b8SStefano Zampini   PetscInt  as_print;
93863406b8SStefano Zampini   PetscInt  as_max_iter;
94863406b8SStefano Zampini   PetscReal as_tol;
95863406b8SStefano Zampini   PetscInt  as_relax_type;
96863406b8SStefano Zampini   PetscInt  as_relax_times;
97863406b8SStefano Zampini   PetscReal as_relax_weight;
98863406b8SStefano Zampini   PetscReal as_omega;
99863406b8SStefano 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) */
100863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
101863406b8SStefano 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) */
102863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
1034cb006feSStefano Zampini   PetscInt  ams_cycle_type;
104863406b8SStefano Zampini   PetscInt  ads_cycle_type;
1054cb006feSStefano Zampini 
1064cb006feSStefano Zampini   /* additional data */
1074cb006feSStefano Zampini   HYPRE_IJVector coords[3];
1084cb006feSStefano Zampini   HYPRE_IJVector constants[3];
1094cb006feSStefano Zampini   HYPRE_IJMatrix G;
110863406b8SStefano Zampini   HYPRE_IJMatrix C;
1114cb006feSStefano Zampini   HYPRE_IJMatrix alpha_Poisson;
1124cb006feSStefano Zampini   HYPRE_IJMatrix beta_Poisson;
1134cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
11423df4f25SStefano Zampini   PetscBool      ams_beta_is_zero_part;
11523df4f25SStefano Zampini   PetscInt       ams_proj_freq;
11616d9e3a6SLisandro Dalcin } PC_HYPRE;
11716d9e3a6SLisandro Dalcin 
118d2128fa2SBarry Smith #undef __FUNCT__
119d2128fa2SBarry Smith #define __FUNCT__ "PCHYPREGetSolver"
120d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
121d2128fa2SBarry Smith {
122d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
123d2128fa2SBarry Smith 
124d2128fa2SBarry Smith   PetscFunctionBegin;
125d2128fa2SBarry Smith   *hsolver = jac->hsolver;
126d2128fa2SBarry Smith   PetscFunctionReturn(0);
127d2128fa2SBarry Smith }
12816d9e3a6SLisandro Dalcin 
12972827435SBarry Smith /*
13072827435SBarry Smith     Replaces the address where the HYPRE vector points to its data with the address of
13172827435SBarry Smith   PETSc's data. Saves the old address so it can be reset when we are finished with it.
13272827435SBarry Smith   Allows use to get the data into a HYPRE vector without the cost of memcopies
13372827435SBarry Smith */
13472827435SBarry Smith #define HYPREReplacePointer(b,newvalue,savedvalue) { \
13572827435SBarry Smith     hypre_ParVector *par_vector   = (hypre_ParVector*)hypre_IJVectorObject(((hypre_IJVector*)b)); \
13672827435SBarry Smith     hypre_Vector    *local_vector = hypre_ParVectorLocalVector(par_vector); \
13772827435SBarry Smith     savedvalue         = local_vector->data; \
13872827435SBarry Smith     local_vector->data = newvalue;          \
13972827435SBarry Smith }
14072827435SBarry Smith 
14116d9e3a6SLisandro Dalcin #undef __FUNCT__
14216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE"
14316d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
14416d9e3a6SLisandro Dalcin {
14516d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
146*49a781f5SStefano Zampini   Mat_HYPRE          *hjac;
14716d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
14816d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
149*49a781f5SStefano Zampini   PetscBool          ishypre;
150*49a781f5SStefano Zampini   PetscErrorCode     ierr;
15116d9e3a6SLisandro Dalcin 
15216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
15316d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
15402a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
15516d9e3a6SLisandro Dalcin   }
1565f5c5b43SBarry Smith 
157*49a781f5SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRE,&ishypre);CHKERRQ(ierr);
158*49a781f5SStefano Zampini   if (!ishypre) {
159*49a781f5SStefano Zampini     MatReuse reuse;
160*49a781f5SStefano Zampini     if (pc->setupcalled) reuse = MAT_REUSE_MATRIX;
161*49a781f5SStefano Zampini     else reuse = MAT_INITIAL_MATRIX;
162*49a781f5SStefano Zampini     ierr = MatConvert(pc->pmat,MATHYPRE,reuse,&jac->hpmat);CHKERRQ(ierr);
163*49a781f5SStefano Zampini   } else {
164*49a781f5SStefano Zampini     ierr = PetscObjectReference((PetscObject)pc->pmat);CHKERRQ(ierr);
165*49a781f5SStefano Zampini     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
166*49a781f5SStefano Zampini     jac->hpmat = pc->pmat;
16716d9e3a6SLisandro Dalcin   }
168*49a781f5SStefano Zampini   hjac = (Mat_HYPRE*)(jac->hpmat->data);
1695f5c5b43SBarry Smith 
17016d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
17116d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
1725272c319SBarry Smith     MatNullSpace    mnull;
1735272c319SBarry Smith     PetscBool       has_const;
174*49a781f5SStefano Zampini     PetscInt        bs,nvec,i;
1755272c319SBarry Smith     const Vec       *vecs;
17672827435SBarry Smith     PetscScalar     *petscvecarray;
1775272c319SBarry Smith 
17816d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1792fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
1805272c319SBarry Smith     ierr = MatGetNearNullSpace(pc->mat, &mnull);CHKERRQ(ierr);
1815272c319SBarry Smith     if (mnull) {
1825272c319SBarry Smith       ierr = MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs);CHKERRQ(ierr);
1835272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull);CHKERRQ(ierr);
18472827435SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull_hypre_data_array);CHKERRQ(ierr);
1855272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->phmnull);CHKERRQ(ierr);
1865272c319SBarry Smith       for (i=0; i<nvec; i++) {
1875272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(vecs[i],&jac->hmnull[i]);CHKERRQ(ierr);
18872827435SBarry Smith         ierr = VecGetArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
18972827435SBarry Smith         HYPREReplacePointer(jac->hmnull[i],petscvecarray,jac->hmnull_hypre_data_array[i]);
19072827435SBarry Smith         ierr = VecRestoreArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
1915272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[i],(void**)&jac->phmnull[i]));
1925272c319SBarry Smith       }
1935272c319SBarry Smith       if (has_const) {
1945272c319SBarry Smith         ierr = MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL);CHKERRQ(ierr);
1955272c319SBarry Smith         ierr = VecSet(jac->hmnull_constant,1);CHKERRQ(ierr);
1965272c319SBarry Smith         ierr = VecNormalize(jac->hmnull_constant,NULL);
1975272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(jac->hmnull_constant,&jac->hmnull[nvec]);CHKERRQ(ierr);
19872827435SBarry Smith         ierr = VecGetArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
19972827435SBarry Smith         HYPREReplacePointer(jac->hmnull[nvec],petscvecarray,jac->hmnull_hypre_data_array[nvec]);
20072827435SBarry Smith         ierr = VecRestoreArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
2015272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[nvec],(void**)&jac->phmnull[nvec]));
2025272c319SBarry Smith         nvec++;
2035272c319SBarry Smith       }
2045272c319SBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVectors,(jac->hsolver,nvec,jac->phmnull));
2055272c319SBarry Smith       jac->n_hmnull = nvec;
2065272c319SBarry Smith     }
2074cb006feSStefano Zampini   }
208863406b8SStefano Zampini 
2094cb006feSStefano Zampini   /* special case for AMS */
2104cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
211*49a781f5SStefano Zampini     if (!jac->coords[0] && !jac->constants[0]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the edge constant vectors via PCHYPRESetEdgeConstantVectors()");
212*49a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
2134cb006feSStefano Zampini   }
214863406b8SStefano Zampini   /* special case for ADS */
215863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
216*49a781f5SStefano Zampini     if (!jac->coords[0]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the coordinate vectors via PCSetCoordinates()");
21737096e45SBarry 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");
218*49a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
219*49a781f5SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient");
220863406b8SStefano Zampini   }
221*49a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
222*49a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&bv));
223*49a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&xv));
224fd3f9acdSBarry Smith   PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr););
22516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
22616d9e3a6SLisandro Dalcin }
22716d9e3a6SLisandro Dalcin 
22816d9e3a6SLisandro Dalcin #undef __FUNCT__
22916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE"
23016d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
23116d9e3a6SLisandro Dalcin {
23216d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
233*49a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
23416d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
23516d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
236d9ca1df4SBarry Smith   PetscScalar        *xv;
237d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
23816d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
239d9ca1df4SBarry Smith   PetscScalar        *sxv;
2404ddd07fcSJed Brown   PetscInt           hierr;
24116d9e3a6SLisandro Dalcin 
24216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
243dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
24416d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
245d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
24616d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
247*49a781f5SStefano Zampini   HYPREReplacePointer(hjac->b,(PetscScalar*)bv,sbv);
248*49a781f5SStefano Zampini   HYPREReplacePointer(hjac->x,xv,sxv);
24916d9e3a6SLisandro Dalcin 
250*49a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
251*49a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
252*49a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
253fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
25465e19b50SBarry Smith                                if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
255fd3f9acdSBarry Smith                                if (hierr) hypre__global_error = 0;);
25616d9e3a6SLisandro Dalcin 
25723df4f25SStefano Zampini   if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) {
25821df291bSStefano Zampini     PetscStackCall("HYPRE_AMSProjectOutGradients",ierr = HYPRE_AMSProjectOutGradients(jac->hsolver,jxv);CHKERRQ(ierr););
25921df291bSStefano Zampini   }
260*49a781f5SStefano Zampini   HYPREReplacePointer(hjac->b,(PetscScalar*)sbv,bv);
261*49a781f5SStefano Zampini   HYPREReplacePointer(hjac->x,sxv,xv);
26216d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
263d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
26416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
26516d9e3a6SLisandro Dalcin }
26616d9e3a6SLisandro Dalcin 
26716d9e3a6SLisandro Dalcin #undef __FUNCT__
2688695de01SBarry Smith #define __FUNCT__ "PCReset_HYPRE"
2698695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc)
2708695de01SBarry Smith {
2718695de01SBarry Smith   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
2728695de01SBarry Smith   PetscErrorCode ierr;
2738695de01SBarry Smith 
2748695de01SBarry Smith   PetscFunctionBegin;
275*49a781f5SStefano Zampini   ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
2768695de01SBarry Smith   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); jac->coords[0] = NULL;
2778695de01SBarry Smith   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); jac->coords[1] = NULL;
2788695de01SBarry Smith   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); jac->coords[2] = NULL;
2798695de01SBarry Smith   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); jac->constants[0] = NULL;
2808695de01SBarry Smith   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); jac->constants[1] = NULL;
2818695de01SBarry Smith   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); jac->constants[2] = NULL;
2828695de01SBarry Smith   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G)); jac->G = NULL;
2838695de01SBarry Smith   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C)); jac->C = NULL;
2848695de01SBarry Smith   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson)); jac->alpha_Poisson = NULL;
2858695de01SBarry Smith   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson)); jac->beta_Poisson = NULL;
286550a8b7dSBarry Smith   if (jac->n_hmnull && jac->hmnull) {
2875272c319SBarry Smith     PetscInt                 i;
288b1c1cd91SBarry Smith     PETSC_UNUSED PetscScalar *petscvecarray;
2895272c319SBarry Smith 
2905272c319SBarry Smith     for (i=0; i<jac->n_hmnull; i++) {
29172827435SBarry Smith       HYPREReplacePointer(jac->hmnull[i],jac->hmnull_hypre_data_array[i],petscvecarray);
2925272c319SBarry Smith       PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->hmnull[i]));
2935272c319SBarry Smith     }
2945272c319SBarry Smith     ierr = PetscFree(jac->hmnull);CHKERRQ(ierr);
29572827435SBarry Smith     ierr = PetscFree(jac->hmnull_hypre_data_array);CHKERRQ(ierr);
2965272c319SBarry Smith     ierr = PetscFree(jac->phmnull);CHKERRQ(ierr);
2975272c319SBarry Smith     ierr = VecDestroy(&jac->hmnull_constant);CHKERRQ(ierr);
2985272c319SBarry Smith   }
2998695de01SBarry Smith   PetscFunctionReturn(0);
3008695de01SBarry Smith }
3018695de01SBarry Smith 
3028695de01SBarry Smith #undef __FUNCT__
30316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE"
30416d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
30516d9e3a6SLisandro Dalcin {
30616d9e3a6SLisandro Dalcin   PC_HYPRE                 *jac = (PC_HYPRE*)pc->data;
30716d9e3a6SLisandro Dalcin   PetscErrorCode           ierr;
30816d9e3a6SLisandro Dalcin 
30916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
3108695de01SBarry Smith   ierr = PCReset_HYPRE(pc);CHKERRQ(ierr);
311226b0620SJed Brown   if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr););
312503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
31316d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
314c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
31516d9e3a6SLisandro Dalcin 
31616d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
317bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
318bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
3194cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
3204cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
321863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
3224cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
3234cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",NULL);CHKERRQ(ierr);
3244cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",NULL);CHKERRQ(ierr);
32516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
32616d9e3a6SLisandro Dalcin }
32716d9e3a6SLisandro Dalcin 
32816d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
32916d9e3a6SLisandro Dalcin #undef __FUNCT__
33016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut"
3314416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptionItems *PetscOptionsObject,PC pc)
33216d9e3a6SLisandro Dalcin {
33316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
33416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
335ace3abfcSBarry Smith   PetscBool      flag;
33616d9e3a6SLisandro Dalcin 
33716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
338e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
33916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
340fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
34116d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
342fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
34316d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
344fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
34516d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
34616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
34716d9e3a6SLisandro Dalcin }
34816d9e3a6SLisandro Dalcin 
34916d9e3a6SLisandro Dalcin #undef __FUNCT__
35016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut"
35116d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
35216d9e3a6SLisandro Dalcin {
35316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
35416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
355ace3abfcSBarry Smith   PetscBool      iascii;
35616d9e3a6SLisandro Dalcin 
35716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
358251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
35916d9e3a6SLisandro Dalcin   if (iascii) {
36016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
36116d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
36216d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
36316d9e3a6SLisandro Dalcin     } else {
36416d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr);
36516d9e3a6SLisandro Dalcin     }
36616d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
36757622a8eSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
36816d9e3a6SLisandro Dalcin     } else {
36916d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr);
37016d9e3a6SLisandro Dalcin     }
37116d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
37216d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
37316d9e3a6SLisandro Dalcin     } else {
37416d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default factor row size \n");CHKERRQ(ierr);
37516d9e3a6SLisandro Dalcin     }
37616d9e3a6SLisandro Dalcin   }
37716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
37816d9e3a6SLisandro Dalcin }
37916d9e3a6SLisandro Dalcin 
38016d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
38116d9e3a6SLisandro Dalcin 
38216d9e3a6SLisandro Dalcin #undef __FUNCT__
38316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG"
38416d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
38516d9e3a6SLisandro Dalcin {
38616d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
387*49a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
38816d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
38916d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
390d9ca1df4SBarry Smith   PetscScalar        *xv;
391d9ca1df4SBarry Smith   const PetscScalar  *bv;
39216d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
39316d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
3944ddd07fcSJed Brown   PetscInt           hierr;
39516d9e3a6SLisandro Dalcin 
39616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
397dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
39816d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
399d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
40016d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
401*49a781f5SStefano Zampini   HYPREReplacePointer(hjac->b,(PetscScalar*)bv,sbv);
402*49a781f5SStefano Zampini   HYPREReplacePointer(hjac->x,xv,sxv);
40316d9e3a6SLisandro Dalcin 
404*49a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
405*49a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
406*49a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
40716d9e3a6SLisandro Dalcin 
40816d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
40916d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
410e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
41116d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
41216d9e3a6SLisandro Dalcin 
413*49a781f5SStefano Zampini   HYPREReplacePointer(hjac->b,sbv,bv);
414*49a781f5SStefano Zampini   HYPREReplacePointer(hjac->x,sxv,xv);
41516d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
416d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
41716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
41816d9e3a6SLisandro Dalcin }
41916d9e3a6SLisandro Dalcin 
420a669f990SJed Brown /* static array length */
421a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
422a669f990SJed Brown 
42316d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
4240f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
42516d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
42665de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
4276a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]   = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
42865de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
42965de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
43065de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
43165de4495SJed Brown                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */,
43265de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
4330f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
4340f1074feSSatish Balay                                                   "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"};
43516d9e3a6SLisandro Dalcin #undef __FUNCT__
43616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG"
4374416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc)
43816d9e3a6SLisandro Dalcin {
43916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
44016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
4414ddd07fcSJed Brown   PetscInt       n,indx,level;
442ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
44316d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
44416d9e3a6SLisandro Dalcin 
44516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
446e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
4474336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
44816d9e3a6SLisandro Dalcin   if (flg) {
4494336a9eeSBarry Smith     jac->cycletype = indx+1;
450fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
45116d9e3a6SLisandro Dalcin   }
45216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
45316d9e3a6SLisandro Dalcin   if (flg) {
454ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
455fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
45616d9e3a6SLisandro Dalcin   }
45716d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
45816d9e3a6SLisandro Dalcin   if (flg) {
459ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
460fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
46116d9e3a6SLisandro Dalcin   }
4620f1074feSSatish 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);
46316d9e3a6SLisandro Dalcin   if (flg) {
46457622a8eSBarry 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);
465fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
46616d9e3a6SLisandro Dalcin   }
46716d9e3a6SLisandro Dalcin 
4680f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
46916d9e3a6SLisandro Dalcin   if (flg) {
47057622a8eSBarry 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);
471fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
47216d9e3a6SLisandro Dalcin   }
47316d9e3a6SLisandro Dalcin 
4740f1074feSSatish 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);
4750f1074feSSatish Balay   if (flg) {
47657622a8eSBarry 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);
477fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
4780f1074feSSatish Balay   }
4790f1074feSSatish Balay 
4800f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
4810f1074feSSatish Balay   if (flg) {
48257622a8eSBarry 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);
4830f1074feSSatish Balay 
484fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
4850f1074feSSatish Balay   }
4860f1074feSSatish Balay 
4870f1074feSSatish Balay 
4880f1074feSSatish 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);
4890f1074feSSatish Balay   if (flg) {
49057622a8eSBarry 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);
4910f1074feSSatish Balay 
492fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
4930f1074feSSatish Balay   }
4940f1074feSSatish Balay 
4950f1074feSSatish Balay 
49616d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
49716d9e3a6SLisandro Dalcin   if (flg) {
49857622a8eSBarry 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);
499fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
50016d9e3a6SLisandro Dalcin   }
50116d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
50216d9e3a6SLisandro Dalcin   if (flg) {
50357622a8eSBarry 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);
50457622a8eSBarry 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);
505fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
50616d9e3a6SLisandro Dalcin   }
50716d9e3a6SLisandro Dalcin 
50816d9e3a6SLisandro Dalcin   /* Grid sweeps */
5090f1074feSSatish 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);
51016d9e3a6SLisandro Dalcin   if (flg) {
511fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
51216d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
51316d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
5140f1074feSSatish Balay     jac->gridsweeps[1] = indx;
5150f1074feSSatish Balay     /*defaults coarse to 1 */
5160f1074feSSatish Balay     jac->gridsweeps[2] = 1;
51716d9e3a6SLisandro Dalcin   }
5180f1074feSSatish Balay 
5195272c319SBarry 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);
5205272c319SBarry Smith   if (flg) {
5215272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,jac->nodal_coarsening));
5225272c319SBarry Smith   }
5235272c319SBarry Smith 
524cbc39033SBarry 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);
5255272c319SBarry Smith   if (flg) {
5265272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,(jac->hsolver,jac->vec_interp_variant));
5275272c319SBarry Smith   }
5285272c319SBarry Smith 
5290f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
53016d9e3a6SLisandro Dalcin   if (flg) {
531fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
5320f1074feSSatish Balay     jac->gridsweeps[0] = indx;
53316d9e3a6SLisandro Dalcin   }
53416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
53516d9e3a6SLisandro Dalcin   if (flg) {
536fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
5370f1074feSSatish Balay     jac->gridsweeps[1] = indx;
53816d9e3a6SLisandro Dalcin   }
5390f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
54016d9e3a6SLisandro Dalcin   if (flg) {
541fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
5420f1074feSSatish Balay     jac->gridsweeps[2] = indx;
54316d9e3a6SLisandro Dalcin   }
54416d9e3a6SLisandro Dalcin 
5456a251517SEike Mueller   /* Smooth type */
5466a251517SEike Mueller   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);
5476a251517SEike Mueller   if (flg) {
5486a251517SEike Mueller     jac->smoothtype = indx;
5496a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
5508131ecf7SEike Mueller     jac->smoothnumlevels = 25;
5518131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
5528131ecf7SEike Mueller   }
5538131ecf7SEike Mueller 
5548131ecf7SEike Mueller   /* Number of smoothing levels */
5558131ecf7SEike 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);
5568131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
5578131ecf7SEike Mueller     jac->smoothnumlevels = indx;
5588131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
5596a251517SEike Mueller   }
5606a251517SEike Mueller 
5611810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
5621810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
5631810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
5641810e44eSEike Mueller     jac->eu_level = indx;
5651810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
5661810e44eSEike Mueller   }
5671810e44eSEike Mueller 
5681810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
5691810e44eSEike Mueller   double droptolerance;
5701810e44eSEike Mueller   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
5711810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
5721810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
5731810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
5741810e44eSEike Mueller   }
5751810e44eSEike Mueller 
5761810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
5771810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5781810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
5791810e44eSEike Mueller     jac->eu_bj = tmp_truth;
580493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
5811810e44eSEike Mueller   }
5821810e44eSEike Mueller 
58316d9e3a6SLisandro Dalcin   /* Relax type */
584a669f990SJed 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);
58516d9e3a6SLisandro Dalcin   if (flg) {
5860f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
587fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
5880f1074feSSatish Balay     /* by default, coarse type set to 9 */
5890f1074feSSatish Balay     jac->relaxtype[2] = 9;
5900f1074feSSatish Balay 
59116d9e3a6SLisandro Dalcin   }
592a669f990SJed 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);
59316d9e3a6SLisandro Dalcin   if (flg) {
59416d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
595fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
59616d9e3a6SLisandro Dalcin   }
597a669f990SJed 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);
59816d9e3a6SLisandro Dalcin   if (flg) {
5990f1074feSSatish Balay     jac->relaxtype[1] = indx;
600fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
60116d9e3a6SLisandro Dalcin   }
602a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
60316d9e3a6SLisandro Dalcin   if (flg) {
6040f1074feSSatish Balay     jac->relaxtype[2] = indx;
605fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
60616d9e3a6SLisandro Dalcin   }
60716d9e3a6SLisandro Dalcin 
60816d9e3a6SLisandro Dalcin   /* Relaxation Weight */
60916d9e3a6SLisandro 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);
61016d9e3a6SLisandro Dalcin   if (flg) {
611fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
61216d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
61316d9e3a6SLisandro Dalcin   }
61416d9e3a6SLisandro Dalcin 
61516d9e3a6SLisandro Dalcin   n         = 2;
61616d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
61716d9e3a6SLisandro 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);
61816d9e3a6SLisandro Dalcin   if (flg) {
61916d9e3a6SLisandro Dalcin     if (n == 2) {
62016d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
621fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
622ce94432eSBarry 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);
62316d9e3a6SLisandro Dalcin   }
62416d9e3a6SLisandro Dalcin 
62516d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
62616d9e3a6SLisandro 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);
62716d9e3a6SLisandro Dalcin   if (flg) {
628fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
62916d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
63016d9e3a6SLisandro Dalcin   }
63116d9e3a6SLisandro Dalcin 
63216d9e3a6SLisandro Dalcin   n         = 2;
63316d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
63416d9e3a6SLisandro 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);
63516d9e3a6SLisandro Dalcin   if (flg) {
63616d9e3a6SLisandro Dalcin     if (n == 2) {
63716d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
638fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
639ce94432eSBarry 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);
64016d9e3a6SLisandro Dalcin   }
64116d9e3a6SLisandro Dalcin 
64216d9e3a6SLisandro Dalcin   /* the Relax Order */
643acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
64416d9e3a6SLisandro Dalcin 
6458afaa268SBarry Smith   if (flg && tmp_truth) {
64616d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
647fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
64816d9e3a6SLisandro Dalcin   }
649a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
65016d9e3a6SLisandro Dalcin   if (flg) {
65116d9e3a6SLisandro Dalcin     jac->measuretype = indx;
652fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
65316d9e3a6SLisandro Dalcin   }
6540f1074feSSatish Balay   /* update list length 3/07 */
655a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
65616d9e3a6SLisandro Dalcin   if (flg) {
65716d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
658fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
65916d9e3a6SLisandro Dalcin   }
6600f1074feSSatish Balay 
6610f1074feSSatish Balay   /* new 3/07 */
662a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
6630f1074feSSatish Balay   if (flg) {
6640f1074feSSatish Balay     jac->interptype = indx;
665fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
6660f1074feSSatish Balay   }
6670f1074feSSatish Balay 
668b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
66916d9e3a6SLisandro Dalcin   if (flg) {
670b96a4a96SBarry Smith     level = 3;
6710298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
6722fa5cd67SKarl Rupp 
673b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
674fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
6752ae77aedSBarry Smith   }
6762ae77aedSBarry Smith 
677b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
6782ae77aedSBarry Smith   if (flg) {
679b96a4a96SBarry Smith     level = 3;
6800298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
6812fa5cd67SKarl Rupp 
682b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
683fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
68416d9e3a6SLisandro Dalcin   }
6858f87f92bSBarry Smith 
686acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
6878f87f92bSBarry Smith   if (flg && tmp_truth) {
6888f87f92bSBarry Smith     PetscInt tmp_int;
6898f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
6908f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
691fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
692fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
693fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
694fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
6958f87f92bSBarry Smith   }
6968f87f92bSBarry Smith 
69716d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
69816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
69916d9e3a6SLisandro Dalcin }
70016d9e3a6SLisandro Dalcin 
70116d9e3a6SLisandro Dalcin #undef __FUNCT__
70216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG"
703ace3abfcSBarry 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)
70416d9e3a6SLisandro Dalcin {
70516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
70616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
7074ddd07fcSJed Brown   PetscInt       oits;
70816d9e3a6SLisandro Dalcin 
70916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
710dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
711fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
712fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
71316d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
71416d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
71516d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
7168b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
7174d0a8057SBarry Smith   *outits = oits;
7184d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
7194d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
720fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
721fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
72216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
72316d9e3a6SLisandro Dalcin }
72416d9e3a6SLisandro Dalcin 
72516d9e3a6SLisandro Dalcin 
72616d9e3a6SLisandro Dalcin #undef __FUNCT__
72716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG"
72816d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
72916d9e3a6SLisandro Dalcin {
73016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
73116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
732ace3abfcSBarry Smith   PetscBool      iascii;
73316d9e3a6SLisandro Dalcin 
73416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
735251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
73616d9e3a6SLisandro Dalcin   if (iascii) {
73716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
73816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
73916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
74016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
74157622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
74257622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
74357622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
7440f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
7450f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
7460f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
7470f1074feSSatish Balay 
74857622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
74916d9e3a6SLisandro Dalcin 
7500f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
7510f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
7520f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
75316d9e3a6SLisandro Dalcin 
7540f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
7550f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
7560f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
75716d9e3a6SLisandro Dalcin 
75857622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
75957622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
76016d9e3a6SLisandro Dalcin 
76116d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
76216d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr);
76316d9e3a6SLisandro Dalcin     } else {
76416d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr);
76516d9e3a6SLisandro Dalcin     }
7666a251517SEike Mueller     if (jac->smoothtype!=-1) {
7676a251517SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
7688131ecf7SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Smooth num levels    %d\n",jac->smoothnumlevels);CHKERRQ(ierr);
7697e352d70SEike Mueller     } else {
770c2bc9be0SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using more complex smoothers.\n");CHKERRQ(ierr);
7711810e44eSEike Mueller     }
7721810e44eSEike Mueller     if (jac->smoothtype==3) {
7731810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU(k) levels %d\n",jac->eu_level);CHKERRQ(ierr);
7741810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU(k) drop tolerance %g\n",jac->eu_droptolerance);CHKERRQ(ierr);
7751810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU use Block-Jacobi? %d\n",jac->eu_bj);CHKERRQ(ierr);
7766a251517SEike Mueller     }
77716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
77816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
7790f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
7805272c319SBarry Smith     if (jac->nodal_coarsening) {
7815272c319SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
7825272c319SBarry Smith     }
7835272c319SBarry Smith     if (jac->vec_interp_variant) {
7845272c319SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
7858f87f92bSBarry Smith     }
7868f87f92bSBarry Smith     if (jac->nodal_relax) {
7878f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
7888f87f92bSBarry Smith     }
78916d9e3a6SLisandro Dalcin   }
79016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
79116d9e3a6SLisandro Dalcin }
79216d9e3a6SLisandro Dalcin 
79316d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
79416d9e3a6SLisandro Dalcin #undef __FUNCT__
79516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails"
7964416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc)
79716d9e3a6SLisandro Dalcin {
79816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
79916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
8004ddd07fcSJed Brown   PetscInt       indx;
801ace3abfcSBarry Smith   PetscBool      flag;
80216d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
80316d9e3a6SLisandro Dalcin 
80416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
805e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
80616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
80716d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
8082fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
80916d9e3a6SLisandro Dalcin 
81016d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
8112fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
81216d9e3a6SLisandro Dalcin 
81316d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
8142fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
81516d9e3a6SLisandro Dalcin 
816acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
8172fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
81816d9e3a6SLisandro Dalcin 
819acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
8202fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
82116d9e3a6SLisandro Dalcin 
822a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
82316d9e3a6SLisandro Dalcin   if (flag) {
82416d9e3a6SLisandro Dalcin     jac->symt = indx;
825fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
82616d9e3a6SLisandro Dalcin   }
82716d9e3a6SLisandro Dalcin 
82816d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
82916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
83016d9e3a6SLisandro Dalcin }
83116d9e3a6SLisandro Dalcin 
83216d9e3a6SLisandro Dalcin #undef __FUNCT__
83316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails"
83416d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
83516d9e3a6SLisandro Dalcin {
83616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
83716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
838ace3abfcSBarry Smith   PetscBool      iascii;
83916d9e3a6SLisandro Dalcin   const char     *symt = 0;;
84016d9e3a6SLisandro Dalcin 
84116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
842251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
84316d9e3a6SLisandro Dalcin   if (iascii) {
84416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
84516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
84657622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
84757622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: filter %g\n",(double)jac->filter);CHKERRQ(ierr);
84857622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
849ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
850ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
8512fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
8522fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
8532fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
854ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
85516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr);
85616d9e3a6SLisandro Dalcin   }
85716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
85816d9e3a6SLisandro Dalcin }
8594cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
8604cb006feSStefano Zampini #undef __FUNCT__
8614cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS"
8624416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc)
8634cb006feSStefano Zampini {
8644cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
8654cb006feSStefano Zampini   PetscErrorCode ierr;
8664cb006feSStefano Zampini   PetscInt       n;
8674cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
8684cb006feSStefano Zampini 
8694cb006feSStefano Zampini   PetscFunctionBegin;
8709fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
871863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
872863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
873863406b8SStefano 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);
874863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
8754cb006feSStefano 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);
8764cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
877863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
878863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
879863406b8SStefano 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);
880863406b8SStefano 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);
881863406b8SStefano 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);
882863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
8834cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
884863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
885863406b8SStefano Zampini                                                                       jac->as_relax_times,
886863406b8SStefano Zampini                                                                       jac->as_relax_weight,
887863406b8SStefano Zampini                                                                       jac->as_omega));
8884cb006feSStefano Zampini   }
889863406b8SStefano 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);
8904cb006feSStefano Zampini   n = 5;
891863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
8924cb006feSStefano Zampini   if (flag || flag2) {
893863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
894863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
895863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
896863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
897863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
898863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
8994cb006feSStefano Zampini   }
900863406b8SStefano 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);
9014cb006feSStefano Zampini   n = 5;
902863406b8SStefano 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);
9034cb006feSStefano Zampini   if (flag || flag2) {
904863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
905863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
906863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
907863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
908863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
909863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
9104cb006feSStefano Zampini   }
91123df4f25SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_projection_frequency","Frequency at which a projection onto the compatible subspace for problems with zero conductivity regions is performed","None",jac->ams_proj_freq,&jac->ams_proj_freq,&flag);CHKERRQ(ierr);
91223df4f25SStefano Zampini   if (flag) { /* override HYPRE's default only if the options is used */
91323df4f25SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetProjectionFrequency,(jac->hsolver,jac->ams_proj_freq));
91423df4f25SStefano Zampini   }
9154cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
9164cb006feSStefano Zampini   PetscFunctionReturn(0);
9174cb006feSStefano Zampini }
9184cb006feSStefano Zampini 
9194cb006feSStefano Zampini #undef __FUNCT__
9204cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS"
9214cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
9224cb006feSStefano Zampini {
9234cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
9244cb006feSStefano Zampini   PetscErrorCode ierr;
9254cb006feSStefano Zampini   PetscBool      iascii;
9264cb006feSStefano Zampini 
9274cb006feSStefano Zampini   PetscFunctionBegin;
9284cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
9294cb006feSStefano Zampini   if (iascii) {
9304cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
931863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
9324cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
933863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
934863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
935863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
936863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
937863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
9384cb006feSStefano Zampini     if (jac->alpha_Poisson) {
9394cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
9404cb006feSStefano Zampini     } else {
9414cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr);
9424cb006feSStefano Zampini     }
943863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
944863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
945863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
946863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
947863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
948863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
9494cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
9504cb006feSStefano Zampini       if (jac->beta_Poisson) {
9514cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
9524cb006feSStefano Zampini       } else {
9534cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr);
9544cb006feSStefano Zampini       }
955863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
956863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
957863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
958863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
959863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
960863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
96123df4f25SStefano Zampini       if (jac->ams_beta_is_zero_part) {
96223df4f25SStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     compatible subspace projection frequency %d (-1 HYPRE uses default)\n",jac->ams_proj_freq);CHKERRQ(ierr);
96323df4f25SStefano Zampini       }
96423df4f25SStefano Zampini     } else {
96523df4f25SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver not used (zero-conductivity everywhere) \n");CHKERRQ(ierr);
9664cb006feSStefano Zampini     }
9674cb006feSStefano Zampini   }
9684cb006feSStefano Zampini   PetscFunctionReturn(0);
9694cb006feSStefano Zampini }
9704cb006feSStefano Zampini 
9714cb006feSStefano Zampini #undef __FUNCT__
972863406b8SStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_ADS"
9734416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc)
974863406b8SStefano Zampini {
975863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
976863406b8SStefano Zampini   PetscErrorCode ierr;
977863406b8SStefano Zampini   PetscInt       n;
978863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
979863406b8SStefano Zampini 
980863406b8SStefano Zampini   PetscFunctionBegin;
981863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
982863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
983863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
984863406b8SStefano 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);
985863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
986863406b8SStefano 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);
987863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
988863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
989863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
990863406b8SStefano 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);
991863406b8SStefano 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);
992863406b8SStefano 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);
993863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
994863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
995863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
996863406b8SStefano Zampini                                                                       jac->as_relax_times,
997863406b8SStefano Zampini                                                                       jac->as_relax_weight,
998863406b8SStefano Zampini                                                                       jac->as_omega));
999863406b8SStefano Zampini   }
1000863406b8SStefano 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);
1001863406b8SStefano Zampini   n = 5;
1002863406b8SStefano 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);
1003863406b8SStefano 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);
1004863406b8SStefano Zampini   if (flag || flag2 || flag3) {
1005863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
1006863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1007863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1008863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1009863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1010863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1011863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1012863406b8SStefano Zampini   }
1013863406b8SStefano 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);
1014863406b8SStefano Zampini   n = 5;
1015863406b8SStefano 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);
1016863406b8SStefano Zampini   if (flag || flag2) {
1017863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1018863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1019863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1020863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1021863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1022863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1023863406b8SStefano Zampini   }
1024863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
1025863406b8SStefano Zampini   PetscFunctionReturn(0);
1026863406b8SStefano Zampini }
1027863406b8SStefano Zampini 
1028863406b8SStefano Zampini #undef __FUNCT__
1029863406b8SStefano Zampini #define __FUNCT__ "PCView_HYPRE_ADS"
1030863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1031863406b8SStefano Zampini {
1032863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1033863406b8SStefano Zampini   PetscErrorCode ierr;
1034863406b8SStefano Zampini   PetscBool      iascii;
1035863406b8SStefano Zampini 
1036863406b8SStefano Zampini   PetscFunctionBegin;
1037863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1038863406b8SStefano Zampini   if (iascii) {
1039863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
1040863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1041863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
1042863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1043863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1044863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1045863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1046863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
1047863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: AMS solver\n");CHKERRQ(ierr);
1048863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1049863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1050863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1051863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1052863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1053863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1054863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
1055863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: vector Poisson solver\n");CHKERRQ(ierr);
1056863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1057863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1058863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1059863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1060863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1061863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
1062863406b8SStefano Zampini   }
1063863406b8SStefano Zampini   PetscFunctionReturn(0);
1064863406b8SStefano Zampini }
1065863406b8SStefano Zampini 
1066863406b8SStefano Zampini #undef __FUNCT__
1067863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE"
1068863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
10694cb006feSStefano Zampini {
10704cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
10714cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_G;
10724cb006feSStefano Zampini   PetscErrorCode     ierr;
10734cb006feSStefano Zampini 
10744cb006feSStefano Zampini   PetscFunctionBegin;
10754cb006feSStefano Zampini   /* throw away any discrete gradient if already set */
10764cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
10774cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(G,&jac->G);CHKERRQ(ierr);
10784cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(G,jac->G);CHKERRQ(ierr);
10794cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->G,(void**)(&parcsr_G)));
1080863406b8SStefano Zampini   PetscStackCall("Hypre set gradient",ierr = (*jac->setdgrad)(jac->hsolver,parcsr_G);CHKERRQ(ierr););
10814cb006feSStefano Zampini   PetscFunctionReturn(0);
10824cb006feSStefano Zampini }
10834cb006feSStefano Zampini 
10844cb006feSStefano Zampini #undef __FUNCT__
10854cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient"
10864cb006feSStefano Zampini /*@
10874cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
10884cb006feSStefano Zampini 
10894cb006feSStefano Zampini    Collective on PC
10904cb006feSStefano Zampini 
10914cb006feSStefano Zampini    Input Parameters:
10924cb006feSStefano Zampini +  pc - the preconditioning context
10934cb006feSStefano Zampini -  G - the discrete gradient
10944cb006feSStefano Zampini 
10954cb006feSStefano Zampini    Level: intermediate
10964cb006feSStefano Zampini 
10974cb006feSStefano 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
1098863406b8SStefano 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
10994cb006feSStefano Zampini 
11004cb006feSStefano Zampini .seealso:
11014cb006feSStefano Zampini @*/
11024cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
11034cb006feSStefano Zampini {
11044cb006feSStefano Zampini   PetscErrorCode ierr;
11054cb006feSStefano Zampini 
11064cb006feSStefano Zampini   PetscFunctionBegin;
11074cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11084cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
11094cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
11104cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
11114cb006feSStefano Zampini   PetscFunctionReturn(0);
11124cb006feSStefano Zampini }
11134cb006feSStefano Zampini 
11144cb006feSStefano Zampini #undef __FUNCT__
1115863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl_HYPRE"
1116863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1117863406b8SStefano Zampini {
1118863406b8SStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
1119863406b8SStefano Zampini   HYPRE_ParCSRMatrix parcsr_C;
1120863406b8SStefano Zampini   PetscErrorCode     ierr;
1121863406b8SStefano Zampini 
1122863406b8SStefano Zampini   PetscFunctionBegin;
1123863406b8SStefano Zampini   /* throw away any discrete curl if already set */
1124863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
1125863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(C,&jac->C);CHKERRQ(ierr);
1126863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(C,jac->C);CHKERRQ(ierr);
1127863406b8SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->C,(void**)(&parcsr_C)));
1128863406b8SStefano Zampini   PetscStackCall("Hypre set curl",ierr = (*jac->setdcurl)(jac->hsolver,parcsr_C);CHKERRQ(ierr););
1129863406b8SStefano Zampini   PetscFunctionReturn(0);
1130863406b8SStefano Zampini }
1131863406b8SStefano Zampini 
1132863406b8SStefano Zampini #undef __FUNCT__
1133863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl"
1134863406b8SStefano Zampini /*@
1135863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1136863406b8SStefano Zampini 
1137863406b8SStefano Zampini    Collective on PC
1138863406b8SStefano Zampini 
1139863406b8SStefano Zampini    Input Parameters:
1140863406b8SStefano Zampini +  pc - the preconditioning context
1141863406b8SStefano Zampini -  C - the discrete curl
1142863406b8SStefano Zampini 
1143863406b8SStefano Zampini    Level: intermediate
1144863406b8SStefano Zampini 
1145863406b8SStefano 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
1146863406b8SStefano 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
1147863406b8SStefano Zampini 
1148863406b8SStefano Zampini .seealso:
1149863406b8SStefano Zampini @*/
1150863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1151863406b8SStefano Zampini {
1152863406b8SStefano Zampini   PetscErrorCode ierr;
1153863406b8SStefano Zampini 
1154863406b8SStefano Zampini   PetscFunctionBegin;
1155863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1156863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1157863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1158863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1159863406b8SStefano Zampini   PetscFunctionReturn(0);
1160863406b8SStefano Zampini }
1161863406b8SStefano Zampini 
1162863406b8SStefano Zampini #undef __FUNCT__
11634cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS"
11644cb006feSStefano Zampini static PetscErrorCode PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
11654cb006feSStefano Zampini {
11664cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11674cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_alpha_Poisson;
11684cb006feSStefano Zampini   PetscErrorCode     ierr;
11694cb006feSStefano Zampini 
11704cb006feSStefano Zampini   PetscFunctionBegin;
11714cb006feSStefano Zampini   /* throw away any matrix if already set */
11724cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
11734cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->alpha_Poisson);CHKERRQ(ierr);
11744cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->alpha_Poisson);CHKERRQ(ierr);
11754cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->alpha_Poisson,(void**)(&parcsr_alpha_Poisson)));
11764cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr_alpha_Poisson));
11774cb006feSStefano Zampini   PetscFunctionReturn(0);
11784cb006feSStefano Zampini }
11794cb006feSStefano Zampini 
11804cb006feSStefano Zampini #undef __FUNCT__
11814cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix"
11824cb006feSStefano Zampini /*@
11834cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
11844cb006feSStefano Zampini 
11854cb006feSStefano Zampini    Collective on PC
11864cb006feSStefano Zampini 
11874cb006feSStefano Zampini    Input Parameters:
11884cb006feSStefano Zampini +  pc - the preconditioning context
11894cb006feSStefano Zampini -  A - the matrix
11904cb006feSStefano Zampini 
11914cb006feSStefano Zampini    Level: intermediate
11924cb006feSStefano Zampini 
11934cb006feSStefano Zampini    Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
11944cb006feSStefano Zampini 
11954cb006feSStefano Zampini .seealso:
11964cb006feSStefano Zampini @*/
11974cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
11984cb006feSStefano Zampini {
11994cb006feSStefano Zampini   PetscErrorCode ierr;
12004cb006feSStefano Zampini 
12014cb006feSStefano Zampini   PetscFunctionBegin;
12024cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12034cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
12044cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
12054cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetAlphaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
12064cb006feSStefano Zampini   PetscFunctionReturn(0);
12074cb006feSStefano Zampini }
12084cb006feSStefano Zampini 
12094cb006feSStefano Zampini #undef __FUNCT__
12104cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix_HYPRE_AMS"
12114cb006feSStefano Zampini static PetscErrorCode PCHYPRESetBetaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
12124cb006feSStefano Zampini {
12134cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
12144cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_beta_Poisson;
12154cb006feSStefano Zampini   PetscErrorCode     ierr;
12164cb006feSStefano Zampini 
12174cb006feSStefano Zampini   PetscFunctionBegin;
12184cb006feSStefano Zampini   if (!A) {
1219484796dcSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
12204cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_TRUE;
12214cb006feSStefano Zampini     PetscFunctionReturn(0);
12224cb006feSStefano Zampini   }
12234cb006feSStefano Zampini   /* throw away any matrix if already set */
12244cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
12254cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->beta_Poisson);CHKERRQ(ierr);
12264cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->beta_Poisson);CHKERRQ(ierr);
12274cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->beta_Poisson,(void**)(&parcsr_beta_Poisson)));
12284cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr_beta_Poisson));
12294cb006feSStefano Zampini   PetscFunctionReturn(0);
12304cb006feSStefano Zampini }
12314cb006feSStefano Zampini 
12324cb006feSStefano Zampini #undef __FUNCT__
12334cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix"
12344cb006feSStefano Zampini /*@
12354cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
12364cb006feSStefano Zampini 
12374cb006feSStefano Zampini    Collective on PC
12384cb006feSStefano Zampini 
12394cb006feSStefano Zampini    Input Parameters:
12404cb006feSStefano Zampini +  pc - the preconditioning context
12414cb006feSStefano Zampini -  A - the matrix
12424cb006feSStefano Zampini 
12434cb006feSStefano Zampini    Level: intermediate
12444cb006feSStefano Zampini 
12454cb006feSStefano Zampini    Notes: A should be obtained by discretizing the Poisson problem with linear finite elements.
12464cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
12474cb006feSStefano Zampini 
12484cb006feSStefano Zampini .seealso:
12494cb006feSStefano Zampini @*/
12504cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
12514cb006feSStefano Zampini {
12524cb006feSStefano Zampini   PetscErrorCode ierr;
12534cb006feSStefano Zampini 
12544cb006feSStefano Zampini   PetscFunctionBegin;
12554cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12564cb006feSStefano Zampini   if (A) {
12574cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
12584cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
12594cb006feSStefano Zampini   }
12604cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetBetaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
12614cb006feSStefano Zampini   PetscFunctionReturn(0);
12624cb006feSStefano Zampini }
12634cb006feSStefano Zampini 
12644cb006feSStefano Zampini #undef __FUNCT__
12654cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE_AMS"
12664cb006feSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE_AMS(PC pc,Vec ozz, Vec zoz, Vec zzo)
12674cb006feSStefano Zampini {
12684cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
12694cb006feSStefano Zampini   HYPRE_ParVector    par_ozz,par_zoz,par_zzo;
127012ddd1b6SStefano Zampini   PetscInt           dim;
12714cb006feSStefano Zampini   PetscErrorCode     ierr;
12724cb006feSStefano Zampini 
12734cb006feSStefano Zampini   PetscFunctionBegin;
12744cb006feSStefano Zampini   /* throw away any vector if already set */
12754cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
12764cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
12774cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
12784cb006feSStefano Zampini   jac->constants[0] = NULL;
12794cb006feSStefano Zampini   jac->constants[1] = NULL;
12804cb006feSStefano Zampini   jac->constants[2] = NULL;
12814cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
12824cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
12834cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&par_ozz)));
12844cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
12854cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
12864cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&par_zoz)));
128712ddd1b6SStefano Zampini   dim = 2;
12884cb006feSStefano Zampini   if (zzo) {
12894cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
12904cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
12914cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&par_zzo)));
129212ddd1b6SStefano Zampini     dim++;
12934cb006feSStefano Zampini   }
12944cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,par_ozz,par_zoz,par_zzo));
129512ddd1b6SStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim));
12964cb006feSStefano Zampini   PetscFunctionReturn(0);
12974cb006feSStefano Zampini }
12984cb006feSStefano Zampini 
12994cb006feSStefano Zampini #undef __FUNCT__
13004cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors"
13014cb006feSStefano Zampini /*@
13024cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
13034cb006feSStefano Zampini 
13044cb006feSStefano Zampini    Collective on PC
13054cb006feSStefano Zampini 
13064cb006feSStefano Zampini    Input Parameters:
13074cb006feSStefano Zampini +  pc - the preconditioning context
13084cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
13094cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
13104cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
13114cb006feSStefano Zampini 
13124cb006feSStefano Zampini    Level: intermediate
13134cb006feSStefano Zampini 
13144cb006feSStefano Zampini    Notes:
13154cb006feSStefano Zampini 
13164cb006feSStefano Zampini .seealso:
13174cb006feSStefano Zampini @*/
13184cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
13194cb006feSStefano Zampini {
13204cb006feSStefano Zampini   PetscErrorCode ierr;
13214cb006feSStefano Zampini 
13224cb006feSStefano Zampini   PetscFunctionBegin;
13234cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
13244cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
13254cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
13264cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
13274cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
13284cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
13294cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
13304cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
13314cb006feSStefano Zampini   PetscFunctionReturn(0);
13324cb006feSStefano Zampini }
13334cb006feSStefano Zampini 
13344cb006feSStefano Zampini #undef __FUNCT__
1335863406b8SStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE"
1336863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
13374cb006feSStefano Zampini {
13384cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
13394cb006feSStefano Zampini   Vec             tv;
13404cb006feSStefano Zampini   HYPRE_ParVector par_coords[3];
13414cb006feSStefano Zampini   PetscInt        i;
13424cb006feSStefano Zampini   PetscErrorCode  ierr;
13434cb006feSStefano Zampini 
13444cb006feSStefano Zampini   PetscFunctionBegin;
13454cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
13464cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
13474cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
13484cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
13494cb006feSStefano Zampini   /* set problem's dimension */
1350863406b8SStefano Zampini   if (jac->setdim) {
1351863406b8SStefano Zampini     PetscStackCall("Hypre set dim",ierr = (*jac->setdim)(jac->hsolver,dim);CHKERRQ(ierr););
1352863406b8SStefano Zampini   }
13534cb006feSStefano Zampini   /* compute IJ vector for coordinates */
13544cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
13554cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
13564cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
13574cb006feSStefano Zampini   for (i=0;i<dim;i++) {
13584cb006feSStefano Zampini     PetscScalar *array;
13594cb006feSStefano Zampini     PetscInt    j;
13604cb006feSStefano Zampini 
13614cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
13624cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
13634cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
13644cb006feSStefano Zampini       array[j] = coords[j*dim+i];
13654cb006feSStefano Zampini     }
13664cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
13674cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
13684cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
13694cb006feSStefano Zampini   }
13704cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
13714cb006feSStefano Zampini   /* pass parCSR vectors to AMS solver */
13724cb006feSStefano Zampini   par_coords[0] = NULL;
13734cb006feSStefano Zampini   par_coords[1] = NULL;
13744cb006feSStefano Zampini   par_coords[2] = NULL;
13754cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&par_coords[0])));
13764cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&par_coords[1])));
13774cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&par_coords[2])));
1378863406b8SStefano Zampini   PetscStackCall("Hypre set coords",ierr = (*jac->setcoord)(jac->hsolver,par_coords[0],par_coords[1],par_coords[2]);CHKERRQ(ierr););
13794cb006feSStefano Zampini   PetscFunctionReturn(0);
13804cb006feSStefano Zampini }
13814cb006feSStefano Zampini 
138216d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
138316d9e3a6SLisandro Dalcin 
138416d9e3a6SLisandro Dalcin #undef __FUNCT__
138516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
1386f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
138716d9e3a6SLisandro Dalcin {
138816d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
138916d9e3a6SLisandro Dalcin 
139016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
139116d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
139216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
139316d9e3a6SLisandro Dalcin }
139416d9e3a6SLisandro Dalcin 
139516d9e3a6SLisandro Dalcin #undef __FUNCT__
139616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
1397f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
139816d9e3a6SLisandro Dalcin {
139916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
140016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1401ace3abfcSBarry Smith   PetscBool      flag;
140216d9e3a6SLisandro Dalcin 
140316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
140416d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
140516d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1406ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
140716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
140816d9e3a6SLisandro Dalcin   } else {
140916d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
141016d9e3a6SLisandro Dalcin   }
141116d9e3a6SLisandro Dalcin 
141216d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
141316d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
141416d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
141516d9e3a6SLisandro Dalcin 
141616d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
141716d9e3a6SLisandro Dalcin   if (flag) {
1418fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
141916d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
142016d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
142116d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
142216d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
142316d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
142416d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
142516d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
142616d9e3a6SLisandro Dalcin   }
142716d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
142816d9e3a6SLisandro Dalcin   if (flag) {
1429fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
143016d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
143116d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
143216d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
143316d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
143416d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
143516d9e3a6SLisandro Dalcin     /* initialize */
143616d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
143716d9e3a6SLisandro Dalcin     jac->threshhold = .1;
143816d9e3a6SLisandro Dalcin     jac->filter     = .1;
143916d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
14402fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
14412fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
14422fa5cd67SKarl Rupp 
144316d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
144416d9e3a6SLisandro Dalcin     jac->symt = 0;
1445fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1446fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1447fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1448fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1449fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1450fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
145116d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
145216d9e3a6SLisandro Dalcin   }
145316d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
145416d9e3a6SLisandro Dalcin   if (flag) {
145516d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
145616d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
145716d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
145816d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
145916d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
146016d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
146116d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
146216d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
146316d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
146416d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
146516d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
146616d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
146716d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
14688f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
146916d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
147016d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
147116d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
147216d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
147316d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
14740f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
14756a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1476b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
14771810e44eSEike Mueller     jac->eu_level         = 0;
14781810e44eSEike Mueller     jac->eu_droptolerance = 0;
14791810e44eSEike Mueller     jac->eu_bj            = 0;
14808f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
14810f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
148216d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
148316d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
148416d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
14850f1074feSSatish Balay     jac->interptype       = 0;
14860f1074feSSatish Balay     jac->agg_nl           = 0;
14870f1074feSSatish Balay     jac->pmax             = 0;
14880f1074feSSatish Balay     jac->truncfactor      = 0.0;
14890f1074feSSatish Balay     jac->agg_num_paths    = 1;
14908f87f92bSBarry Smith 
14918f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
14928f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
14938f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1494fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1495fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1496fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1497fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1498fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1499fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1500fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1501fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1502fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1503fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1504fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1505fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1506fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1507fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1508fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1509fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
151016d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
151116d9e3a6SLisandro Dalcin   }
15124cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
15134cb006feSStefano Zampini   if (flag) {
15144cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
15154cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
15164cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
15174cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
15184cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
15194cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
1520863406b8SStefano Zampini     jac->setdgrad            = HYPRE_AMSSetDiscreteGradient;
1521863406b8SStefano Zampini     jac->setcoord            = HYPRE_AMSSetCoordinateVectors;
1522863406b8SStefano Zampini     jac->setdim              = HYPRE_AMSSetDimension;
15234cb006feSStefano Zampini     jac->coords[0]           = NULL;
15244cb006feSStefano Zampini     jac->coords[1]           = NULL;
15254cb006feSStefano Zampini     jac->coords[2]           = NULL;
15264cb006feSStefano Zampini     jac->G                   = NULL;
15274cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1528863406b8SStefano Zampini     jac->as_print           = 0;
1529863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1530863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
15314cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
15324cb006feSStefano Zampini     /* Smoothing options */
1533863406b8SStefano Zampini     jac->as_relax_type      = 2;
1534863406b8SStefano Zampini     jac->as_relax_times     = 1;
1535863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1536863406b8SStefano Zampini     jac->as_omega           = 1.0;
15374cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1538863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1539863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
15400bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1541863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1542863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1543863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
15444cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1545863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1546863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
15470bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1548863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1549863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1550863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1551863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1552863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
15534cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1554863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1555863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1556863406b8SStefano Zampini                                                                       jac->as_relax_times,
1557863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1558863406b8SStefano Zampini                                                                       jac->as_omega));
1559863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1560863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1561863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1562863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1563863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1564863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1565863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1566863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1567863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1568863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1569863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1570863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
157123df4f25SStefano Zampini     /* Zero conductivity */
157223df4f25SStefano Zampini     jac->ams_beta_is_zero      = PETSC_FALSE;
157323df4f25SStefano Zampini     jac->ams_beta_is_zero_part = PETSC_FALSE;
1574863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1575863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
15764cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE_AMS);CHKERRQ(ierr);
15774cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
15784cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",PCHYPRESetBetaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
15794cb006feSStefano Zampini     PetscFunctionReturn(0);
15804cb006feSStefano Zampini   }
1581863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1582863406b8SStefano Zampini   if (flag) {
1583863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1584863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1585863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1586863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1587863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1588863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1589863406b8SStefano Zampini     jac->setdgrad            = HYPRE_ADSSetDiscreteGradient;
1590863406b8SStefano Zampini     jac->setdcurl            = HYPRE_ADSSetDiscreteCurl;
1591863406b8SStefano Zampini     jac->setcoord            = HYPRE_ADSSetCoordinateVectors;
1592863406b8SStefano Zampini     jac->coords[0]           = NULL;
1593863406b8SStefano Zampini     jac->coords[1]           = NULL;
1594863406b8SStefano Zampini     jac->coords[2]           = NULL;
1595863406b8SStefano Zampini     jac->G                   = NULL;
1596863406b8SStefano Zampini     jac->C                   = NULL;
1597863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1598863406b8SStefano Zampini     jac->as_print           = 0;
1599863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1600863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1601863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1602863406b8SStefano Zampini     /* Smoothing options */
1603863406b8SStefano Zampini     jac->as_relax_type      = 2;
1604863406b8SStefano Zampini     jac->as_relax_times     = 1;
1605863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1606863406b8SStefano Zampini     jac->as_omega           = 1.0;
1607863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1608863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1609863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1610863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1611863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1612863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1613863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1614863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1615863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1616863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1617863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1618863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1619863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1620863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1621863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1622863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1623863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1624863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1625863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1626863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1627863406b8SStefano Zampini                                                                       jac->as_relax_times,
1628863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1629863406b8SStefano Zampini                                                                       jac->as_omega));
1630863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1631863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1632863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1633863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1634863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1635863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1636863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1637863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1638863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1639863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1640863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1641863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1642863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1643863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1644863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
1645863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
1646863406b8SStefano Zampini     PetscFunctionReturn(0);
1647863406b8SStefano Zampini   }
1648503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
16492fa5cd67SKarl Rupp 
16500298fd71SBarry Smith   jac->hypre_type = NULL;
165133263987SBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, boomeramg, ams",name);
165216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
165316d9e3a6SLisandro Dalcin }
165416d9e3a6SLisandro Dalcin 
165516d9e3a6SLisandro Dalcin /*
165616d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
165716d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
165816d9e3a6SLisandro Dalcin */
165916d9e3a6SLisandro Dalcin #undef __FUNCT__
166016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
16614416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc)
166216d9e3a6SLisandro Dalcin {
166316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
16644ddd07fcSJed Brown   PetscInt       indx;
1665863406b8SStefano Zampini   const char     *type[] = {"pilut","parasails","boomeramg","ams","ads"};
1666ace3abfcSBarry Smith   PetscBool      flg;
166716d9e3a6SLisandro Dalcin 
166816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16699fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
16709c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
167116d9e3a6SLisandro Dalcin   if (flg) {
167216d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
167302a17cd4SBarry Smith   } else {
167402a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
167516d9e3a6SLisandro Dalcin   }
167616d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
16773931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
167816d9e3a6SLisandro Dalcin   }
167916d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
168016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
168116d9e3a6SLisandro Dalcin }
168216d9e3a6SLisandro Dalcin 
168316d9e3a6SLisandro Dalcin #undef __FUNCT__
168416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
168516d9e3a6SLisandro Dalcin /*@C
168616d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
168716d9e3a6SLisandro Dalcin 
168816d9e3a6SLisandro Dalcin    Input Parameters:
168916d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1690863406b8SStefano Zampini -     name - either  pilut, parasails, boomeramg, ams, ads
169116d9e3a6SLisandro Dalcin 
169216d9e3a6SLisandro Dalcin    Options Database Keys:
1693863406b8SStefano Zampini    -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
169416d9e3a6SLisandro Dalcin 
169516d9e3a6SLisandro Dalcin    Level: intermediate
169616d9e3a6SLisandro Dalcin 
169716d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
169816d9e3a6SLisandro Dalcin            PCHYPRE
169916d9e3a6SLisandro Dalcin 
170016d9e3a6SLisandro Dalcin @*/
17017087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
170216d9e3a6SLisandro Dalcin {
17034ac538c5SBarry Smith   PetscErrorCode ierr;
170416d9e3a6SLisandro Dalcin 
170516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
17060700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
170716d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
17084ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
170916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
171016d9e3a6SLisandro Dalcin }
171116d9e3a6SLisandro Dalcin 
171216d9e3a6SLisandro Dalcin #undef __FUNCT__
171316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
171416d9e3a6SLisandro Dalcin /*@C
171516d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
171616d9e3a6SLisandro Dalcin 
171716d9e3a6SLisandro Dalcin    Input Parameter:
171816d9e3a6SLisandro Dalcin .     pc - the preconditioner context
171916d9e3a6SLisandro Dalcin 
172016d9e3a6SLisandro Dalcin    Output Parameter:
1721863406b8SStefano Zampini .     name - either  pilut, parasails, boomeramg, ams, ads
172216d9e3a6SLisandro Dalcin 
172316d9e3a6SLisandro Dalcin    Level: intermediate
172416d9e3a6SLisandro Dalcin 
172516d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
172616d9e3a6SLisandro Dalcin            PCHYPRE
172716d9e3a6SLisandro Dalcin 
172816d9e3a6SLisandro Dalcin @*/
17297087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
173016d9e3a6SLisandro Dalcin {
17314ac538c5SBarry Smith   PetscErrorCode ierr;
173216d9e3a6SLisandro Dalcin 
173316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
17340700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
173516d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
17364ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
173716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
173816d9e3a6SLisandro Dalcin }
173916d9e3a6SLisandro Dalcin 
174016d9e3a6SLisandro Dalcin /*MC
174116d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
174216d9e3a6SLisandro Dalcin 
174316d9e3a6SLisandro Dalcin    Options Database Keys:
1744863406b8SStefano Zampini +   -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
174516d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
174616d9e3a6SLisandro Dalcin           preconditioner
174716d9e3a6SLisandro Dalcin 
174816d9e3a6SLisandro Dalcin    Level: intermediate
174916d9e3a6SLisandro Dalcin 
175016d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
175116d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
175216d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
175316d9e3a6SLisandro Dalcin 
175416d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
17550f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
17560f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
17570f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
17588f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
17590f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
17600f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
176116d9e3a6SLisandro Dalcin 
17620f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
17630f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
17640f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
176516d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
176616d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
176716d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
176816d9e3a6SLisandro Dalcin 
176916d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
177016d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
177116d9e3a6SLisandro Dalcin 
17725272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
17735272c319SBarry Smith           the two options:
17745272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
1775cbc39033SBarry Smith -   -pc_hypre_boomeramg_vec_interp_variant <v> where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
17765272c319SBarry Smith 
17775272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
17785272c319SBarry Smith 
17799e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
17809e5bc791SBarry Smith 
178116d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
17829e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
178316d9e3a6SLisandro Dalcin 
178416d9e3a6SLisandro Dalcin M*/
178516d9e3a6SLisandro Dalcin 
178616d9e3a6SLisandro Dalcin #undef __FUNCT__
178716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
17888cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
178916d9e3a6SLisandro Dalcin {
179016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
179116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
179216d9e3a6SLisandro Dalcin 
179316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1794b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
17952fa5cd67SKarl Rupp 
179616d9e3a6SLisandro Dalcin   pc->data                = jac;
17978695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
179816d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
179916d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
180016d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
180116d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
180216d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
18030298fd71SBarry Smith   jac->hypre_type         = NULL;
18044cb006feSStefano Zampini   jac->coords[0]          = NULL;
18054cb006feSStefano Zampini   jac->coords[1]          = NULL;
18064cb006feSStefano Zampini   jac->coords[2]          = NULL;
18074cb006feSStefano Zampini   jac->constants[0]       = NULL;
18084cb006feSStefano Zampini   jac->constants[1]       = NULL;
18094cb006feSStefano Zampini   jac->constants[2]       = NULL;
1810863406b8SStefano Zampini   jac->G                  = NULL;
1811863406b8SStefano Zampini   jac->C                  = NULL;
1812863406b8SStefano Zampini   jac->alpha_Poisson      = NULL;
1813863406b8SStefano Zampini   jac->beta_Poisson       = NULL;
1814fd444223SStefano Zampini   jac->setdim             = NULL;
18155272c319SBarry Smith   jac->hmnull             = NULL;
18165272c319SBarry Smith   jac->n_hmnull           = 0;
181716d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1818ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1819bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1820bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
182116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
182216d9e3a6SLisandro Dalcin }
1823ebc551c0SBarry Smith 
1824f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1825f91d8e95SBarry Smith 
1826ebc551c0SBarry Smith typedef struct {
182768326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1828f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
18299e5bc791SBarry Smith 
18309e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
18314ddd07fcSJed Brown   PetscInt its;
18329e5bc791SBarry Smith   double   tol;
18334ddd07fcSJed Brown   PetscInt relax_type;
18344ddd07fcSJed Brown   PetscInt rap_type;
18354ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
18364ddd07fcSJed Brown   PetscInt max_levels;
1837ebc551c0SBarry Smith } PC_PFMG;
1838ebc551c0SBarry Smith 
1839ebc551c0SBarry Smith #undef __FUNCT__
1840ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1841ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1842ebc551c0SBarry Smith {
1843ebc551c0SBarry Smith   PetscErrorCode ierr;
1844f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1845ebc551c0SBarry Smith 
1846ebc551c0SBarry Smith   PetscFunctionBegin;
18472fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1848f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1849c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1850ebc551c0SBarry Smith   PetscFunctionReturn(0);
1851ebc551c0SBarry Smith }
1852ebc551c0SBarry Smith 
18539e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
18549e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
18559e5bc791SBarry Smith 
1856ebc551c0SBarry Smith #undef __FUNCT__
1857ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1858ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1859ebc551c0SBarry Smith {
1860ebc551c0SBarry Smith   PetscErrorCode ierr;
1861ace3abfcSBarry Smith   PetscBool      iascii;
1862f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1863ebc551c0SBarry Smith 
1864ebc551c0SBarry Smith   PetscFunctionBegin;
1865251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
18669e5bc791SBarry Smith   if (iascii) {
18679e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
18689e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
18699e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
18709e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
18719e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
18729e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
18733b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
18749e5bc791SBarry Smith   }
1875ebc551c0SBarry Smith   PetscFunctionReturn(0);
1876ebc551c0SBarry Smith }
1877ebc551c0SBarry Smith 
18789e5bc791SBarry Smith 
1879ebc551c0SBarry Smith #undef __FUNCT__
1880ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
18814416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc)
1882ebc551c0SBarry Smith {
1883ebc551c0SBarry Smith   PetscErrorCode ierr;
1884f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1885ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1886ebc551c0SBarry Smith 
1887ebc551c0SBarry Smith   PetscFunctionBegin;
1888e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
18890298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
189068326731SBarry Smith   if (flg) {
1891a0324ebeSBarry Smith     int level=3;
1892fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
189368326731SBarry Smith   }
18940298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1895fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
18960298fd71SBarry 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);
1897fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
18980298fd71SBarry 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);
1899fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
19009e5bc791SBarry Smith 
19010298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
1902fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
19033b46a515SGlenn Hammond 
19040298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1905fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
19060298fd71SBarry 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);
1907fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
19080298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
1909fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1910ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1911ebc551c0SBarry Smith   PetscFunctionReturn(0);
1912ebc551c0SBarry Smith }
1913ebc551c0SBarry Smith 
1914f91d8e95SBarry Smith #undef __FUNCT__
1915f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1916f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1917f91d8e95SBarry Smith {
1918f91d8e95SBarry Smith   PetscErrorCode    ierr;
1919f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
1920d9ca1df4SBarry Smith   PetscScalar       *yy;
1921d9ca1df4SBarry Smith   const PetscScalar *xx;
19224ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
192368326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1924f91d8e95SBarry Smith 
1925f91d8e95SBarry Smith   PetscFunctionBegin;
1926dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1927aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1928f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1929f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1930f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1931f91d8e95SBarry Smith 
1932f91d8e95SBarry Smith   /* copy x values over to hypre */
1933fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1934d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1935d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
1936d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1937fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
1938fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1939f91d8e95SBarry Smith 
1940f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1941f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
19428b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
1943f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1944f91d8e95SBarry Smith   PetscFunctionReturn(0);
1945f91d8e95SBarry Smith }
1946f91d8e95SBarry Smith 
19479e5bc791SBarry Smith #undef __FUNCT__
19489e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1949ace3abfcSBarry 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)
19509e5bc791SBarry Smith {
19519e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
19529e5bc791SBarry Smith   PetscErrorCode ierr;
19534ddd07fcSJed Brown   PetscInt       oits;
19549e5bc791SBarry Smith 
19559e5bc791SBarry Smith   PetscFunctionBegin;
1956dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1957fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1958fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
19599e5bc791SBarry Smith 
19609e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
19618b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
19629e5bc791SBarry Smith   *outits = oits;
19639e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
19649e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1965fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1966fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
19679e5bc791SBarry Smith   PetscFunctionReturn(0);
19689e5bc791SBarry Smith }
19699e5bc791SBarry Smith 
19709e5bc791SBarry Smith 
19713a32d3dbSGlenn Hammond #undef __FUNCT__
19723a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
19733a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
19743a32d3dbSGlenn Hammond {
19753a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
19763a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
19773a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1978ace3abfcSBarry Smith   PetscBool       flg;
19793a32d3dbSGlenn Hammond 
19803a32d3dbSGlenn Hammond   PetscFunctionBegin;
1981251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1982ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
19833a32d3dbSGlenn Hammond 
19843a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
19852fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1986fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1987fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1988fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
19893a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
19903a32d3dbSGlenn Hammond }
19913a32d3dbSGlenn Hammond 
1992ebc551c0SBarry Smith 
1993ebc551c0SBarry Smith /*MC
1994ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1995ebc551c0SBarry Smith 
1996ebc551c0SBarry Smith    Level: advanced
1997ebc551c0SBarry Smith 
19989e5bc791SBarry Smith    Options Database:
19999e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
20009e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
20019e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
20029e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
20039e5bc791SBarry 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
20049e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
2005f91d8e95SBarry Smith 
20069e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
20079e5bc791SBarry Smith 
20088e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
2009aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
20109e5bc791SBarry Smith 
20119e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
2012ebc551c0SBarry Smith M*/
2013ebc551c0SBarry Smith 
2014ebc551c0SBarry Smith #undef __FUNCT__
2015ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
20168cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
2017ebc551c0SBarry Smith {
2018ebc551c0SBarry Smith   PetscErrorCode ierr;
2019ebc551c0SBarry Smith   PC_PFMG        *ex;
2020ebc551c0SBarry Smith 
2021ebc551c0SBarry Smith   PetscFunctionBegin;
2022b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
202368326731SBarry Smith   pc->data = ex;
2024ebc551c0SBarry Smith 
20259e5bc791SBarry Smith   ex->its            = 1;
20269e5bc791SBarry Smith   ex->tol            = 1.e-8;
20279e5bc791SBarry Smith   ex->relax_type     = 1;
20289e5bc791SBarry Smith   ex->rap_type       = 0;
20299e5bc791SBarry Smith   ex->num_pre_relax  = 1;
20309e5bc791SBarry Smith   ex->num_post_relax = 1;
20313b46a515SGlenn Hammond   ex->max_levels     = 0;
20329e5bc791SBarry Smith 
2033ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2034ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2035ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2036f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
20379e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
203868326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
20392fa5cd67SKarl Rupp 
2040ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2041fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2042ebc551c0SBarry Smith   PetscFunctionReturn(0);
2043ebc551c0SBarry Smith }
2044d851a50bSGlenn Hammond 
2045325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2046325fc9f4SBarry Smith 
2047d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2048d851a50bSGlenn Hammond typedef struct {
2049d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2050d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2051d851a50bSGlenn Hammond 
2052d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
20534ddd07fcSJed Brown   PetscInt its;
2054d851a50bSGlenn Hammond   double   tol;
20554ddd07fcSJed Brown   PetscInt relax_type;
20564ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2057d851a50bSGlenn Hammond } PC_SysPFMG;
2058d851a50bSGlenn Hammond 
2059d851a50bSGlenn Hammond #undef __FUNCT__
2060d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
2061d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2062d851a50bSGlenn Hammond {
2063d851a50bSGlenn Hammond   PetscErrorCode ierr;
2064d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2065d851a50bSGlenn Hammond 
2066d851a50bSGlenn Hammond   PetscFunctionBegin;
20672fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2068d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2069c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2070d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2071d851a50bSGlenn Hammond }
2072d851a50bSGlenn Hammond 
2073d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2074d851a50bSGlenn Hammond 
2075d851a50bSGlenn Hammond #undef __FUNCT__
2076d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
2077d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2078d851a50bSGlenn Hammond {
2079d851a50bSGlenn Hammond   PetscErrorCode ierr;
2080ace3abfcSBarry Smith   PetscBool      iascii;
2081d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2082d851a50bSGlenn Hammond 
2083d851a50bSGlenn Hammond   PetscFunctionBegin;
2084251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2085d851a50bSGlenn Hammond   if (iascii) {
2086d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2087d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
2088d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
2089d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2090d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2091d851a50bSGlenn Hammond   }
2092d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2093d851a50bSGlenn Hammond }
2094d851a50bSGlenn Hammond 
2095d851a50bSGlenn Hammond 
2096d851a50bSGlenn Hammond #undef __FUNCT__
2097d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
20984416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2099d851a50bSGlenn Hammond {
2100d851a50bSGlenn Hammond   PetscErrorCode ierr;
2101d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2102ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2103d851a50bSGlenn Hammond 
2104d851a50bSGlenn Hammond   PetscFunctionBegin;
2105e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
21060298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2107d851a50bSGlenn Hammond   if (flg) {
2108d851a50bSGlenn Hammond     int level=3;
2109fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
2110d851a50bSGlenn Hammond   }
21110298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2112fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
21130298fd71SBarry 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);
2114fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
21150298fd71SBarry 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);
2116fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2117d851a50bSGlenn Hammond 
21180298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2119fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
21200298fd71SBarry 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);
2121fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2122d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2123d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2124d851a50bSGlenn Hammond }
2125d851a50bSGlenn Hammond 
2126d851a50bSGlenn Hammond #undef __FUNCT__
2127d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
2128d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2129d851a50bSGlenn Hammond {
2130d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2131d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2132d9ca1df4SBarry Smith   PetscScalar       *yy;
2133d9ca1df4SBarry Smith   const PetscScalar *xx;
21344ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
2135d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
21364ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
21374ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
21384ddd07fcSJed Brown   PetscInt          part    = 0;
21394ddd07fcSJed Brown   PetscInt          size;
21404ddd07fcSJed Brown   PetscInt          i;
2141d851a50bSGlenn Hammond 
2142d851a50bSGlenn Hammond   PetscFunctionBegin;
2143dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2144aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2145d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2146d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2147d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2148d851a50bSGlenn Hammond 
2149d851a50bSGlenn Hammond   size = 1;
21502fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
21512fa5cd67SKarl Rupp 
2152d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2153d851a50bSGlenn Hammond   if (ordering) {
2154fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2155d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2156d9ca1df4SBarry 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)));
2157d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2158fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2159fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2160fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2161d851a50bSGlenn Hammond 
2162d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2163d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
21648b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2165d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2166a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2167d851a50bSGlenn Hammond     PetscScalar *z;
21684ddd07fcSJed Brown     PetscInt    j, k;
2169d851a50bSGlenn Hammond 
2170785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2171fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2172d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2173d851a50bSGlenn Hammond 
2174d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2175d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2176d851a50bSGlenn Hammond       k= i*nvars;
21772fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2178d851a50bSGlenn Hammond     }
21798b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2180d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2181fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2182fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2183d851a50bSGlenn Hammond 
2184d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2185d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
21868b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2187d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2188d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2189d851a50bSGlenn Hammond       k= i*nvars;
21902fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2191d851a50bSGlenn Hammond     }
2192d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2193d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2194d851a50bSGlenn Hammond   }
2195d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2196d851a50bSGlenn Hammond }
2197d851a50bSGlenn Hammond 
2198d851a50bSGlenn Hammond #undef __FUNCT__
2199d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
2200ace3abfcSBarry 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)
2201d851a50bSGlenn Hammond {
2202d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2203d851a50bSGlenn Hammond   PetscErrorCode ierr;
22044ddd07fcSJed Brown   PetscInt       oits;
2205d851a50bSGlenn Hammond 
2206d851a50bSGlenn Hammond   PetscFunctionBegin;
2207dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2208fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2209fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2210d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
22118b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2212d851a50bSGlenn Hammond   *outits = oits;
2213d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2214d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2215fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2216fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2217d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2218d851a50bSGlenn Hammond }
2219d851a50bSGlenn Hammond 
2220d851a50bSGlenn Hammond 
2221d851a50bSGlenn Hammond #undef __FUNCT__
2222d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
2223d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2224d851a50bSGlenn Hammond {
2225d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2226d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2227d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2228ace3abfcSBarry Smith   PetscBool        flg;
2229d851a50bSGlenn Hammond 
2230d851a50bSGlenn Hammond   PetscFunctionBegin;
2231251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2232ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2233d851a50bSGlenn Hammond 
2234d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
22352fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2236fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2237fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2238fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2239d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2240d851a50bSGlenn Hammond }
2241d851a50bSGlenn Hammond 
2242d851a50bSGlenn Hammond 
2243d851a50bSGlenn Hammond /*MC
2244d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2245d851a50bSGlenn Hammond 
2246d851a50bSGlenn Hammond    Level: advanced
2247d851a50bSGlenn Hammond 
2248d851a50bSGlenn Hammond    Options Database:
2249d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2250d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2251d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2252d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2253d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2254d851a50bSGlenn Hammond 
2255d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
2256d851a50bSGlenn Hammond 
2257f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2258aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2259d851a50bSGlenn Hammond            Also, only cell-centered variables.
2260d851a50bSGlenn Hammond 
2261d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2262d851a50bSGlenn Hammond M*/
2263d851a50bSGlenn Hammond 
2264d851a50bSGlenn Hammond #undef __FUNCT__
2265d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
22668cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2267d851a50bSGlenn Hammond {
2268d851a50bSGlenn Hammond   PetscErrorCode ierr;
2269d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2270d851a50bSGlenn Hammond 
2271d851a50bSGlenn Hammond   PetscFunctionBegin;
2272b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2273d851a50bSGlenn Hammond   pc->data = ex;
2274d851a50bSGlenn Hammond 
2275d851a50bSGlenn Hammond   ex->its            = 1;
2276d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2277d851a50bSGlenn Hammond   ex->relax_type     = 1;
2278d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2279d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2280d851a50bSGlenn Hammond 
2281d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2282d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2283d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2284d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2285d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2286d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
22872fa5cd67SKarl Rupp 
2288ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2289fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2290d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2291d851a50bSGlenn Hammond }
2292