xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 22e51d3105627497e60da4e31b66a4692041e808)
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;
76ace3abfcSBarry Smith   PetscBool nodal_relax;
774ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
784cb006feSStefano Zampini 
795272c319SBarry Smith   PetscInt  nodal_coarsening;
80*22e51d31SStefano Zampini   PetscInt  nodal_coarsening_diag;
815272c319SBarry Smith   PetscInt  vec_interp_variant;
82*22e51d31SStefano Zampini   PetscInt  vec_interp_qmax;
83*22e51d31SStefano Zampini   PetscBool vec_interp_smooth;
84*22e51d31SStefano Zampini   PetscInt  interp_refine;
85*22e51d31SStefano Zampini 
865272c319SBarry Smith   HYPRE_IJVector  *hmnull;
875272c319SBarry Smith   HYPRE_ParVector *phmnull;  /* near null space passed to hypre */
885272c319SBarry Smith   PetscInt        n_hmnull;
895272c319SBarry Smith   Vec             hmnull_constant;
9072827435SBarry 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 */
915272c319SBarry Smith 
92863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
93863406b8SStefano Zampini   PetscInt  as_print;
94863406b8SStefano Zampini   PetscInt  as_max_iter;
95863406b8SStefano Zampini   PetscReal as_tol;
96863406b8SStefano Zampini   PetscInt  as_relax_type;
97863406b8SStefano Zampini   PetscInt  as_relax_times;
98863406b8SStefano Zampini   PetscReal as_relax_weight;
99863406b8SStefano Zampini   PetscReal as_omega;
100863406b8SStefano 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) */
101863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
102863406b8SStefano 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) */
103863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
1044cb006feSStefano Zampini   PetscInt  ams_cycle_type;
105863406b8SStefano Zampini   PetscInt  ads_cycle_type;
1064cb006feSStefano Zampini 
1074cb006feSStefano Zampini   /* additional data */
1085ac14e1cSStefano Zampini   Mat G;             /* MatHYPRE */
1095ac14e1cSStefano Zampini   Mat C;             /* MatHYPRE */
1105ac14e1cSStefano Zampini   Mat alpha_Poisson; /* MatHYPRE */
1115ac14e1cSStefano Zampini   Mat beta_Poisson;  /* MatHYPRE */
1125ac14e1cSStefano Zampini 
1135ac14e1cSStefano Zampini   /* extra information for AMS */
1145ac14e1cSStefano Zampini   PetscInt       dim; /* geometrical dimension */
1154cb006feSStefano Zampini   HYPRE_IJVector coords[3];
1164cb006feSStefano Zampini   HYPRE_IJVector constants[3];
1176bf688a0SCe Qin   Mat            RT_PiFull, RT_Pi[3];
1186bf688a0SCe Qin   Mat            ND_PiFull, ND_Pi[3];
1194cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
12023df4f25SStefano Zampini   PetscBool      ams_beta_is_zero_part;
12123df4f25SStefano Zampini   PetscInt       ams_proj_freq;
12216d9e3a6SLisandro Dalcin } PC_HYPRE;
12316d9e3a6SLisandro Dalcin 
124d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
125d2128fa2SBarry Smith {
126d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
127d2128fa2SBarry Smith 
128d2128fa2SBarry Smith   PetscFunctionBegin;
129d2128fa2SBarry Smith   *hsolver = jac->hsolver;
130d2128fa2SBarry Smith   PetscFunctionReturn(0);
131d2128fa2SBarry Smith }
13216d9e3a6SLisandro Dalcin 
13316d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
13416d9e3a6SLisandro Dalcin {
13516d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
13649a781f5SStefano Zampini   Mat_HYPRE          *hjac;
13716d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
13816d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
13949a781f5SStefano Zampini   PetscBool          ishypre;
14049a781f5SStefano Zampini   PetscErrorCode     ierr;
14116d9e3a6SLisandro Dalcin 
14216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
14316d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
14402a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
14516d9e3a6SLisandro Dalcin   }
1465f5c5b43SBarry Smith 
14749a781f5SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRE,&ishypre);CHKERRQ(ierr);
14849a781f5SStefano Zampini   if (!ishypre) {
1496bf688a0SCe Qin     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
1506bf688a0SCe Qin     ierr = MatConvert(pc->pmat,MATHYPRE,MAT_INITIAL_MATRIX,&jac->hpmat);CHKERRQ(ierr);
15149a781f5SStefano Zampini   } else {
15249a781f5SStefano Zampini     ierr = PetscObjectReference((PetscObject)pc->pmat);CHKERRQ(ierr);
15349a781f5SStefano Zampini     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
15449a781f5SStefano Zampini     jac->hpmat = pc->pmat;
15516d9e3a6SLisandro Dalcin   }
15649a781f5SStefano Zampini   hjac = (Mat_HYPRE*)(jac->hpmat->data);
1575f5c5b43SBarry Smith 
15816d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
15916d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
1605272c319SBarry Smith     MatNullSpace    mnull;
1615272c319SBarry Smith     PetscBool       has_const;
16249a781f5SStefano Zampini     PetscInt        bs,nvec,i;
1635272c319SBarry Smith     const Vec       *vecs;
16472827435SBarry Smith     PetscScalar     *petscvecarray;
1655272c319SBarry Smith 
16616d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1672fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
1685272c319SBarry Smith     ierr = MatGetNearNullSpace(pc->mat, &mnull);CHKERRQ(ierr);
1695272c319SBarry Smith     if (mnull) {
1705272c319SBarry Smith       ierr = MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs);CHKERRQ(ierr);
1715272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull);CHKERRQ(ierr);
17272827435SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull_hypre_data_array);CHKERRQ(ierr);
1735272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->phmnull);CHKERRQ(ierr);
1745272c319SBarry Smith       for (i=0; i<nvec; i++) {
1755272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(vecs[i],&jac->hmnull[i]);CHKERRQ(ierr);
17672827435SBarry Smith         ierr = VecGetArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
17758968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],petscvecarray,jac->hmnull_hypre_data_array[i]);
17872827435SBarry Smith         ierr = VecRestoreArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
1795272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[i],(void**)&jac->phmnull[i]));
1805272c319SBarry Smith       }
1815272c319SBarry Smith       if (has_const) {
1825272c319SBarry Smith         ierr = MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL);CHKERRQ(ierr);
1835272c319SBarry Smith         ierr = VecSet(jac->hmnull_constant,1);CHKERRQ(ierr);
1845272c319SBarry Smith         ierr = VecNormalize(jac->hmnull_constant,NULL);
1855272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(jac->hmnull_constant,&jac->hmnull[nvec]);CHKERRQ(ierr);
18672827435SBarry Smith         ierr = VecGetArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
18758968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[nvec],petscvecarray,jac->hmnull_hypre_data_array[nvec]);
18872827435SBarry Smith         ierr = VecRestoreArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
1895272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[nvec],(void**)&jac->phmnull[nvec]));
1905272c319SBarry Smith         nvec++;
1915272c319SBarry Smith       }
1925272c319SBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVectors,(jac->hsolver,nvec,jac->phmnull));
1935272c319SBarry Smith       jac->n_hmnull = nvec;
1945272c319SBarry Smith     }
1954cb006feSStefano Zampini   }
196863406b8SStefano Zampini 
1974cb006feSStefano Zampini   /* special case for AMS */
1984cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
1995ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2005ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
2016bf688a0SCe Qin     if (!jac->coords[0] && !jac->constants[0] && !(jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
2026bf688a0SCe 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");
2036bf688a0SCe Qin     }
2045ac14e1cSStefano Zampini     if (jac->dim) {
2055ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,jac->dim));
2065ac14e1cSStefano Zampini     }
2075ac14e1cSStefano Zampini     if (jac->constants[0]) {
2085ac14e1cSStefano Zampini       HYPRE_ParVector ozz,zoz,zzo = NULL;
2095ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&ozz)));
2105ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&zoz)));
2115ac14e1cSStefano Zampini       if (jac->constants[2]) {
2125ac14e1cSStefano Zampini         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&zzo)));
2135ac14e1cSStefano Zampini       }
2145ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,ozz,zoz,zzo));
2155ac14e1cSStefano Zampini     }
2165ac14e1cSStefano Zampini     if (jac->coords[0]) {
2175ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
2185ac14e1cSStefano Zampini       coords[0] = NULL;
2195ac14e1cSStefano Zampini       coords[1] = NULL;
2205ac14e1cSStefano Zampini       coords[2] = NULL;
2215ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
2225ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
2235ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
2245ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
2255ac14e1cSStefano Zampini     }
22649a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
2275ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
2285ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2295ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr));
2305ac14e1cSStefano Zampini     if (jac->alpha_Poisson) {
2315ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->alpha_Poisson->data);
2325ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2335ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr));
2345ac14e1cSStefano Zampini     }
2355ac14e1cSStefano Zampini     if (jac->ams_beta_is_zero) {
2365ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
2375ac14e1cSStefano Zampini     } else if (jac->beta_Poisson) {
2385ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->beta_Poisson->data);
2395ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2405ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr));
2415ac14e1cSStefano Zampini     }
2426bf688a0SCe Qin     if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) {
2436bf688a0SCe Qin       PetscInt           i;
2446bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
2456bf688a0SCe Qin       if (jac->ND_PiFull) {
2466bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
2476bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
2486bf688a0SCe Qin       } else {
2496bf688a0SCe Qin         nd_parcsrfull = NULL;
2506bf688a0SCe Qin       }
2516bf688a0SCe Qin       for (i=0;i<3;++i) {
2526bf688a0SCe Qin         if (jac->ND_Pi[i]) {
2536bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
2546bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
2556bf688a0SCe Qin         } else {
2566bf688a0SCe Qin           nd_parcsr[i] = NULL;
2576bf688a0SCe Qin         }
2586bf688a0SCe Qin       }
2596bf688a0SCe Qin       PetscStackCallStandard(HYPRE_AMSSetInterpolations,(jac->hsolver,nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]));
2606bf688a0SCe Qin     }
2614cb006feSStefano Zampini   }
262863406b8SStefano Zampini   /* special case for ADS */
263863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
2645ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2655ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
2666bf688a0SCe 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])))) {
2676bf688a0SCe Qin       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations");
2686bf688a0SCe Qin     }
26937096e45SBarry 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");
27049a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
27149a781f5SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient");
2725ac14e1cSStefano Zampini     if (jac->coords[0]) {
2735ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
2745ac14e1cSStefano Zampini       coords[0] = NULL;
2755ac14e1cSStefano Zampini       coords[1] = NULL;
2765ac14e1cSStefano Zampini       coords[2] = NULL;
2775ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
2785ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
2795ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
2805ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_ADSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
2815ac14e1cSStefano Zampini     }
2825ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
2835ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2845ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteGradient,(jac->hsolver,parcsr));
2855ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->C->data);
2865ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2875ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteCurl,(jac->hsolver,parcsr));
2886bf688a0SCe Qin     if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
2896bf688a0SCe Qin       PetscInt           i;
2906bf688a0SCe Qin       HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3];
2916bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
2926bf688a0SCe Qin       if (jac->RT_PiFull) {
2936bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->RT_PiFull->data);
2946bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsrfull)));
2956bf688a0SCe Qin       } else {
2966bf688a0SCe Qin         rt_parcsrfull = NULL;
2976bf688a0SCe Qin       }
2986bf688a0SCe Qin       for (i=0;i<3;++i) {
2996bf688a0SCe Qin         if (jac->RT_Pi[i]) {
3006bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->RT_Pi[i]->data);
3016bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsr[i])));
3026bf688a0SCe Qin         } else {
3036bf688a0SCe Qin           rt_parcsr[i] = NULL;
3046bf688a0SCe Qin         }
3056bf688a0SCe Qin       }
3066bf688a0SCe Qin       if (jac->ND_PiFull) {
3076bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
3086bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
3096bf688a0SCe Qin       } else {
3106bf688a0SCe Qin         nd_parcsrfull = NULL;
3116bf688a0SCe Qin       }
3126bf688a0SCe Qin       for (i=0;i<3;++i) {
3136bf688a0SCe Qin         if (jac->ND_Pi[i]) {
3146bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
3156bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
3166bf688a0SCe Qin         } else {
3176bf688a0SCe Qin           nd_parcsr[i] = NULL;
3186bf688a0SCe Qin         }
3196bf688a0SCe Qin       }
3206bf688a0SCe 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]));
3216bf688a0SCe Qin     }
322863406b8SStefano Zampini   }
32349a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
32449a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&bv));
32549a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&xv));
326*22e51d31SStefano Zampini   PetscStackCallStandard(jac->setup,(jac->hsolver,hmat,bv,xv));
32716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
32816d9e3a6SLisandro Dalcin }
32916d9e3a6SLisandro Dalcin 
33016d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
33116d9e3a6SLisandro Dalcin {
33216d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
33349a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
33416d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
33516d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
336d9ca1df4SBarry Smith   PetscScalar        *xv;
337d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
33816d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
339d9ca1df4SBarry Smith   PetscScalar        *sxv;
3404ddd07fcSJed Brown   PetscInt           hierr;
34116d9e3a6SLisandro Dalcin 
34216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
343dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
34416d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
345d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
34616d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
34758968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)bv,sbv);
34858968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
34916d9e3a6SLisandro Dalcin 
35049a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
35149a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
35249a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
353fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
35465e19b50SBarry Smith   if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
355fd3f9acdSBarry Smith   if (hierr) hypre__global_error = 0;);
35616d9e3a6SLisandro Dalcin 
35723df4f25SStefano Zampini   if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) {
3585ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSProjectOutGradients,(jac->hsolver,jxv));
35921df291bSStefano Zampini   }
36058968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)sbv,bv);
36158968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
36216d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
363d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
36416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
36516d9e3a6SLisandro Dalcin }
36616d9e3a6SLisandro Dalcin 
3678695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc)
3688695de01SBarry Smith {
3698695de01SBarry Smith   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
3708695de01SBarry Smith   PetscErrorCode ierr;
3718695de01SBarry Smith 
3728695de01SBarry Smith   PetscFunctionBegin;
37349a781f5SStefano Zampini   ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
3745ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
3755ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
3765ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
3775ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
3786bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
3796bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[0]);CHKERRQ(ierr);
3806bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[1]);CHKERRQ(ierr);
3816bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[2]);CHKERRQ(ierr);
3826bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
3836bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[0]);CHKERRQ(ierr);
3846bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[1]);CHKERRQ(ierr);
3856bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[2]);CHKERRQ(ierr);
3868695de01SBarry Smith   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); jac->coords[0] = NULL;
3878695de01SBarry Smith   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); jac->coords[1] = NULL;
3888695de01SBarry Smith   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); jac->coords[2] = NULL;
3898695de01SBarry Smith   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); jac->constants[0] = NULL;
3908695de01SBarry Smith   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); jac->constants[1] = NULL;
3918695de01SBarry Smith   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); jac->constants[2] = NULL;
392550a8b7dSBarry Smith   if (jac->n_hmnull && jac->hmnull) {
3935272c319SBarry Smith     PetscInt                 i;
394b1c1cd91SBarry Smith     PETSC_UNUSED PetscScalar *petscvecarray;
3955272c319SBarry Smith 
3965272c319SBarry Smith     for (i=0; i<jac->n_hmnull; i++) {
39758968eb6SStefano Zampini       VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],jac->hmnull_hypre_data_array[i],petscvecarray);
3985272c319SBarry Smith       PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->hmnull[i]));
3995272c319SBarry Smith     }
4005272c319SBarry Smith     ierr = PetscFree(jac->hmnull);CHKERRQ(ierr);
40172827435SBarry Smith     ierr = PetscFree(jac->hmnull_hypre_data_array);CHKERRQ(ierr);
4025272c319SBarry Smith     ierr = PetscFree(jac->phmnull);CHKERRQ(ierr);
4035272c319SBarry Smith     ierr = VecDestroy(&jac->hmnull_constant);CHKERRQ(ierr);
4045272c319SBarry Smith   }
4055ac14e1cSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
4065ac14e1cSStefano Zampini   jac->dim = 0;
4078695de01SBarry Smith   PetscFunctionReturn(0);
4088695de01SBarry Smith }
4098695de01SBarry Smith 
41016d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
41116d9e3a6SLisandro Dalcin {
41216d9e3a6SLisandro Dalcin   PC_HYPRE                 *jac = (PC_HYPRE*)pc->data;
41316d9e3a6SLisandro Dalcin   PetscErrorCode           ierr;
41416d9e3a6SLisandro Dalcin 
41516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
4168695de01SBarry Smith   ierr = PCReset_HYPRE(pc);CHKERRQ(ierr);
417*22e51d31SStefano Zampini   if (jac->destroy) PetscStackCallStandard(jac->destroy,(jac->hsolver));
418503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
41916d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
420c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
42116d9e3a6SLisandro Dalcin 
42216d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
423bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
424bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
4254cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
4264cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
427863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
4286bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",NULL);CHKERRQ(ierr);
4294cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
4305ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",NULL);CHKERRQ(ierr);
43116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
43216d9e3a6SLisandro Dalcin }
43316d9e3a6SLisandro Dalcin 
43416d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
4354416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptionItems *PetscOptionsObject,PC pc)
43616d9e3a6SLisandro Dalcin {
43716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
43816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
439ace3abfcSBarry Smith   PetscBool      flag;
44016d9e3a6SLisandro Dalcin 
44116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
442e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
44316d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
444fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
44516d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
446fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
44716d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
448fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
44916d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
45016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
45116d9e3a6SLisandro Dalcin }
45216d9e3a6SLisandro Dalcin 
45316d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
45416d9e3a6SLisandro Dalcin {
45516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
45616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
457ace3abfcSBarry Smith   PetscBool      iascii;
45816d9e3a6SLisandro Dalcin 
45916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
460251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
46116d9e3a6SLisandro Dalcin   if (iascii) {
46216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
46316d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
464efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
46516d9e3a6SLisandro Dalcin     } else {
466efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default maximum number of iterations \n");CHKERRQ(ierr);
46716d9e3a6SLisandro Dalcin     }
46816d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
469efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
47016d9e3a6SLisandro Dalcin     } else {
471efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default drop tolerance \n");CHKERRQ(ierr);
47216d9e3a6SLisandro Dalcin     }
47316d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
474efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
47516d9e3a6SLisandro Dalcin     } else {
476efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default factor row size \n");CHKERRQ(ierr);
47716d9e3a6SLisandro Dalcin     }
47816d9e3a6SLisandro Dalcin   }
47916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
48016d9e3a6SLisandro Dalcin }
48116d9e3a6SLisandro Dalcin 
48216d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
483db966c6cSHong Zhang static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PetscOptionItems *PetscOptionsObject,PC pc)
484db966c6cSHong Zhang {
485db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
486db966c6cSHong Zhang   PetscErrorCode ierr;
487db966c6cSHong Zhang   PetscBool      flag;
488db966c6cSHong Zhang 
489db966c6cSHong Zhang   PetscFunctionBegin;
490db966c6cSHong Zhang   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Euclid Options");CHKERRQ(ierr);
491db966c6cSHong Zhang   ierr = PetscOptionsInt("-pc_hypre_euclid_level","Factorization levels","None",jac->eu_level,&jac->eu_level,&flag);CHKERRQ(ierr);
492db966c6cSHong Zhang   if (flag) PetscStackCallStandard(HYPRE_EuclidSetLevel,(jac->hsolver,jac->eu_level));
493db966c6cSHong Zhang   ierr = PetscOptionsTail();CHKERRQ(ierr);
494db966c6cSHong Zhang   PetscFunctionReturn(0);
495db966c6cSHong Zhang }
496db966c6cSHong Zhang 
497db966c6cSHong Zhang static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer)
498db966c6cSHong Zhang {
499db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
500db966c6cSHong Zhang   PetscErrorCode ierr;
501db966c6cSHong Zhang   PetscBool      iascii;
502db966c6cSHong Zhang 
503db966c6cSHong Zhang   PetscFunctionBegin;
504db966c6cSHong Zhang   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
505db966c6cSHong Zhang   if (iascii) {
506db966c6cSHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid preconditioning\n");CHKERRQ(ierr);
507db966c6cSHong Zhang     if (jac->eu_level != PETSC_DEFAULT) {
508db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    factorization levels %d\n",jac->eu_level);CHKERRQ(ierr);
509db966c6cSHong Zhang     } else {
510db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    default factorization levels \n");CHKERRQ(ierr);
511db966c6cSHong Zhang     }
512db966c6cSHong Zhang   }
513db966c6cSHong Zhang   PetscFunctionReturn(0);
514db966c6cSHong Zhang }
515db966c6cSHong Zhang 
516db966c6cSHong Zhang /* --------------------------------------------------------------------------------------------*/
51716d9e3a6SLisandro Dalcin 
51816d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
51916d9e3a6SLisandro Dalcin {
52016d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
52149a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
52216d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
52316d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
524d9ca1df4SBarry Smith   PetscScalar        *xv;
525d9ca1df4SBarry Smith   const PetscScalar  *bv;
52616d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
52716d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
5284ddd07fcSJed Brown   PetscInt           hierr;
52916d9e3a6SLisandro Dalcin 
53016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
531dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
53216d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
533d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
53416d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
53558968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)bv,sbv);
53658968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
53716d9e3a6SLisandro Dalcin 
53849a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
53949a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
54049a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
54116d9e3a6SLisandro Dalcin 
54216d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
54316d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
544e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
54516d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
54616d9e3a6SLisandro Dalcin 
54758968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,sbv,bv);
54858968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
54916d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
550d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
55116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
55216d9e3a6SLisandro Dalcin }
55316d9e3a6SLisandro Dalcin 
554a669f990SJed Brown /* static array length */
555a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
556a669f990SJed Brown 
55716d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
5580f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
55916d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
56065de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
5616a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]   = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
56265de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
56365de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
56465de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
5657b7fa87dSPierre Jolivet                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "l1-Gauss-Seidel" /* nonsymmetric */, "backward-l1-Gauss-Seidel" /* nonsymmetric */,
56665de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
5670f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
568e2287abbSStefano Zampini                                                   "ext+i-cc", "standard", "standard-wts", "block", "block-wtd", "FF", "FF1"};
5694416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc)
57016d9e3a6SLisandro Dalcin {
57116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
57216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
573*22e51d31SStefano Zampini   PetscInt       bs,n,indx,level;
574ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
57516d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
57616d9e3a6SLisandro Dalcin 
57716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
578e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
5794336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
58016d9e3a6SLisandro Dalcin   if (flg) {
5814336a9eeSBarry Smith     jac->cycletype = indx+1;
582fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
58316d9e3a6SLisandro Dalcin   }
58416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
58516d9e3a6SLisandro Dalcin   if (flg) {
586ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
587fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
58816d9e3a6SLisandro Dalcin   }
58916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
59016d9e3a6SLisandro Dalcin   if (flg) {
591ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
592fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
59316d9e3a6SLisandro Dalcin   }
5940f1074feSSatish 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);
59516d9e3a6SLisandro Dalcin   if (flg) {
59657622a8eSBarry 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);
597fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
59816d9e3a6SLisandro Dalcin   }
599*22e51d31SStefano Zampini   bs = 1;
600*22e51d31SStefano Zampini   if (pc->pmat) {
601*22e51d31SStefano Zampini     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
602*22e51d31SStefano Zampini   }
603*22e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_numfunctions","Number of functions","HYPRE_BoomerAMGSetNumFunctions",bs,&bs,&flg);CHKERRQ(ierr);
604*22e51d31SStefano Zampini   if (flg) {
605*22e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
606*22e51d31SStefano Zampini   }
60716d9e3a6SLisandro Dalcin 
6080f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
60916d9e3a6SLisandro Dalcin   if (flg) {
61057622a8eSBarry 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);
611fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
61216d9e3a6SLisandro Dalcin   }
61316d9e3a6SLisandro Dalcin 
6140f1074feSSatish 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);
6150f1074feSSatish Balay   if (flg) {
61657622a8eSBarry 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);
617fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
6180f1074feSSatish Balay   }
6190f1074feSSatish Balay 
6200f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
6210f1074feSSatish Balay   if (flg) {
62257622a8eSBarry 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);
6230f1074feSSatish Balay 
624fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
6250f1074feSSatish Balay   }
6260f1074feSSatish Balay 
6270f1074feSSatish 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);
6280f1074feSSatish Balay   if (flg) {
62957622a8eSBarry 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);
6300f1074feSSatish Balay 
631fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
6320f1074feSSatish Balay   }
6330f1074feSSatish Balay 
6340f1074feSSatish Balay 
63516d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
63616d9e3a6SLisandro Dalcin   if (flg) {
63757622a8eSBarry 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);
638fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
63916d9e3a6SLisandro Dalcin   }
64016d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
64116d9e3a6SLisandro Dalcin   if (flg) {
64257622a8eSBarry 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);
64357622a8eSBarry 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);
644fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
64516d9e3a6SLisandro Dalcin   }
64616d9e3a6SLisandro Dalcin 
64716d9e3a6SLisandro Dalcin   /* Grid sweeps */
6480f1074feSSatish 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);
64916d9e3a6SLisandro Dalcin   if (flg) {
650fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
65116d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
65216d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
6530f1074feSSatish Balay     jac->gridsweeps[1] = indx;
6540f1074feSSatish Balay     /*defaults coarse to 1 */
6550f1074feSSatish Balay     jac->gridsweeps[2] = 1;
65616d9e3a6SLisandro Dalcin   }
6575272c319SBarry 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);
6585272c319SBarry Smith   if (flg) {
6595272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,jac->nodal_coarsening));
6605272c319SBarry Smith   }
661*22e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_coarsen_diag","Diagonal in strength matrix for nodal based coarsening 0-2","HYPRE_BoomerAMGSetNodalDiag",jac->nodal_coarsening_diag,&jac->nodal_coarsening_diag,&flg);CHKERRQ(ierr);
662*22e51d31SStefano Zampini   if (flg) {
663*22e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNodalDiag,(jac->hsolver,jac->nodal_coarsening_diag));
664*22e51d31SStefano Zampini   }
665cbc39033SBarry 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);
6665272c319SBarry Smith   if (flg) {
6675272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,(jac->hsolver,jac->vec_interp_variant));
6685272c319SBarry Smith   }
669*22e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_vec_interp_qmax","Max elements per row for each Q","HYPRE_BoomerAMGSetInterpVecQMax",jac->vec_interp_qmax, &jac->vec_interp_qmax,&flg);CHKERRQ(ierr);
670*22e51d31SStefano Zampini   if (flg) {
671*22e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecQMax,(jac->hsolver,jac->vec_interp_qmax));
672*22e51d31SStefano Zampini   }
673*22e51d31SStefano Zampini   ierr = PetscOptionsBool("-pc_hypre_boomeramg_vec_interp_smooth","Whether to smooth the interpolation vectors","HYPRE_BoomerAMGSetSmoothInterpVectors",jac->vec_interp_smooth, &jac->vec_interp_smooth,&flg);CHKERRQ(ierr);
674*22e51d31SStefano Zampini   if (flg) {
675*22e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothInterpVectors,(jac->hsolver,jac->vec_interp_smooth));
676*22e51d31SStefano Zampini   }
677*22e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_interp_refine","Preprocess the interpolation matrix through iterative weight refinement","HYPRE_BoomerAMGSetInterpRefine",jac->interp_refine, &jac->interp_refine,&flg);CHKERRQ(ierr);
678*22e51d31SStefano Zampini   if (flg) {
679*22e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpRefine,(jac->hsolver,jac->interp_refine));
680*22e51d31SStefano Zampini   }
6810f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
68216d9e3a6SLisandro Dalcin   if (flg) {
683fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
6840f1074feSSatish Balay     jac->gridsweeps[0] = indx;
68516d9e3a6SLisandro Dalcin   }
68616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
68716d9e3a6SLisandro Dalcin   if (flg) {
688fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
6890f1074feSSatish Balay     jac->gridsweeps[1] = indx;
69016d9e3a6SLisandro Dalcin   }
6910f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
69216d9e3a6SLisandro Dalcin   if (flg) {
693fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
6940f1074feSSatish Balay     jac->gridsweeps[2] = indx;
69516d9e3a6SLisandro Dalcin   }
69616d9e3a6SLisandro Dalcin 
6976a251517SEike Mueller   /* Smooth type */
6986a251517SEike Mueller   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);
6996a251517SEike Mueller   if (flg) {
7006a251517SEike Mueller     jac->smoothtype = indx;
7016a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
7028131ecf7SEike Mueller     jac->smoothnumlevels = 25;
7038131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
7048131ecf7SEike Mueller   }
7058131ecf7SEike Mueller 
7068131ecf7SEike Mueller   /* Number of smoothing levels */
7078131ecf7SEike 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);
7088131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
7098131ecf7SEike Mueller     jac->smoothnumlevels = indx;
7108131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
7116a251517SEike Mueller   }
7126a251517SEike Mueller 
7131810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
7141810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
7151810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
7161810e44eSEike Mueller     jac->eu_level = indx;
7171810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
7181810e44eSEike Mueller   }
7191810e44eSEike Mueller 
7201810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
7211810e44eSEike Mueller   double droptolerance;
7221810e44eSEike Mueller   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
7231810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
7241810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
7251810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
7261810e44eSEike Mueller   }
7271810e44eSEike Mueller 
7281810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
7291810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
7301810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
7311810e44eSEike Mueller     jac->eu_bj = tmp_truth;
732493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
7331810e44eSEike Mueller   }
7341810e44eSEike Mueller 
73516d9e3a6SLisandro Dalcin   /* Relax type */
736a669f990SJed 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);
73716d9e3a6SLisandro Dalcin   if (flg) {
7380f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
739fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
7400f1074feSSatish Balay     /* by default, coarse type set to 9 */
7410f1074feSSatish Balay     jac->relaxtype[2] = 9;
742ddbeb582SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, 9, 3));
74316d9e3a6SLisandro Dalcin   }
744a669f990SJed 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);
74516d9e3a6SLisandro Dalcin   if (flg) {
74616d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
747fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
74816d9e3a6SLisandro Dalcin   }
749a669f990SJed 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);
75016d9e3a6SLisandro Dalcin   if (flg) {
7510f1074feSSatish Balay     jac->relaxtype[1] = indx;
752fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
75316d9e3a6SLisandro Dalcin   }
754a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
75516d9e3a6SLisandro Dalcin   if (flg) {
7560f1074feSSatish Balay     jac->relaxtype[2] = indx;
757fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
75816d9e3a6SLisandro Dalcin   }
75916d9e3a6SLisandro Dalcin 
76016d9e3a6SLisandro Dalcin   /* Relaxation Weight */
76116d9e3a6SLisandro 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);
76216d9e3a6SLisandro Dalcin   if (flg) {
763fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
76416d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
76516d9e3a6SLisandro Dalcin   }
76616d9e3a6SLisandro Dalcin 
76716d9e3a6SLisandro Dalcin   n         = 2;
76816d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
76916d9e3a6SLisandro 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);
77016d9e3a6SLisandro Dalcin   if (flg) {
77116d9e3a6SLisandro Dalcin     if (n == 2) {
77216d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
773fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
774ce94432eSBarry 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);
77516d9e3a6SLisandro Dalcin   }
77616d9e3a6SLisandro Dalcin 
77716d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
77816d9e3a6SLisandro 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);
77916d9e3a6SLisandro Dalcin   if (flg) {
780fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
78116d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
78216d9e3a6SLisandro Dalcin   }
78316d9e3a6SLisandro Dalcin 
78416d9e3a6SLisandro Dalcin   n         = 2;
78516d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
78616d9e3a6SLisandro 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);
78716d9e3a6SLisandro Dalcin   if (flg) {
78816d9e3a6SLisandro Dalcin     if (n == 2) {
78916d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
790fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
791ce94432eSBarry 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);
79216d9e3a6SLisandro Dalcin   }
79316d9e3a6SLisandro Dalcin 
79416d9e3a6SLisandro Dalcin   /* the Relax Order */
795acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
79616d9e3a6SLisandro Dalcin 
7978afaa268SBarry Smith   if (flg && tmp_truth) {
79816d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
799fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
80016d9e3a6SLisandro Dalcin   }
801a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
80216d9e3a6SLisandro Dalcin   if (flg) {
80316d9e3a6SLisandro Dalcin     jac->measuretype = indx;
804fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
80516d9e3a6SLisandro Dalcin   }
8060f1074feSSatish Balay   /* update list length 3/07 */
807a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
80816d9e3a6SLisandro Dalcin   if (flg) {
80916d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
810fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
81116d9e3a6SLisandro Dalcin   }
8120f1074feSSatish Balay 
8130f1074feSSatish Balay   /* new 3/07 */
814a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
8150f1074feSSatish Balay   if (flg) {
8160f1074feSSatish Balay     jac->interptype = indx;
817fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
8180f1074feSSatish Balay   }
8190f1074feSSatish Balay 
820b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
82116d9e3a6SLisandro Dalcin   if (flg) {
822b96a4a96SBarry Smith     level = 3;
8230298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
8242fa5cd67SKarl Rupp 
825b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
826fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
8272ae77aedSBarry Smith   }
8282ae77aedSBarry Smith 
829b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
8302ae77aedSBarry Smith   if (flg) {
831b96a4a96SBarry Smith     level = 3;
8320298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
8332fa5cd67SKarl Rupp 
834b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
835fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
83616d9e3a6SLisandro Dalcin   }
8378f87f92bSBarry Smith 
838acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
8398f87f92bSBarry Smith   if (flg && tmp_truth) {
8408f87f92bSBarry Smith     PetscInt tmp_int;
8418f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
8428f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
843fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
844fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
845fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
846fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
8478f87f92bSBarry Smith   }
8488f87f92bSBarry Smith 
84916d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
85016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
85116d9e3a6SLisandro Dalcin }
85216d9e3a6SLisandro Dalcin 
853ace3abfcSBarry 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)
85416d9e3a6SLisandro Dalcin {
85516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
85616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
8574ddd07fcSJed Brown   PetscInt       oits;
85816d9e3a6SLisandro Dalcin 
85916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
860dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
861fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
862fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
86316d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
86416d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
86516d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
8668b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
8674d0a8057SBarry Smith   *outits = oits;
8684d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
8694d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
870fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
871fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
87216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
87316d9e3a6SLisandro Dalcin }
87416d9e3a6SLisandro Dalcin 
87516d9e3a6SLisandro Dalcin 
87616d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
87716d9e3a6SLisandro Dalcin {
87816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
87916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
880ace3abfcSBarry Smith   PetscBool      iascii;
88116d9e3a6SLisandro Dalcin 
88216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
883251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
88416d9e3a6SLisandro Dalcin   if (iascii) {
88516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
886efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
887*22e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of levels %D\n",jac->maxlevels);CHKERRQ(ierr);
888*22e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of iterations PER hypre call %D\n",jac->maxiter);CHKERRQ(ierr);
889efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
890efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
891efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
892*22e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: max elements per row %D\n",jac->pmax);CHKERRQ(ierr);
893*22e51d31SStefano Zampini     if (jac->interp_refine) {
894*22e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: number of steps of weighted refinement %D\n",jac->interp_refine);CHKERRQ(ierr);
895*22e51d31SStefano Zampini     }
896*22e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of levels of aggressive coarsening %D\n",jac->agg_nl);CHKERRQ(ierr);
897*22e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of paths for aggressive coarsening %D\n",jac->agg_num_paths);CHKERRQ(ierr);
8980f1074feSSatish Balay 
899efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
90016d9e3a6SLisandro Dalcin 
901*22e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps down         %D\n",jac->gridsweeps[0]);CHKERRQ(ierr);
902*22e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps up           %D\n",jac->gridsweeps[1]);CHKERRQ(ierr);
903*22e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps on coarse    %D\n",jac->gridsweeps[2]);CHKERRQ(ierr);
90416d9e3a6SLisandro Dalcin 
905efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
906efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
907efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
90816d9e3a6SLisandro Dalcin 
909efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
910efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
91116d9e3a6SLisandro Dalcin 
91216d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
913efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using CF-relaxation\n");CHKERRQ(ierr);
91416d9e3a6SLisandro Dalcin     } else {
915efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using CF-relaxation\n");CHKERRQ(ierr);
91616d9e3a6SLisandro Dalcin     }
9176a251517SEike Mueller     if (jac->smoothtype!=-1) {
918efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
919*22e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth num levels    %D\n",jac->smoothnumlevels);CHKERRQ(ierr);
9207e352d70SEike Mueller     } else {
921efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using more complex smoothers.\n");CHKERRQ(ierr);
9221810e44eSEike Mueller     }
9231810e44eSEike Mueller     if (jac->smoothtype==3) {
924*22e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) levels %D\n",jac->eu_level);CHKERRQ(ierr);
925*22e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) drop tolerance %g\n",(double)jac->eu_droptolerance);CHKERRQ(ierr);
926*22e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU use Block-Jacobi? %D\n",jac->eu_bj);CHKERRQ(ierr);
9276a251517SEike Mueller     }
928efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
929efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
930efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
9315272c319SBarry Smith     if (jac->nodal_coarsening) {
932efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
9335272c319SBarry Smith     }
9345272c319SBarry Smith     if (jac->vec_interp_variant) {
935efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
936*22e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecQMax() %D\n",jac->vec_interp_qmax);CHKERRQ(ierr);
937*22e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n",jac->vec_interp_smooth);CHKERRQ(ierr);
9388f87f92bSBarry Smith     }
9398f87f92bSBarry Smith     if (jac->nodal_relax) {
940*22e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal relaxation via Schwarz smoothing on levels %D\n",jac->nodal_relax_levels);CHKERRQ(ierr);
9418f87f92bSBarry Smith     }
94216d9e3a6SLisandro Dalcin   }
94316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
94416d9e3a6SLisandro Dalcin }
94516d9e3a6SLisandro Dalcin 
94616d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
9474416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc)
94816d9e3a6SLisandro Dalcin {
94916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
95016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
9514ddd07fcSJed Brown   PetscInt       indx;
952ace3abfcSBarry Smith   PetscBool      flag;
95316d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
95416d9e3a6SLisandro Dalcin 
95516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
956e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
95716d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
95816d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
9592fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
96016d9e3a6SLisandro Dalcin 
96116d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
9622fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
96316d9e3a6SLisandro Dalcin 
96416d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
9652fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
96616d9e3a6SLisandro Dalcin 
967acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
9682fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
96916d9e3a6SLisandro Dalcin 
970acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
9712fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
97216d9e3a6SLisandro Dalcin 
973a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
97416d9e3a6SLisandro Dalcin   if (flag) {
97516d9e3a6SLisandro Dalcin     jac->symt = indx;
976fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
97716d9e3a6SLisandro Dalcin   }
97816d9e3a6SLisandro Dalcin 
97916d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
98016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
98116d9e3a6SLisandro Dalcin }
98216d9e3a6SLisandro Dalcin 
98316d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
98416d9e3a6SLisandro Dalcin {
98516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
98616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
987ace3abfcSBarry Smith   PetscBool      iascii;
98816d9e3a6SLisandro Dalcin   const char     *symt = 0;;
98916d9e3a6SLisandro Dalcin 
99016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
991251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
99216d9e3a6SLisandro Dalcin   if (iascii) {
99316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
994efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
995efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
996efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    filter %g\n",(double)jac->filter);CHKERRQ(ierr);
997efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
998efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
999efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
10002fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
10012fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
10022fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
1003ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
1004efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    %s\n",symt);CHKERRQ(ierr);
100516d9e3a6SLisandro Dalcin   }
100616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
100716d9e3a6SLisandro Dalcin }
10084cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
10094416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc)
10104cb006feSStefano Zampini {
10114cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
10124cb006feSStefano Zampini   PetscErrorCode ierr;
10134cb006feSStefano Zampini   PetscInt       n;
10144cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
10154cb006feSStefano Zampini 
10164cb006feSStefano Zampini   PetscFunctionBegin;
10179fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
1018863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1019863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1020863406b8SStefano 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);
1021863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
10224cb006feSStefano 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);
10234cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1024863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1025863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1026863406b8SStefano 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);
1027863406b8SStefano 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);
1028863406b8SStefano 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);
1029863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
10304cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1031863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1032863406b8SStefano Zampini                                                                       jac->as_relax_times,
1033863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1034863406b8SStefano Zampini                                                                       jac->as_omega));
10354cb006feSStefano Zampini   }
1036863406b8SStefano 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);
10374cb006feSStefano Zampini   n = 5;
1038863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
10394cb006feSStefano Zampini   if (flag || flag2) {
1040863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1041863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1042863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1043863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1044863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1045863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
10464cb006feSStefano Zampini   }
1047863406b8SStefano 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);
10484cb006feSStefano Zampini   n = 5;
1049863406b8SStefano 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);
10504cb006feSStefano Zampini   if (flag || flag2) {
1051863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1052863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1053863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1054863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1055863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1056863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
10574cb006feSStefano Zampini   }
105823df4f25SStefano 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);
105923df4f25SStefano Zampini   if (flag) { /* override HYPRE's default only if the options is used */
106023df4f25SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetProjectionFrequency,(jac->hsolver,jac->ams_proj_freq));
106123df4f25SStefano Zampini   }
10624cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
10634cb006feSStefano Zampini   PetscFunctionReturn(0);
10644cb006feSStefano Zampini }
10654cb006feSStefano Zampini 
10664cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
10674cb006feSStefano Zampini {
10684cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
10694cb006feSStefano Zampini   PetscErrorCode ierr;
10704cb006feSStefano Zampini   PetscBool      iascii;
10714cb006feSStefano Zampini 
10724cb006feSStefano Zampini   PetscFunctionBegin;
10734cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
10744cb006feSStefano Zampini   if (iascii) {
10754cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
1076efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1077efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1078efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1079efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1080efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1081efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1082efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
10834cb006feSStefano Zampini     if (jac->alpha_Poisson) {
1084efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
10854cb006feSStefano Zampini     } else {
1086efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (computed) \n");CHKERRQ(ierr);
10874cb006feSStefano Zampini     }
1088efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1089efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1090efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1091efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1092efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1093efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
10944cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
10954cb006feSStefano Zampini       if (jac->beta_Poisson) {
1096efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
10974cb006feSStefano Zampini       } else {
1098efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (computed) \n");CHKERRQ(ierr);
10994cb006feSStefano Zampini       }
1100efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1101efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1102efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1103efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1104efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1105efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
110623df4f25SStefano Zampini       if (jac->ams_beta_is_zero_part) {
1107efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"        compatible subspace projection frequency %d (-1 HYPRE uses default)\n",jac->ams_proj_freq);CHKERRQ(ierr);
110823df4f25SStefano Zampini       }
110923df4f25SStefano Zampini     } else {
1110efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver not used (zero-conductivity everywhere) \n");CHKERRQ(ierr);
11114cb006feSStefano Zampini     }
11124cb006feSStefano Zampini   }
11134cb006feSStefano Zampini   PetscFunctionReturn(0);
11144cb006feSStefano Zampini }
11154cb006feSStefano Zampini 
11164416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc)
1117863406b8SStefano Zampini {
1118863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1119863406b8SStefano Zampini   PetscErrorCode ierr;
1120863406b8SStefano Zampini   PetscInt       n;
1121863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
1122863406b8SStefano Zampini 
1123863406b8SStefano Zampini   PetscFunctionBegin;
1124863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
1125863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1126863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1127863406b8SStefano 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);
1128863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1129863406b8SStefano 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);
1130863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
1131863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1132863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1133863406b8SStefano 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);
1134863406b8SStefano 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);
1135863406b8SStefano 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);
1136863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
1137863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1138863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1139863406b8SStefano Zampini                                                                       jac->as_relax_times,
1140863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1141863406b8SStefano Zampini                                                                       jac->as_omega));
1142863406b8SStefano Zampini   }
1143863406b8SStefano 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);
1144863406b8SStefano Zampini   n = 5;
1145863406b8SStefano 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);
1146863406b8SStefano 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);
1147863406b8SStefano Zampini   if (flag || flag2 || flag3) {
1148863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
1149863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1150863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1151863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1152863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1153863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1154863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1155863406b8SStefano Zampini   }
1156863406b8SStefano 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);
1157863406b8SStefano Zampini   n = 5;
1158863406b8SStefano 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);
1159863406b8SStefano Zampini   if (flag || flag2) {
1160863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1161863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1162863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1163863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1164863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1165863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1166863406b8SStefano Zampini   }
1167863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
1168863406b8SStefano Zampini   PetscFunctionReturn(0);
1169863406b8SStefano Zampini }
1170863406b8SStefano Zampini 
1171863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1172863406b8SStefano Zampini {
1173863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1174863406b8SStefano Zampini   PetscErrorCode ierr;
1175863406b8SStefano Zampini   PetscBool      iascii;
1176863406b8SStefano Zampini 
1177863406b8SStefano Zampini   PetscFunctionBegin;
1178863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1179863406b8SStefano Zampini   if (iascii) {
1180863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
1181efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1182efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
1183efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1184efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1185efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1186efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1187efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
1188efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    AMS solver using boomerAMG\n");CHKERRQ(ierr);
1189efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1190efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1191efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1192efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1193efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1194efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1195efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
1196efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver using boomerAMG\n");CHKERRQ(ierr);
1197efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1198efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1199efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1200efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1201efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1202efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
1203863406b8SStefano Zampini   }
1204863406b8SStefano Zampini   PetscFunctionReturn(0);
1205863406b8SStefano Zampini }
1206863406b8SStefano Zampini 
1207863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
12084cb006feSStefano Zampini {
12094cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12105ac14e1cSStefano Zampini   PetscBool      ishypre;
12114cb006feSStefano Zampini   PetscErrorCode ierr;
12124cb006feSStefano Zampini 
12134cb006feSStefano Zampini   PetscFunctionBegin;
12145ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)G,MATHYPRE,&ishypre);CHKERRQ(ierr);
12155ac14e1cSStefano Zampini   if (ishypre) {
12165ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr);
12175ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
12185ac14e1cSStefano Zampini     jac->G = G;
12195ac14e1cSStefano Zampini   } else {
12206bf688a0SCe Qin     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
12216bf688a0SCe Qin     ierr = MatConvert(G,MATHYPRE,MAT_INITIAL_MATRIX,&jac->G);CHKERRQ(ierr);
12225ac14e1cSStefano Zampini   }
12234cb006feSStefano Zampini   PetscFunctionReturn(0);
12244cb006feSStefano Zampini }
12254cb006feSStefano Zampini 
12264cb006feSStefano Zampini /*@
12274cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
12284cb006feSStefano Zampini 
12294cb006feSStefano Zampini    Collective on PC
12304cb006feSStefano Zampini 
12314cb006feSStefano Zampini    Input Parameters:
12324cb006feSStefano Zampini +  pc - the preconditioning context
12334cb006feSStefano Zampini -  G - the discrete gradient
12344cb006feSStefano Zampini 
12354cb006feSStefano Zampini    Level: intermediate
12364cb006feSStefano Zampini 
123795452b02SPatrick Sanan    Notes:
123895452b02SPatrick Sanan     G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh
1239863406b8SStefano 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
12404cb006feSStefano Zampini 
12414cb006feSStefano Zampini .seealso:
12424cb006feSStefano Zampini @*/
12434cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
12444cb006feSStefano Zampini {
12454cb006feSStefano Zampini   PetscErrorCode ierr;
12464cb006feSStefano Zampini 
12474cb006feSStefano Zampini   PetscFunctionBegin;
12484cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12494cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
12504cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
12514cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
12524cb006feSStefano Zampini   PetscFunctionReturn(0);
12534cb006feSStefano Zampini }
12544cb006feSStefano Zampini 
1255863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1256863406b8SStefano Zampini {
1257863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12585ac14e1cSStefano Zampini   PetscBool      ishypre;
1259863406b8SStefano Zampini   PetscErrorCode ierr;
1260863406b8SStefano Zampini 
1261863406b8SStefano Zampini   PetscFunctionBegin;
12625ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)C,MATHYPRE,&ishypre);CHKERRQ(ierr);
12635ac14e1cSStefano Zampini   if (ishypre) {
12645ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr);
12655ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
12665ac14e1cSStefano Zampini     jac->C = C;
12675ac14e1cSStefano Zampini   } else {
12686bf688a0SCe Qin     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
12696bf688a0SCe Qin     ierr = MatConvert(C,MATHYPRE,MAT_INITIAL_MATRIX,&jac->C);CHKERRQ(ierr);
12705ac14e1cSStefano Zampini   }
1271863406b8SStefano Zampini   PetscFunctionReturn(0);
1272863406b8SStefano Zampini }
1273863406b8SStefano Zampini 
1274863406b8SStefano Zampini /*@
1275863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1276863406b8SStefano Zampini 
1277863406b8SStefano Zampini    Collective on PC
1278863406b8SStefano Zampini 
1279863406b8SStefano Zampini    Input Parameters:
1280863406b8SStefano Zampini +  pc - the preconditioning context
1281863406b8SStefano Zampini -  C - the discrete curl
1282863406b8SStefano Zampini 
1283863406b8SStefano Zampini    Level: intermediate
1284863406b8SStefano Zampini 
128595452b02SPatrick Sanan    Notes:
128695452b02SPatrick Sanan     C should have as many rows as the number of faces and as many columns as the number of edges in the mesh
1287863406b8SStefano 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
1288863406b8SStefano Zampini 
1289863406b8SStefano Zampini .seealso:
1290863406b8SStefano Zampini @*/
1291863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1292863406b8SStefano Zampini {
1293863406b8SStefano Zampini   PetscErrorCode ierr;
1294863406b8SStefano Zampini 
1295863406b8SStefano Zampini   PetscFunctionBegin;
1296863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1297863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1298863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1299863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1300863406b8SStefano Zampini   PetscFunctionReturn(0);
1301863406b8SStefano Zampini }
1302863406b8SStefano Zampini 
13036bf688a0SCe Qin static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
13046bf688a0SCe Qin {
13056bf688a0SCe Qin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
13066bf688a0SCe Qin   PetscBool      ishypre;
13076bf688a0SCe Qin   PetscErrorCode ierr;
13086bf688a0SCe Qin   PetscInt       i;
13096bf688a0SCe Qin   PetscFunctionBegin;
13106bf688a0SCe Qin 
13116bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
13126bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
13136bf688a0SCe Qin   for (i=0;i<3;++i) {
13146bf688a0SCe Qin     ierr = MatDestroy(&jac->RT_Pi[i]);CHKERRQ(ierr);
13156bf688a0SCe Qin     ierr = MatDestroy(&jac->ND_Pi[i]);CHKERRQ(ierr);
13166bf688a0SCe Qin   }
13176bf688a0SCe Qin 
13186bf688a0SCe Qin   jac->dim = dim;
13196bf688a0SCe Qin   if (RT_PiFull) {
13206bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)RT_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
13216bf688a0SCe Qin     if (ishypre) {
13226bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)RT_PiFull);CHKERRQ(ierr);
13236bf688a0SCe Qin       jac->RT_PiFull = RT_PiFull;
13246bf688a0SCe Qin     } else {
13256bf688a0SCe Qin       ierr = MatConvert(RT_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_PiFull);CHKERRQ(ierr);
13266bf688a0SCe Qin     }
13276bf688a0SCe Qin   }
13286bf688a0SCe Qin   if (RT_Pi) {
13296bf688a0SCe Qin     for (i=0;i<dim;++i) {
13306bf688a0SCe Qin       if (RT_Pi[i]) {
13316bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)RT_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
13326bf688a0SCe Qin         if (ishypre) {
13336bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)RT_Pi[i]);CHKERRQ(ierr);
13346bf688a0SCe Qin           jac->RT_Pi[i] = RT_Pi[i];
13356bf688a0SCe Qin         } else {
13366bf688a0SCe Qin           ierr = MatConvert(RT_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_Pi[i]);CHKERRQ(ierr);
13376bf688a0SCe Qin         }
13386bf688a0SCe Qin       }
13396bf688a0SCe Qin     }
13406bf688a0SCe Qin   }
13416bf688a0SCe Qin   if (ND_PiFull) {
13426bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)ND_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
13436bf688a0SCe Qin     if (ishypre) {
13446bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)ND_PiFull);CHKERRQ(ierr);
13456bf688a0SCe Qin       jac->ND_PiFull = ND_PiFull;
13466bf688a0SCe Qin     } else {
13476bf688a0SCe Qin       ierr = MatConvert(ND_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_PiFull);CHKERRQ(ierr);
13486bf688a0SCe Qin     }
13496bf688a0SCe Qin   }
13506bf688a0SCe Qin   if (ND_Pi) {
13516bf688a0SCe Qin     for (i=0;i<dim;++i) {
13526bf688a0SCe Qin       if (ND_Pi[i]) {
13536bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)ND_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
13546bf688a0SCe Qin         if (ishypre) {
13556bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)ND_Pi[i]);CHKERRQ(ierr);
13566bf688a0SCe Qin           jac->ND_Pi[i] = ND_Pi[i];
13576bf688a0SCe Qin         } else {
13586bf688a0SCe Qin           ierr = MatConvert(ND_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_Pi[i]);CHKERRQ(ierr);
13596bf688a0SCe Qin         }
13606bf688a0SCe Qin       }
13616bf688a0SCe Qin     }
13626bf688a0SCe Qin   }
13636bf688a0SCe Qin 
13646bf688a0SCe Qin   PetscFunctionReturn(0);
13656bf688a0SCe Qin }
13666bf688a0SCe Qin 
13676bf688a0SCe Qin /*@
13686bf688a0SCe Qin  PCHYPRESetInterpolations - Set interpolation matrices for AMS/ADS preconditioner
13696bf688a0SCe Qin 
13706bf688a0SCe Qin    Collective on PC
13716bf688a0SCe Qin 
13726bf688a0SCe Qin    Input Parameters:
13736bf688a0SCe Qin +  pc - the preconditioning context
13746bf688a0SCe Qin -  dim - the dimension of the problem, only used in AMS
13756bf688a0SCe Qin -  RT_PiFull - Raviart-Thomas interpolation matrix
13766bf688a0SCe Qin -  RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix
13776bf688a0SCe Qin -  ND_PiFull - Nedelec interpolation matrix
13786bf688a0SCe Qin -  ND_Pi - x/y/z component of Nedelec interpolation matrix
13796bf688a0SCe Qin 
138095452b02SPatrick Sanan    Notes:
138195452b02SPatrick Sanan     For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL.
13826bf688a0SCe Qin           For ADS, both type of interpolation matrices are needed.
13836bf688a0SCe Qin    Level: intermediate
13846bf688a0SCe Qin 
13856bf688a0SCe Qin .seealso:
13866bf688a0SCe Qin @*/
13876bf688a0SCe Qin PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
13886bf688a0SCe Qin {
13896bf688a0SCe Qin   PetscErrorCode ierr;
13906bf688a0SCe Qin   PetscInt       i;
13916bf688a0SCe Qin 
13926bf688a0SCe Qin   PetscFunctionBegin;
13936bf688a0SCe Qin   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
13946bf688a0SCe Qin   if (RT_PiFull) {
13956bf688a0SCe Qin     PetscValidHeaderSpecific(RT_PiFull,MAT_CLASSID,3);
13966bf688a0SCe Qin     PetscCheckSameComm(pc,1,RT_PiFull,3);
13976bf688a0SCe Qin   }
13986bf688a0SCe Qin   if (RT_Pi) {
13996bf688a0SCe Qin     PetscValidPointer(RT_Pi,4);
14006bf688a0SCe Qin     for (i=0;i<dim;++i) {
14016bf688a0SCe Qin       if (RT_Pi[i]) {
14026bf688a0SCe Qin         PetscValidHeaderSpecific(RT_Pi[i],MAT_CLASSID,4);
14036bf688a0SCe Qin         PetscCheckSameComm(pc,1,RT_Pi[i],4);
14046bf688a0SCe Qin       }
14056bf688a0SCe Qin     }
14066bf688a0SCe Qin   }
14076bf688a0SCe Qin   if (ND_PiFull) {
14086bf688a0SCe Qin     PetscValidHeaderSpecific(ND_PiFull,MAT_CLASSID,5);
14096bf688a0SCe Qin     PetscCheckSameComm(pc,1,ND_PiFull,5);
14106bf688a0SCe Qin   }
14116bf688a0SCe Qin   if (ND_Pi) {
14126bf688a0SCe Qin     PetscValidPointer(ND_Pi,6);
14136bf688a0SCe Qin     for (i=0;i<dim;++i) {
14146bf688a0SCe Qin       if (ND_Pi[i]) {
14156bf688a0SCe Qin         PetscValidHeaderSpecific(ND_Pi[i],MAT_CLASSID,6);
14166bf688a0SCe Qin         PetscCheckSameComm(pc,1,ND_Pi[i],6);
14176bf688a0SCe Qin       }
14186bf688a0SCe Qin     }
14196bf688a0SCe Qin   }
14206bf688a0SCe Qin   ierr = PetscTryMethod(pc,"PCHYPRESetInterpolations_C",(PC,PetscInt,Mat,Mat[],Mat,Mat[]),(pc,dim,RT_PiFull,RT_Pi,ND_PiFull,ND_Pi));CHKERRQ(ierr);
14216bf688a0SCe Qin   PetscFunctionReturn(0);
14226bf688a0SCe Qin }
14236bf688a0SCe Qin 
14245ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha)
14254cb006feSStefano Zampini {
14264cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
14275ac14e1cSStefano Zampini   PetscBool      ishypre;
14284cb006feSStefano Zampini   PetscErrorCode ierr;
14294cb006feSStefano Zampini 
14304cb006feSStefano Zampini   PetscFunctionBegin;
14315ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr);
14325ac14e1cSStefano Zampini   if (ishypre) {
14335ac14e1cSStefano Zampini     if (isalpha) {
14345ac14e1cSStefano Zampini       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
14355ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
14365ac14e1cSStefano Zampini       jac->alpha_Poisson = A;
14375ac14e1cSStefano Zampini     } else {
14385ac14e1cSStefano Zampini       if (A) {
14395ac14e1cSStefano Zampini         ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
14405ac14e1cSStefano Zampini       } else {
14415ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
14425ac14e1cSStefano Zampini       }
14435ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
14445ac14e1cSStefano Zampini       jac->beta_Poisson = A;
14455ac14e1cSStefano Zampini     }
14465ac14e1cSStefano Zampini   } else {
14475ac14e1cSStefano Zampini     if (isalpha) {
14486bf688a0SCe Qin       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
14496bf688a0SCe Qin       ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->alpha_Poisson);CHKERRQ(ierr);
14505ac14e1cSStefano Zampini     } else {
14515ac14e1cSStefano Zampini       if (A) {
14526bf688a0SCe Qin         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
14536bf688a0SCe Qin         ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->beta_Poisson);CHKERRQ(ierr);
14545ac14e1cSStefano Zampini       } else {
14555ac14e1cSStefano Zampini         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
14565ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
14575ac14e1cSStefano Zampini       }
14585ac14e1cSStefano Zampini     }
14595ac14e1cSStefano Zampini   }
14604cb006feSStefano Zampini   PetscFunctionReturn(0);
14614cb006feSStefano Zampini }
14624cb006feSStefano Zampini 
14634cb006feSStefano Zampini /*@
14644cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
14654cb006feSStefano Zampini 
14664cb006feSStefano Zampini    Collective on PC
14674cb006feSStefano Zampini 
14684cb006feSStefano Zampini    Input Parameters:
14694cb006feSStefano Zampini +  pc - the preconditioning context
14704cb006feSStefano Zampini -  A - the matrix
14714cb006feSStefano Zampini 
14724cb006feSStefano Zampini    Level: intermediate
14734cb006feSStefano Zampini 
147495452b02SPatrick Sanan    Notes:
147595452b02SPatrick Sanan     A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
14764cb006feSStefano Zampini 
14774cb006feSStefano Zampini .seealso:
14784cb006feSStefano Zampini @*/
14794cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
14804cb006feSStefano Zampini {
14814cb006feSStefano Zampini   PetscErrorCode ierr;
14824cb006feSStefano Zampini 
14834cb006feSStefano Zampini   PetscFunctionBegin;
14844cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
14854cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
14864cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
14875ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_TRUE));CHKERRQ(ierr);
14884cb006feSStefano Zampini   PetscFunctionReturn(0);
14894cb006feSStefano Zampini }
14904cb006feSStefano Zampini 
14914cb006feSStefano Zampini /*@
14924cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
14934cb006feSStefano Zampini 
14944cb006feSStefano Zampini    Collective on PC
14954cb006feSStefano Zampini 
14964cb006feSStefano Zampini    Input Parameters:
14974cb006feSStefano Zampini +  pc - the preconditioning context
14984cb006feSStefano Zampini -  A - the matrix
14994cb006feSStefano Zampini 
15004cb006feSStefano Zampini    Level: intermediate
15014cb006feSStefano Zampini 
150295452b02SPatrick Sanan    Notes:
150395452b02SPatrick Sanan     A should be obtained by discretizing the Poisson problem with linear finite elements.
15044cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
15054cb006feSStefano Zampini 
15064cb006feSStefano Zampini .seealso:
15074cb006feSStefano Zampini @*/
15084cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
15094cb006feSStefano Zampini {
15104cb006feSStefano Zampini   PetscErrorCode ierr;
15114cb006feSStefano Zampini 
15124cb006feSStefano Zampini   PetscFunctionBegin;
15134cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15144cb006feSStefano Zampini   if (A) {
15154cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
15164cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
15174cb006feSStefano Zampini   }
15185ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_FALSE));CHKERRQ(ierr);
15194cb006feSStefano Zampini   PetscFunctionReturn(0);
15204cb006feSStefano Zampini }
15214cb006feSStefano Zampini 
15225ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz, Vec zoz, Vec zzo)
15234cb006feSStefano Zampini {
15244cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
15254cb006feSStefano Zampini   PetscErrorCode     ierr;
15264cb006feSStefano Zampini 
15274cb006feSStefano Zampini   PetscFunctionBegin;
15284cb006feSStefano Zampini   /* throw away any vector if already set */
15294cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
15304cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
15314cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
15324cb006feSStefano Zampini   jac->constants[0] = NULL;
15334cb006feSStefano Zampini   jac->constants[1] = NULL;
15344cb006feSStefano Zampini   jac->constants[2] = NULL;
15354cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
15364cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
15374cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
15384cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
15395ac14e1cSStefano Zampini   jac->dim = 2;
15404cb006feSStefano Zampini   if (zzo) {
15414cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
15424cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
15435ac14e1cSStefano Zampini     jac->dim++;
15444cb006feSStefano Zampini   }
15454cb006feSStefano Zampini   PetscFunctionReturn(0);
15464cb006feSStefano Zampini }
15474cb006feSStefano Zampini 
15484cb006feSStefano Zampini /*@
15494cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
15504cb006feSStefano Zampini 
15514cb006feSStefano Zampini    Collective on PC
15524cb006feSStefano Zampini 
15534cb006feSStefano Zampini    Input Parameters:
15544cb006feSStefano Zampini +  pc - the preconditioning context
15554cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
15564cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
15574cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
15584cb006feSStefano Zampini 
15594cb006feSStefano Zampini    Level: intermediate
15604cb006feSStefano Zampini 
15614cb006feSStefano Zampini    Notes:
15624cb006feSStefano Zampini 
15634cb006feSStefano Zampini .seealso:
15644cb006feSStefano Zampini @*/
15654cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
15664cb006feSStefano Zampini {
15674cb006feSStefano Zampini   PetscErrorCode ierr;
15684cb006feSStefano Zampini 
15694cb006feSStefano Zampini   PetscFunctionBegin;
15704cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15714cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
15724cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
15734cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
15744cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
15754cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
15764cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
15774cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
15784cb006feSStefano Zampini   PetscFunctionReturn(0);
15794cb006feSStefano Zampini }
15804cb006feSStefano Zampini 
1581863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
15824cb006feSStefano Zampini {
15834cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
15844cb006feSStefano Zampini   Vec             tv;
15854cb006feSStefano Zampini   PetscInt        i;
15864cb006feSStefano Zampini   PetscErrorCode  ierr;
15874cb006feSStefano Zampini 
15884cb006feSStefano Zampini   PetscFunctionBegin;
15894cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
15904cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
15914cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
15924cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
15935ac14e1cSStefano Zampini   jac->dim = dim;
15945ac14e1cSStefano Zampini 
15954cb006feSStefano Zampini   /* compute IJ vector for coordinates */
15964cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
15974cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
15984cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
15994cb006feSStefano Zampini   for (i=0;i<dim;i++) {
16004cb006feSStefano Zampini     PetscScalar *array;
16014cb006feSStefano Zampini     PetscInt    j;
16024cb006feSStefano Zampini 
16034cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
16044cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
16054cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
16064cb006feSStefano Zampini       array[j] = coords[j*dim+i];
16074cb006feSStefano Zampini     }
16084cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
16094cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
16104cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
16114cb006feSStefano Zampini   }
16124cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
16134cb006feSStefano Zampini   PetscFunctionReturn(0);
16144cb006feSStefano Zampini }
16154cb006feSStefano Zampini 
161616d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
161716d9e3a6SLisandro Dalcin 
1618f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
161916d9e3a6SLisandro Dalcin {
162016d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
162116d9e3a6SLisandro Dalcin 
162216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
162316d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
162416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
162516d9e3a6SLisandro Dalcin }
162616d9e3a6SLisandro Dalcin 
1627f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
162816d9e3a6SLisandro Dalcin {
162916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
163016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1631ace3abfcSBarry Smith   PetscBool      flag;
163216d9e3a6SLisandro Dalcin 
163316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
163416d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
163516d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1636ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
163716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
163816d9e3a6SLisandro Dalcin   } else {
163916d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
164016d9e3a6SLisandro Dalcin   }
164116d9e3a6SLisandro Dalcin 
164216d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
164316d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
164416d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
164516d9e3a6SLisandro Dalcin 
164616d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
164716d9e3a6SLisandro Dalcin   if (flag) {
1648572a0576SBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1649fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
165016d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
165116d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
165216d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
165316d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
165416d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
165516d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
165616d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
165716d9e3a6SLisandro Dalcin   }
1658db966c6cSHong Zhang   ierr = PetscStrcmp("euclid",jac->hypre_type,&flag);CHKERRQ(ierr);
1659db966c6cSHong Zhang   if (flag) {
1660db966c6cSHong Zhang     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1661db966c6cSHong Zhang     PetscStackCallStandard(HYPRE_EuclidCreate,(jac->comm_hypre,&jac->hsolver));
1662db966c6cSHong Zhang     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
1663db966c6cSHong Zhang     pc->ops->view           = PCView_HYPRE_Euclid;
1664db966c6cSHong Zhang     jac->destroy            = HYPRE_EuclidDestroy;
1665db966c6cSHong Zhang     jac->setup              = HYPRE_EuclidSetup;
1666db966c6cSHong Zhang     jac->solve              = HYPRE_EuclidSolve;
1667db966c6cSHong Zhang     jac->factorrowsize      = PETSC_DEFAULT;
1668db966c6cSHong Zhang     jac->eu_level           = PETSC_DEFAULT; /* default */
1669db966c6cSHong Zhang     PetscFunctionReturn(0);
1670db966c6cSHong Zhang   }
167116d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
167216d9e3a6SLisandro Dalcin   if (flag) {
1673572a0576SBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1674fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
167516d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
167616d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
167716d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
167816d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
167916d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
168016d9e3a6SLisandro Dalcin     /* initialize */
168116d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
168216d9e3a6SLisandro Dalcin     jac->threshhold = .1;
168316d9e3a6SLisandro Dalcin     jac->filter     = .1;
168416d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
16852fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
16862fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
16872fa5cd67SKarl Rupp 
168816d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
168916d9e3a6SLisandro Dalcin     jac->symt = 0;
1690fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1691fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1692fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1693fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1694fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1695fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
169616d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
169716d9e3a6SLisandro Dalcin   }
169816d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
169916d9e3a6SLisandro Dalcin   if (flag) {
170016d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
170116d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
170216d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
170316d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
170416d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
170516d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
170616d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
170716d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
170816d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
170916d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
171016d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
171116d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
171216d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
17138f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
171416d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
171516d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
171616d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
171716d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
171816d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
17190f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
17206a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1721b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
17221810e44eSEike Mueller     jac->eu_level         = 0;
17231810e44eSEike Mueller     jac->eu_droptolerance = 0;
17241810e44eSEike Mueller     jac->eu_bj            = 0;
17258f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
17260f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
172716d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
172816d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
172916d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
17300f1074feSSatish Balay     jac->interptype       = 0;
17310f1074feSSatish Balay     jac->agg_nl           = 0;
17320f1074feSSatish Balay     jac->pmax             = 0;
17330f1074feSSatish Balay     jac->truncfactor      = 0.0;
17340f1074feSSatish Balay     jac->agg_num_paths    = 1;
17358f87f92bSBarry Smith 
1736*22e51d31SStefano Zampini     jac->nodal_coarsening      = 0;
1737*22e51d31SStefano Zampini     jac->nodal_coarsening_diag = 0;
1738*22e51d31SStefano Zampini     jac->vec_interp_variant    = 0;
1739*22e51d31SStefano Zampini     jac->vec_interp_qmax       = 0;
1740*22e51d31SStefano Zampini     jac->vec_interp_smooth     = PETSC_FALSE;
1741*22e51d31SStefano Zampini     jac->interp_refine         = 0;
17428f87f92bSBarry Smith     jac->nodal_relax           = PETSC_FALSE;
17438f87f92bSBarry Smith     jac->nodal_relax_levels    = 1;
1744fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1745fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1746fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1747fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1748fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1749fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1750fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1751fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1752fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1753fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1754fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1755fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1756fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1757fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1758fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1759fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
176016d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
176116d9e3a6SLisandro Dalcin   }
17624cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
17634cb006feSStefano Zampini   if (flag) {
17644cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
17654cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
17664cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
17674cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
17684cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
17694cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
17704cb006feSStefano Zampini     jac->coords[0]           = NULL;
17714cb006feSStefano Zampini     jac->coords[1]           = NULL;
17724cb006feSStefano Zampini     jac->coords[2]           = NULL;
17734cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1774863406b8SStefano Zampini     jac->as_print           = 0;
1775863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1776863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
17774cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
17784cb006feSStefano Zampini     /* Smoothing options */
1779863406b8SStefano Zampini     jac->as_relax_type      = 2;
1780863406b8SStefano Zampini     jac->as_relax_times     = 1;
1781863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1782863406b8SStefano Zampini     jac->as_omega           = 1.0;
17834cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1784863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1785863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
17860bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1787863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1788863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1789863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
17904cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1791863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1792863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
17930bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1794863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1795863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1796863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1797863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1798863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
17994cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1800863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1801863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1802863406b8SStefano Zampini                                                                       jac->as_relax_times,
1803863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1804863406b8SStefano Zampini                                                                       jac->as_omega));
1805863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1806863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1807863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1808863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1809863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1810863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1811863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1812863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1813863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1814863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1815863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1816863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
181723df4f25SStefano Zampini     /* Zero conductivity */
181823df4f25SStefano Zampini     jac->ams_beta_is_zero      = PETSC_FALSE;
181923df4f25SStefano Zampini     jac->ams_beta_is_zero_part = PETSC_FALSE;
18204cb006feSStefano Zampini     PetscFunctionReturn(0);
18214cb006feSStefano Zampini   }
1822863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1823863406b8SStefano Zampini   if (flag) {
1824863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1825863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1826863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1827863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1828863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1829863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1830863406b8SStefano Zampini     jac->coords[0]           = NULL;
1831863406b8SStefano Zampini     jac->coords[1]           = NULL;
1832863406b8SStefano Zampini     jac->coords[2]           = NULL;
1833863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1834863406b8SStefano Zampini     jac->as_print           = 0;
1835863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1836863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1837863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1838863406b8SStefano Zampini     /* Smoothing options */
1839863406b8SStefano Zampini     jac->as_relax_type      = 2;
1840863406b8SStefano Zampini     jac->as_relax_times     = 1;
1841863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1842863406b8SStefano Zampini     jac->as_omega           = 1.0;
1843863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1844863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1845863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1846863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1847863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1848863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1849863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1850863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1851863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1852863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1853863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1854863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1855863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1856863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1857863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1858863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1859863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1860863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1861863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1862863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1863863406b8SStefano Zampini                                                                       jac->as_relax_times,
1864863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1865863406b8SStefano Zampini                                                                       jac->as_omega));
1866863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1867863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1868863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1869863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1870863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1871863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1872863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1873863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1874863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1875863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1876863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1877863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1878863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1879863406b8SStefano Zampini     PetscFunctionReturn(0);
1880863406b8SStefano Zampini   }
1881503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
18822fa5cd67SKarl Rupp 
18830298fd71SBarry Smith   jac->hypre_type = NULL;
1884db966c6cSHong Zhang   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams",name);
188516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
188616d9e3a6SLisandro Dalcin }
188716d9e3a6SLisandro Dalcin 
188816d9e3a6SLisandro Dalcin /*
188916d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
189016d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
189116d9e3a6SLisandro Dalcin */
18924416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc)
189316d9e3a6SLisandro Dalcin {
189416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
18954ddd07fcSJed Brown   PetscInt       indx;
1896db966c6cSHong Zhang   const char     *type[] = {"euclid","pilut","parasails","boomeramg","ams","ads"};
1897ace3abfcSBarry Smith   PetscBool      flg;
189816d9e3a6SLisandro Dalcin 
189916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
19009fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
19019c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
190216d9e3a6SLisandro Dalcin   if (flg) {
190316d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
190402a17cd4SBarry Smith   } else {
190502a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
190616d9e3a6SLisandro Dalcin   }
190716d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
19083931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
190916d9e3a6SLisandro Dalcin   }
191016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
191116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
191216d9e3a6SLisandro Dalcin }
191316d9e3a6SLisandro Dalcin 
191416d9e3a6SLisandro Dalcin /*@C
191516d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
191616d9e3a6SLisandro Dalcin 
191716d9e3a6SLisandro Dalcin    Input Parameters:
191816d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1919db966c6cSHong Zhang -     name - either  euclid, pilut, parasails, boomeramg, ams, ads
192016d9e3a6SLisandro Dalcin 
192116d9e3a6SLisandro Dalcin    Options Database Keys:
1922db966c6cSHong Zhang    -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
192316d9e3a6SLisandro Dalcin 
192416d9e3a6SLisandro Dalcin    Level: intermediate
192516d9e3a6SLisandro Dalcin 
192616d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
192716d9e3a6SLisandro Dalcin            PCHYPRE
192816d9e3a6SLisandro Dalcin 
192916d9e3a6SLisandro Dalcin @*/
19307087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
193116d9e3a6SLisandro Dalcin {
19324ac538c5SBarry Smith   PetscErrorCode ierr;
193316d9e3a6SLisandro Dalcin 
193416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
19350700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
193616d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
19374ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
193816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
193916d9e3a6SLisandro Dalcin }
194016d9e3a6SLisandro Dalcin 
194116d9e3a6SLisandro Dalcin /*@C
194216d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
194316d9e3a6SLisandro Dalcin 
194416d9e3a6SLisandro Dalcin    Input Parameter:
194516d9e3a6SLisandro Dalcin .     pc - the preconditioner context
194616d9e3a6SLisandro Dalcin 
194716d9e3a6SLisandro Dalcin    Output Parameter:
1948db966c6cSHong Zhang .     name - either  euclid, pilut, parasails, boomeramg, ams, ads
194916d9e3a6SLisandro Dalcin 
195016d9e3a6SLisandro Dalcin    Level: intermediate
195116d9e3a6SLisandro Dalcin 
195216d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
195316d9e3a6SLisandro Dalcin            PCHYPRE
195416d9e3a6SLisandro Dalcin 
195516d9e3a6SLisandro Dalcin @*/
19567087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
195716d9e3a6SLisandro Dalcin {
19584ac538c5SBarry Smith   PetscErrorCode ierr;
195916d9e3a6SLisandro Dalcin 
196016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
19610700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
196216d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
19634ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
196416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
196516d9e3a6SLisandro Dalcin }
196616d9e3a6SLisandro Dalcin 
196716d9e3a6SLisandro Dalcin /*MC
196816d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
196916d9e3a6SLisandro Dalcin 
197016d9e3a6SLisandro Dalcin    Options Database Keys:
1971db966c6cSHong Zhang +   -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
197216d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
197316d9e3a6SLisandro Dalcin           preconditioner
197416d9e3a6SLisandro Dalcin 
197516d9e3a6SLisandro Dalcin    Level: intermediate
197616d9e3a6SLisandro Dalcin 
197795452b02SPatrick Sanan    Notes:
197895452b02SPatrick Sanan     Apart from pc_hypre_type (for which there is PCHYPRESetType()),
197916d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
198016d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
198116d9e3a6SLisandro Dalcin 
1982c231f9e3SBarryFSmith           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_tol refer to the number of iterations
19830f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
19840f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
1985c231f9e3SBarryFSmith           (-pc_hypre_boomeramg_tol should be set to 0.0 - the default - to strictly use a fixed number of
19868f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
19870f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
19880f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
198916d9e3a6SLisandro Dalcin 
19900f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
19910f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
19920f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
199316d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
199416d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
199516d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
199616d9e3a6SLisandro Dalcin 
199716d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
199816d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
199916d9e3a6SLisandro Dalcin 
20005272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
20015272c319SBarry Smith           the two options:
20025272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
2003cbc39033SBarry Smith -   -pc_hypre_boomeramg_vec_interp_variant <v> where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
20045272c319SBarry Smith 
20055272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
20065272c319SBarry Smith 
20079e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
20089e5bc791SBarry Smith 
200916d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
20109e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
201116d9e3a6SLisandro Dalcin 
201216d9e3a6SLisandro Dalcin M*/
201316d9e3a6SLisandro Dalcin 
20148cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
201516d9e3a6SLisandro Dalcin {
201616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
201716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
201816d9e3a6SLisandro Dalcin 
201916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
2020b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
20212fa5cd67SKarl Rupp 
202216d9e3a6SLisandro Dalcin   pc->data                = jac;
20238695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
202416d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
202516d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
202616d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
202716d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
202816d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
2029bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
2030bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
20315ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
20325ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
20335ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
20346bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",PCHYPRESetInterpolations_HYPRE);CHKERRQ(ierr);
20355ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE);CHKERRQ(ierr);
20365ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",PCHYPRESetPoissonMatrix_HYPRE);CHKERRQ(ierr);
203716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
203816d9e3a6SLisandro Dalcin }
2039ebc551c0SBarry Smith 
2040f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
2041f91d8e95SBarry Smith 
2042ebc551c0SBarry Smith typedef struct {
204368326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
2044f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
20459e5bc791SBarry Smith 
20469e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
20474ddd07fcSJed Brown   PetscInt its;
20489e5bc791SBarry Smith   double   tol;
20494ddd07fcSJed Brown   PetscInt relax_type;
20504ddd07fcSJed Brown   PetscInt rap_type;
20514ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
20524ddd07fcSJed Brown   PetscInt max_levels;
2053ebc551c0SBarry Smith } PC_PFMG;
2054ebc551c0SBarry Smith 
2055ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
2056ebc551c0SBarry Smith {
2057ebc551c0SBarry Smith   PetscErrorCode ierr;
2058f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2059ebc551c0SBarry Smith 
2060ebc551c0SBarry Smith   PetscFunctionBegin;
20612fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2062f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2063c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2064ebc551c0SBarry Smith   PetscFunctionReturn(0);
2065ebc551c0SBarry Smith }
2066ebc551c0SBarry Smith 
20679e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
20689e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
20699e5bc791SBarry Smith 
2070ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
2071ebc551c0SBarry Smith {
2072ebc551c0SBarry Smith   PetscErrorCode ierr;
2073ace3abfcSBarry Smith   PetscBool      iascii;
2074f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2075ebc551c0SBarry Smith 
2076ebc551c0SBarry Smith   PetscFunctionBegin;
2077251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
20789e5bc791SBarry Smith   if (iascii) {
20799e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
2080efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max iterations %d\n",ex->its);CHKERRQ(ierr);
2081efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    tolerance %g\n",ex->tol);CHKERRQ(ierr);
2082efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2083efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
2084efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2085efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max levels %d\n",ex->max_levels);CHKERRQ(ierr);
20869e5bc791SBarry Smith   }
2087ebc551c0SBarry Smith   PetscFunctionReturn(0);
2088ebc551c0SBarry Smith }
2089ebc551c0SBarry Smith 
20904416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2091ebc551c0SBarry Smith {
2092ebc551c0SBarry Smith   PetscErrorCode ierr;
2093f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2094ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2095ebc551c0SBarry Smith 
2096ebc551c0SBarry Smith   PetscFunctionBegin;
2097e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
20980298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
209968326731SBarry Smith   if (flg) {
2100a0324ebeSBarry Smith     int level=3;
2101fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
210268326731SBarry Smith   }
21030298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2104fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
21050298fd71SBarry 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);
2106fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
21070298fd71SBarry 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);
2108fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
21099e5bc791SBarry Smith 
21100298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
2111fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
21123b46a515SGlenn Hammond 
21130298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2114fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
21150298fd71SBarry 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);
2116fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
21170298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
2118fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
2119ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
2120ebc551c0SBarry Smith   PetscFunctionReturn(0);
2121ebc551c0SBarry Smith }
2122ebc551c0SBarry Smith 
2123f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
2124f91d8e95SBarry Smith {
2125f91d8e95SBarry Smith   PetscErrorCode    ierr;
2126f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
2127d9ca1df4SBarry Smith   PetscScalar       *yy;
2128d9ca1df4SBarry Smith   const PetscScalar *xx;
21294ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
213068326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2131f91d8e95SBarry Smith 
2132f91d8e95SBarry Smith   PetscFunctionBegin;
2133dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2134aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2135f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
2136f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
2137f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
2138f91d8e95SBarry Smith 
2139f91d8e95SBarry Smith   /* copy x values over to hypre */
2140fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
2141d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2142d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
2143d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2144fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
2145fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2146f91d8e95SBarry Smith 
2147f91d8e95SBarry Smith   /* copy solution values back to PETSc */
2148f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
21498b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
2150f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2151f91d8e95SBarry Smith   PetscFunctionReturn(0);
2152f91d8e95SBarry Smith }
2153f91d8e95SBarry Smith 
2154ace3abfcSBarry 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)
21559e5bc791SBarry Smith {
21569e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
21579e5bc791SBarry Smith   PetscErrorCode ierr;
21584ddd07fcSJed Brown   PetscInt       oits;
21599e5bc791SBarry Smith 
21609e5bc791SBarry Smith   PetscFunctionBegin;
2161dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2162fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
2163fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
21649e5bc791SBarry Smith 
21659e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
21668b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
21679e5bc791SBarry Smith   *outits = oits;
21689e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
21699e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2170fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
2171fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
21729e5bc791SBarry Smith   PetscFunctionReturn(0);
21739e5bc791SBarry Smith }
21749e5bc791SBarry Smith 
21759e5bc791SBarry Smith 
21763a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
21773a32d3dbSGlenn Hammond {
21783a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
21793a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
21803a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2181ace3abfcSBarry Smith   PetscBool       flg;
21823a32d3dbSGlenn Hammond 
21833a32d3dbSGlenn Hammond   PetscFunctionBegin;
2184251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
2185ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
21863a32d3dbSGlenn Hammond 
21873a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
21882fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2189fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2190fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2191fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
21923a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
21933a32d3dbSGlenn Hammond }
21943a32d3dbSGlenn Hammond 
2195ebc551c0SBarry Smith /*MC
2196ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
2197ebc551c0SBarry Smith 
2198ebc551c0SBarry Smith    Level: advanced
2199ebc551c0SBarry Smith 
22009e5bc791SBarry Smith    Options Database:
22019e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
22029e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
22039e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
22049e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
22059e5bc791SBarry 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
22069e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
2207f91d8e95SBarry Smith 
220895452b02SPatrick Sanan    Notes:
220995452b02SPatrick Sanan     This is for CELL-centered descretizations
22109e5bc791SBarry Smith 
22118e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
2212aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
22139e5bc791SBarry Smith 
22149e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
2215ebc551c0SBarry Smith M*/
2216ebc551c0SBarry Smith 
22178cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
2218ebc551c0SBarry Smith {
2219ebc551c0SBarry Smith   PetscErrorCode ierr;
2220ebc551c0SBarry Smith   PC_PFMG        *ex;
2221ebc551c0SBarry Smith 
2222ebc551c0SBarry Smith   PetscFunctionBegin;
2223b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
222468326731SBarry Smith   pc->data = ex;
2225ebc551c0SBarry Smith 
22269e5bc791SBarry Smith   ex->its            = 1;
22279e5bc791SBarry Smith   ex->tol            = 1.e-8;
22289e5bc791SBarry Smith   ex->relax_type     = 1;
22299e5bc791SBarry Smith   ex->rap_type       = 0;
22309e5bc791SBarry Smith   ex->num_pre_relax  = 1;
22319e5bc791SBarry Smith   ex->num_post_relax = 1;
22323b46a515SGlenn Hammond   ex->max_levels     = 0;
22339e5bc791SBarry Smith 
2234ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2235ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2236ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2237f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
22389e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
223968326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
22402fa5cd67SKarl Rupp 
2241ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2242fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2243ebc551c0SBarry Smith   PetscFunctionReturn(0);
2244ebc551c0SBarry Smith }
2245d851a50bSGlenn Hammond 
2246325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2247325fc9f4SBarry Smith 
2248d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2249d851a50bSGlenn Hammond typedef struct {
2250d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2251d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2252d851a50bSGlenn Hammond 
2253d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
22544ddd07fcSJed Brown   PetscInt its;
2255d851a50bSGlenn Hammond   double   tol;
22564ddd07fcSJed Brown   PetscInt relax_type;
22574ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2258d851a50bSGlenn Hammond } PC_SysPFMG;
2259d851a50bSGlenn Hammond 
2260d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2261d851a50bSGlenn Hammond {
2262d851a50bSGlenn Hammond   PetscErrorCode ierr;
2263d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2264d851a50bSGlenn Hammond 
2265d851a50bSGlenn Hammond   PetscFunctionBegin;
22662fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2267d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2268c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2269d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2270d851a50bSGlenn Hammond }
2271d851a50bSGlenn Hammond 
2272d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2273d851a50bSGlenn Hammond 
2274d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2275d851a50bSGlenn Hammond {
2276d851a50bSGlenn Hammond   PetscErrorCode ierr;
2277ace3abfcSBarry Smith   PetscBool      iascii;
2278d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2279d851a50bSGlenn Hammond 
2280d851a50bSGlenn Hammond   PetscFunctionBegin;
2281251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2282d851a50bSGlenn Hammond   if (iascii) {
2283d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2284efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  max iterations %d\n",ex->its);CHKERRQ(ierr);
2285efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerance %g\n",ex->tol);CHKERRQ(ierr);
2286efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2287efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2288d851a50bSGlenn Hammond   }
2289d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2290d851a50bSGlenn Hammond }
2291d851a50bSGlenn Hammond 
22924416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2293d851a50bSGlenn Hammond {
2294d851a50bSGlenn Hammond   PetscErrorCode ierr;
2295d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2296ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2297d851a50bSGlenn Hammond 
2298d851a50bSGlenn Hammond   PetscFunctionBegin;
2299e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
23000298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2301d851a50bSGlenn Hammond   if (flg) {
2302d851a50bSGlenn Hammond     int level=3;
2303fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
2304d851a50bSGlenn Hammond   }
23050298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2306fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
23070298fd71SBarry 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);
2308fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
23090298fd71SBarry 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);
2310fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2311d851a50bSGlenn Hammond 
23120298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2313fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
231461710fbeSStefano Zampini   ierr = PetscOptionsEList("-pc_syspfmg_relax_type","Relax type for the up and down cycles","HYPRE_SStructSysPFMGSetRelaxType",SysPFMGRelaxType,ALEN(SysPFMGRelaxType),SysPFMGRelaxType[ex->relax_type],&ex->relax_type,NULL);CHKERRQ(ierr);
2315fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2316d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2317d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2318d851a50bSGlenn Hammond }
2319d851a50bSGlenn Hammond 
2320d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2321d851a50bSGlenn Hammond {
2322d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2323d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2324d9ca1df4SBarry Smith   PetscScalar       *yy;
2325d9ca1df4SBarry Smith   const PetscScalar *xx;
23264ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
2327d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
23284ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
23294ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
23304ddd07fcSJed Brown   PetscInt          part    = 0;
23314ddd07fcSJed Brown   PetscInt          size;
23324ddd07fcSJed Brown   PetscInt          i;
2333d851a50bSGlenn Hammond 
2334d851a50bSGlenn Hammond   PetscFunctionBegin;
2335dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2336aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2337d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2338d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2339d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2340d851a50bSGlenn Hammond 
2341d851a50bSGlenn Hammond   size = 1;
23422fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
23432fa5cd67SKarl Rupp 
2344d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2345d851a50bSGlenn Hammond   if (ordering) {
2346fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2347d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2348d9ca1df4SBarry 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)));
2349d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2350fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2351fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2352fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2353d851a50bSGlenn Hammond 
2354d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2355d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
23568b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2357d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2358a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2359d851a50bSGlenn Hammond     PetscScalar *z;
23604ddd07fcSJed Brown     PetscInt    j, k;
2361d851a50bSGlenn Hammond 
2362785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2363fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2364d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2365d851a50bSGlenn Hammond 
2366d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2367d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2368d851a50bSGlenn Hammond       k= i*nvars;
23692fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2370d851a50bSGlenn Hammond     }
23718b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2372d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2373fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2374fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2375d851a50bSGlenn Hammond 
2376d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2377d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
23788b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2379d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2380d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2381d851a50bSGlenn Hammond       k= i*nvars;
23822fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2383d851a50bSGlenn Hammond     }
2384d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2385d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2386d851a50bSGlenn Hammond   }
2387d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2388d851a50bSGlenn Hammond }
2389d851a50bSGlenn Hammond 
2390ace3abfcSBarry 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)
2391d851a50bSGlenn Hammond {
2392d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2393d851a50bSGlenn Hammond   PetscErrorCode ierr;
23944ddd07fcSJed Brown   PetscInt       oits;
2395d851a50bSGlenn Hammond 
2396d851a50bSGlenn Hammond   PetscFunctionBegin;
2397dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2398fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2399fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2400d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
24018b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2402d851a50bSGlenn Hammond   *outits = oits;
2403d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2404d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2405fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2406fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2407d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2408d851a50bSGlenn Hammond }
2409d851a50bSGlenn Hammond 
2410d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2411d851a50bSGlenn Hammond {
2412d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2413d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2414d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2415ace3abfcSBarry Smith   PetscBool        flg;
2416d851a50bSGlenn Hammond 
2417d851a50bSGlenn Hammond   PetscFunctionBegin;
2418251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2419ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2420d851a50bSGlenn Hammond 
2421d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
24222fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2423fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2424fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2425fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2426d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2427d851a50bSGlenn Hammond }
2428d851a50bSGlenn Hammond 
2429d851a50bSGlenn Hammond /*MC
2430d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2431d851a50bSGlenn Hammond 
2432d851a50bSGlenn Hammond    Level: advanced
2433d851a50bSGlenn Hammond 
2434d851a50bSGlenn Hammond    Options Database:
2435d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2436d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2437d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2438d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2439d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2440d851a50bSGlenn Hammond 
244195452b02SPatrick Sanan    Notes:
244295452b02SPatrick Sanan     This is for CELL-centered descretizations
2443d851a50bSGlenn Hammond 
2444f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2445aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2446d851a50bSGlenn Hammond            Also, only cell-centered variables.
2447d851a50bSGlenn Hammond 
2448d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2449d851a50bSGlenn Hammond M*/
2450d851a50bSGlenn Hammond 
24518cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2452d851a50bSGlenn Hammond {
2453d851a50bSGlenn Hammond   PetscErrorCode ierr;
2454d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2455d851a50bSGlenn Hammond 
2456d851a50bSGlenn Hammond   PetscFunctionBegin;
2457b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2458d851a50bSGlenn Hammond   pc->data = ex;
2459d851a50bSGlenn Hammond 
2460d851a50bSGlenn Hammond   ex->its            = 1;
2461d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2462d851a50bSGlenn Hammond   ex->relax_type     = 1;
2463d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2464d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2465d851a50bSGlenn Hammond 
2466d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2467d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2468d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2469d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2470d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2471d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
24722fa5cd67SKarl Rupp 
2473ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2474fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2475d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2476d851a50bSGlenn Hammond }
2477