xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 6bf688a086b375024d78ab522c49ff746e0c2ebd)
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*/
949a781f5SStefano Zampini /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1049a781f5SStefano Zampini #include <petsc/private/matimpl.h>
1158968eb6SStefano Zampini #include <../src/vec/vec/impls/hypre/vhyp.h>
1249a781f5SStefano Zampini #include <../src/mat/impls/hypre/mhypre.h>
13c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h>
144cb006feSStefano Zampini #include <_hypre_parcsr_ls.h>
1516d9e3a6SLisandro Dalcin 
16dff31646SBarry Smith static PetscBool cite = PETSC_FALSE;
171f817a21SBarry 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";
181f817a21SBarry Smith 
1916d9e3a6SLisandro Dalcin /*
2016d9e3a6SLisandro Dalcin    Private context (data structure) for the  preconditioner.
2116d9e3a6SLisandro Dalcin */
2216d9e3a6SLisandro Dalcin typedef struct {
2316d9e3a6SLisandro Dalcin   HYPRE_Solver   hsolver;
2449a781f5SStefano Zampini   Mat            hpmat; /* MatHYPRE */
2516d9e3a6SLisandro Dalcin 
264ddd07fcSJed Brown   HYPRE_Int (*destroy)(HYPRE_Solver);
274ddd07fcSJed Brown   HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
284ddd07fcSJed Brown   HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
2916d9e3a6SLisandro Dalcin 
3016d9e3a6SLisandro Dalcin   MPI_Comm comm_hypre;
3116d9e3a6SLisandro Dalcin   char     *hypre_type;
3216d9e3a6SLisandro Dalcin 
3316d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
344ddd07fcSJed Brown   PetscInt maxiter;
3516d9e3a6SLisandro Dalcin   double   tol;
3616d9e3a6SLisandro Dalcin 
3716d9e3a6SLisandro Dalcin   /* options for Pilut */
384ddd07fcSJed Brown   PetscInt factorrowsize;
3916d9e3a6SLisandro Dalcin 
4016d9e3a6SLisandro Dalcin   /* options for ParaSails */
414ddd07fcSJed Brown   PetscInt nlevels;
4216d9e3a6SLisandro Dalcin   double   threshhold;
4316d9e3a6SLisandro Dalcin   double   filter;
444ddd07fcSJed Brown   PetscInt sym;
4516d9e3a6SLisandro Dalcin   double   loadbal;
464ddd07fcSJed Brown   PetscInt logging;
474ddd07fcSJed Brown   PetscInt ruse;
484ddd07fcSJed Brown   PetscInt symt;
4916d9e3a6SLisandro Dalcin 
5022b6d1caSBarry Smith   /* options for BoomerAMG */
51ace3abfcSBarry Smith   PetscBool printstatistics;
5216d9e3a6SLisandro Dalcin 
5316d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
544ddd07fcSJed Brown   PetscInt  cycletype;
554ddd07fcSJed Brown   PetscInt  maxlevels;
5616d9e3a6SLisandro Dalcin   double    strongthreshold;
5716d9e3a6SLisandro Dalcin   double    maxrowsum;
584ddd07fcSJed Brown   PetscInt  gridsweeps[3];
594ddd07fcSJed Brown   PetscInt  coarsentype;
604ddd07fcSJed Brown   PetscInt  measuretype;
616a251517SEike Mueller   PetscInt  smoothtype;
628131ecf7SEike Mueller   PetscInt  smoothnumlevels;
63ec64516dSEike Mueller   PetscInt  eu_level;   /* Number of levels for ILU(k) in Euclid */
64ec64516dSEike Mueller   double    eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */
65ec64516dSEike Mueller   PetscInt  eu_bj;      /* Defines use of Block Jacobi ILU in Euclid */
664ddd07fcSJed Brown   PetscInt  relaxtype[3];
6716d9e3a6SLisandro Dalcin   double    relaxweight;
6816d9e3a6SLisandro Dalcin   double    outerrelaxweight;
694ddd07fcSJed Brown   PetscInt  relaxorder;
7016d9e3a6SLisandro Dalcin   double    truncfactor;
71ace3abfcSBarry Smith   PetscBool applyrichardson;
724ddd07fcSJed Brown   PetscInt  pmax;
734ddd07fcSJed Brown   PetscInt  interptype;
744ddd07fcSJed Brown   PetscInt  agg_nl;
754ddd07fcSJed Brown   PetscInt  agg_num_paths;
764ddd07fcSJed Brown   PetscInt  nodal_coarsen;
77ace3abfcSBarry Smith   PetscBool nodal_relax;
784ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
794cb006feSStefano Zampini 
805272c319SBarry Smith   PetscInt  nodal_coarsening;
815272c319SBarry Smith   PetscInt  vec_interp_variant;
825272c319SBarry Smith   HYPRE_IJVector  *hmnull;
835272c319SBarry Smith   HYPRE_ParVector *phmnull;  /* near null space passed to hypre */
845272c319SBarry Smith   PetscInt        n_hmnull;
855272c319SBarry Smith   Vec             hmnull_constant;
8672827435SBarry 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 */
875272c319SBarry Smith 
88863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
89863406b8SStefano Zampini   PetscInt  as_print;
90863406b8SStefano Zampini   PetscInt  as_max_iter;
91863406b8SStefano Zampini   PetscReal as_tol;
92863406b8SStefano Zampini   PetscInt  as_relax_type;
93863406b8SStefano Zampini   PetscInt  as_relax_times;
94863406b8SStefano Zampini   PetscReal as_relax_weight;
95863406b8SStefano Zampini   PetscReal as_omega;
96863406b8SStefano 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) */
97863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
98863406b8SStefano 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) */
99863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
1004cb006feSStefano Zampini   PetscInt  ams_cycle_type;
101863406b8SStefano Zampini   PetscInt  ads_cycle_type;
1024cb006feSStefano Zampini 
1034cb006feSStefano Zampini   /* additional data */
1045ac14e1cSStefano Zampini   Mat G;             /* MatHYPRE */
1055ac14e1cSStefano Zampini   Mat C;             /* MatHYPRE */
1065ac14e1cSStefano Zampini   Mat alpha_Poisson; /* MatHYPRE */
1075ac14e1cSStefano Zampini   Mat beta_Poisson;  /* MatHYPRE */
1085ac14e1cSStefano Zampini 
1095ac14e1cSStefano Zampini   /* extra information for AMS */
1105ac14e1cSStefano Zampini   PetscInt       dim; /* geometrical dimension */
1114cb006feSStefano Zampini   HYPRE_IJVector coords[3];
1124cb006feSStefano Zampini   HYPRE_IJVector constants[3];
113*6bf688a0SCe Qin   Mat            RT_PiFull, RT_Pi[3];
114*6bf688a0SCe Qin   Mat            ND_PiFull, ND_Pi[3];
1154cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
11623df4f25SStefano Zampini   PetscBool      ams_beta_is_zero_part;
11723df4f25SStefano Zampini   PetscInt       ams_proj_freq;
11816d9e3a6SLisandro Dalcin } PC_HYPRE;
11916d9e3a6SLisandro Dalcin 
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 
12916d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
13016d9e3a6SLisandro Dalcin {
13116d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
13249a781f5SStefano Zampini   Mat_HYPRE          *hjac;
13316d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
13416d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
13549a781f5SStefano Zampini   PetscBool          ishypre;
13649a781f5SStefano Zampini   PetscErrorCode     ierr;
13716d9e3a6SLisandro Dalcin 
13816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
13916d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
14002a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
14116d9e3a6SLisandro Dalcin   }
1425f5c5b43SBarry Smith 
14349a781f5SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRE,&ishypre);CHKERRQ(ierr);
14449a781f5SStefano Zampini   if (!ishypre) {
145*6bf688a0SCe Qin     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
146*6bf688a0SCe Qin     ierr = MatConvert(pc->pmat,MATHYPRE,MAT_INITIAL_MATRIX,&jac->hpmat);CHKERRQ(ierr);
14749a781f5SStefano Zampini   } else {
14849a781f5SStefano Zampini     ierr = PetscObjectReference((PetscObject)pc->pmat);CHKERRQ(ierr);
14949a781f5SStefano Zampini     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
15049a781f5SStefano Zampini     jac->hpmat = pc->pmat;
15116d9e3a6SLisandro Dalcin   }
15249a781f5SStefano Zampini   hjac = (Mat_HYPRE*)(jac->hpmat->data);
1535f5c5b43SBarry Smith 
15416d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
15516d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
1565272c319SBarry Smith     MatNullSpace    mnull;
1575272c319SBarry Smith     PetscBool       has_const;
15849a781f5SStefano Zampini     PetscInt        bs,nvec,i;
1595272c319SBarry Smith     const Vec       *vecs;
16072827435SBarry Smith     PetscScalar     *petscvecarray;
1615272c319SBarry Smith 
16216d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1632fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
1645272c319SBarry Smith     ierr = MatGetNearNullSpace(pc->mat, &mnull);CHKERRQ(ierr);
1655272c319SBarry Smith     if (mnull) {
1665272c319SBarry Smith       ierr = MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs);CHKERRQ(ierr);
1675272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull);CHKERRQ(ierr);
16872827435SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull_hypre_data_array);CHKERRQ(ierr);
1695272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->phmnull);CHKERRQ(ierr);
1705272c319SBarry Smith       for (i=0; i<nvec; i++) {
1715272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(vecs[i],&jac->hmnull[i]);CHKERRQ(ierr);
17272827435SBarry Smith         ierr = VecGetArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
17358968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],petscvecarray,jac->hmnull_hypre_data_array[i]);
17472827435SBarry Smith         ierr = VecRestoreArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
1755272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[i],(void**)&jac->phmnull[i]));
1765272c319SBarry Smith       }
1775272c319SBarry Smith       if (has_const) {
1785272c319SBarry Smith         ierr = MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL);CHKERRQ(ierr);
1795272c319SBarry Smith         ierr = VecSet(jac->hmnull_constant,1);CHKERRQ(ierr);
1805272c319SBarry Smith         ierr = VecNormalize(jac->hmnull_constant,NULL);
1815272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(jac->hmnull_constant,&jac->hmnull[nvec]);CHKERRQ(ierr);
18272827435SBarry Smith         ierr = VecGetArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
18358968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[nvec],petscvecarray,jac->hmnull_hypre_data_array[nvec]);
18472827435SBarry Smith         ierr = VecRestoreArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
1855272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[nvec],(void**)&jac->phmnull[nvec]));
1865272c319SBarry Smith         nvec++;
1875272c319SBarry Smith       }
1885272c319SBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVectors,(jac->hsolver,nvec,jac->phmnull));
1895272c319SBarry Smith       jac->n_hmnull = nvec;
1905272c319SBarry Smith     }
1914cb006feSStefano Zampini   }
192863406b8SStefano Zampini 
1934cb006feSStefano Zampini   /* special case for AMS */
1944cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
1955ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
1965ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
197*6bf688a0SCe Qin     if (!jac->coords[0] && !jac->constants[0] && !(jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
198*6bf688a0SCe Qin       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the edge constant vectors via PCHYPRESetEdgeConstantVectors() or the interpolation matrix via PCHYPRESetInterpolations");
199*6bf688a0SCe Qin     }
2005ac14e1cSStefano Zampini     if (jac->dim) {
2015ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,jac->dim));
2025ac14e1cSStefano Zampini     }
2035ac14e1cSStefano Zampini     if (jac->constants[0]) {
2045ac14e1cSStefano Zampini       HYPRE_ParVector ozz,zoz,zzo = NULL;
2055ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&ozz)));
2065ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&zoz)));
2075ac14e1cSStefano Zampini       if (jac->constants[2]) {
2085ac14e1cSStefano Zampini         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&zzo)));
2095ac14e1cSStefano Zampini       }
2105ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,ozz,zoz,zzo));
2115ac14e1cSStefano Zampini     }
2125ac14e1cSStefano Zampini     if (jac->coords[0]) {
2135ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
2145ac14e1cSStefano Zampini       coords[0] = NULL;
2155ac14e1cSStefano Zampini       coords[1] = NULL;
2165ac14e1cSStefano Zampini       coords[2] = NULL;
2175ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
2185ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
2195ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
2205ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
2215ac14e1cSStefano Zampini     }
22249a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
2235ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
2245ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2255ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr));
2265ac14e1cSStefano Zampini     if (jac->alpha_Poisson) {
2275ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->alpha_Poisson->data);
2285ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2295ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr));
2305ac14e1cSStefano Zampini     }
2315ac14e1cSStefano Zampini     if (jac->ams_beta_is_zero) {
2325ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
2335ac14e1cSStefano Zampini     } else if (jac->beta_Poisson) {
2345ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->beta_Poisson->data);
2355ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2365ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr));
2375ac14e1cSStefano Zampini     }
238*6bf688a0SCe Qin     if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) {
239*6bf688a0SCe Qin       PetscInt           i;
240*6bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
241*6bf688a0SCe Qin       if (jac->ND_PiFull) {
242*6bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
243*6bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
244*6bf688a0SCe Qin       } else {
245*6bf688a0SCe Qin         nd_parcsrfull = NULL;
246*6bf688a0SCe Qin       }
247*6bf688a0SCe Qin       for (i=0;i<3;++i) {
248*6bf688a0SCe Qin         if (jac->ND_Pi[i]) {
249*6bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
250*6bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
251*6bf688a0SCe Qin         } else {
252*6bf688a0SCe Qin           nd_parcsr[i] = NULL;
253*6bf688a0SCe Qin         }
254*6bf688a0SCe Qin       }
255*6bf688a0SCe Qin       PetscStackCallStandard(HYPRE_AMSSetInterpolations,(jac->hsolver,nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]));
256*6bf688a0SCe Qin     }
2574cb006feSStefano Zampini   }
258863406b8SStefano Zampini   /* special case for ADS */
259863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
2605ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2615ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
262*6bf688a0SCe Qin     if (!jac->coords[0] && !((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])))) {
263*6bf688a0SCe Qin       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations");
264*6bf688a0SCe Qin     }
26537096e45SBarry 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");
26649a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
26749a781f5SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient");
2685ac14e1cSStefano Zampini     if (jac->coords[0]) {
2695ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
2705ac14e1cSStefano Zampini       coords[0] = NULL;
2715ac14e1cSStefano Zampini       coords[1] = NULL;
2725ac14e1cSStefano Zampini       coords[2] = NULL;
2735ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
2745ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
2755ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
2765ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_ADSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
2775ac14e1cSStefano Zampini     }
2785ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
2795ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2805ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteGradient,(jac->hsolver,parcsr));
2815ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->C->data);
2825ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2835ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteCurl,(jac->hsolver,parcsr));
284*6bf688a0SCe Qin     if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
285*6bf688a0SCe Qin       PetscInt           i;
286*6bf688a0SCe Qin       HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3];
287*6bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
288*6bf688a0SCe Qin       if (jac->RT_PiFull) {
289*6bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->RT_PiFull->data);
290*6bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsrfull)));
291*6bf688a0SCe Qin       } else {
292*6bf688a0SCe Qin         rt_parcsrfull = NULL;
293*6bf688a0SCe Qin       }
294*6bf688a0SCe Qin       for (i=0;i<3;++i) {
295*6bf688a0SCe Qin         if (jac->RT_Pi[i]) {
296*6bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->RT_Pi[i]->data);
297*6bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsr[i])));
298*6bf688a0SCe Qin         } else {
299*6bf688a0SCe Qin           rt_parcsr[i] = NULL;
300*6bf688a0SCe Qin         }
301*6bf688a0SCe Qin       }
302*6bf688a0SCe Qin       if (jac->ND_PiFull) {
303*6bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
304*6bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
305*6bf688a0SCe Qin       } else {
306*6bf688a0SCe Qin         nd_parcsrfull = NULL;
307*6bf688a0SCe Qin       }
308*6bf688a0SCe Qin       for (i=0;i<3;++i) {
309*6bf688a0SCe Qin         if (jac->ND_Pi[i]) {
310*6bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
311*6bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
312*6bf688a0SCe Qin         } else {
313*6bf688a0SCe Qin           nd_parcsr[i] = NULL;
314*6bf688a0SCe Qin         }
315*6bf688a0SCe Qin       }
316*6bf688a0SCe Qin       PetscStackCallStandard(HYPRE_ADSSetInterpolations,(jac->hsolver,rt_parcsrfull,rt_parcsr[0],rt_parcsr[1],rt_parcsr[2],nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]));
317*6bf688a0SCe Qin     }
318863406b8SStefano Zampini   }
31949a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
32049a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&bv));
32149a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&xv));
322fd3f9acdSBarry Smith   PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr););
32316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
32416d9e3a6SLisandro Dalcin }
32516d9e3a6SLisandro Dalcin 
32616d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
32716d9e3a6SLisandro Dalcin {
32816d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
32949a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
33016d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
33116d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
332d9ca1df4SBarry Smith   PetscScalar        *xv;
333d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
33416d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
335d9ca1df4SBarry Smith   PetscScalar        *sxv;
3364ddd07fcSJed Brown   PetscInt           hierr;
33716d9e3a6SLisandro Dalcin 
33816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
339dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
34016d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
341d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
34216d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
34358968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)bv,sbv);
34458968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
34516d9e3a6SLisandro Dalcin 
34649a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
34749a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
34849a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
349fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
35065e19b50SBarry Smith                                if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
351fd3f9acdSBarry Smith                                if (hierr) hypre__global_error = 0;);
35216d9e3a6SLisandro Dalcin 
35323df4f25SStefano Zampini   if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) {
3545ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSProjectOutGradients,(jac->hsolver,jxv));
35521df291bSStefano Zampini   }
35658968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)sbv,bv);
35758968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
35816d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
359d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
36016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
36116d9e3a6SLisandro Dalcin }
36216d9e3a6SLisandro Dalcin 
3638695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc)
3648695de01SBarry Smith {
3658695de01SBarry Smith   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
3668695de01SBarry Smith   PetscErrorCode ierr;
3678695de01SBarry Smith 
3688695de01SBarry Smith   PetscFunctionBegin;
36949a781f5SStefano Zampini   ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
3705ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
3715ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
3725ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
3735ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
374*6bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
375*6bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[0]);CHKERRQ(ierr);
376*6bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[1]);CHKERRQ(ierr);
377*6bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[2]);CHKERRQ(ierr);
378*6bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
379*6bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[0]);CHKERRQ(ierr);
380*6bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[1]);CHKERRQ(ierr);
381*6bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[2]);CHKERRQ(ierr);
3828695de01SBarry Smith   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); jac->coords[0] = NULL;
3838695de01SBarry Smith   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); jac->coords[1] = NULL;
3848695de01SBarry Smith   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); jac->coords[2] = NULL;
3858695de01SBarry Smith   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); jac->constants[0] = NULL;
3868695de01SBarry Smith   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); jac->constants[1] = NULL;
3878695de01SBarry Smith   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); jac->constants[2] = NULL;
388550a8b7dSBarry Smith   if (jac->n_hmnull && jac->hmnull) {
3895272c319SBarry Smith     PetscInt                 i;
390b1c1cd91SBarry Smith     PETSC_UNUSED PetscScalar *petscvecarray;
3915272c319SBarry Smith 
3925272c319SBarry Smith     for (i=0; i<jac->n_hmnull; i++) {
39358968eb6SStefano Zampini       VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],jac->hmnull_hypre_data_array[i],petscvecarray);
3945272c319SBarry Smith       PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->hmnull[i]));
3955272c319SBarry Smith     }
3965272c319SBarry Smith     ierr = PetscFree(jac->hmnull);CHKERRQ(ierr);
39772827435SBarry Smith     ierr = PetscFree(jac->hmnull_hypre_data_array);CHKERRQ(ierr);
3985272c319SBarry Smith     ierr = PetscFree(jac->phmnull);CHKERRQ(ierr);
3995272c319SBarry Smith     ierr = VecDestroy(&jac->hmnull_constant);CHKERRQ(ierr);
4005272c319SBarry Smith   }
4015ac14e1cSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
4025ac14e1cSStefano Zampini   jac->dim = 0;
4038695de01SBarry Smith   PetscFunctionReturn(0);
4048695de01SBarry Smith }
4058695de01SBarry Smith 
40616d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
40716d9e3a6SLisandro Dalcin {
40816d9e3a6SLisandro Dalcin   PC_HYPRE                 *jac = (PC_HYPRE*)pc->data;
40916d9e3a6SLisandro Dalcin   PetscErrorCode           ierr;
41016d9e3a6SLisandro Dalcin 
41116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
4128695de01SBarry Smith   ierr = PCReset_HYPRE(pc);CHKERRQ(ierr);
413226b0620SJed Brown   if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr););
414503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
41516d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
416c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
41716d9e3a6SLisandro Dalcin 
41816d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
419bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
420bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
4214cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
4224cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
423863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
424*6bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",NULL);CHKERRQ(ierr);
4254cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
4265ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",NULL);CHKERRQ(ierr);
42716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
42816d9e3a6SLisandro Dalcin }
42916d9e3a6SLisandro Dalcin 
43016d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
4314416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptionItems *PetscOptionsObject,PC pc)
43216d9e3a6SLisandro Dalcin {
43316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
43416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
435ace3abfcSBarry Smith   PetscBool      flag;
43616d9e3a6SLisandro Dalcin 
43716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
438e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
43916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
440fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
44116d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
442fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
44316d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
444fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
44516d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
44616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
44716d9e3a6SLisandro Dalcin }
44816d9e3a6SLisandro Dalcin 
44916d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
45016d9e3a6SLisandro Dalcin {
45116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
45216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
453ace3abfcSBarry Smith   PetscBool      iascii;
45416d9e3a6SLisandro Dalcin 
45516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
456251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
45716d9e3a6SLisandro Dalcin   if (iascii) {
45816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
45916d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
460efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
46116d9e3a6SLisandro Dalcin     } else {
462efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default maximum number of iterations \n");CHKERRQ(ierr);
46316d9e3a6SLisandro Dalcin     }
46416d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
465efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
46616d9e3a6SLisandro Dalcin     } else {
467efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default drop tolerance \n");CHKERRQ(ierr);
46816d9e3a6SLisandro Dalcin     }
46916d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
470efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
47116d9e3a6SLisandro Dalcin     } else {
472efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default factor row size \n");CHKERRQ(ierr);
47316d9e3a6SLisandro Dalcin     }
47416d9e3a6SLisandro Dalcin   }
47516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
47616d9e3a6SLisandro Dalcin }
47716d9e3a6SLisandro Dalcin 
47816d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
47916d9e3a6SLisandro Dalcin 
48016d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
48116d9e3a6SLisandro Dalcin {
48216d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
48349a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
48416d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
48516d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
486d9ca1df4SBarry Smith   PetscScalar        *xv;
487d9ca1df4SBarry Smith   const PetscScalar  *bv;
48816d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
48916d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
4904ddd07fcSJed Brown   PetscInt           hierr;
49116d9e3a6SLisandro Dalcin 
49216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
493dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
49416d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
495d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
49616d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
49758968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)bv,sbv);
49858968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
49916d9e3a6SLisandro Dalcin 
50049a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
50149a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
50249a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
50316d9e3a6SLisandro Dalcin 
50416d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
50516d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
506e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
50716d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
50816d9e3a6SLisandro Dalcin 
50958968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,sbv,bv);
51058968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
51116d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
512d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
51316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
51416d9e3a6SLisandro Dalcin }
51516d9e3a6SLisandro Dalcin 
516a669f990SJed Brown /* static array length */
517a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
518a669f990SJed Brown 
51916d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
5200f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
52116d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
52265de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
5236a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]   = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
52465de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
52565de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
52665de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
52765de4495SJed Brown                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */,
52865de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
5290f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
530e2287abbSStefano Zampini                                                   "ext+i-cc", "standard", "standard-wts", "block", "block-wtd", "FF", "FF1"};
5314416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc)
53216d9e3a6SLisandro Dalcin {
53316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
53416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
5354ddd07fcSJed Brown   PetscInt       n,indx,level;
536ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
53716d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
53816d9e3a6SLisandro Dalcin 
53916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
540e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
5414336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
54216d9e3a6SLisandro Dalcin   if (flg) {
5434336a9eeSBarry Smith     jac->cycletype = indx+1;
544fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
54516d9e3a6SLisandro Dalcin   }
54616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
54716d9e3a6SLisandro Dalcin   if (flg) {
548ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
549fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
55016d9e3a6SLisandro Dalcin   }
55116d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
55216d9e3a6SLisandro Dalcin   if (flg) {
553ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
554fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
55516d9e3a6SLisandro Dalcin   }
5560f1074feSSatish 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);
55716d9e3a6SLisandro Dalcin   if (flg) {
55857622a8eSBarry 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);
559fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
56016d9e3a6SLisandro Dalcin   }
56116d9e3a6SLisandro Dalcin 
5620f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
56316d9e3a6SLisandro Dalcin   if (flg) {
56457622a8eSBarry 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);
565fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
56616d9e3a6SLisandro Dalcin   }
56716d9e3a6SLisandro Dalcin 
5680f1074feSSatish 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);
5690f1074feSSatish Balay   if (flg) {
57057622a8eSBarry 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);
571fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
5720f1074feSSatish Balay   }
5730f1074feSSatish Balay 
5740f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
5750f1074feSSatish Balay   if (flg) {
57657622a8eSBarry 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);
5770f1074feSSatish Balay 
578fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
5790f1074feSSatish Balay   }
5800f1074feSSatish Balay 
5810f1074feSSatish Balay 
5820f1074feSSatish 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);
5830f1074feSSatish Balay   if (flg) {
58457622a8eSBarry 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);
5850f1074feSSatish Balay 
586fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
5870f1074feSSatish Balay   }
5880f1074feSSatish Balay 
5890f1074feSSatish Balay 
59016d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
59116d9e3a6SLisandro Dalcin   if (flg) {
59257622a8eSBarry 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);
593fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
59416d9e3a6SLisandro Dalcin   }
59516d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
59616d9e3a6SLisandro Dalcin   if (flg) {
59757622a8eSBarry 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);
59857622a8eSBarry 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);
599fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
60016d9e3a6SLisandro Dalcin   }
60116d9e3a6SLisandro Dalcin 
60216d9e3a6SLisandro Dalcin   /* Grid sweeps */
6030f1074feSSatish 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);
60416d9e3a6SLisandro Dalcin   if (flg) {
605fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
60616d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
60716d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
6080f1074feSSatish Balay     jac->gridsweeps[1] = indx;
6090f1074feSSatish Balay     /*defaults coarse to 1 */
6100f1074feSSatish Balay     jac->gridsweeps[2] = 1;
61116d9e3a6SLisandro Dalcin   }
6120f1074feSSatish Balay 
6135272c319SBarry 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);
6145272c319SBarry Smith   if (flg) {
6155272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,jac->nodal_coarsening));
6165272c319SBarry Smith   }
6175272c319SBarry Smith 
618cbc39033SBarry 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);
6195272c319SBarry Smith   if (flg) {
6205272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,(jac->hsolver,jac->vec_interp_variant));
6215272c319SBarry Smith   }
6225272c319SBarry Smith 
6230f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
62416d9e3a6SLisandro Dalcin   if (flg) {
625fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
6260f1074feSSatish Balay     jac->gridsweeps[0] = indx;
62716d9e3a6SLisandro Dalcin   }
62816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
62916d9e3a6SLisandro Dalcin   if (flg) {
630fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
6310f1074feSSatish Balay     jac->gridsweeps[1] = indx;
63216d9e3a6SLisandro Dalcin   }
6330f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
63416d9e3a6SLisandro Dalcin   if (flg) {
635fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
6360f1074feSSatish Balay     jac->gridsweeps[2] = indx;
63716d9e3a6SLisandro Dalcin   }
63816d9e3a6SLisandro Dalcin 
6396a251517SEike Mueller   /* Smooth type */
6406a251517SEike Mueller   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);
6416a251517SEike Mueller   if (flg) {
6426a251517SEike Mueller     jac->smoothtype = indx;
6436a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
6448131ecf7SEike Mueller     jac->smoothnumlevels = 25;
6458131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
6468131ecf7SEike Mueller   }
6478131ecf7SEike Mueller 
6488131ecf7SEike Mueller   /* Number of smoothing levels */
6498131ecf7SEike 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);
6508131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
6518131ecf7SEike Mueller     jac->smoothnumlevels = indx;
6528131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
6536a251517SEike Mueller   }
6546a251517SEike Mueller 
6551810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
6561810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
6571810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
6581810e44eSEike Mueller     jac->eu_level = indx;
6591810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
6601810e44eSEike Mueller   }
6611810e44eSEike Mueller 
6621810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
6631810e44eSEike Mueller   double droptolerance;
6641810e44eSEike Mueller   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
6651810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
6661810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
6671810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
6681810e44eSEike Mueller   }
6691810e44eSEike Mueller 
6701810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
6711810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
6721810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
6731810e44eSEike Mueller     jac->eu_bj = tmp_truth;
674493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
6751810e44eSEike Mueller   }
6761810e44eSEike Mueller 
67716d9e3a6SLisandro Dalcin   /* Relax type */
678a669f990SJed 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);
67916d9e3a6SLisandro Dalcin   if (flg) {
6800f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
681fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
6820f1074feSSatish Balay     /* by default, coarse type set to 9 */
6830f1074feSSatish Balay     jac->relaxtype[2] = 9;
6840f1074feSSatish Balay 
68516d9e3a6SLisandro Dalcin   }
686a669f990SJed 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);
68716d9e3a6SLisandro Dalcin   if (flg) {
68816d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
689fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
69016d9e3a6SLisandro Dalcin   }
691a669f990SJed 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);
69216d9e3a6SLisandro Dalcin   if (flg) {
6930f1074feSSatish Balay     jac->relaxtype[1] = indx;
694fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
69516d9e3a6SLisandro Dalcin   }
696a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
69716d9e3a6SLisandro Dalcin   if (flg) {
6980f1074feSSatish Balay     jac->relaxtype[2] = indx;
699fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
70016d9e3a6SLisandro Dalcin   }
70116d9e3a6SLisandro Dalcin 
70216d9e3a6SLisandro Dalcin   /* Relaxation Weight */
70316d9e3a6SLisandro 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);
70416d9e3a6SLisandro Dalcin   if (flg) {
705fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
70616d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
70716d9e3a6SLisandro Dalcin   }
70816d9e3a6SLisandro Dalcin 
70916d9e3a6SLisandro Dalcin   n         = 2;
71016d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
71116d9e3a6SLisandro 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);
71216d9e3a6SLisandro Dalcin   if (flg) {
71316d9e3a6SLisandro Dalcin     if (n == 2) {
71416d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
715fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
716ce94432eSBarry 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);
71716d9e3a6SLisandro Dalcin   }
71816d9e3a6SLisandro Dalcin 
71916d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
72016d9e3a6SLisandro 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);
72116d9e3a6SLisandro Dalcin   if (flg) {
722fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
72316d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
72416d9e3a6SLisandro Dalcin   }
72516d9e3a6SLisandro Dalcin 
72616d9e3a6SLisandro Dalcin   n         = 2;
72716d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
72816d9e3a6SLisandro 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);
72916d9e3a6SLisandro Dalcin   if (flg) {
73016d9e3a6SLisandro Dalcin     if (n == 2) {
73116d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
732fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
733ce94432eSBarry 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);
73416d9e3a6SLisandro Dalcin   }
73516d9e3a6SLisandro Dalcin 
73616d9e3a6SLisandro Dalcin   /* the Relax Order */
737acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
73816d9e3a6SLisandro Dalcin 
7398afaa268SBarry Smith   if (flg && tmp_truth) {
74016d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
741fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
74216d9e3a6SLisandro Dalcin   }
743a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
74416d9e3a6SLisandro Dalcin   if (flg) {
74516d9e3a6SLisandro Dalcin     jac->measuretype = indx;
746fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
74716d9e3a6SLisandro Dalcin   }
7480f1074feSSatish Balay   /* update list length 3/07 */
749a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
75016d9e3a6SLisandro Dalcin   if (flg) {
75116d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
752fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
75316d9e3a6SLisandro Dalcin   }
7540f1074feSSatish Balay 
7550f1074feSSatish Balay   /* new 3/07 */
756a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
7570f1074feSSatish Balay   if (flg) {
7580f1074feSSatish Balay     jac->interptype = indx;
759fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
7600f1074feSSatish Balay   }
7610f1074feSSatish Balay 
762b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
76316d9e3a6SLisandro Dalcin   if (flg) {
764b96a4a96SBarry Smith     level = 3;
7650298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
7662fa5cd67SKarl Rupp 
767b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
768fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
7692ae77aedSBarry Smith   }
7702ae77aedSBarry Smith 
771b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
7722ae77aedSBarry Smith   if (flg) {
773b96a4a96SBarry Smith     level = 3;
7740298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
7752fa5cd67SKarl Rupp 
776b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
777fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
77816d9e3a6SLisandro Dalcin   }
7798f87f92bSBarry Smith 
780acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
7818f87f92bSBarry Smith   if (flg && tmp_truth) {
7828f87f92bSBarry Smith     PetscInt tmp_int;
7838f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
7848f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
785fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
786fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
787fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
788fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
7898f87f92bSBarry Smith   }
7908f87f92bSBarry Smith 
79116d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
79216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
79316d9e3a6SLisandro Dalcin }
79416d9e3a6SLisandro Dalcin 
795ace3abfcSBarry 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)
79616d9e3a6SLisandro Dalcin {
79716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
79816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
7994ddd07fcSJed Brown   PetscInt       oits;
80016d9e3a6SLisandro Dalcin 
80116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
802dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
803fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
804fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
80516d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
80616d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
80716d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
8088b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
8094d0a8057SBarry Smith   *outits = oits;
8104d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
8114d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
812fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
813fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
81416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
81516d9e3a6SLisandro Dalcin }
81616d9e3a6SLisandro Dalcin 
81716d9e3a6SLisandro Dalcin 
81816d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
81916d9e3a6SLisandro Dalcin {
82016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
82116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
822ace3abfcSBarry Smith   PetscBool      iascii;
82316d9e3a6SLisandro Dalcin 
82416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
825251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
82616d9e3a6SLisandro Dalcin   if (iascii) {
82716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
828efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
829efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
830efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
831efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
832efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
833efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
834efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
835efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
836efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
8370f1074feSSatish Balay 
838efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
83916d9e3a6SLisandro Dalcin 
840efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
841efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
842efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
84316d9e3a6SLisandro Dalcin 
844efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
845efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
846efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
84716d9e3a6SLisandro Dalcin 
848efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
849efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
85016d9e3a6SLisandro Dalcin 
85116d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
852efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using CF-relaxation\n");CHKERRQ(ierr);
85316d9e3a6SLisandro Dalcin     } else {
854efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using CF-relaxation\n");CHKERRQ(ierr);
85516d9e3a6SLisandro Dalcin     }
8566a251517SEike Mueller     if (jac->smoothtype!=-1) {
857efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
858efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth num levels    %d\n",jac->smoothnumlevels);CHKERRQ(ierr);
8597e352d70SEike Mueller     } else {
860efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using more complex smoothers.\n");CHKERRQ(ierr);
8611810e44eSEike Mueller     }
8621810e44eSEike Mueller     if (jac->smoothtype==3) {
863efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) levels %d\n",jac->eu_level);CHKERRQ(ierr);
864efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) drop tolerance %g\n",jac->eu_droptolerance);CHKERRQ(ierr);
865efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU use Block-Jacobi? %d\n",jac->eu_bj);CHKERRQ(ierr);
8666a251517SEike Mueller     }
867efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
868efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
869efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
8705272c319SBarry Smith     if (jac->nodal_coarsening) {
871efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
8725272c319SBarry Smith     }
8735272c319SBarry Smith     if (jac->vec_interp_variant) {
874efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
8758f87f92bSBarry Smith     }
8768f87f92bSBarry Smith     if (jac->nodal_relax) {
877efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
8788f87f92bSBarry Smith     }
87916d9e3a6SLisandro Dalcin   }
88016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
88116d9e3a6SLisandro Dalcin }
88216d9e3a6SLisandro Dalcin 
88316d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
8844416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc)
88516d9e3a6SLisandro Dalcin {
88616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
88716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
8884ddd07fcSJed Brown   PetscInt       indx;
889ace3abfcSBarry Smith   PetscBool      flag;
89016d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
89116d9e3a6SLisandro Dalcin 
89216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
893e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
89416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
89516d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
8962fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
89716d9e3a6SLisandro Dalcin 
89816d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
8992fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
90016d9e3a6SLisandro Dalcin 
90116d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
9022fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
90316d9e3a6SLisandro Dalcin 
904acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
9052fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
90616d9e3a6SLisandro Dalcin 
907acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
9082fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
90916d9e3a6SLisandro Dalcin 
910a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
91116d9e3a6SLisandro Dalcin   if (flag) {
91216d9e3a6SLisandro Dalcin     jac->symt = indx;
913fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
91416d9e3a6SLisandro Dalcin   }
91516d9e3a6SLisandro Dalcin 
91616d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
91716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
91816d9e3a6SLisandro Dalcin }
91916d9e3a6SLisandro Dalcin 
92016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
92116d9e3a6SLisandro Dalcin {
92216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
92316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
924ace3abfcSBarry Smith   PetscBool      iascii;
92516d9e3a6SLisandro Dalcin   const char     *symt = 0;;
92616d9e3a6SLisandro Dalcin 
92716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
928251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
92916d9e3a6SLisandro Dalcin   if (iascii) {
93016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
931efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
932efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
933efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    filter %g\n",(double)jac->filter);CHKERRQ(ierr);
934efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
935efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
936efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
9372fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
9382fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
9392fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
940ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
941efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    %s\n",symt);CHKERRQ(ierr);
94216d9e3a6SLisandro Dalcin   }
94316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
94416d9e3a6SLisandro Dalcin }
9454cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
9464416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc)
9474cb006feSStefano Zampini {
9484cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
9494cb006feSStefano Zampini   PetscErrorCode ierr;
9504cb006feSStefano Zampini   PetscInt       n;
9514cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
9524cb006feSStefano Zampini 
9534cb006feSStefano Zampini   PetscFunctionBegin;
9549fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
955863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
956863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
957863406b8SStefano 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);
958863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
9594cb006feSStefano 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);
9604cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
961863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
962863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
963863406b8SStefano 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);
964863406b8SStefano 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);
965863406b8SStefano 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);
966863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
9674cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
968863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
969863406b8SStefano Zampini                                                                       jac->as_relax_times,
970863406b8SStefano Zampini                                                                       jac->as_relax_weight,
971863406b8SStefano Zampini                                                                       jac->as_omega));
9724cb006feSStefano Zampini   }
973863406b8SStefano 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);
9744cb006feSStefano Zampini   n = 5;
975863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
9764cb006feSStefano Zampini   if (flag || flag2) {
977863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
978863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
979863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
980863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
981863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
982863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
9834cb006feSStefano Zampini   }
984863406b8SStefano 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);
9854cb006feSStefano Zampini   n = 5;
986863406b8SStefano 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);
9874cb006feSStefano Zampini   if (flag || flag2) {
988863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
989863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
990863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
991863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
992863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
993863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
9944cb006feSStefano Zampini   }
99523df4f25SStefano 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);
99623df4f25SStefano Zampini   if (flag) { /* override HYPRE's default only if the options is used */
99723df4f25SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetProjectionFrequency,(jac->hsolver,jac->ams_proj_freq));
99823df4f25SStefano Zampini   }
9994cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
10004cb006feSStefano Zampini   PetscFunctionReturn(0);
10014cb006feSStefano Zampini }
10024cb006feSStefano Zampini 
10034cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
10044cb006feSStefano Zampini {
10054cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
10064cb006feSStefano Zampini   PetscErrorCode ierr;
10074cb006feSStefano Zampini   PetscBool      iascii;
10084cb006feSStefano Zampini 
10094cb006feSStefano Zampini   PetscFunctionBegin;
10104cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
10114cb006feSStefano Zampini   if (iascii) {
10124cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
1013efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1014efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1015efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1016efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1017efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1018efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1019efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
10204cb006feSStefano Zampini     if (jac->alpha_Poisson) {
1021efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
10224cb006feSStefano Zampini     } else {
1023efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (computed) \n");CHKERRQ(ierr);
10244cb006feSStefano Zampini     }
1025efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1026efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1027efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1028efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1029efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1030efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
10314cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
10324cb006feSStefano Zampini       if (jac->beta_Poisson) {
1033efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
10344cb006feSStefano Zampini       } else {
1035efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (computed) \n");CHKERRQ(ierr);
10364cb006feSStefano Zampini       }
1037efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1038efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1039efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1040efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1041efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1042efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
104323df4f25SStefano Zampini       if (jac->ams_beta_is_zero_part) {
1044efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"        compatible subspace projection frequency %d (-1 HYPRE uses default)\n",jac->ams_proj_freq);CHKERRQ(ierr);
104523df4f25SStefano Zampini       }
104623df4f25SStefano Zampini     } else {
1047efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver not used (zero-conductivity everywhere) \n");CHKERRQ(ierr);
10484cb006feSStefano Zampini     }
10494cb006feSStefano Zampini   }
10504cb006feSStefano Zampini   PetscFunctionReturn(0);
10514cb006feSStefano Zampini }
10524cb006feSStefano Zampini 
10534416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc)
1054863406b8SStefano Zampini {
1055863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1056863406b8SStefano Zampini   PetscErrorCode ierr;
1057863406b8SStefano Zampini   PetscInt       n;
1058863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
1059863406b8SStefano Zampini 
1060863406b8SStefano Zampini   PetscFunctionBegin;
1061863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
1062863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1063863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1064863406b8SStefano 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);
1065863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1066863406b8SStefano 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);
1067863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
1068863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1069863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1070863406b8SStefano 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);
1071863406b8SStefano 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);
1072863406b8SStefano 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);
1073863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
1074863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1075863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1076863406b8SStefano Zampini                                                                       jac->as_relax_times,
1077863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1078863406b8SStefano Zampini                                                                       jac->as_omega));
1079863406b8SStefano Zampini   }
1080863406b8SStefano 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);
1081863406b8SStefano Zampini   n = 5;
1082863406b8SStefano 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);
1083863406b8SStefano 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);
1084863406b8SStefano Zampini   if (flag || flag2 || flag3) {
1085863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
1086863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1087863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1088863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1089863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1090863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1091863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1092863406b8SStefano Zampini   }
1093863406b8SStefano 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);
1094863406b8SStefano Zampini   n = 5;
1095863406b8SStefano 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);
1096863406b8SStefano Zampini   if (flag || flag2) {
1097863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1098863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1099863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1100863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1101863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1102863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1103863406b8SStefano Zampini   }
1104863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
1105863406b8SStefano Zampini   PetscFunctionReturn(0);
1106863406b8SStefano Zampini }
1107863406b8SStefano Zampini 
1108863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1109863406b8SStefano Zampini {
1110863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1111863406b8SStefano Zampini   PetscErrorCode ierr;
1112863406b8SStefano Zampini   PetscBool      iascii;
1113863406b8SStefano Zampini 
1114863406b8SStefano Zampini   PetscFunctionBegin;
1115863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1116863406b8SStefano Zampini   if (iascii) {
1117863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
1118efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1119efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
1120efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1121efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1122efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1123efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1124efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
1125efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    AMS solver using boomerAMG\n");CHKERRQ(ierr);
1126efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1127efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1128efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1129efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1130efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1131efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1132efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
1133efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver using boomerAMG\n");CHKERRQ(ierr);
1134efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1135efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1136efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1137efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1138efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1139efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
1140863406b8SStefano Zampini   }
1141863406b8SStefano Zampini   PetscFunctionReturn(0);
1142863406b8SStefano Zampini }
1143863406b8SStefano Zampini 
1144863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
11454cb006feSStefano Zampini {
11464cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
11475ac14e1cSStefano Zampini   PetscBool      ishypre;
11484cb006feSStefano Zampini   PetscErrorCode ierr;
11494cb006feSStefano Zampini 
11504cb006feSStefano Zampini   PetscFunctionBegin;
11515ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)G,MATHYPRE,&ishypre);CHKERRQ(ierr);
11525ac14e1cSStefano Zampini   if (ishypre) {
11535ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr);
11545ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
11555ac14e1cSStefano Zampini     jac->G = G;
11565ac14e1cSStefano Zampini   } else {
1157*6bf688a0SCe Qin     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
1158*6bf688a0SCe Qin     ierr = MatConvert(G,MATHYPRE,MAT_INITIAL_MATRIX,&jac->G);CHKERRQ(ierr);
11595ac14e1cSStefano Zampini   }
11604cb006feSStefano Zampini   PetscFunctionReturn(0);
11614cb006feSStefano Zampini }
11624cb006feSStefano Zampini 
11634cb006feSStefano Zampini /*@
11644cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
11654cb006feSStefano Zampini 
11664cb006feSStefano Zampini    Collective on PC
11674cb006feSStefano Zampini 
11684cb006feSStefano Zampini    Input Parameters:
11694cb006feSStefano Zampini +  pc - the preconditioning context
11704cb006feSStefano Zampini -  G - the discrete gradient
11714cb006feSStefano Zampini 
11724cb006feSStefano Zampini    Level: intermediate
11734cb006feSStefano Zampini 
11744cb006feSStefano 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
1175863406b8SStefano 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
11764cb006feSStefano Zampini 
11774cb006feSStefano Zampini .seealso:
11784cb006feSStefano Zampini @*/
11794cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
11804cb006feSStefano Zampini {
11814cb006feSStefano Zampini   PetscErrorCode ierr;
11824cb006feSStefano Zampini 
11834cb006feSStefano Zampini   PetscFunctionBegin;
11844cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11854cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
11864cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
11874cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
11884cb006feSStefano Zampini   PetscFunctionReturn(0);
11894cb006feSStefano Zampini }
11904cb006feSStefano Zampini 
1191863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1192863406b8SStefano Zampini {
1193863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
11945ac14e1cSStefano Zampini   PetscBool      ishypre;
1195863406b8SStefano Zampini   PetscErrorCode ierr;
1196863406b8SStefano Zampini 
1197863406b8SStefano Zampini   PetscFunctionBegin;
11985ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)C,MATHYPRE,&ishypre);CHKERRQ(ierr);
11995ac14e1cSStefano Zampini   if (ishypre) {
12005ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr);
12015ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
12025ac14e1cSStefano Zampini     jac->C = C;
12035ac14e1cSStefano Zampini   } else {
1204*6bf688a0SCe Qin     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
1205*6bf688a0SCe Qin     ierr = MatConvert(C,MATHYPRE,MAT_INITIAL_MATRIX,&jac->C);CHKERRQ(ierr);
12065ac14e1cSStefano Zampini   }
1207863406b8SStefano Zampini   PetscFunctionReturn(0);
1208863406b8SStefano Zampini }
1209863406b8SStefano Zampini 
1210863406b8SStefano Zampini /*@
1211863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1212863406b8SStefano Zampini 
1213863406b8SStefano Zampini    Collective on PC
1214863406b8SStefano Zampini 
1215863406b8SStefano Zampini    Input Parameters:
1216863406b8SStefano Zampini +  pc - the preconditioning context
1217863406b8SStefano Zampini -  C - the discrete curl
1218863406b8SStefano Zampini 
1219863406b8SStefano Zampini    Level: intermediate
1220863406b8SStefano Zampini 
1221863406b8SStefano 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
1222863406b8SStefano 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
1223863406b8SStefano Zampini 
1224863406b8SStefano Zampini .seealso:
1225863406b8SStefano Zampini @*/
1226863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1227863406b8SStefano Zampini {
1228863406b8SStefano Zampini   PetscErrorCode ierr;
1229863406b8SStefano Zampini 
1230863406b8SStefano Zampini   PetscFunctionBegin;
1231863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1232863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1233863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1234863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1235863406b8SStefano Zampini   PetscFunctionReturn(0);
1236863406b8SStefano Zampini }
1237863406b8SStefano Zampini 
1238*6bf688a0SCe Qin static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
1239*6bf688a0SCe Qin {
1240*6bf688a0SCe Qin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1241*6bf688a0SCe Qin   PetscBool      ishypre;
1242*6bf688a0SCe Qin   PetscErrorCode ierr;
1243*6bf688a0SCe Qin   PetscInt       i;
1244*6bf688a0SCe Qin   PetscFunctionBegin;
1245*6bf688a0SCe Qin 
1246*6bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
1247*6bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
1248*6bf688a0SCe Qin   for (i=0;i<3;++i) {
1249*6bf688a0SCe Qin     ierr = MatDestroy(&jac->RT_Pi[i]);CHKERRQ(ierr);
1250*6bf688a0SCe Qin     ierr = MatDestroy(&jac->ND_Pi[i]);CHKERRQ(ierr);
1251*6bf688a0SCe Qin   }
1252*6bf688a0SCe Qin 
1253*6bf688a0SCe Qin   jac->dim = dim;
1254*6bf688a0SCe Qin   if (RT_PiFull) {
1255*6bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)RT_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
1256*6bf688a0SCe Qin     if (ishypre) {
1257*6bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)RT_PiFull);CHKERRQ(ierr);
1258*6bf688a0SCe Qin       jac->RT_PiFull = RT_PiFull;
1259*6bf688a0SCe Qin     } else {
1260*6bf688a0SCe Qin       ierr = MatConvert(RT_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_PiFull);CHKERRQ(ierr);
1261*6bf688a0SCe Qin     }
1262*6bf688a0SCe Qin   }
1263*6bf688a0SCe Qin   if (RT_Pi) {
1264*6bf688a0SCe Qin     for (i=0;i<dim;++i) {
1265*6bf688a0SCe Qin       if (RT_Pi[i]) {
1266*6bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)RT_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
1267*6bf688a0SCe Qin         if (ishypre) {
1268*6bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)RT_Pi[i]);CHKERRQ(ierr);
1269*6bf688a0SCe Qin           jac->RT_Pi[i] = RT_Pi[i];
1270*6bf688a0SCe Qin         } else {
1271*6bf688a0SCe Qin           ierr = MatConvert(RT_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_Pi[i]);CHKERRQ(ierr);
1272*6bf688a0SCe Qin         }
1273*6bf688a0SCe Qin       }
1274*6bf688a0SCe Qin     }
1275*6bf688a0SCe Qin   }
1276*6bf688a0SCe Qin   if (ND_PiFull) {
1277*6bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)ND_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
1278*6bf688a0SCe Qin     if (ishypre) {
1279*6bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)ND_PiFull);CHKERRQ(ierr);
1280*6bf688a0SCe Qin       jac->ND_PiFull = ND_PiFull;
1281*6bf688a0SCe Qin     } else {
1282*6bf688a0SCe Qin       ierr = MatConvert(ND_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_PiFull);CHKERRQ(ierr);
1283*6bf688a0SCe Qin     }
1284*6bf688a0SCe Qin   }
1285*6bf688a0SCe Qin   if (ND_Pi) {
1286*6bf688a0SCe Qin     for (i=0;i<dim;++i) {
1287*6bf688a0SCe Qin       if (ND_Pi[i]) {
1288*6bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)ND_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
1289*6bf688a0SCe Qin         if (ishypre) {
1290*6bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)ND_Pi[i]);CHKERRQ(ierr);
1291*6bf688a0SCe Qin           jac->ND_Pi[i] = ND_Pi[i];
1292*6bf688a0SCe Qin         } else {
1293*6bf688a0SCe Qin           ierr = MatConvert(ND_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_Pi[i]);CHKERRQ(ierr);
1294*6bf688a0SCe Qin         }
1295*6bf688a0SCe Qin       }
1296*6bf688a0SCe Qin     }
1297*6bf688a0SCe Qin   }
1298*6bf688a0SCe Qin 
1299*6bf688a0SCe Qin   PetscFunctionReturn(0);
1300*6bf688a0SCe Qin }
1301*6bf688a0SCe Qin 
1302*6bf688a0SCe Qin /*@
1303*6bf688a0SCe Qin  PCHYPRESetInterpolations - Set interpolation matrices for AMS/ADS preconditioner
1304*6bf688a0SCe Qin 
1305*6bf688a0SCe Qin    Collective on PC
1306*6bf688a0SCe Qin 
1307*6bf688a0SCe Qin    Input Parameters:
1308*6bf688a0SCe Qin +  pc - the preconditioning context
1309*6bf688a0SCe Qin -  dim - the dimension of the problem, only used in AMS
1310*6bf688a0SCe Qin -  RT_PiFull - Raviart-Thomas interpolation matrix
1311*6bf688a0SCe Qin -  RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix
1312*6bf688a0SCe Qin -  ND_PiFull - Nedelec interpolation matrix
1313*6bf688a0SCe Qin -  ND_Pi - x/y/z component of Nedelec interpolation matrix
1314*6bf688a0SCe Qin 
1315*6bf688a0SCe Qin    Notes: For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL.
1316*6bf688a0SCe Qin           For ADS, both type of interpolation matrices are needed.
1317*6bf688a0SCe Qin    Level: intermediate
1318*6bf688a0SCe Qin 
1319*6bf688a0SCe Qin .seealso:
1320*6bf688a0SCe Qin @*/
1321*6bf688a0SCe Qin PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
1322*6bf688a0SCe Qin {
1323*6bf688a0SCe Qin   PetscErrorCode ierr;
1324*6bf688a0SCe Qin   PetscInt       i;
1325*6bf688a0SCe Qin 
1326*6bf688a0SCe Qin   PetscFunctionBegin;
1327*6bf688a0SCe Qin   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1328*6bf688a0SCe Qin   if (RT_PiFull) {
1329*6bf688a0SCe Qin     PetscValidHeaderSpecific(RT_PiFull,MAT_CLASSID,3);
1330*6bf688a0SCe Qin     PetscCheckSameComm(pc,1,RT_PiFull,3);
1331*6bf688a0SCe Qin   }
1332*6bf688a0SCe Qin   if (RT_Pi) {
1333*6bf688a0SCe Qin     PetscValidPointer(RT_Pi,4);
1334*6bf688a0SCe Qin     for (i=0;i<dim;++i) {
1335*6bf688a0SCe Qin       if (RT_Pi[i]) {
1336*6bf688a0SCe Qin         PetscValidHeaderSpecific(RT_Pi[i],MAT_CLASSID,4);
1337*6bf688a0SCe Qin         PetscCheckSameComm(pc,1,RT_Pi[i],4);
1338*6bf688a0SCe Qin       }
1339*6bf688a0SCe Qin     }
1340*6bf688a0SCe Qin   }
1341*6bf688a0SCe Qin   if (ND_PiFull) {
1342*6bf688a0SCe Qin     PetscValidHeaderSpecific(ND_PiFull,MAT_CLASSID,5);
1343*6bf688a0SCe Qin     PetscCheckSameComm(pc,1,ND_PiFull,5);
1344*6bf688a0SCe Qin   }
1345*6bf688a0SCe Qin   if (ND_Pi) {
1346*6bf688a0SCe Qin     PetscValidPointer(ND_Pi,6);
1347*6bf688a0SCe Qin     for (i=0;i<dim;++i) {
1348*6bf688a0SCe Qin       if (ND_Pi[i]) {
1349*6bf688a0SCe Qin         PetscValidHeaderSpecific(ND_Pi[i],MAT_CLASSID,6);
1350*6bf688a0SCe Qin         PetscCheckSameComm(pc,1,ND_Pi[i],6);
1351*6bf688a0SCe Qin       }
1352*6bf688a0SCe Qin     }
1353*6bf688a0SCe Qin   }
1354*6bf688a0SCe Qin   ierr = PetscTryMethod(pc,"PCHYPRESetInterpolations_C",(PC,PetscInt,Mat,Mat[],Mat,Mat[]),(pc,dim,RT_PiFull,RT_Pi,ND_PiFull,ND_Pi));CHKERRQ(ierr);
1355*6bf688a0SCe Qin   PetscFunctionReturn(0);
1356*6bf688a0SCe Qin }
1357*6bf688a0SCe Qin 
13585ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha)
13594cb006feSStefano Zampini {
13604cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
13615ac14e1cSStefano Zampini   PetscBool      ishypre;
13624cb006feSStefano Zampini   PetscErrorCode ierr;
13634cb006feSStefano Zampini 
13644cb006feSStefano Zampini   PetscFunctionBegin;
13655ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr);
13665ac14e1cSStefano Zampini   if (ishypre) {
13675ac14e1cSStefano Zampini     if (isalpha) {
13685ac14e1cSStefano Zampini       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
13695ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
13705ac14e1cSStefano Zampini       jac->alpha_Poisson = A;
13715ac14e1cSStefano Zampini     } else {
13725ac14e1cSStefano Zampini       if (A) {
13735ac14e1cSStefano Zampini         ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
13745ac14e1cSStefano Zampini       } else {
13755ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
13765ac14e1cSStefano Zampini       }
13775ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
13785ac14e1cSStefano Zampini       jac->beta_Poisson = A;
13795ac14e1cSStefano Zampini     }
13805ac14e1cSStefano Zampini   } else {
13815ac14e1cSStefano Zampini     if (isalpha) {
1382*6bf688a0SCe Qin       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
1383*6bf688a0SCe Qin       ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->alpha_Poisson);CHKERRQ(ierr);
13845ac14e1cSStefano Zampini     } else {
13855ac14e1cSStefano Zampini       if (A) {
1386*6bf688a0SCe Qin         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
1387*6bf688a0SCe Qin         ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->beta_Poisson);CHKERRQ(ierr);
13885ac14e1cSStefano Zampini       } else {
13895ac14e1cSStefano Zampini         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
13905ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
13915ac14e1cSStefano Zampini       }
13925ac14e1cSStefano Zampini     }
13935ac14e1cSStefano Zampini   }
13944cb006feSStefano Zampini   PetscFunctionReturn(0);
13954cb006feSStefano Zampini }
13964cb006feSStefano Zampini 
13974cb006feSStefano Zampini /*@
13984cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
13994cb006feSStefano Zampini 
14004cb006feSStefano Zampini    Collective on PC
14014cb006feSStefano Zampini 
14024cb006feSStefano Zampini    Input Parameters:
14034cb006feSStefano Zampini +  pc - the preconditioning context
14044cb006feSStefano Zampini -  A - the matrix
14054cb006feSStefano Zampini 
14064cb006feSStefano Zampini    Level: intermediate
14074cb006feSStefano Zampini 
14084cb006feSStefano Zampini    Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
14094cb006feSStefano Zampini 
14104cb006feSStefano Zampini .seealso:
14114cb006feSStefano Zampini @*/
14124cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
14134cb006feSStefano Zampini {
14144cb006feSStefano Zampini   PetscErrorCode ierr;
14154cb006feSStefano Zampini 
14164cb006feSStefano Zampini   PetscFunctionBegin;
14174cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
14184cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
14194cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
14205ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_TRUE));CHKERRQ(ierr);
14214cb006feSStefano Zampini   PetscFunctionReturn(0);
14224cb006feSStefano Zampini }
14234cb006feSStefano Zampini 
14244cb006feSStefano Zampini /*@
14254cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
14264cb006feSStefano Zampini 
14274cb006feSStefano Zampini    Collective on PC
14284cb006feSStefano Zampini 
14294cb006feSStefano Zampini    Input Parameters:
14304cb006feSStefano Zampini +  pc - the preconditioning context
14314cb006feSStefano Zampini -  A - the matrix
14324cb006feSStefano Zampini 
14334cb006feSStefano Zampini    Level: intermediate
14344cb006feSStefano Zampini 
14354cb006feSStefano Zampini    Notes: A should be obtained by discretizing the Poisson problem with linear finite elements.
14364cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
14374cb006feSStefano Zampini 
14384cb006feSStefano Zampini .seealso:
14394cb006feSStefano Zampini @*/
14404cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
14414cb006feSStefano Zampini {
14424cb006feSStefano Zampini   PetscErrorCode ierr;
14434cb006feSStefano Zampini 
14444cb006feSStefano Zampini   PetscFunctionBegin;
14454cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
14464cb006feSStefano Zampini   if (A) {
14474cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
14484cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
14494cb006feSStefano Zampini   }
14505ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_FALSE));CHKERRQ(ierr);
14514cb006feSStefano Zampini   PetscFunctionReturn(0);
14524cb006feSStefano Zampini }
14534cb006feSStefano Zampini 
14545ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz, Vec zoz, Vec zzo)
14554cb006feSStefano Zampini {
14564cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
14574cb006feSStefano Zampini   PetscErrorCode     ierr;
14584cb006feSStefano Zampini 
14594cb006feSStefano Zampini   PetscFunctionBegin;
14604cb006feSStefano Zampini   /* throw away any vector if already set */
14614cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
14624cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
14634cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
14644cb006feSStefano Zampini   jac->constants[0] = NULL;
14654cb006feSStefano Zampini   jac->constants[1] = NULL;
14664cb006feSStefano Zampini   jac->constants[2] = NULL;
14674cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
14684cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
14694cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
14704cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
14715ac14e1cSStefano Zampini   jac->dim = 2;
14724cb006feSStefano Zampini   if (zzo) {
14734cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
14744cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
14755ac14e1cSStefano Zampini     jac->dim++;
14764cb006feSStefano Zampini   }
14774cb006feSStefano Zampini   PetscFunctionReturn(0);
14784cb006feSStefano Zampini }
14794cb006feSStefano Zampini 
14804cb006feSStefano Zampini /*@
14814cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
14824cb006feSStefano Zampini 
14834cb006feSStefano Zampini    Collective on PC
14844cb006feSStefano Zampini 
14854cb006feSStefano Zampini    Input Parameters:
14864cb006feSStefano Zampini +  pc - the preconditioning context
14874cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
14884cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
14894cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
14904cb006feSStefano Zampini 
14914cb006feSStefano Zampini    Level: intermediate
14924cb006feSStefano Zampini 
14934cb006feSStefano Zampini    Notes:
14944cb006feSStefano Zampini 
14954cb006feSStefano Zampini .seealso:
14964cb006feSStefano Zampini @*/
14974cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
14984cb006feSStefano Zampini {
14994cb006feSStefano Zampini   PetscErrorCode ierr;
15004cb006feSStefano Zampini 
15014cb006feSStefano Zampini   PetscFunctionBegin;
15024cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15034cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
15044cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
15054cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
15064cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
15074cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
15084cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
15094cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
15104cb006feSStefano Zampini   PetscFunctionReturn(0);
15114cb006feSStefano Zampini }
15124cb006feSStefano Zampini 
1513863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
15144cb006feSStefano Zampini {
15154cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
15164cb006feSStefano Zampini   Vec             tv;
15174cb006feSStefano Zampini   PetscInt        i;
15184cb006feSStefano Zampini   PetscErrorCode  ierr;
15194cb006feSStefano Zampini 
15204cb006feSStefano Zampini   PetscFunctionBegin;
15214cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
15224cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
15234cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
15244cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
15255ac14e1cSStefano Zampini   jac->dim = dim;
15265ac14e1cSStefano Zampini 
15274cb006feSStefano Zampini   /* compute IJ vector for coordinates */
15284cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
15294cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
15304cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
15314cb006feSStefano Zampini   for (i=0;i<dim;i++) {
15324cb006feSStefano Zampini     PetscScalar *array;
15334cb006feSStefano Zampini     PetscInt    j;
15344cb006feSStefano Zampini 
15354cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
15364cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
15374cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
15384cb006feSStefano Zampini       array[j] = coords[j*dim+i];
15394cb006feSStefano Zampini     }
15404cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
15414cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
15424cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
15434cb006feSStefano Zampini   }
15444cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
15454cb006feSStefano Zampini   PetscFunctionReturn(0);
15464cb006feSStefano Zampini }
15474cb006feSStefano Zampini 
154816d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
154916d9e3a6SLisandro Dalcin 
1550f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
155116d9e3a6SLisandro Dalcin {
155216d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
155316d9e3a6SLisandro Dalcin 
155416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
155516d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
155616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
155716d9e3a6SLisandro Dalcin }
155816d9e3a6SLisandro Dalcin 
1559f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
156016d9e3a6SLisandro Dalcin {
156116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
156216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1563ace3abfcSBarry Smith   PetscBool      flag;
156416d9e3a6SLisandro Dalcin 
156516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
156616d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
156716d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1568ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
156916d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
157016d9e3a6SLisandro Dalcin   } else {
157116d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
157216d9e3a6SLisandro Dalcin   }
157316d9e3a6SLisandro Dalcin 
157416d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
157516d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
157616d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
157716d9e3a6SLisandro Dalcin 
157816d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
157916d9e3a6SLisandro Dalcin   if (flag) {
1580fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
158116d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
158216d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
158316d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
158416d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
158516d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
158616d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
158716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
158816d9e3a6SLisandro Dalcin   }
158916d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
159016d9e3a6SLisandro Dalcin   if (flag) {
1591fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
159216d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
159316d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
159416d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
159516d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
159616d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
159716d9e3a6SLisandro Dalcin     /* initialize */
159816d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
159916d9e3a6SLisandro Dalcin     jac->threshhold = .1;
160016d9e3a6SLisandro Dalcin     jac->filter     = .1;
160116d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
16022fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
16032fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
16042fa5cd67SKarl Rupp 
160516d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
160616d9e3a6SLisandro Dalcin     jac->symt = 0;
1607fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1608fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1609fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1610fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1611fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1612fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
161316d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
161416d9e3a6SLisandro Dalcin   }
161516d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
161616d9e3a6SLisandro Dalcin   if (flag) {
161716d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
161816d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
161916d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
162016d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
162116d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
162216d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
162316d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
162416d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
162516d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
162616d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
162716d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
162816d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
162916d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
16308f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
163116d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
163216d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
163316d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
163416d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
163516d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
16360f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
16376a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1638b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
16391810e44eSEike Mueller     jac->eu_level         = 0;
16401810e44eSEike Mueller     jac->eu_droptolerance = 0;
16411810e44eSEike Mueller     jac->eu_bj            = 0;
16428f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
16430f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
164416d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
164516d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
164616d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
16470f1074feSSatish Balay     jac->interptype       = 0;
16480f1074feSSatish Balay     jac->agg_nl           = 0;
16490f1074feSSatish Balay     jac->pmax             = 0;
16500f1074feSSatish Balay     jac->truncfactor      = 0.0;
16510f1074feSSatish Balay     jac->agg_num_paths    = 1;
16528f87f92bSBarry Smith 
16538f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
16548f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
16558f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1656fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1657fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1658fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1659fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1660fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1661fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1662fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1663fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1664fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1665fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1666fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1667fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1668fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1669fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1670fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1671fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
167216d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
167316d9e3a6SLisandro Dalcin   }
16744cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
16754cb006feSStefano Zampini   if (flag) {
16764cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
16774cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
16784cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
16794cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
16804cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
16814cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
16824cb006feSStefano Zampini     jac->coords[0]           = NULL;
16834cb006feSStefano Zampini     jac->coords[1]           = NULL;
16844cb006feSStefano Zampini     jac->coords[2]           = NULL;
16854cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1686863406b8SStefano Zampini     jac->as_print           = 0;
1687863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1688863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
16894cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
16904cb006feSStefano Zampini     /* Smoothing options */
1691863406b8SStefano Zampini     jac->as_relax_type      = 2;
1692863406b8SStefano Zampini     jac->as_relax_times     = 1;
1693863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1694863406b8SStefano Zampini     jac->as_omega           = 1.0;
16954cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1696863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1697863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
16980bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1699863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1700863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1701863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
17024cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1703863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1704863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
17050bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1706863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1707863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1708863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1709863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1710863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
17114cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1712863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1713863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1714863406b8SStefano Zampini                                                                       jac->as_relax_times,
1715863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1716863406b8SStefano Zampini                                                                       jac->as_omega));
1717863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1718863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1719863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1720863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1721863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1722863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1723863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1724863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1725863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1726863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1727863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1728863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
172923df4f25SStefano Zampini     /* Zero conductivity */
173023df4f25SStefano Zampini     jac->ams_beta_is_zero      = PETSC_FALSE;
173123df4f25SStefano Zampini     jac->ams_beta_is_zero_part = PETSC_FALSE;
17324cb006feSStefano Zampini     PetscFunctionReturn(0);
17334cb006feSStefano Zampini   }
1734863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1735863406b8SStefano Zampini   if (flag) {
1736863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1737863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1738863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1739863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1740863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1741863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1742863406b8SStefano Zampini     jac->coords[0]           = NULL;
1743863406b8SStefano Zampini     jac->coords[1]           = NULL;
1744863406b8SStefano Zampini     jac->coords[2]           = NULL;
1745863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1746863406b8SStefano Zampini     jac->as_print           = 0;
1747863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1748863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1749863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1750863406b8SStefano Zampini     /* Smoothing options */
1751863406b8SStefano Zampini     jac->as_relax_type      = 2;
1752863406b8SStefano Zampini     jac->as_relax_times     = 1;
1753863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1754863406b8SStefano Zampini     jac->as_omega           = 1.0;
1755863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1756863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1757863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1758863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1759863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1760863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1761863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1762863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1763863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1764863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1765863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1766863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1767863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1768863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1769863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1770863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1771863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1772863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1773863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1774863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1775863406b8SStefano Zampini                                                                       jac->as_relax_times,
1776863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1777863406b8SStefano Zampini                                                                       jac->as_omega));
1778863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1779863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1780863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1781863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1782863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1783863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1784863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1785863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1786863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1787863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1788863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1789863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1790863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1791863406b8SStefano Zampini     PetscFunctionReturn(0);
1792863406b8SStefano Zampini   }
1793503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
17942fa5cd67SKarl Rupp 
17950298fd71SBarry Smith   jac->hypre_type = NULL;
179633263987SBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, boomeramg, ams",name);
179716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
179816d9e3a6SLisandro Dalcin }
179916d9e3a6SLisandro Dalcin 
180016d9e3a6SLisandro Dalcin /*
180116d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
180216d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
180316d9e3a6SLisandro Dalcin */
18044416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc)
180516d9e3a6SLisandro Dalcin {
180616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
18074ddd07fcSJed Brown   PetscInt       indx;
1808863406b8SStefano Zampini   const char     *type[] = {"pilut","parasails","boomeramg","ams","ads"};
1809ace3abfcSBarry Smith   PetscBool      flg;
181016d9e3a6SLisandro Dalcin 
181116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
18129fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
18139c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
181416d9e3a6SLisandro Dalcin   if (flg) {
181516d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
181602a17cd4SBarry Smith   } else {
181702a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
181816d9e3a6SLisandro Dalcin   }
181916d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
18203931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
182116d9e3a6SLisandro Dalcin   }
182216d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
182316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
182416d9e3a6SLisandro Dalcin }
182516d9e3a6SLisandro Dalcin 
182616d9e3a6SLisandro Dalcin /*@C
182716d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
182816d9e3a6SLisandro Dalcin 
182916d9e3a6SLisandro Dalcin    Input Parameters:
183016d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1831863406b8SStefano Zampini -     name - either  pilut, parasails, boomeramg, ams, ads
183216d9e3a6SLisandro Dalcin 
183316d9e3a6SLisandro Dalcin    Options Database Keys:
1834863406b8SStefano Zampini    -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
183516d9e3a6SLisandro Dalcin 
183616d9e3a6SLisandro Dalcin    Level: intermediate
183716d9e3a6SLisandro Dalcin 
183816d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
183916d9e3a6SLisandro Dalcin            PCHYPRE
184016d9e3a6SLisandro Dalcin 
184116d9e3a6SLisandro Dalcin @*/
18427087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
184316d9e3a6SLisandro Dalcin {
18444ac538c5SBarry Smith   PetscErrorCode ierr;
184516d9e3a6SLisandro Dalcin 
184616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
18470700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
184816d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
18494ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
185016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
185116d9e3a6SLisandro Dalcin }
185216d9e3a6SLisandro Dalcin 
185316d9e3a6SLisandro Dalcin /*@C
185416d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
185516d9e3a6SLisandro Dalcin 
185616d9e3a6SLisandro Dalcin    Input Parameter:
185716d9e3a6SLisandro Dalcin .     pc - the preconditioner context
185816d9e3a6SLisandro Dalcin 
185916d9e3a6SLisandro Dalcin    Output Parameter:
1860863406b8SStefano Zampini .     name - either  pilut, parasails, boomeramg, ams, ads
186116d9e3a6SLisandro Dalcin 
186216d9e3a6SLisandro Dalcin    Level: intermediate
186316d9e3a6SLisandro Dalcin 
186416d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
186516d9e3a6SLisandro Dalcin            PCHYPRE
186616d9e3a6SLisandro Dalcin 
186716d9e3a6SLisandro Dalcin @*/
18687087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
186916d9e3a6SLisandro Dalcin {
18704ac538c5SBarry Smith   PetscErrorCode ierr;
187116d9e3a6SLisandro Dalcin 
187216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
18730700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
187416d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
18754ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
187616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
187716d9e3a6SLisandro Dalcin }
187816d9e3a6SLisandro Dalcin 
187916d9e3a6SLisandro Dalcin /*MC
188016d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
188116d9e3a6SLisandro Dalcin 
188216d9e3a6SLisandro Dalcin    Options Database Keys:
1883863406b8SStefano Zampini +   -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
188416d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
188516d9e3a6SLisandro Dalcin           preconditioner
188616d9e3a6SLisandro Dalcin 
188716d9e3a6SLisandro Dalcin    Level: intermediate
188816d9e3a6SLisandro Dalcin 
188916d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
189016d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
189116d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
189216d9e3a6SLisandro Dalcin 
1893c231f9e3SBarryFSmith           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_tol refer to the number of iterations
18940f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
18950f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
1896c231f9e3SBarryFSmith           (-pc_hypre_boomeramg_tol should be set to 0.0 - the default - to strictly use a fixed number of
18978f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
18980f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
18990f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
190016d9e3a6SLisandro Dalcin 
19010f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
19020f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
19030f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
190416d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
190516d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
190616d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
190716d9e3a6SLisandro Dalcin 
190816d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
190916d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
191016d9e3a6SLisandro Dalcin 
19115272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
19125272c319SBarry Smith           the two options:
19135272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
1914cbc39033SBarry Smith -   -pc_hypre_boomeramg_vec_interp_variant <v> where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
19155272c319SBarry Smith 
19165272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
19175272c319SBarry Smith 
19189e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
19199e5bc791SBarry Smith 
192016d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
19219e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
192216d9e3a6SLisandro Dalcin 
192316d9e3a6SLisandro Dalcin M*/
192416d9e3a6SLisandro Dalcin 
19258cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
192616d9e3a6SLisandro Dalcin {
192716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
192816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
192916d9e3a6SLisandro Dalcin 
193016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1931b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
19322fa5cd67SKarl Rupp 
193316d9e3a6SLisandro Dalcin   pc->data                = jac;
19348695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
193516d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
193616d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
193716d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
193816d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
193916d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
1940*6bf688a0SCe Qin   jac->G                  = NULL;
1941*6bf688a0SCe Qin   jac->C                  = NULL;
1942*6bf688a0SCe Qin   jac->alpha_Poisson      = NULL;
1943*6bf688a0SCe Qin   jac->beta_Poisson       = NULL;
19444cb006feSStefano Zampini   jac->coords[0]          = NULL;
19454cb006feSStefano Zampini   jac->coords[1]          = NULL;
19464cb006feSStefano Zampini   jac->coords[2]          = NULL;
19474cb006feSStefano Zampini   jac->constants[0]       = NULL;
19484cb006feSStefano Zampini   jac->constants[1]       = NULL;
19494cb006feSStefano Zampini   jac->constants[2]       = NULL;
1950*6bf688a0SCe Qin   jac->RT_PiFull          = NULL;
1951*6bf688a0SCe Qin   jac->RT_Pi[0]           = NULL;
1952*6bf688a0SCe Qin   jac->RT_Pi[1]           = NULL;
1953*6bf688a0SCe Qin   jac->RT_Pi[2]           = NULL;
1954*6bf688a0SCe Qin   jac->ND_PiFull          = NULL;
1955*6bf688a0SCe Qin   jac->ND_Pi[0]           = NULL;
1956*6bf688a0SCe Qin   jac->ND_Pi[1]           = NULL;
1957*6bf688a0SCe Qin   jac->ND_Pi[2]           = NULL;
19585272c319SBarry Smith   jac->hmnull             = NULL;
19595272c319SBarry Smith   jac->n_hmnull           = 0;
196016d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1961ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1962bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1963bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
19645ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
19655ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
19665ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
1967*6bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",PCHYPRESetInterpolations_HYPRE);CHKERRQ(ierr);
19685ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE);CHKERRQ(ierr);
19695ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",PCHYPRESetPoissonMatrix_HYPRE);CHKERRQ(ierr);
197016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
197116d9e3a6SLisandro Dalcin }
1972ebc551c0SBarry Smith 
1973f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1974f91d8e95SBarry Smith 
1975ebc551c0SBarry Smith typedef struct {
197668326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1977f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
19789e5bc791SBarry Smith 
19799e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
19804ddd07fcSJed Brown   PetscInt its;
19819e5bc791SBarry Smith   double   tol;
19824ddd07fcSJed Brown   PetscInt relax_type;
19834ddd07fcSJed Brown   PetscInt rap_type;
19844ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
19854ddd07fcSJed Brown   PetscInt max_levels;
1986ebc551c0SBarry Smith } PC_PFMG;
1987ebc551c0SBarry Smith 
1988ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1989ebc551c0SBarry Smith {
1990ebc551c0SBarry Smith   PetscErrorCode ierr;
1991f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1992ebc551c0SBarry Smith 
1993ebc551c0SBarry Smith   PetscFunctionBegin;
19942fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1995f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1996c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1997ebc551c0SBarry Smith   PetscFunctionReturn(0);
1998ebc551c0SBarry Smith }
1999ebc551c0SBarry Smith 
20009e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
20019e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
20029e5bc791SBarry Smith 
2003ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
2004ebc551c0SBarry Smith {
2005ebc551c0SBarry Smith   PetscErrorCode ierr;
2006ace3abfcSBarry Smith   PetscBool      iascii;
2007f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2008ebc551c0SBarry Smith 
2009ebc551c0SBarry Smith   PetscFunctionBegin;
2010251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
20119e5bc791SBarry Smith   if (iascii) {
20129e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
2013efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max iterations %d\n",ex->its);CHKERRQ(ierr);
2014efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    tolerance %g\n",ex->tol);CHKERRQ(ierr);
2015efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2016efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
2017efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2018efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max levels %d\n",ex->max_levels);CHKERRQ(ierr);
20199e5bc791SBarry Smith   }
2020ebc551c0SBarry Smith   PetscFunctionReturn(0);
2021ebc551c0SBarry Smith }
2022ebc551c0SBarry Smith 
20239e5bc791SBarry Smith 
20244416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2025ebc551c0SBarry Smith {
2026ebc551c0SBarry Smith   PetscErrorCode ierr;
2027f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2028ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2029ebc551c0SBarry Smith 
2030ebc551c0SBarry Smith   PetscFunctionBegin;
2031e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
20320298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
203368326731SBarry Smith   if (flg) {
2034a0324ebeSBarry Smith     int level=3;
2035fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
203668326731SBarry Smith   }
20370298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2038fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
20390298fd71SBarry 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);
2040fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
20410298fd71SBarry 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);
2042fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
20439e5bc791SBarry Smith 
20440298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
2045fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
20463b46a515SGlenn Hammond 
20470298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2048fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
20490298fd71SBarry 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);
2050fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
20510298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
2052fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
2053ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
2054ebc551c0SBarry Smith   PetscFunctionReturn(0);
2055ebc551c0SBarry Smith }
2056ebc551c0SBarry Smith 
2057f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
2058f91d8e95SBarry Smith {
2059f91d8e95SBarry Smith   PetscErrorCode    ierr;
2060f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
2061d9ca1df4SBarry Smith   PetscScalar       *yy;
2062d9ca1df4SBarry Smith   const PetscScalar *xx;
20634ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
206468326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2065f91d8e95SBarry Smith 
2066f91d8e95SBarry Smith   PetscFunctionBegin;
2067dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2068aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2069f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
2070f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
2071f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
2072f91d8e95SBarry Smith 
2073f91d8e95SBarry Smith   /* copy x values over to hypre */
2074fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
2075d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2076d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
2077d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2078fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
2079fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2080f91d8e95SBarry Smith 
2081f91d8e95SBarry Smith   /* copy solution values back to PETSc */
2082f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
20838b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
2084f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2085f91d8e95SBarry Smith   PetscFunctionReturn(0);
2086f91d8e95SBarry Smith }
2087f91d8e95SBarry Smith 
2088ace3abfcSBarry 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)
20899e5bc791SBarry Smith {
20909e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
20919e5bc791SBarry Smith   PetscErrorCode ierr;
20924ddd07fcSJed Brown   PetscInt       oits;
20939e5bc791SBarry Smith 
20949e5bc791SBarry Smith   PetscFunctionBegin;
2095dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2096fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
2097fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
20989e5bc791SBarry Smith 
20999e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
21008b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
21019e5bc791SBarry Smith   *outits = oits;
21029e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
21039e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2104fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
2105fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
21069e5bc791SBarry Smith   PetscFunctionReturn(0);
21079e5bc791SBarry Smith }
21089e5bc791SBarry Smith 
21099e5bc791SBarry Smith 
21103a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
21113a32d3dbSGlenn Hammond {
21123a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
21133a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
21143a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2115ace3abfcSBarry Smith   PetscBool       flg;
21163a32d3dbSGlenn Hammond 
21173a32d3dbSGlenn Hammond   PetscFunctionBegin;
2118251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
2119ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
21203a32d3dbSGlenn Hammond 
21213a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
21222fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2123fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2124fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2125fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
21263a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
21273a32d3dbSGlenn Hammond }
21283a32d3dbSGlenn Hammond 
2129ebc551c0SBarry Smith 
2130ebc551c0SBarry Smith /*MC
2131ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
2132ebc551c0SBarry Smith 
2133ebc551c0SBarry Smith    Level: advanced
2134ebc551c0SBarry Smith 
21359e5bc791SBarry Smith    Options Database:
21369e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
21379e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
21389e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
21399e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
21409e5bc791SBarry 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
21419e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
2142f91d8e95SBarry Smith 
21439e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
21449e5bc791SBarry Smith 
21458e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
2146aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
21479e5bc791SBarry Smith 
21489e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
2149ebc551c0SBarry Smith M*/
2150ebc551c0SBarry Smith 
21518cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
2152ebc551c0SBarry Smith {
2153ebc551c0SBarry Smith   PetscErrorCode ierr;
2154ebc551c0SBarry Smith   PC_PFMG        *ex;
2155ebc551c0SBarry Smith 
2156ebc551c0SBarry Smith   PetscFunctionBegin;
2157b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
215868326731SBarry Smith   pc->data = ex;
2159ebc551c0SBarry Smith 
21609e5bc791SBarry Smith   ex->its            = 1;
21619e5bc791SBarry Smith   ex->tol            = 1.e-8;
21629e5bc791SBarry Smith   ex->relax_type     = 1;
21639e5bc791SBarry Smith   ex->rap_type       = 0;
21649e5bc791SBarry Smith   ex->num_pre_relax  = 1;
21659e5bc791SBarry Smith   ex->num_post_relax = 1;
21663b46a515SGlenn Hammond   ex->max_levels     = 0;
21679e5bc791SBarry Smith 
2168ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2169ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2170ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2171f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
21729e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
217368326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
21742fa5cd67SKarl Rupp 
2175ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2176fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2177ebc551c0SBarry Smith   PetscFunctionReturn(0);
2178ebc551c0SBarry Smith }
2179d851a50bSGlenn Hammond 
2180325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2181325fc9f4SBarry Smith 
2182d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2183d851a50bSGlenn Hammond typedef struct {
2184d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2185d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2186d851a50bSGlenn Hammond 
2187d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
21884ddd07fcSJed Brown   PetscInt its;
2189d851a50bSGlenn Hammond   double   tol;
21904ddd07fcSJed Brown   PetscInt relax_type;
21914ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2192d851a50bSGlenn Hammond } PC_SysPFMG;
2193d851a50bSGlenn Hammond 
2194d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2195d851a50bSGlenn Hammond {
2196d851a50bSGlenn Hammond   PetscErrorCode ierr;
2197d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2198d851a50bSGlenn Hammond 
2199d851a50bSGlenn Hammond   PetscFunctionBegin;
22002fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2201d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2202c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2203d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2204d851a50bSGlenn Hammond }
2205d851a50bSGlenn Hammond 
2206d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2207d851a50bSGlenn Hammond 
2208d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2209d851a50bSGlenn Hammond {
2210d851a50bSGlenn Hammond   PetscErrorCode ierr;
2211ace3abfcSBarry Smith   PetscBool      iascii;
2212d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2213d851a50bSGlenn Hammond 
2214d851a50bSGlenn Hammond   PetscFunctionBegin;
2215251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2216d851a50bSGlenn Hammond   if (iascii) {
2217d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2218efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  max iterations %d\n",ex->its);CHKERRQ(ierr);
2219efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerance %g\n",ex->tol);CHKERRQ(ierr);
2220efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2221efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2222d851a50bSGlenn Hammond   }
2223d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2224d851a50bSGlenn Hammond }
2225d851a50bSGlenn Hammond 
2226d851a50bSGlenn Hammond 
22274416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2228d851a50bSGlenn Hammond {
2229d851a50bSGlenn Hammond   PetscErrorCode ierr;
2230d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2231ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2232d851a50bSGlenn Hammond 
2233d851a50bSGlenn Hammond   PetscFunctionBegin;
2234e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
22350298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2236d851a50bSGlenn Hammond   if (flg) {
2237d851a50bSGlenn Hammond     int level=3;
2238fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
2239d851a50bSGlenn Hammond   }
22400298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2241fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
22420298fd71SBarry 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);
2243fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
22440298fd71SBarry 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);
2245fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2246d851a50bSGlenn Hammond 
22470298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2248fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
22490298fd71SBarry 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);
2250fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2251d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2252d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2253d851a50bSGlenn Hammond }
2254d851a50bSGlenn Hammond 
2255d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2256d851a50bSGlenn Hammond {
2257d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2258d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2259d9ca1df4SBarry Smith   PetscScalar       *yy;
2260d9ca1df4SBarry Smith   const PetscScalar *xx;
22614ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
2262d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
22634ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
22644ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
22654ddd07fcSJed Brown   PetscInt          part    = 0;
22664ddd07fcSJed Brown   PetscInt          size;
22674ddd07fcSJed Brown   PetscInt          i;
2268d851a50bSGlenn Hammond 
2269d851a50bSGlenn Hammond   PetscFunctionBegin;
2270dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2271aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2272d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2273d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2274d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2275d851a50bSGlenn Hammond 
2276d851a50bSGlenn Hammond   size = 1;
22772fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
22782fa5cd67SKarl Rupp 
2279d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2280d851a50bSGlenn Hammond   if (ordering) {
2281fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2282d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2283d9ca1df4SBarry 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)));
2284d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2285fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2286fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2287fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2288d851a50bSGlenn Hammond 
2289d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2290d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
22918b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2292d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2293a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2294d851a50bSGlenn Hammond     PetscScalar *z;
22954ddd07fcSJed Brown     PetscInt    j, k;
2296d851a50bSGlenn Hammond 
2297785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2298fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2299d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2300d851a50bSGlenn Hammond 
2301d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2302d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2303d851a50bSGlenn Hammond       k= i*nvars;
23042fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2305d851a50bSGlenn Hammond     }
23068b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2307d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2308fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2309fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2310d851a50bSGlenn Hammond 
2311d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2312d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
23138b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2314d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2315d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2316d851a50bSGlenn Hammond       k= i*nvars;
23172fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2318d851a50bSGlenn Hammond     }
2319d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2320d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2321d851a50bSGlenn Hammond   }
2322d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2323d851a50bSGlenn Hammond }
2324d851a50bSGlenn Hammond 
2325ace3abfcSBarry 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)
2326d851a50bSGlenn Hammond {
2327d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2328d851a50bSGlenn Hammond   PetscErrorCode ierr;
23294ddd07fcSJed Brown   PetscInt       oits;
2330d851a50bSGlenn Hammond 
2331d851a50bSGlenn Hammond   PetscFunctionBegin;
2332dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2333fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2334fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2335d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
23368b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2337d851a50bSGlenn Hammond   *outits = oits;
2338d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2339d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2340fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2341fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2342d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2343d851a50bSGlenn Hammond }
2344d851a50bSGlenn Hammond 
2345d851a50bSGlenn Hammond 
2346d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2347d851a50bSGlenn Hammond {
2348d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2349d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2350d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2351ace3abfcSBarry Smith   PetscBool        flg;
2352d851a50bSGlenn Hammond 
2353d851a50bSGlenn Hammond   PetscFunctionBegin;
2354251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2355ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2356d851a50bSGlenn Hammond 
2357d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
23582fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2359fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2360fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2361fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2362d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2363d851a50bSGlenn Hammond }
2364d851a50bSGlenn Hammond 
2365d851a50bSGlenn Hammond 
2366d851a50bSGlenn Hammond /*MC
2367d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2368d851a50bSGlenn Hammond 
2369d851a50bSGlenn Hammond    Level: advanced
2370d851a50bSGlenn Hammond 
2371d851a50bSGlenn Hammond    Options Database:
2372d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2373d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2374d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2375d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2376d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2377d851a50bSGlenn Hammond 
2378d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
2379d851a50bSGlenn Hammond 
2380f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2381aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2382d851a50bSGlenn Hammond            Also, only cell-centered variables.
2383d851a50bSGlenn Hammond 
2384d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2385d851a50bSGlenn Hammond M*/
2386d851a50bSGlenn Hammond 
23878cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2388d851a50bSGlenn Hammond {
2389d851a50bSGlenn Hammond   PetscErrorCode ierr;
2390d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2391d851a50bSGlenn Hammond 
2392d851a50bSGlenn Hammond   PetscFunctionBegin;
2393b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2394d851a50bSGlenn Hammond   pc->data = ex;
2395d851a50bSGlenn Hammond 
2396d851a50bSGlenn Hammond   ex->its            = 1;
2397d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2398d851a50bSGlenn Hammond   ex->relax_type     = 1;
2399d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2400d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2401d851a50bSGlenn Hammond 
2402d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2403d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2404d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2405d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2406d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2407d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
24082fa5cd67SKarl Rupp 
2409ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2410fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2411d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2412d851a50bSGlenn Hammond }
2413