xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision a74df02f222316236ed1d8002178a4355feb2b02)
116d9e3a6SLisandro Dalcin /*
216d9e3a6SLisandro Dalcin    Provides an interface to the LLNL package hypre
316d9e3a6SLisandro Dalcin */
40f1074feSSatish Balay 
5589dcaf0SStefano Zampini #include <petscpkg_version.h>
6af0996ceSBarry Smith #include <petsc/private/pcimpl.h>          /*I "petscpc.h" I*/
749a781f5SStefano Zampini /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
849a781f5SStefano Zampini #include <petsc/private/matimpl.h>
96ea7df73SStefano Zampini #include <petsc/private/vecimpl.h>
1058968eb6SStefano Zampini #include <../src/vec/vec/impls/hypre/vhyp.h>
1149a781f5SStefano Zampini #include <../src/mat/impls/hypre/mhypre.h>
12c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h>
134cb006feSStefano Zampini #include <_hypre_parcsr_ls.h>
148a2c336bSFande Kong #include <petscmathypre.h>
1516d9e3a6SLisandro Dalcin 
16a4af0ceeSJacob Faibussowitsch #if defined(PETSC_HAVE_HYPRE_DEVICE)
17a4af0ceeSJacob Faibussowitsch #include <petsc/private/deviceimpl.h>
18a4af0ceeSJacob Faibussowitsch #endif
19a4af0ceeSJacob Faibussowitsch 
20dff31646SBarry Smith static PetscBool cite = PETSC_FALSE;
21a8d69d7bSBarry 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{https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods}}\n}\n";
221f817a21SBarry Smith 
2316d9e3a6SLisandro Dalcin /*
2416d9e3a6SLisandro Dalcin    Private context (data structure) for the  preconditioner.
2516d9e3a6SLisandro Dalcin */
2616d9e3a6SLisandro Dalcin typedef struct {
2716d9e3a6SLisandro Dalcin   HYPRE_Solver   hsolver;
2849a781f5SStefano Zampini   Mat            hpmat; /* MatHYPRE */
2916d9e3a6SLisandro Dalcin 
304ddd07fcSJed Brown   HYPRE_Int (*destroy)(HYPRE_Solver);
314ddd07fcSJed Brown   HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
324ddd07fcSJed Brown   HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
3316d9e3a6SLisandro Dalcin 
3416d9e3a6SLisandro Dalcin   MPI_Comm comm_hypre;
3516d9e3a6SLisandro Dalcin   char     *hypre_type;
3616d9e3a6SLisandro Dalcin 
3716d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
384ddd07fcSJed Brown   PetscInt  maxiter;
3939accc25SStefano Zampini   PetscReal tol;
4016d9e3a6SLisandro Dalcin 
4116d9e3a6SLisandro Dalcin   /* options for Pilut */
424ddd07fcSJed Brown   PetscInt factorrowsize;
4316d9e3a6SLisandro Dalcin 
4416d9e3a6SLisandro Dalcin   /* options for ParaSails */
454ddd07fcSJed Brown   PetscInt  nlevels;
468966356dSPierre Jolivet   PetscReal threshold;
4739accc25SStefano Zampini   PetscReal filter;
4839accc25SStefano Zampini   PetscReal loadbal;
494ddd07fcSJed Brown   PetscInt  logging;
504ddd07fcSJed Brown   PetscInt  ruse;
514ddd07fcSJed Brown   PetscInt  symt;
5216d9e3a6SLisandro Dalcin 
5322b6d1caSBarry Smith   /* options for BoomerAMG */
54ace3abfcSBarry Smith   PetscBool printstatistics;
5516d9e3a6SLisandro Dalcin 
5616d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
574ddd07fcSJed Brown   PetscInt  cycletype;
584ddd07fcSJed Brown   PetscInt  maxlevels;
5939accc25SStefano Zampini   PetscReal strongthreshold;
6039accc25SStefano Zampini   PetscReal maxrowsum;
614ddd07fcSJed Brown   PetscInt  gridsweeps[3];
624ddd07fcSJed Brown   PetscInt  coarsentype;
634ddd07fcSJed Brown   PetscInt  measuretype;
646a251517SEike Mueller   PetscInt  smoothtype;
658131ecf7SEike Mueller   PetscInt  smoothnumlevels;
66ec64516dSEike Mueller   PetscInt  eu_level;   /* Number of levels for ILU(k) in Euclid */
6739accc25SStefano Zampini   PetscReal eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */
68ec64516dSEike Mueller   PetscInt  eu_bj;      /* Defines use of Block Jacobi ILU in Euclid */
694ddd07fcSJed Brown   PetscInt  relaxtype[3];
7039accc25SStefano Zampini   PetscReal relaxweight;
7139accc25SStefano Zampini   PetscReal outerrelaxweight;
724ddd07fcSJed Brown   PetscInt  relaxorder;
7339accc25SStefano Zampini   PetscReal truncfactor;
74ace3abfcSBarry Smith   PetscBool applyrichardson;
754ddd07fcSJed Brown   PetscInt  pmax;
764ddd07fcSJed Brown   PetscInt  interptype;
77589dcaf0SStefano Zampini   PetscInt  maxc;
78589dcaf0SStefano Zampini   PetscInt  minc;
79db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0)
80db6f9c32SMark Adams   char      *spgemm_type; // this is a global hypre parameter but is closely associated with BoomerAMG
81db6f9c32SMark Adams #endif
826ea7df73SStefano Zampini   /* GPU */
836ea7df73SStefano Zampini   PetscBool keeptranspose;
846ea7df73SStefano Zampini   PetscInt  rap2;
856ea7df73SStefano Zampini   PetscInt  mod_rap2;
866ea7df73SStefano Zampini 
87589dcaf0SStefano Zampini   /* AIR */
88589dcaf0SStefano Zampini   PetscInt  Rtype;
89589dcaf0SStefano Zampini   PetscReal Rstrongthreshold;
90589dcaf0SStefano Zampini   PetscReal Rfilterthreshold;
91589dcaf0SStefano Zampini   PetscInt  Adroptype;
92589dcaf0SStefano Zampini   PetscReal Adroptol;
93589dcaf0SStefano Zampini 
944ddd07fcSJed Brown   PetscInt  agg_nl;
956ea7df73SStefano Zampini   PetscInt  agg_interptype;
964ddd07fcSJed Brown   PetscInt  agg_num_paths;
97ace3abfcSBarry Smith   PetscBool nodal_relax;
984ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
994cb006feSStefano Zampini 
1005272c319SBarry Smith   PetscInt  nodal_coarsening;
10122e51d31SStefano Zampini   PetscInt  nodal_coarsening_diag;
1025272c319SBarry Smith   PetscInt  vec_interp_variant;
10322e51d31SStefano Zampini   PetscInt  vec_interp_qmax;
10422e51d31SStefano Zampini   PetscBool vec_interp_smooth;
10522e51d31SStefano Zampini   PetscInt  interp_refine;
10622e51d31SStefano Zampini 
1076ea7df73SStefano Zampini   /* NearNullSpace support */
1086ea7df73SStefano Zampini   VecHYPRE_IJVector *hmnull;
1096ea7df73SStefano Zampini   HYPRE_ParVector   *phmnull;
1105272c319SBarry Smith   PetscInt          n_hmnull;
1115272c319SBarry Smith   Vec               hmnull_constant;
1125272c319SBarry Smith 
113863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
114863406b8SStefano Zampini   PetscInt  as_print;
115863406b8SStefano Zampini   PetscInt  as_max_iter;
116863406b8SStefano Zampini   PetscReal as_tol;
117863406b8SStefano Zampini   PetscInt  as_relax_type;
118863406b8SStefano Zampini   PetscInt  as_relax_times;
119863406b8SStefano Zampini   PetscReal as_relax_weight;
120863406b8SStefano Zampini   PetscReal as_omega;
121863406b8SStefano 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) */
122863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
123863406b8SStefano 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) */
124863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
1254cb006feSStefano Zampini   PetscInt  ams_cycle_type;
126863406b8SStefano Zampini   PetscInt  ads_cycle_type;
1274cb006feSStefano Zampini 
1284cb006feSStefano Zampini   /* additional data */
1295ac14e1cSStefano Zampini   Mat G;             /* MatHYPRE */
1305ac14e1cSStefano Zampini   Mat C;             /* MatHYPRE */
1315ac14e1cSStefano Zampini   Mat alpha_Poisson; /* MatHYPRE */
1325ac14e1cSStefano Zampini   Mat beta_Poisson;  /* MatHYPRE */
1335ac14e1cSStefano Zampini 
1345ac14e1cSStefano Zampini   /* extra information for AMS */
1355ac14e1cSStefano Zampini   PetscInt          dim; /* geometrical dimension */
1366ea7df73SStefano Zampini   VecHYPRE_IJVector coords[3];
1376ea7df73SStefano Zampini   VecHYPRE_IJVector constants[3];
1386bf688a0SCe Qin   Mat               RT_PiFull, RT_Pi[3];
1396bf688a0SCe Qin   Mat               ND_PiFull, ND_Pi[3];
1404cb006feSStefano Zampini   PetscBool         ams_beta_is_zero;
14123df4f25SStefano Zampini   PetscBool         ams_beta_is_zero_part;
14223df4f25SStefano Zampini   PetscInt          ams_proj_freq;
14316d9e3a6SLisandro Dalcin } PC_HYPRE;
14416d9e3a6SLisandro Dalcin 
145d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
146d2128fa2SBarry Smith {
147d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
148d2128fa2SBarry Smith 
149d2128fa2SBarry Smith   PetscFunctionBegin;
150d2128fa2SBarry Smith   *hsolver = jac->hsolver;
151d2128fa2SBarry Smith   PetscFunctionReturn(0);
152d2128fa2SBarry Smith }
15316d9e3a6SLisandro Dalcin 
154fd2dd295SFande Kong /*
1558a2c336bSFande Kong   Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix
1568a2c336bSFande Kong   is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine.
1578a2c336bSFande Kong   It is used in PCHMG. Other users should avoid using this function.
158fd2dd295SFande Kong */
159fd2dd295SFande Kong static PetscErrorCode PCGetCoarseOperators_BoomerAMG(PC pc,PetscInt *nlevels,Mat *operators[])
1608a2c336bSFande Kong {
1618a2c336bSFande Kong   PC_HYPRE             *jac  = (PC_HYPRE*)pc->data;
1628a2c336bSFande Kong   PetscBool            same = PETSC_FALSE;
1638a2c336bSFande Kong   PetscErrorCode       ierr;
1648a2c336bSFande Kong   PetscInt             num_levels,l;
1658a2c336bSFande Kong   Mat                  *mattmp;
1668a2c336bSFande Kong   hypre_ParCSRMatrix   **A_array;
1678a2c336bSFande Kong 
1688a2c336bSFande Kong   PetscFunctionBegin;
1698a2c336bSFande Kong   ierr = PetscStrcmp(jac->hypre_type,"boomeramg",&same);CHKERRQ(ierr);
1709ace16cdSJacob Faibussowitsch   PetscAssertFalse(!same,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_NOTSAMETYPE,"Hypre type is not BoomerAMG ");
1718a2c336bSFande Kong   num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData*) (jac->hsolver));
1728a2c336bSFande Kong   ierr = PetscMalloc1(num_levels,&mattmp);CHKERRQ(ierr);
1738a2c336bSFande Kong   A_array    = hypre_ParAMGDataAArray((hypre_ParAMGData*) (jac->hsolver));
1748a2c336bSFande Kong   for (l=1; l<num_levels; l++) {
1758a2c336bSFande Kong     ierr = MatCreateFromParCSR(A_array[l],MATAIJ,PETSC_OWN_POINTER, &(mattmp[num_levels-1-l]));CHKERRQ(ierr);
1768a2c336bSFande Kong     /* We want to own the data, and HYPRE can not touch this matrix any more */
1778a2c336bSFande Kong     A_array[l] = NULL;
1788a2c336bSFande Kong   }
1798a2c336bSFande Kong   *nlevels = num_levels;
1808a2c336bSFande Kong   *operators = mattmp;
1818a2c336bSFande Kong   PetscFunctionReturn(0);
1828a2c336bSFande Kong }
1838a2c336bSFande Kong 
184fd2dd295SFande Kong /*
1858a2c336bSFande Kong   Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix
1868a2c336bSFande Kong   is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine.
1878a2c336bSFande Kong   It is used in PCHMG. Other users should avoid using this function.
188fd2dd295SFande Kong */
189fd2dd295SFande Kong static PetscErrorCode PCGetInterpolations_BoomerAMG(PC pc,PetscInt *nlevels,Mat *interpolations[])
1908a2c336bSFande Kong {
1918a2c336bSFande Kong   PC_HYPRE             *jac  = (PC_HYPRE*)pc->data;
1928a2c336bSFande Kong   PetscBool            same = PETSC_FALSE;
1938a2c336bSFande Kong   PetscErrorCode       ierr;
1948a2c336bSFande Kong   PetscInt             num_levels,l;
1958a2c336bSFande Kong   Mat                  *mattmp;
1968a2c336bSFande Kong   hypre_ParCSRMatrix   **P_array;
1978a2c336bSFande Kong 
1988a2c336bSFande Kong   PetscFunctionBegin;
1998a2c336bSFande Kong   ierr = PetscStrcmp(jac->hypre_type,"boomeramg",&same);CHKERRQ(ierr);
2009ace16cdSJacob Faibussowitsch   PetscAssertFalse(!same,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_NOTSAMETYPE,"Hypre type is not BoomerAMG ");
2018a2c336bSFande Kong   num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData*) (jac->hsolver));
2028a2c336bSFande Kong   ierr = PetscMalloc1(num_levels,&mattmp);CHKERRQ(ierr);
2038a2c336bSFande Kong   P_array  = hypre_ParAMGDataPArray((hypre_ParAMGData*) (jac->hsolver));
2048a2c336bSFande Kong   for (l=1; l<num_levels; l++) {
2058a2c336bSFande Kong     ierr = MatCreateFromParCSR(P_array[num_levels-1-l],MATAIJ,PETSC_OWN_POINTER, &(mattmp[l-1]));CHKERRQ(ierr);
2068a2c336bSFande Kong     /* We want to own the data, and HYPRE can not touch this matrix any more */
2078a2c336bSFande Kong     P_array[num_levels-1-l] = NULL;
2088a2c336bSFande Kong   }
2098a2c336bSFande Kong   *nlevels = num_levels;
2108a2c336bSFande Kong   *interpolations = mattmp;
2118a2c336bSFande Kong   PetscFunctionReturn(0);
2128a2c336bSFande Kong }
2138a2c336bSFande Kong 
214ce6a8a0dSJed Brown /* Resets (frees) Hypre's representation of the near null space */
215ce6a8a0dSJed Brown static PetscErrorCode PCHYPREResetNearNullSpace_Private(PC pc)
216ce6a8a0dSJed Brown {
217ce6a8a0dSJed Brown   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
218ce6a8a0dSJed Brown   PetscInt       i;
2199d678128SJed Brown   PetscErrorCode ierr;
220ce6a8a0dSJed Brown 
2219d678128SJed Brown   PetscFunctionBegin;
222ce6a8a0dSJed Brown   for (i=0; i<jac->n_hmnull; i++) {
2236ea7df73SStefano Zampini     ierr = VecHYPRE_IJVectorDestroy(&jac->hmnull[i]);CHKERRQ(ierr);
224ce6a8a0dSJed Brown   }
225ce6a8a0dSJed Brown   ierr = PetscFree(jac->hmnull);CHKERRQ(ierr);
226ce6a8a0dSJed Brown   ierr = PetscFree(jac->phmnull);CHKERRQ(ierr);
227ce6a8a0dSJed Brown   ierr = VecDestroy(&jac->hmnull_constant);CHKERRQ(ierr);
2289d678128SJed Brown   jac->n_hmnull = 0;
229ce6a8a0dSJed Brown   PetscFunctionReturn(0);
230ce6a8a0dSJed Brown }
231ce6a8a0dSJed Brown 
23216d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
23316d9e3a6SLisandro Dalcin {
23416d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
23549a781f5SStefano Zampini   Mat_HYPRE          *hjac;
23616d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
23716d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
23849a781f5SStefano Zampini   PetscBool          ishypre;
23949a781f5SStefano Zampini   PetscErrorCode     ierr;
24016d9e3a6SLisandro Dalcin 
24116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
24216d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
24302a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
24416d9e3a6SLisandro Dalcin   }
2455f5c5b43SBarry Smith 
24649a781f5SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRE,&ishypre);CHKERRQ(ierr);
24749a781f5SStefano Zampini   if (!ishypre) {
2486bf688a0SCe Qin     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
2496bf688a0SCe Qin     ierr = MatConvert(pc->pmat,MATHYPRE,MAT_INITIAL_MATRIX,&jac->hpmat);CHKERRQ(ierr);
250589dcaf0SStefano Zampini     ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)jac->hpmat);CHKERRQ(ierr);
25149a781f5SStefano Zampini   } else {
25249a781f5SStefano Zampini     ierr = PetscObjectReference((PetscObject)pc->pmat);CHKERRQ(ierr);
25349a781f5SStefano Zampini     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
25449a781f5SStefano Zampini     jac->hpmat = pc->pmat;
25516d9e3a6SLisandro Dalcin   }
2566ea7df73SStefano Zampini   /* allow debug */
2576ea7df73SStefano Zampini   ierr = MatViewFromOptions(jac->hpmat,NULL,"-pc_hypre_mat_view");CHKERRQ(ierr);
25849a781f5SStefano Zampini   hjac = (Mat_HYPRE*)(jac->hpmat->data);
2595f5c5b43SBarry Smith 
26016d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
26116d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
2625272c319SBarry Smith     MatNullSpace mnull;
2635272c319SBarry Smith     PetscBool    has_const;
26449a781f5SStefano Zampini     PetscInt     bs,nvec,i;
2655272c319SBarry Smith     const Vec    *vecs;
2665272c319SBarry Smith 
26716d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
268*a74df02fSJacob Faibussowitsch     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,jac->hsolver,bs);
2695272c319SBarry Smith     ierr = MatGetNearNullSpace(pc->mat, &mnull);CHKERRQ(ierr);
2705272c319SBarry Smith     if (mnull) {
271ce6a8a0dSJed Brown       ierr = PCHYPREResetNearNullSpace_Private(pc);CHKERRQ(ierr);
2725272c319SBarry Smith       ierr = MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs);CHKERRQ(ierr);
2735272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull);CHKERRQ(ierr);
2745272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->phmnull);CHKERRQ(ierr);
2755272c319SBarry Smith       for (i=0; i<nvec; i++) {
2766ea7df73SStefano Zampini         ierr = VecHYPRE_IJVectorCreate(vecs[i]->map,&jac->hmnull[i]);CHKERRQ(ierr);
2776ea7df73SStefano Zampini         ierr = VecHYPRE_IJVectorCopy(vecs[i],jac->hmnull[i]);CHKERRQ(ierr);
278*a74df02fSJacob Faibussowitsch         PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->hmnull[i]->ij,(void**)&jac->phmnull[i]);
2795272c319SBarry Smith       }
2805272c319SBarry Smith       if (has_const) {
2815272c319SBarry Smith         ierr = MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL);CHKERRQ(ierr);
282589dcaf0SStefano Zampini         ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)jac->hmnull_constant);CHKERRQ(ierr);
2835272c319SBarry Smith         ierr = VecSet(jac->hmnull_constant,1);CHKERRQ(ierr);
2841e1ea65dSPierre Jolivet         ierr = VecNormalize(jac->hmnull_constant,NULL);CHKERRQ(ierr);
2856ea7df73SStefano Zampini         ierr = VecHYPRE_IJVectorCreate(jac->hmnull_constant->map,&jac->hmnull[nvec]);CHKERRQ(ierr);
2866ea7df73SStefano Zampini         ierr = VecHYPRE_IJVectorCopy(jac->hmnull_constant,jac->hmnull[nvec]);CHKERRQ(ierr);
287*a74df02fSJacob Faibussowitsch         PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->hmnull[nvec]->ij,(void**)&jac->phmnull[nvec]);
2885272c319SBarry Smith         nvec++;
2895272c319SBarry Smith       }
290*a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVectors,jac->hsolver,nvec,jac->phmnull);
2915272c319SBarry Smith       jac->n_hmnull = nvec;
2925272c319SBarry Smith     }
2934cb006feSStefano Zampini   }
294863406b8SStefano Zampini 
2954cb006feSStefano Zampini   /* special case for AMS */
2964cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
2975ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2985ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
2996bf688a0SCe Qin     if (!jac->coords[0] && !jac->constants[0] && !(jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
3006bf688a0SCe 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");
3016bf688a0SCe Qin     }
3025ac14e1cSStefano Zampini     if (jac->dim) {
303*a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_AMSSetDimension,jac->hsolver,jac->dim);
3045ac14e1cSStefano Zampini     }
3055ac14e1cSStefano Zampini     if (jac->constants[0]) {
3065ac14e1cSStefano Zampini       HYPRE_ParVector ozz,zoz,zzo = NULL;
307*a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->constants[0]->ij,(void**)(&ozz));
308*a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->constants[1]->ij,(void**)(&zoz));
3095ac14e1cSStefano Zampini       if (jac->constants[2]) {
310*a74df02fSJacob Faibussowitsch         PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->constants[2]->ij,(void**)(&zzo));
3115ac14e1cSStefano Zampini       }
312*a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,jac->hsolver,ozz,zoz,zzo);
3135ac14e1cSStefano Zampini     }
3145ac14e1cSStefano Zampini     if (jac->coords[0]) {
3155ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
3165ac14e1cSStefano Zampini       coords[0] = NULL;
3175ac14e1cSStefano Zampini       coords[1] = NULL;
3185ac14e1cSStefano Zampini       coords[2] = NULL;
319*a74df02fSJacob Faibussowitsch       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->coords[0]->ij,(void**)(&coords[0]));
320*a74df02fSJacob Faibussowitsch       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->coords[1]->ij,(void**)(&coords[1]));
321*a74df02fSJacob Faibussowitsch       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->coords[2]->ij,(void**)(&coords[2]));
322*a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,jac->hsolver,coords[0],coords[1],coords[2]);
3235ac14e1cSStefano Zampini     }
3249ace16cdSJacob Faibussowitsch     PetscAssertFalse(!jac->G,PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
3255ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
326*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr));
327*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,jac->hsolver,parcsr);
3285ac14e1cSStefano Zampini     if (jac->alpha_Poisson) {
3295ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->alpha_Poisson->data);
330*a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr));
331*a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,jac->hsolver,parcsr);
3325ac14e1cSStefano Zampini     }
3335ac14e1cSStefano Zampini     if (jac->ams_beta_is_zero) {
334*a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,jac->hsolver,NULL);
3355ac14e1cSStefano Zampini     } else if (jac->beta_Poisson) {
3365ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->beta_Poisson->data);
337*a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr));
338*a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,jac->hsolver,parcsr);
3395ac14e1cSStefano Zampini     }
3406bf688a0SCe Qin     if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) {
3416bf688a0SCe Qin       PetscInt           i;
3426bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
3436bf688a0SCe Qin       if (jac->ND_PiFull) {
3446bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
345*a74df02fSJacob Faibussowitsch         PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&nd_parcsrfull));
3466bf688a0SCe Qin       } else {
3476bf688a0SCe Qin         nd_parcsrfull = NULL;
3486bf688a0SCe Qin       }
3496bf688a0SCe Qin       for (i=0;i<3;++i) {
3506bf688a0SCe Qin         if (jac->ND_Pi[i]) {
3516bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
352*a74df02fSJacob Faibussowitsch           PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&nd_parcsr[i]));
3536bf688a0SCe Qin         } else {
3546bf688a0SCe Qin           nd_parcsr[i] = NULL;
3556bf688a0SCe Qin         }
3566bf688a0SCe Qin       }
357*a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_AMSSetInterpolations,jac->hsolver,nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]);
3586bf688a0SCe Qin     }
3594cb006feSStefano Zampini   }
360863406b8SStefano Zampini   /* special case for ADS */
361863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
3625ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
3635ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
3646bf688a0SCe 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])))) {
3656bf688a0SCe Qin       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations");
3666bf688a0SCe Qin     }
3679ace16cdSJacob Faibussowitsch     else PetscAssertFalse(!jac->coords[1] || !jac->coords[2],PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner has been designed for three dimensional problems! For two dimensional problems, use HYPRE AMS instead");
3689ace16cdSJacob Faibussowitsch     PetscAssertFalse(!jac->G,PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
3699ace16cdSJacob Faibussowitsch     PetscAssertFalse(!jac->C,PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient");
3705ac14e1cSStefano Zampini     if (jac->coords[0]) {
3715ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
3725ac14e1cSStefano Zampini       coords[0] = NULL;
3735ac14e1cSStefano Zampini       coords[1] = NULL;
3745ac14e1cSStefano Zampini       coords[2] = NULL;
375*a74df02fSJacob Faibussowitsch       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->coords[0]->ij,(void**)(&coords[0]));
376*a74df02fSJacob Faibussowitsch       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->coords[1]->ij,(void**)(&coords[1]));
377*a74df02fSJacob Faibussowitsch       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->coords[2]->ij,(void**)(&coords[2]));
378*a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_ADSSetCoordinateVectors,jac->hsolver,coords[0],coords[1],coords[2]);
3795ac14e1cSStefano Zampini     }
3805ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
381*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr));
382*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetDiscreteGradient,jac->hsolver,parcsr);
3835ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->C->data);
384*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr));
385*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetDiscreteCurl,jac->hsolver,parcsr);
3866bf688a0SCe Qin     if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
3876bf688a0SCe Qin       PetscInt           i;
3886bf688a0SCe Qin       HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3];
3896bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
3906bf688a0SCe Qin       if (jac->RT_PiFull) {
3916bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->RT_PiFull->data);
392*a74df02fSJacob Faibussowitsch         PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&rt_parcsrfull));
3936bf688a0SCe Qin       } else {
3946bf688a0SCe Qin         rt_parcsrfull = NULL;
3956bf688a0SCe Qin       }
3966bf688a0SCe Qin       for (i=0;i<3;++i) {
3976bf688a0SCe Qin         if (jac->RT_Pi[i]) {
3986bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->RT_Pi[i]->data);
399*a74df02fSJacob Faibussowitsch           PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&rt_parcsr[i]));
4006bf688a0SCe Qin         } else {
4016bf688a0SCe Qin           rt_parcsr[i] = NULL;
4026bf688a0SCe Qin         }
4036bf688a0SCe Qin       }
4046bf688a0SCe Qin       if (jac->ND_PiFull) {
4056bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
406*a74df02fSJacob Faibussowitsch         PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&nd_parcsrfull));
4076bf688a0SCe Qin       } else {
4086bf688a0SCe Qin         nd_parcsrfull = NULL;
4096bf688a0SCe Qin       }
4106bf688a0SCe Qin       for (i=0;i<3;++i) {
4116bf688a0SCe Qin         if (jac->ND_Pi[i]) {
4126bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
413*a74df02fSJacob Faibussowitsch           PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&nd_parcsr[i]));
4146bf688a0SCe Qin         } else {
4156bf688a0SCe Qin           nd_parcsr[i] = NULL;
4166bf688a0SCe Qin         }
4176bf688a0SCe Qin       }
418*a74df02fSJacob Faibussowitsch       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]);
4196bf688a0SCe Qin     }
420863406b8SStefano Zampini   }
421*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_IJMatrixGetObject,hjac->ij,(void**)&hmat);
422*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_IJVectorGetObject,hjac->b->ij,(void**)&bv);
423*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_IJVectorGetObject,hjac->x->ij,(void**)&xv);
424*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(jac->setup,jac->hsolver,hmat,bv,xv);
42516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
42616d9e3a6SLisandro Dalcin }
42716d9e3a6SLisandro Dalcin 
42816d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
42916d9e3a6SLisandro Dalcin {
43016d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
43149a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
43216d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
43316d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
43416d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
4354ddd07fcSJed Brown   PetscInt           hierr;
43616d9e3a6SLisandro Dalcin 
43716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
438dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
43916d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
4406ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPushVecRead(hjac->b,b);CHKERRQ(ierr);
4416ea7df73SStefano Zampini   if (jac->applyrichardson) { ierr = VecHYPRE_IJVectorPushVec(hjac->x,x);CHKERRQ(ierr); }
4426ea7df73SStefano Zampini   else { ierr = VecHYPRE_IJVectorPushVecWrite(hjac->x,x);CHKERRQ(ierr); }
443*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_IJMatrixGetObject,hjac->ij,(void**)&hmat);
444*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_IJVectorGetObject,hjac->b->ij,(void**)&jbv);
445*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_IJVectorGetObject,hjac->x->ij,(void**)&jxv);
446fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
4479ace16cdSJacob Faibussowitsch   PetscAssertFalse(hierr && hierr != HYPRE_ERROR_CONV,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
448fd3f9acdSBarry Smith   if (hierr) hypre__global_error = 0;);
44916d9e3a6SLisandro Dalcin 
45023df4f25SStefano Zampini   if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) {
451*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSProjectOutGradients,jac->hsolver,jxv);
45221df291bSStefano Zampini   }
4536ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPopVec(hjac->x);CHKERRQ(ierr);
4546ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPopVec(hjac->b);CHKERRQ(ierr);
45516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
45616d9e3a6SLisandro Dalcin }
45716d9e3a6SLisandro Dalcin 
4588695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc)
4598695de01SBarry Smith {
4608695de01SBarry Smith   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
4618695de01SBarry Smith   PetscErrorCode ierr;
4628695de01SBarry Smith 
4638695de01SBarry Smith   PetscFunctionBegin;
46449a781f5SStefano Zampini   ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
4655ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
4665ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
4675ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
4685ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
4696bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
4706bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[0]);CHKERRQ(ierr);
4716bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[1]);CHKERRQ(ierr);
4726bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[2]);CHKERRQ(ierr);
4736bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
4746bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[0]);CHKERRQ(ierr);
4756bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[1]);CHKERRQ(ierr);
4766bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[2]);CHKERRQ(ierr);
4776ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->coords[0]);CHKERRQ(ierr);
4786ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->coords[1]);CHKERRQ(ierr);
4796ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->coords[2]);CHKERRQ(ierr);
4806ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->constants[0]);CHKERRQ(ierr);
4816ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->constants[1]);CHKERRQ(ierr);
4826ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->constants[2]);CHKERRQ(ierr);
483ce6a8a0dSJed Brown   ierr = PCHYPREResetNearNullSpace_Private(pc);CHKERRQ(ierr);
4845ac14e1cSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
4855ac14e1cSStefano Zampini   jac->dim = 0;
4868695de01SBarry Smith   PetscFunctionReturn(0);
4878695de01SBarry Smith }
4888695de01SBarry Smith 
48916d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
49016d9e3a6SLisandro Dalcin {
49116d9e3a6SLisandro Dalcin   PC_HYPRE                 *jac = (PC_HYPRE*)pc->data;
49216d9e3a6SLisandro Dalcin   PetscErrorCode           ierr;
49316d9e3a6SLisandro Dalcin 
49416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
4958695de01SBarry Smith   ierr = PCReset_HYPRE(pc);CHKERRQ(ierr);
496*a74df02fSJacob Faibussowitsch   if (jac->destroy) PetscStackCallStandard(jac->destroy,jac->hsolver);
497503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
498db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0)
499db6f9c32SMark Adams   ierr = PetscFree(jac->spgemm_type);CHKERRQ(ierr);
500db6f9c32SMark Adams #endif
50157f21012SBarry Smith   if (jac->comm_hypre != MPI_COMM_NULL) {ierr = PetscCommRestoreComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre);CHKERRQ(ierr);}
502c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
50316d9e3a6SLisandro Dalcin 
50416d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
505bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
506bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
5074cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
5084cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
509863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
5106bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",NULL);CHKERRQ(ierr);
5114cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
5125ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",NULL);CHKERRQ(ierr);
513fd2dd295SFande Kong   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",NULL);CHKERRQ(ierr);
514fd2dd295SFande Kong   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",NULL);CHKERRQ(ierr);
515db6f9c32SMark Adams   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinSetMatProductAlgorithm_C",NULL);CHKERRQ(ierr);
516db6f9c32SMark Adams   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinGetMatProductAlgorithm_C",NULL);CHKERRQ(ierr);
517db6f9c32SMark Adams 
51816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
51916d9e3a6SLisandro Dalcin }
52016d9e3a6SLisandro Dalcin 
52116d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
5224416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptionItems *PetscOptionsObject,PC pc)
52316d9e3a6SLisandro Dalcin {
52416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
52516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
526ace3abfcSBarry Smith   PetscBool      flag;
52716d9e3a6SLisandro Dalcin 
52816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
529e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
53016d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
531*a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,jac->hsolver,jac->maxiter);
53216d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
533*a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,jac->hsolver,jac->tol);
53416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
535*a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,jac->hsolver,jac->factorrowsize);
53616d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
53716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
53816d9e3a6SLisandro Dalcin }
53916d9e3a6SLisandro Dalcin 
54016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
54116d9e3a6SLisandro Dalcin {
54216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
54316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
544ace3abfcSBarry Smith   PetscBool      iascii;
54516d9e3a6SLisandro Dalcin 
54616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
547251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
54816d9e3a6SLisandro Dalcin   if (iascii) {
54916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
55016d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
551efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
55216d9e3a6SLisandro Dalcin     } else {
553efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default maximum number of iterations \n");CHKERRQ(ierr);
55416d9e3a6SLisandro Dalcin     }
55516d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
556efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
55716d9e3a6SLisandro Dalcin     } else {
558efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default drop tolerance \n");CHKERRQ(ierr);
55916d9e3a6SLisandro Dalcin     }
56016d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
561efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
56216d9e3a6SLisandro Dalcin     } else {
563efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default factor row size \n");CHKERRQ(ierr);
56416d9e3a6SLisandro Dalcin     }
56516d9e3a6SLisandro Dalcin   }
56616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
56716d9e3a6SLisandro Dalcin }
56816d9e3a6SLisandro Dalcin 
56916d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
570db966c6cSHong Zhang static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PetscOptionItems *PetscOptionsObject,PC pc)
571db966c6cSHong Zhang {
572db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
573db966c6cSHong Zhang   PetscErrorCode ierr;
5748bf83915SBarry Smith   PetscBool      flag,eu_bj = jac->eu_bj ? PETSC_TRUE : PETSC_FALSE;
575db966c6cSHong Zhang 
576db966c6cSHong Zhang   PetscFunctionBegin;
577db966c6cSHong Zhang   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Euclid Options");CHKERRQ(ierr);
578db966c6cSHong Zhang   ierr = PetscOptionsInt("-pc_hypre_euclid_level","Factorization levels","None",jac->eu_level,&jac->eu_level,&flag);CHKERRQ(ierr);
579*a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_EuclidSetLevel,jac->hsolver,jac->eu_level);
5808bf83915SBarry Smith 
5818bf83915SBarry Smith   ierr = PetscOptionsReal("-pc_hypre_euclid_droptolerance","Drop tolerance for ILU(k) in Euclid","None",jac->eu_droptolerance,&jac->eu_droptolerance,&flag);CHKERRQ(ierr);
5828bf83915SBarry Smith   if (flag) {
5838bf83915SBarry Smith     PetscMPIInt size;
5848bf83915SBarry Smith 
58555b25c41SPierre Jolivet     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRMPI(ierr);
5869ace16cdSJacob Faibussowitsch     PetscAssertFalse(size > 1,PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"hypre's Euclid does not support a parallel drop tolerance");
587*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_EuclidSetILUT,jac->hsolver,jac->eu_droptolerance);
5888bf83915SBarry Smith   }
5898bf83915SBarry Smith 
5908bf83915SBarry Smith   ierr = PetscOptionsBool("-pc_hypre_euclid_bj", "Use Block Jacobi for ILU in Euclid", "None", eu_bj,&eu_bj,&flag);CHKERRQ(ierr);
5918bf83915SBarry Smith   if (flag) {
5928bf83915SBarry Smith     jac->eu_bj = eu_bj ? 1 : 0;
593*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_EuclidSetBJ,jac->hsolver,jac->eu_bj);
5948bf83915SBarry Smith   }
595db966c6cSHong Zhang   ierr = PetscOptionsTail();CHKERRQ(ierr);
596db966c6cSHong Zhang   PetscFunctionReturn(0);
597db966c6cSHong Zhang }
598db966c6cSHong Zhang 
599db966c6cSHong Zhang static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer)
600db966c6cSHong Zhang {
601db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
602db966c6cSHong Zhang   PetscErrorCode ierr;
603db966c6cSHong Zhang   PetscBool      iascii;
604db966c6cSHong Zhang 
605db966c6cSHong Zhang   PetscFunctionBegin;
606db966c6cSHong Zhang   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
607db966c6cSHong Zhang   if (iascii) {
608db966c6cSHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid preconditioning\n");CHKERRQ(ierr);
609db966c6cSHong Zhang     if (jac->eu_level != PETSC_DEFAULT) {
610db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    factorization levels %d\n",jac->eu_level);CHKERRQ(ierr);
611db966c6cSHong Zhang     } else {
612db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    default factorization levels \n");CHKERRQ(ierr);
613db966c6cSHong Zhang     }
6148bf83915SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->eu_droptolerance);CHKERRQ(ierr);
6158bf83915SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    use Block-Jacobi? %D\n",jac->eu_bj);CHKERRQ(ierr);
616db966c6cSHong Zhang   }
617db966c6cSHong Zhang   PetscFunctionReturn(0);
618db966c6cSHong Zhang }
619db966c6cSHong Zhang 
620db966c6cSHong Zhang /* --------------------------------------------------------------------------------------------*/
62116d9e3a6SLisandro Dalcin 
62216d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
62316d9e3a6SLisandro Dalcin {
62416d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
62549a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
62616d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
62716d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
62816d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
6294ddd07fcSJed Brown   PetscInt           hierr;
63016d9e3a6SLisandro Dalcin 
63116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
632dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
63316d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
6346ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPushVecRead(hjac->x,b);CHKERRQ(ierr);
6356ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPushVecWrite(hjac->b,x);CHKERRQ(ierr);
63616d9e3a6SLisandro Dalcin 
637*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_IJMatrixGetObject,hjac->ij,(void**)&hmat);
638*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_IJVectorGetObject,hjac->b->ij,(void**)&jbv);
639*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_IJVectorGetObject,hjac->x->ij,(void**)&jxv);
64016d9e3a6SLisandro Dalcin 
6416ea7df73SStefano Zampini   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jxv,jbv);
64216d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
6439ace16cdSJacob Faibussowitsch   PetscAssertFalse(hierr && (hierr != 1),PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
64416d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
64516d9e3a6SLisandro Dalcin 
6466ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPopVec(hjac->x);CHKERRQ(ierr);
6476ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPopVec(hjac->b);CHKERRQ(ierr);
64816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
64916d9e3a6SLisandro Dalcin }
65016d9e3a6SLisandro Dalcin 
651a669f990SJed Brown /* static array length */
652a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
653a669f990SJed Brown 
654db6f9c32SMark Adams static PetscErrorCode PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc,const char name[])
655db6f9c32SMark Adams {
656db6f9c32SMark Adams   PC_HYPRE *jac  = (PC_HYPRE*)pc->data;
657db6f9c32SMark Adams   PetscErrorCode ierr;
658db6f9c32SMark Adams   PetscBool      flag;
659db6f9c32SMark Adams 
660db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0)
661db6f9c32SMark Adams   PetscFunctionBegin;
662db6f9c32SMark Adams   if (jac->spgemm_type) {
663db6f9c32SMark Adams     ierr = PetscStrcmp(jac->spgemm_type,name,&flag);CHKERRQ(ierr);
6649ace16cdSJacob Faibussowitsch     PetscAssertFalse(!flag,PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE SpGEMM (really we can)");
665db6f9c32SMark Adams     PetscFunctionReturn(0);
666db6f9c32SMark Adams   } else {
667db6f9c32SMark Adams     ierr = PetscStrallocpy(name, &jac->spgemm_type);CHKERRQ(ierr);
668db6f9c32SMark Adams   }
669db6f9c32SMark Adams   ierr = PetscStrcmp("cusparse",jac->spgemm_type,&flag);CHKERRQ(ierr);
670db6f9c32SMark Adams   if (flag) {
671*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SetSpGemmUseCusparse,1);
672db6f9c32SMark Adams     PetscFunctionReturn(0);
673db6f9c32SMark Adams   }
674db6f9c32SMark Adams   ierr = PetscStrcmp("hypre",jac->spgemm_type,&flag);CHKERRQ(ierr);
675db6f9c32SMark Adams   if (flag) {
676*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SetSpGemmUseCusparse,0);
677db6f9c32SMark Adams     PetscFunctionReturn(0);
678db6f9c32SMark Adams   }
679db6f9c32SMark Adams   jac->spgemm_type = NULL;
68098921bdaSJacob Faibussowitsch   SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE SpGEM type %s; Choices are cusparse, hypre",name);
681db6f9c32SMark Adams #endif
682db6f9c32SMark Adams }
683db6f9c32SMark Adams 
684db6f9c32SMark Adams static PetscErrorCode PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc, const char *spgemm[])
685db6f9c32SMark Adams {
686db6f9c32SMark Adams   PC_HYPRE *jac  = (PC_HYPRE*)pc->data;
687db6f9c32SMark Adams 
688db6f9c32SMark Adams   PetscFunctionBegin;
689db6f9c32SMark Adams   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
690db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0)
691db6f9c32SMark Adams   *spgemm = jac->spgemm_type;
692db6f9c32SMark Adams #endif
693db6f9c32SMark Adams   PetscFunctionReturn(0);
694db6f9c32SMark Adams }
695db6f9c32SMark Adams 
69616d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
6970f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
69816d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
69965de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
7006a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]  = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
70165de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
70265de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
70365de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
7047b7fa87dSPierre Jolivet                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "l1-Gauss-Seidel" /* nonsymmetric */, "backward-l1-Gauss-Seidel" /* nonsymmetric */,
70565de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
7060f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
707589dcaf0SStefano Zampini                                                   "ext+i-cc", "standard", "standard-wts", "block", "block-wtd", "FF", "FF1",
708589dcaf0SStefano Zampini                                                   "ext", "ad-wts", "ext-mm", "ext+i-mm", "ext+e-mm"};
7094416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc)
71016d9e3a6SLisandro Dalcin {
71116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
71216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
71322e51d31SStefano Zampini   PetscInt       bs,n,indx,level;
714ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
71516d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
716589dcaf0SStefano Zampini   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
717db6f9c32SMark Adams   const char     *PCHYPRESpgemmTypes[] = {"cusparse","hypre"};
71816d9e3a6SLisandro Dalcin 
71916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
720e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
7214336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
72216d9e3a6SLisandro Dalcin   if (flg) {
7234336a9eeSBarry Smith     jac->cycletype = indx+1;
724*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,jac->hsolver,jac->cycletype);
72516d9e3a6SLisandro Dalcin   }
72616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
72716d9e3a6SLisandro Dalcin   if (flg) {
7289ace16cdSJacob Faibussowitsch     PetscAssertFalse(jac->maxlevels < 2,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
729*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,jac->hsolver,jac->maxlevels);
73016d9e3a6SLisandro Dalcin   }
73116d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
73216d9e3a6SLisandro Dalcin   if (flg) {
7339ace16cdSJacob Faibussowitsch     PetscAssertFalse(jac->maxiter < 1,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
734*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,jac->maxiter);
73516d9e3a6SLisandro Dalcin   }
73639accc25SStefano Zampini   ierr = PetscOptionsReal("-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);
73716d9e3a6SLisandro Dalcin   if (flg) {
7389ace16cdSJacob Faibussowitsch     PetscAssertFalse(jac->tol < 0.0,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Tolerance %g must be greater than or equal to zero",(double)jac->tol);
739*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,jac->hsolver,jac->tol);
74016d9e3a6SLisandro Dalcin   }
74122e51d31SStefano Zampini   bs = 1;
74222e51d31SStefano Zampini   if (pc->pmat) {
74322e51d31SStefano Zampini     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
74422e51d31SStefano Zampini   }
74522e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_numfunctions","Number of functions","HYPRE_BoomerAMGSetNumFunctions",bs,&bs,&flg);CHKERRQ(ierr);
74622e51d31SStefano Zampini   if (flg) {
747*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,jac->hsolver,bs);
74822e51d31SStefano Zampini   }
74916d9e3a6SLisandro Dalcin 
75039accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
75116d9e3a6SLisandro Dalcin   if (flg) {
7529ace16cdSJacob Faibussowitsch     PetscAssertFalse(jac->truncfactor < 0.0,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Truncation factor %g must be great than or equal zero",(double)jac->truncfactor);
753*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,jac->hsolver,jac->truncfactor);
75416d9e3a6SLisandro Dalcin   }
75516d9e3a6SLisandro Dalcin 
7560f1074feSSatish 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);
7570f1074feSSatish Balay   if (flg) {
7589ace16cdSJacob Faibussowitsch     PetscAssertFalse(jac->pmax < 0,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"P_max %D must be greater than or equal to zero",jac->pmax);
759*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,jac->hsolver,jac->pmax);
7600f1074feSSatish Balay   }
7610f1074feSSatish Balay 
762f8add624SPierre Jolivet   ierr = PetscOptionsRangeInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg,0,jac->maxlevels);CHKERRQ(ierr);
763*a74df02fSJacob Faibussowitsch   if (flg) PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,jac->hsolver,jac->agg_nl);
7640f1074feSSatish Balay 
7650f1074feSSatish 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);
7660f1074feSSatish Balay   if (flg) {
7679ace16cdSJacob Faibussowitsch     PetscAssertFalse(jac->agg_num_paths < 1,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of paths %D must be greater than or equal to 1",jac->agg_num_paths);
768*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,jac->hsolver,jac->agg_num_paths);
7690f1074feSSatish Balay   }
7700f1074feSSatish Balay 
77139accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
77216d9e3a6SLisandro Dalcin   if (flg) {
7739ace16cdSJacob Faibussowitsch     PetscAssertFalse(jac->strongthreshold < 0.0,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Strong threshold %g must be great than or equal zero",(double)jac->strongthreshold);
774*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,jac->hsolver,jac->strongthreshold);
77516d9e3a6SLisandro Dalcin   }
77639accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
77716d9e3a6SLisandro Dalcin   if (flg) {
7789ace16cdSJacob Faibussowitsch     PetscAssertFalse(jac->maxrowsum < 0.0,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Maximum row sum %g must be greater than zero",(double)jac->maxrowsum);
7799ace16cdSJacob Faibussowitsch     PetscAssertFalse(jac->maxrowsum > 1.0,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Maximum row sum %g must be less than or equal one",(double)jac->maxrowsum);
780*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,jac->hsolver,jac->maxrowsum);
78116d9e3a6SLisandro Dalcin   }
78216d9e3a6SLisandro Dalcin 
78316d9e3a6SLisandro Dalcin   /* Grid sweeps */
7840f1074feSSatish 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);
78516d9e3a6SLisandro Dalcin   if (flg) {
786*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,jac->hsolver,indx);
78716d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
78816d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
7890f1074feSSatish Balay     jac->gridsweeps[1] = indx;
7900f1074feSSatish Balay     /*defaults coarse to 1 */
7910f1074feSSatish Balay     jac->gridsweeps[2] = 1;
79216d9e3a6SLisandro Dalcin   }
7935272c319SBarry 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);
7945272c319SBarry Smith   if (flg) {
795*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,jac->hsolver,jac->nodal_coarsening);
7965272c319SBarry Smith   }
79722e51d31SStefano 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);
79822e51d31SStefano Zampini   if (flg) {
799*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetNodalDiag,jac->hsolver,jac->nodal_coarsening_diag);
80022e51d31SStefano Zampini   }
801cbc39033SBarry 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);
8025272c319SBarry Smith   if (flg) {
803*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,jac->hsolver,jac->vec_interp_variant);
8045272c319SBarry Smith   }
80522e51d31SStefano 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);
80622e51d31SStefano Zampini   if (flg) {
807*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecQMax,jac->hsolver,jac->vec_interp_qmax);
80822e51d31SStefano Zampini   }
80922e51d31SStefano 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);
81022e51d31SStefano Zampini   if (flg) {
811*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothInterpVectors,jac->hsolver,jac->vec_interp_smooth);
81222e51d31SStefano Zampini   }
81322e51d31SStefano 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);
81422e51d31SStefano Zampini   if (flg) {
815*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpRefine,jac->hsolver,jac->interp_refine);
81622e51d31SStefano Zampini   }
8170f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
81816d9e3a6SLisandro Dalcin   if (flg) {
819*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,jac->hsolver,indx, 1);
8200f1074feSSatish Balay     jac->gridsweeps[0] = indx;
82116d9e3a6SLisandro Dalcin   }
82216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
82316d9e3a6SLisandro Dalcin   if (flg) {
824*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,jac->hsolver,indx, 2);
8250f1074feSSatish Balay     jac->gridsweeps[1] = indx;
82616d9e3a6SLisandro Dalcin   }
8270f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
82816d9e3a6SLisandro Dalcin   if (flg) {
829*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,jac->hsolver,indx, 3);
8300f1074feSSatish Balay     jac->gridsweeps[2] = indx;
83116d9e3a6SLisandro Dalcin   }
83216d9e3a6SLisandro Dalcin 
8336a251517SEike Mueller   /* Smooth type */
8341e1ea65dSPierre Jolivet   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);CHKERRQ(ierr);
8356a251517SEike Mueller   if (flg) {
8366a251517SEike Mueller     jac->smoothtype = indx;
837*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,jac->hsolver,indx+6);
8388131ecf7SEike Mueller     jac->smoothnumlevels = 25;
839*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,jac->hsolver,25);
8408131ecf7SEike Mueller   }
8418131ecf7SEike Mueller 
8428131ecf7SEike Mueller   /* Number of smoothing levels */
8438131ecf7SEike 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);
8448131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
8458131ecf7SEike Mueller     jac->smoothnumlevels = indx;
846*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,jac->hsolver,indx);
8476a251517SEike Mueller   }
8486a251517SEike Mueller 
8491810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
8501810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
8511810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8521810e44eSEike Mueller     jac->eu_level = indx;
853*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,jac->hsolver,indx);
8541810e44eSEike Mueller   }
8551810e44eSEike Mueller 
8561810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
8571810e44eSEike Mueller   double droptolerance;
85839accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
8591810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8601810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
861*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,jac->hsolver,droptolerance);
8621810e44eSEike Mueller   }
8631810e44eSEike Mueller 
8641810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
8651810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
8661810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8671810e44eSEike Mueller     jac->eu_bj = tmp_truth;
868*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,jac->hsolver,jac->eu_bj);
8691810e44eSEike Mueller   }
8701810e44eSEike Mueller 
87116d9e3a6SLisandro Dalcin   /* Relax type */
872a669f990SJed 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);
87316d9e3a6SLisandro Dalcin   if (flg) {
8740f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
875*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,jac->hsolver, indx);
8760f1074feSSatish Balay     /* by default, coarse type set to 9 */
8770f1074feSSatish Balay     jac->relaxtype[2] = 9;
878*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, 9, 3);
87916d9e3a6SLisandro Dalcin   }
880a669f990SJed 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);
88116d9e3a6SLisandro Dalcin   if (flg) {
88216d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
883*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, indx, 1);
88416d9e3a6SLisandro Dalcin   }
885a669f990SJed 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);
88616d9e3a6SLisandro Dalcin   if (flg) {
8870f1074feSSatish Balay     jac->relaxtype[1] = indx;
888*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, indx, 2);
88916d9e3a6SLisandro Dalcin   }
890a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
89116d9e3a6SLisandro Dalcin   if (flg) {
8920f1074feSSatish Balay     jac->relaxtype[2] = indx;
893*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, indx, 3);
89416d9e3a6SLisandro Dalcin   }
89516d9e3a6SLisandro Dalcin 
89616d9e3a6SLisandro Dalcin   /* Relaxation Weight */
89716d9e3a6SLisandro 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);
89816d9e3a6SLisandro Dalcin   if (flg) {
899*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,jac->hsolver,tmpdbl);
90016d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
90116d9e3a6SLisandro Dalcin   }
90216d9e3a6SLisandro Dalcin 
90316d9e3a6SLisandro Dalcin   n         = 2;
90416d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
90516d9e3a6SLisandro 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);
90616d9e3a6SLisandro Dalcin   if (flg) {
90716d9e3a6SLisandro Dalcin     if (n == 2) {
90816d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
909*a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,jac->hsolver,twodbl[0],indx);
91098921bdaSJacob Faibussowitsch     } else SETERRQ(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);
91116d9e3a6SLisandro Dalcin   }
91216d9e3a6SLisandro Dalcin 
91316d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
91416d9e3a6SLisandro 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);
91516d9e3a6SLisandro Dalcin   if (flg) {
916*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,jac->hsolver, tmpdbl);
91716d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
91816d9e3a6SLisandro Dalcin   }
91916d9e3a6SLisandro Dalcin 
92016d9e3a6SLisandro Dalcin   n         = 2;
92116d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
92216d9e3a6SLisandro 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);
92316d9e3a6SLisandro Dalcin   if (flg) {
92416d9e3a6SLisandro Dalcin     if (n == 2) {
92516d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
926*a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,jac->hsolver, twodbl[0], indx);
92798921bdaSJacob Faibussowitsch     } else SETERRQ(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);
92816d9e3a6SLisandro Dalcin   }
92916d9e3a6SLisandro Dalcin 
93016d9e3a6SLisandro Dalcin   /* the Relax Order */
931acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
93216d9e3a6SLisandro Dalcin 
9338afaa268SBarry Smith   if (flg && tmp_truth) {
93416d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
935*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,jac->hsolver, jac->relaxorder);
93616d9e3a6SLisandro Dalcin   }
937a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
93816d9e3a6SLisandro Dalcin   if (flg) {
93916d9e3a6SLisandro Dalcin     jac->measuretype = indx;
940*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,jac->hsolver,jac->measuretype);
94116d9e3a6SLisandro Dalcin   }
9420f1074feSSatish Balay   /* update list length 3/07 */
943a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
94416d9e3a6SLisandro Dalcin   if (flg) {
94516d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
946*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,jac->hsolver,jac->coarsentype);
94716d9e3a6SLisandro Dalcin   }
9480f1074feSSatish Balay 
949589dcaf0SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_coarse_size", "Maximum size of coarsest grid", "None", jac->maxc, &jac->maxc, &flg);CHKERRQ(ierr);
950589dcaf0SStefano Zampini   if (flg) {
951*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxCoarseSize,jac->hsolver, jac->maxc);
952589dcaf0SStefano Zampini   }
953589dcaf0SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_min_coarse_size", "Minimum size of coarsest grid", "None", jac->minc, &jac->minc, &flg);CHKERRQ(ierr);
954589dcaf0SStefano Zampini   if (flg) {
955*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMinCoarseSize,jac->hsolver, jac->minc);
956589dcaf0SStefano Zampini   }
957db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0)
958db6f9c32SMark Adams   // global parameter but is closely associated with BoomerAMG
959db6f9c32SMark Adams   ierr = PetscOptionsEList("-pc_mg_galerkin_mat_product_algorithm","Type of SpGEMM to use in hypre (only for now)","PCMGGalerkinSetMatProductAlgorithm",PCHYPRESpgemmTypes,ALEN(PCHYPRESpgemmTypes),PCHYPRESpgemmTypes[0],&indx,&flg);CHKERRQ(ierr);
960db6f9c32SMark Adams   if (!flg) indx = 0;
961db6f9c32SMark Adams   ierr = PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(pc,PCHYPRESpgemmTypes[indx]);CHKERRQ(ierr);
962db6f9c32SMark Adams #endif
963589dcaf0SStefano Zampini   /* AIR */
964589dcaf0SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0)
965589dcaf0SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_restriction_type", "Type of AIR method (distance 1 or 2, 0 means no AIR)", "None", jac->Rtype, &jac->Rtype, NULL);CHKERRQ(ierr);
966*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_BoomerAMGSetRestriction,jac->hsolver,jac->Rtype);
967589dcaf0SStefano Zampini   if (jac->Rtype) {
968589dcaf0SStefano Zampini     jac->interptype = 100; /* no way we can pass this with strings... Set it as default as in MFEM, then users can still customize it back to a different one */
969589dcaf0SStefano Zampini 
970589dcaf0SStefano Zampini     ierr = PetscOptionsReal("-pc_hypre_boomeramg_strongthresholdR","Threshold for R","None",jac->Rstrongthreshold,&jac->Rstrongthreshold,NULL);CHKERRQ(ierr);
971*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThresholdR,jac->hsolver,jac->Rstrongthreshold);
972589dcaf0SStefano Zampini 
973589dcaf0SStefano Zampini     ierr = PetscOptionsReal("-pc_hypre_boomeramg_filterthresholdR","Filter threshold for R","None",jac->Rfilterthreshold,&jac->Rfilterthreshold,NULL);CHKERRQ(ierr);
974*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetFilterThresholdR,jac->hsolver,jac->Rfilterthreshold);
975589dcaf0SStefano Zampini 
976589dcaf0SStefano Zampini     ierr = PetscOptionsReal("-pc_hypre_boomeramg_Adroptol","Defines the drop tolerance for the A-matrices from the 2nd level of AMG","None",jac->Adroptol,&jac->Adroptol,NULL);CHKERRQ(ierr);
977*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetADropTol,jac->hsolver,jac->Adroptol);
978589dcaf0SStefano Zampini 
979589dcaf0SStefano Zampini     ierr = PetscOptionsInt("-pc_hypre_boomeramg_Adroptype","Drops the entries that are not on the diagonal and smaller than its row norm: type 1: 1-norm, 2: 2-norm, -1: infinity norm","None",jac->Adroptype,&jac->Adroptype,NULL);CHKERRQ(ierr);
980*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetADropType,jac->hsolver,jac->Adroptype);
981589dcaf0SStefano Zampini   }
982589dcaf0SStefano Zampini #endif
983589dcaf0SStefano Zampini 
984ecae95adSPierre Jolivet #if PETSC_PKG_HYPRE_VERSION_LE(9,9,9)
9859ace16cdSJacob Faibussowitsch   PetscAssertFalse(jac->Rtype && jac->agg_nl,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"-pc_hypre_boomeramg_restriction_type (%D) and -pc_hypre_boomeramg_agg_nl (%D)",jac->Rtype,jac->agg_nl);
986ecae95adSPierre Jolivet #endif
987ecae95adSPierre Jolivet 
9880f1074feSSatish Balay   /* new 3/07 */
989a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
990589dcaf0SStefano Zampini   if (flg || jac->Rtype) {
991589dcaf0SStefano Zampini     if (flg) jac->interptype = indx;
992*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,jac->hsolver,jac->interptype);
9930f1074feSSatish Balay   }
9940f1074feSSatish Balay 
995b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
99616d9e3a6SLisandro Dalcin   if (flg) {
997b96a4a96SBarry Smith     level = 3;
9980298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
9992fa5cd67SKarl Rupp 
1000b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
1001*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,jac->hsolver,level);
10022ae77aedSBarry Smith   }
10032ae77aedSBarry Smith 
1004b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
10052ae77aedSBarry Smith   if (flg) {
1006b96a4a96SBarry Smith     level = 3;
10070298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
10082fa5cd67SKarl Rupp 
1009b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
1010*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,jac->hsolver,level);
101116d9e3a6SLisandro Dalcin   }
10128f87f92bSBarry Smith 
1013acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
10148f87f92bSBarry Smith   if (flg && tmp_truth) {
10158f87f92bSBarry Smith     PetscInt tmp_int;
10168f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
10178f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
1018*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,jac->hsolver,6);
1019*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,jac->hsolver,1);
1020*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,jac->hsolver,0);
1021*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,jac->hsolver,jac->nodal_relax_levels);
10228f87f92bSBarry Smith   }
10238f87f92bSBarry Smith 
1024589dcaf0SStefano Zampini   ierr = PetscOptionsBool("-pc_hypre_boomeramg_keeptranspose", "Avoid transpose matvecs in preconditioner application", "None", jac->keeptranspose, &jac->keeptranspose, NULL);CHKERRQ(ierr);
1025*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_BoomerAMGSetKeepTranspose,jac->hsolver,jac->keeptranspose ? 1 : 0);
1026589dcaf0SStefano Zampini 
1027589dcaf0SStefano Zampini   /* options for ParaSails solvers */
1028589dcaf0SStefano Zampini   ierr = PetscOptionsEList("-pc_hypre_boomeramg_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flg);CHKERRQ(ierr);
1029589dcaf0SStefano Zampini   if (flg) {
1030589dcaf0SStefano Zampini     jac->symt = indx;
1031*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetSym,jac->hsolver,jac->symt);
1032589dcaf0SStefano Zampini   }
1033589dcaf0SStefano Zampini 
103416d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
103516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
103616d9e3a6SLisandro Dalcin }
103716d9e3a6SLisandro Dalcin 
1038ace3abfcSBarry 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)
103916d9e3a6SLisandro Dalcin {
104016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
104116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
10422cf14000SStefano Zampini   HYPRE_Int      oits;
104316d9e3a6SLisandro Dalcin 
104416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1045dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1046*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,its*jac->maxiter);
1047*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,jac->hsolver,rtol);
104816d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
104916d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
105016d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
1051*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,jac->hsolver,&oits);
10524d0a8057SBarry Smith   *outits = oits;
10534d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
10544d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1055*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,jac->hsolver,jac->tol);
1056*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,jac->maxiter);
105716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
105816d9e3a6SLisandro Dalcin }
105916d9e3a6SLisandro Dalcin 
106016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
106116d9e3a6SLisandro Dalcin {
106216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
106316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1064ace3abfcSBarry Smith   PetscBool      iascii;
106516d9e3a6SLisandro Dalcin 
106616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1067251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
106816d9e3a6SLisandro Dalcin   if (iascii) {
106916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
1070efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
107122e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of levels %D\n",jac->maxlevels);CHKERRQ(ierr);
107222e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of iterations PER hypre call %D\n",jac->maxiter);CHKERRQ(ierr);
1073efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
1074efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
1075efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
107622e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: max elements per row %D\n",jac->pmax);CHKERRQ(ierr);
107722e51d31SStefano Zampini     if (jac->interp_refine) {
107822e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: number of steps of weighted refinement %D\n",jac->interp_refine);CHKERRQ(ierr);
107922e51d31SStefano Zampini     }
108022e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of levels of aggressive coarsening %D\n",jac->agg_nl);CHKERRQ(ierr);
108122e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of paths for aggressive coarsening %D\n",jac->agg_num_paths);CHKERRQ(ierr);
10820f1074feSSatish Balay 
1083efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
108416d9e3a6SLisandro Dalcin 
108522e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps down         %D\n",jac->gridsweeps[0]);CHKERRQ(ierr);
108622e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps up           %D\n",jac->gridsweeps[1]);CHKERRQ(ierr);
108722e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps on coarse    %D\n",jac->gridsweeps[2]);CHKERRQ(ierr);
108816d9e3a6SLisandro Dalcin 
1089efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
1090efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
1091efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
109216d9e3a6SLisandro Dalcin 
1093efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
1094efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
109516d9e3a6SLisandro Dalcin 
109616d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
1097efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using CF-relaxation\n");CHKERRQ(ierr);
109816d9e3a6SLisandro Dalcin     } else {
1099efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using CF-relaxation\n");CHKERRQ(ierr);
110016d9e3a6SLisandro Dalcin     }
11016a251517SEike Mueller     if (jac->smoothtype!=-1) {
1102efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
110322e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth num levels    %D\n",jac->smoothnumlevels);CHKERRQ(ierr);
11047e352d70SEike Mueller     } else {
1105efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using more complex smoothers.\n");CHKERRQ(ierr);
11061810e44eSEike Mueller     }
11071810e44eSEike Mueller     if (jac->smoothtype==3) {
110822e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) levels %D\n",jac->eu_level);CHKERRQ(ierr);
110922e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) drop tolerance %g\n",(double)jac->eu_droptolerance);CHKERRQ(ierr);
111022e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU use Block-Jacobi? %D\n",jac->eu_bj);CHKERRQ(ierr);
11116a251517SEike Mueller     }
1112efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
1113efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
1114589dcaf0SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation type  %s\n",jac->interptype != 100 ? HYPREBoomerAMGInterpType[jac->interptype] : "1pt");CHKERRQ(ierr);
11155272c319SBarry Smith     if (jac->nodal_coarsening) {
111684c7a2fdSPierre Jolivet       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal coarsening with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
11175272c319SBarry Smith     }
11185272c319SBarry Smith     if (jac->vec_interp_variant) {
1119efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
112022e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecQMax() %D\n",jac->vec_interp_qmax);CHKERRQ(ierr);
112122e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n",jac->vec_interp_smooth);CHKERRQ(ierr);
11228f87f92bSBarry Smith     }
11238f87f92bSBarry Smith     if (jac->nodal_relax) {
112422e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal relaxation via Schwarz smoothing on levels %D\n",jac->nodal_relax_levels);CHKERRQ(ierr);
11258f87f92bSBarry Smith     }
1126db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0)
1127db6f9c32SMark Adams     ierr = PetscViewerASCIIPrintf(viewer,"    SpGEMM type         %s\n",jac->spgemm_type);CHKERRQ(ierr);
1128db6f9c32SMark Adams #endif
1129589dcaf0SStefano Zampini     /* AIR */
1130589dcaf0SStefano Zampini     if (jac->Rtype) {
1131589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Using approximate ideal restriction type %D\n",jac->Rtype);CHKERRQ(ierr);
1132589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"      Threshold for R %g\n",(double)jac->Rstrongthreshold);CHKERRQ(ierr);
1133589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"      Filter for R %g\n",(double)jac->Rfilterthreshold);CHKERRQ(ierr);
1134589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"      A drop tolerance %g\n",(double)jac->Adroptol);CHKERRQ(ierr);
1135589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"      A drop type %D\n",jac->Adroptype);CHKERRQ(ierr);
1136589dcaf0SStefano Zampini     }
113716d9e3a6SLisandro Dalcin   }
113816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
113916d9e3a6SLisandro Dalcin }
114016d9e3a6SLisandro Dalcin 
114116d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
11424416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc)
114316d9e3a6SLisandro Dalcin {
114416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
114516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
11464ddd07fcSJed Brown   PetscInt       indx;
1147ace3abfcSBarry Smith   PetscBool      flag;
114816d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
114916d9e3a6SLisandro Dalcin 
115016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1151e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
115216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
11538966356dSPierre Jolivet   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshold,&jac->threshold,&flag);CHKERRQ(ierr);
1154*a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,jac->hsolver,jac->threshold,jac->nlevels);
115516d9e3a6SLisandro Dalcin 
115616d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
1157*a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,jac->hsolver,jac->filter);
115816d9e3a6SLisandro Dalcin 
115916d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
1160*a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,jac->hsolver,jac->loadbal);
116116d9e3a6SLisandro Dalcin 
1162acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
1163*a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,jac->hsolver,jac->logging);
116416d9e3a6SLisandro Dalcin 
1165acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
1166*a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,jac->hsolver,jac->ruse);
116716d9e3a6SLisandro Dalcin 
1168a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
116916d9e3a6SLisandro Dalcin   if (flag) {
117016d9e3a6SLisandro Dalcin     jac->symt = indx;
1171*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ParaSailsSetSym,jac->hsolver,jac->symt);
117216d9e3a6SLisandro Dalcin   }
117316d9e3a6SLisandro Dalcin 
117416d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
117516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
117616d9e3a6SLisandro Dalcin }
117716d9e3a6SLisandro Dalcin 
117816d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
117916d9e3a6SLisandro Dalcin {
118016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
118116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1182ace3abfcSBarry Smith   PetscBool      iascii;
1183feb237baSPierre Jolivet   const char     *symt = 0;
118416d9e3a6SLisandro Dalcin 
118516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1186251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
118716d9e3a6SLisandro Dalcin   if (iascii) {
118816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
1189efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
11908966356dSPierre Jolivet     ierr = PetscViewerASCIIPrintf(viewer,"    threshold %g\n",(double)jac->threshold);CHKERRQ(ierr);
1191efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    filter %g\n",(double)jac->filter);CHKERRQ(ierr);
1192efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
1193efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
1194efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
11952fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
11962fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
11972fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
119898921bdaSJacob Faibussowitsch     else SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
1199efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    %s\n",symt);CHKERRQ(ierr);
120016d9e3a6SLisandro Dalcin   }
120116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
120216d9e3a6SLisandro Dalcin }
12034cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
12044416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc)
12054cb006feSStefano Zampini {
12064cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12074cb006feSStefano Zampini   PetscErrorCode ierr;
12084cb006feSStefano Zampini   PetscInt       n;
12094cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
12104cb006feSStefano Zampini 
12114cb006feSStefano Zampini   PetscFunctionBegin;
12129fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
1213863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1214*a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,jac->hsolver,jac->as_print);
1215863406b8SStefano 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);
1216*a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,jac->hsolver,jac->as_max_iter);
12174cb006feSStefano 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);
1218*a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,jac->hsolver,jac->ams_cycle_type);
1219863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1220*a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,jac->hsolver,jac->as_tol);
1221863406b8SStefano 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);
1222863406b8SStefano 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);
1223863406b8SStefano 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);
1224863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
12254cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1226*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,jac->hsolver,jac->as_relax_type,
1227863406b8SStefano Zampini                                                                       jac->as_relax_times,
1228863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1229*a74df02fSJacob Faibussowitsch                                                                       jac->as_omega);
12304cb006feSStefano Zampini   }
1231863406b8SStefano 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);
12324cb006feSStefano Zampini   n = 5;
1233863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
12344cb006feSStefano Zampini   if (flag || flag2) {
1235*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1236863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1237863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1238863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1239863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1240*a74df02fSJacob Faibussowitsch                                                                      jac->as_amg_alpha_opts[4]);     /* AMG Pmax */
12414cb006feSStefano Zampini   }
1242863406b8SStefano 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);
12434cb006feSStefano Zampini   n = 5;
1244863406b8SStefano 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);
12454cb006feSStefano Zampini   if (flag || flag2) {
1246*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1247863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1248863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1249863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1250863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1251*a74df02fSJacob Faibussowitsch                                                                     jac->as_amg_beta_opts[4]);     /* AMG Pmax */
12524cb006feSStefano Zampini   }
125323df4f25SStefano 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);
125423df4f25SStefano Zampini   if (flag) { /* override HYPRE's default only if the options is used */
1255*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetProjectionFrequency,jac->hsolver,jac->ams_proj_freq);
125623df4f25SStefano Zampini   }
12574cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
12584cb006feSStefano Zampini   PetscFunctionReturn(0);
12594cb006feSStefano Zampini }
12604cb006feSStefano Zampini 
12614cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
12624cb006feSStefano Zampini {
12634cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12644cb006feSStefano Zampini   PetscErrorCode ierr;
12654cb006feSStefano Zampini   PetscBool      iascii;
12664cb006feSStefano Zampini 
12674cb006feSStefano Zampini   PetscFunctionBegin;
12684cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
12694cb006feSStefano Zampini   if (iascii) {
12704cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
1271efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1272efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1273efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1274efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1275efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1276efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1277efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
12784cb006feSStefano Zampini     if (jac->alpha_Poisson) {
1279efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
12804cb006feSStefano Zampini     } else {
1281efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (computed) \n");CHKERRQ(ierr);
12824cb006feSStefano Zampini     }
1283efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1284efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1285efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1286efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1287efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1288efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
12894cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
12904cb006feSStefano Zampini       if (jac->beta_Poisson) {
1291efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
12924cb006feSStefano Zampini       } else {
1293efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (computed) \n");CHKERRQ(ierr);
12944cb006feSStefano Zampini       }
1295efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1296efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1297efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1298efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1299efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1300efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
130123df4f25SStefano Zampini       if (jac->ams_beta_is_zero_part) {
1302efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"        compatible subspace projection frequency %d (-1 HYPRE uses default)\n",jac->ams_proj_freq);CHKERRQ(ierr);
130323df4f25SStefano Zampini       }
130423df4f25SStefano Zampini     } else {
1305efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver not used (zero-conductivity everywhere) \n");CHKERRQ(ierr);
13064cb006feSStefano Zampini     }
13074cb006feSStefano Zampini   }
13084cb006feSStefano Zampini   PetscFunctionReturn(0);
13094cb006feSStefano Zampini }
13104cb006feSStefano Zampini 
13114416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc)
1312863406b8SStefano Zampini {
1313863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1314863406b8SStefano Zampini   PetscErrorCode ierr;
1315863406b8SStefano Zampini   PetscInt       n;
1316863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
1317863406b8SStefano Zampini 
1318863406b8SStefano Zampini   PetscFunctionBegin;
1319863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
1320863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1321*a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,jac->hsolver,jac->as_print);
1322863406b8SStefano 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);
1323*a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,jac->hsolver,jac->as_max_iter);
1324863406b8SStefano 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);
1325*a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,jac->hsolver,jac->ads_cycle_type);
1326863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1327*a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,jac->hsolver,jac->as_tol);
1328863406b8SStefano 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);
1329863406b8SStefano 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);
1330863406b8SStefano 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);
1331863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
1332863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1333*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,jac->hsolver,jac->as_relax_type,
1334863406b8SStefano Zampini                                                                       jac->as_relax_times,
1335863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1336*a74df02fSJacob Faibussowitsch                                                                       jac->as_omega);
1337863406b8SStefano Zampini   }
1338863406b8SStefano 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);
1339863406b8SStefano Zampini   n = 5;
1340863406b8SStefano 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);
1341863406b8SStefano 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);
1342863406b8SStefano Zampini   if (flag || flag2 || flag3) {
1343*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
1344863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1345863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1346863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1347863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1348863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1349*a74df02fSJacob Faibussowitsch                                                                 jac->as_amg_alpha_opts[4]);     /* AMG Pmax */
1350863406b8SStefano Zampini   }
1351863406b8SStefano 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);
1352863406b8SStefano Zampini   n = 5;
1353863406b8SStefano 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);
1354863406b8SStefano Zampini   if (flag || flag2) {
1355*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1356863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1357863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1358863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1359863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1360*a74df02fSJacob Faibussowitsch                                                                 jac->as_amg_beta_opts[4]);     /* AMG Pmax */
1361863406b8SStefano Zampini   }
1362863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
1363863406b8SStefano Zampini   PetscFunctionReturn(0);
1364863406b8SStefano Zampini }
1365863406b8SStefano Zampini 
1366863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1367863406b8SStefano Zampini {
1368863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1369863406b8SStefano Zampini   PetscErrorCode ierr;
1370863406b8SStefano Zampini   PetscBool      iascii;
1371863406b8SStefano Zampini 
1372863406b8SStefano Zampini   PetscFunctionBegin;
1373863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1374863406b8SStefano Zampini   if (iascii) {
1375863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
1376efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1377efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
1378efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1379efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1380efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1381efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1382efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
1383efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    AMS solver using boomerAMG\n");CHKERRQ(ierr);
1384efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1385efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1386efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1387efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1388efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1389efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1390efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
1391efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver using boomerAMG\n");CHKERRQ(ierr);
1392efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1393efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1394efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1395efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1396efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1397efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
1398863406b8SStefano Zampini   }
1399863406b8SStefano Zampini   PetscFunctionReturn(0);
1400863406b8SStefano Zampini }
1401863406b8SStefano Zampini 
1402863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
14034cb006feSStefano Zampini {
14044cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
14055ac14e1cSStefano Zampini   PetscBool      ishypre;
14064cb006feSStefano Zampini   PetscErrorCode ierr;
14074cb006feSStefano Zampini 
14084cb006feSStefano Zampini   PetscFunctionBegin;
14095ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)G,MATHYPRE,&ishypre);CHKERRQ(ierr);
14105ac14e1cSStefano Zampini   if (ishypre) {
14115ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr);
14125ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
14135ac14e1cSStefano Zampini     jac->G = G;
14145ac14e1cSStefano Zampini   } else {
14156bf688a0SCe Qin     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
14166bf688a0SCe Qin     ierr = MatConvert(G,MATHYPRE,MAT_INITIAL_MATRIX,&jac->G);CHKERRQ(ierr);
14175ac14e1cSStefano Zampini   }
14184cb006feSStefano Zampini   PetscFunctionReturn(0);
14194cb006feSStefano Zampini }
14204cb006feSStefano Zampini 
14214cb006feSStefano Zampini /*@
14224cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
14234cb006feSStefano Zampini 
14244cb006feSStefano Zampini    Collective on PC
14254cb006feSStefano Zampini 
14264cb006feSStefano Zampini    Input Parameters:
14274cb006feSStefano Zampini +  pc - the preconditioning context
14284cb006feSStefano Zampini -  G - the discrete gradient
14294cb006feSStefano Zampini 
14304cb006feSStefano Zampini    Level: intermediate
14314cb006feSStefano Zampini 
143295452b02SPatrick Sanan    Notes:
143395452b02SPatrick Sanan     G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh
1434863406b8SStefano 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
14354cb006feSStefano Zampini 
14364cb006feSStefano Zampini .seealso:
14374cb006feSStefano Zampini @*/
14384cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
14394cb006feSStefano Zampini {
14404cb006feSStefano Zampini   PetscErrorCode ierr;
14414cb006feSStefano Zampini 
14424cb006feSStefano Zampini   PetscFunctionBegin;
14434cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
14444cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
14454cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
14464cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
14474cb006feSStefano Zampini   PetscFunctionReturn(0);
14484cb006feSStefano Zampini }
14494cb006feSStefano Zampini 
1450863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1451863406b8SStefano Zampini {
1452863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
14535ac14e1cSStefano Zampini   PetscBool      ishypre;
1454863406b8SStefano Zampini   PetscErrorCode ierr;
1455863406b8SStefano Zampini 
1456863406b8SStefano Zampini   PetscFunctionBegin;
14575ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)C,MATHYPRE,&ishypre);CHKERRQ(ierr);
14585ac14e1cSStefano Zampini   if (ishypre) {
14595ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr);
14605ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
14615ac14e1cSStefano Zampini     jac->C = C;
14625ac14e1cSStefano Zampini   } else {
14636bf688a0SCe Qin     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
14646bf688a0SCe Qin     ierr = MatConvert(C,MATHYPRE,MAT_INITIAL_MATRIX,&jac->C);CHKERRQ(ierr);
14655ac14e1cSStefano Zampini   }
1466863406b8SStefano Zampini   PetscFunctionReturn(0);
1467863406b8SStefano Zampini }
1468863406b8SStefano Zampini 
1469863406b8SStefano Zampini /*@
1470863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1471863406b8SStefano Zampini 
1472863406b8SStefano Zampini    Collective on PC
1473863406b8SStefano Zampini 
1474863406b8SStefano Zampini    Input Parameters:
1475863406b8SStefano Zampini +  pc - the preconditioning context
1476863406b8SStefano Zampini -  C - the discrete curl
1477863406b8SStefano Zampini 
1478863406b8SStefano Zampini    Level: intermediate
1479863406b8SStefano Zampini 
148095452b02SPatrick Sanan    Notes:
148195452b02SPatrick Sanan     C should have as many rows as the number of faces and as many columns as the number of edges in the mesh
1482863406b8SStefano 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
1483863406b8SStefano Zampini 
1484863406b8SStefano Zampini .seealso:
1485863406b8SStefano Zampini @*/
1486863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1487863406b8SStefano Zampini {
1488863406b8SStefano Zampini   PetscErrorCode ierr;
1489863406b8SStefano Zampini 
1490863406b8SStefano Zampini   PetscFunctionBegin;
1491863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1492863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1493863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1494863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1495863406b8SStefano Zampini   PetscFunctionReturn(0);
1496863406b8SStefano Zampini }
1497863406b8SStefano Zampini 
14986bf688a0SCe Qin static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
14996bf688a0SCe Qin {
15006bf688a0SCe Qin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
15016bf688a0SCe Qin   PetscBool      ishypre;
15026bf688a0SCe Qin   PetscErrorCode ierr;
15036bf688a0SCe Qin   PetscInt       i;
15046bf688a0SCe Qin   PetscFunctionBegin;
15056bf688a0SCe Qin 
15066bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
15076bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
15086bf688a0SCe Qin   for (i=0;i<3;++i) {
15096bf688a0SCe Qin     ierr = MatDestroy(&jac->RT_Pi[i]);CHKERRQ(ierr);
15106bf688a0SCe Qin     ierr = MatDestroy(&jac->ND_Pi[i]);CHKERRQ(ierr);
15116bf688a0SCe Qin   }
15126bf688a0SCe Qin 
15136bf688a0SCe Qin   jac->dim = dim;
15146bf688a0SCe Qin   if (RT_PiFull) {
15156bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)RT_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
15166bf688a0SCe Qin     if (ishypre) {
15176bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)RT_PiFull);CHKERRQ(ierr);
15186bf688a0SCe Qin       jac->RT_PiFull = RT_PiFull;
15196bf688a0SCe Qin     } else {
15206bf688a0SCe Qin       ierr = MatConvert(RT_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_PiFull);CHKERRQ(ierr);
15216bf688a0SCe Qin     }
15226bf688a0SCe Qin   }
15236bf688a0SCe Qin   if (RT_Pi) {
15246bf688a0SCe Qin     for (i=0;i<dim;++i) {
15256bf688a0SCe Qin       if (RT_Pi[i]) {
15266bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)RT_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
15276bf688a0SCe Qin         if (ishypre) {
15286bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)RT_Pi[i]);CHKERRQ(ierr);
15296bf688a0SCe Qin           jac->RT_Pi[i] = RT_Pi[i];
15306bf688a0SCe Qin         } else {
15316bf688a0SCe Qin           ierr = MatConvert(RT_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_Pi[i]);CHKERRQ(ierr);
15326bf688a0SCe Qin         }
15336bf688a0SCe Qin       }
15346bf688a0SCe Qin     }
15356bf688a0SCe Qin   }
15366bf688a0SCe Qin   if (ND_PiFull) {
15376bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)ND_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
15386bf688a0SCe Qin     if (ishypre) {
15396bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)ND_PiFull);CHKERRQ(ierr);
15406bf688a0SCe Qin       jac->ND_PiFull = ND_PiFull;
15416bf688a0SCe Qin     } else {
15426bf688a0SCe Qin       ierr = MatConvert(ND_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_PiFull);CHKERRQ(ierr);
15436bf688a0SCe Qin     }
15446bf688a0SCe Qin   }
15456bf688a0SCe Qin   if (ND_Pi) {
15466bf688a0SCe Qin     for (i=0;i<dim;++i) {
15476bf688a0SCe Qin       if (ND_Pi[i]) {
15486bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)ND_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
15496bf688a0SCe Qin         if (ishypre) {
15506bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)ND_Pi[i]);CHKERRQ(ierr);
15516bf688a0SCe Qin           jac->ND_Pi[i] = ND_Pi[i];
15526bf688a0SCe Qin         } else {
15536bf688a0SCe Qin           ierr = MatConvert(ND_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_Pi[i]);CHKERRQ(ierr);
15546bf688a0SCe Qin         }
15556bf688a0SCe Qin       }
15566bf688a0SCe Qin     }
15576bf688a0SCe Qin   }
15586bf688a0SCe Qin 
15596bf688a0SCe Qin   PetscFunctionReturn(0);
15606bf688a0SCe Qin }
15616bf688a0SCe Qin 
15626bf688a0SCe Qin /*@
15636bf688a0SCe Qin  PCHYPRESetInterpolations - Set interpolation matrices for AMS/ADS preconditioner
15646bf688a0SCe Qin 
15656bf688a0SCe Qin    Collective on PC
15666bf688a0SCe Qin 
15676bf688a0SCe Qin    Input Parameters:
15686bf688a0SCe Qin +  pc - the preconditioning context
15696bf688a0SCe Qin -  dim - the dimension of the problem, only used in AMS
15706bf688a0SCe Qin -  RT_PiFull - Raviart-Thomas interpolation matrix
15716bf688a0SCe Qin -  RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix
15726bf688a0SCe Qin -  ND_PiFull - Nedelec interpolation matrix
15736bf688a0SCe Qin -  ND_Pi - x/y/z component of Nedelec interpolation matrix
15746bf688a0SCe Qin 
157595452b02SPatrick Sanan    Notes:
157695452b02SPatrick Sanan     For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL.
15776bf688a0SCe Qin           For ADS, both type of interpolation matrices are needed.
15786bf688a0SCe Qin    Level: intermediate
15796bf688a0SCe Qin 
15806bf688a0SCe Qin .seealso:
15816bf688a0SCe Qin @*/
15826bf688a0SCe Qin PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
15836bf688a0SCe Qin {
15846bf688a0SCe Qin   PetscErrorCode ierr;
15856bf688a0SCe Qin   PetscInt       i;
15866bf688a0SCe Qin 
15876bf688a0SCe Qin   PetscFunctionBegin;
15886bf688a0SCe Qin   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15896bf688a0SCe Qin   if (RT_PiFull) {
15906bf688a0SCe Qin     PetscValidHeaderSpecific(RT_PiFull,MAT_CLASSID,3);
15916bf688a0SCe Qin     PetscCheckSameComm(pc,1,RT_PiFull,3);
15926bf688a0SCe Qin   }
15936bf688a0SCe Qin   if (RT_Pi) {
15946bf688a0SCe Qin     PetscValidPointer(RT_Pi,4);
15956bf688a0SCe Qin     for (i=0;i<dim;++i) {
15966bf688a0SCe Qin       if (RT_Pi[i]) {
15976bf688a0SCe Qin         PetscValidHeaderSpecific(RT_Pi[i],MAT_CLASSID,4);
15986bf688a0SCe Qin         PetscCheckSameComm(pc,1,RT_Pi[i],4);
15996bf688a0SCe Qin       }
16006bf688a0SCe Qin     }
16016bf688a0SCe Qin   }
16026bf688a0SCe Qin   if (ND_PiFull) {
16036bf688a0SCe Qin     PetscValidHeaderSpecific(ND_PiFull,MAT_CLASSID,5);
16046bf688a0SCe Qin     PetscCheckSameComm(pc,1,ND_PiFull,5);
16056bf688a0SCe Qin   }
16066bf688a0SCe Qin   if (ND_Pi) {
16076bf688a0SCe Qin     PetscValidPointer(ND_Pi,6);
16086bf688a0SCe Qin     for (i=0;i<dim;++i) {
16096bf688a0SCe Qin       if (ND_Pi[i]) {
16106bf688a0SCe Qin         PetscValidHeaderSpecific(ND_Pi[i],MAT_CLASSID,6);
16116bf688a0SCe Qin         PetscCheckSameComm(pc,1,ND_Pi[i],6);
16126bf688a0SCe Qin       }
16136bf688a0SCe Qin     }
16146bf688a0SCe Qin   }
16156bf688a0SCe Qin   ierr = PetscTryMethod(pc,"PCHYPRESetInterpolations_C",(PC,PetscInt,Mat,Mat[],Mat,Mat[]),(pc,dim,RT_PiFull,RT_Pi,ND_PiFull,ND_Pi));CHKERRQ(ierr);
16166bf688a0SCe Qin   PetscFunctionReturn(0);
16176bf688a0SCe Qin }
16186bf688a0SCe Qin 
16195ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha)
16204cb006feSStefano Zampini {
16214cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
16225ac14e1cSStefano Zampini   PetscBool      ishypre;
16234cb006feSStefano Zampini   PetscErrorCode ierr;
16244cb006feSStefano Zampini 
16254cb006feSStefano Zampini   PetscFunctionBegin;
16265ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr);
16275ac14e1cSStefano Zampini   if (ishypre) {
16285ac14e1cSStefano Zampini     if (isalpha) {
16295ac14e1cSStefano Zampini       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
16305ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
16315ac14e1cSStefano Zampini       jac->alpha_Poisson = A;
16325ac14e1cSStefano Zampini     } else {
16335ac14e1cSStefano Zampini       if (A) {
16345ac14e1cSStefano Zampini         ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
16355ac14e1cSStefano Zampini       } else {
16365ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
16375ac14e1cSStefano Zampini       }
16385ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
16395ac14e1cSStefano Zampini       jac->beta_Poisson = A;
16405ac14e1cSStefano Zampini     }
16415ac14e1cSStefano Zampini   } else {
16425ac14e1cSStefano Zampini     if (isalpha) {
16436bf688a0SCe Qin       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
16446bf688a0SCe Qin       ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->alpha_Poisson);CHKERRQ(ierr);
16455ac14e1cSStefano Zampini     } else {
16465ac14e1cSStefano Zampini       if (A) {
16476bf688a0SCe Qin         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
16486bf688a0SCe Qin         ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->beta_Poisson);CHKERRQ(ierr);
16495ac14e1cSStefano Zampini       } else {
16505ac14e1cSStefano Zampini         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
16515ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
16525ac14e1cSStefano Zampini       }
16535ac14e1cSStefano Zampini     }
16545ac14e1cSStefano Zampini   }
16554cb006feSStefano Zampini   PetscFunctionReturn(0);
16564cb006feSStefano Zampini }
16574cb006feSStefano Zampini 
16584cb006feSStefano Zampini /*@
16594cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
16604cb006feSStefano Zampini 
16614cb006feSStefano Zampini    Collective on PC
16624cb006feSStefano Zampini 
16634cb006feSStefano Zampini    Input Parameters:
16644cb006feSStefano Zampini +  pc - the preconditioning context
16654cb006feSStefano Zampini -  A - the matrix
16664cb006feSStefano Zampini 
16674cb006feSStefano Zampini    Level: intermediate
16684cb006feSStefano Zampini 
166995452b02SPatrick Sanan    Notes:
167095452b02SPatrick Sanan     A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
16714cb006feSStefano Zampini 
16724cb006feSStefano Zampini .seealso:
16734cb006feSStefano Zampini @*/
16744cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
16754cb006feSStefano Zampini {
16764cb006feSStefano Zampini   PetscErrorCode ierr;
16774cb006feSStefano Zampini 
16784cb006feSStefano Zampini   PetscFunctionBegin;
16794cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
16804cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
16814cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
16825ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_TRUE));CHKERRQ(ierr);
16834cb006feSStefano Zampini   PetscFunctionReturn(0);
16844cb006feSStefano Zampini }
16854cb006feSStefano Zampini 
16864cb006feSStefano Zampini /*@
16874cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
16884cb006feSStefano Zampini 
16894cb006feSStefano Zampini    Collective on PC
16904cb006feSStefano Zampini 
16914cb006feSStefano Zampini    Input Parameters:
16924cb006feSStefano Zampini +  pc - the preconditioning context
16934cb006feSStefano Zampini -  A - the matrix
16944cb006feSStefano Zampini 
16954cb006feSStefano Zampini    Level: intermediate
16964cb006feSStefano Zampini 
169795452b02SPatrick Sanan    Notes:
169895452b02SPatrick Sanan     A should be obtained by discretizing the Poisson problem with linear finite elements.
16994cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
17004cb006feSStefano Zampini 
17014cb006feSStefano Zampini .seealso:
17024cb006feSStefano Zampini @*/
17034cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
17044cb006feSStefano Zampini {
17054cb006feSStefano Zampini   PetscErrorCode ierr;
17064cb006feSStefano Zampini 
17074cb006feSStefano Zampini   PetscFunctionBegin;
17084cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
17094cb006feSStefano Zampini   if (A) {
17104cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
17114cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
17124cb006feSStefano Zampini   }
17135ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_FALSE));CHKERRQ(ierr);
17144cb006feSStefano Zampini   PetscFunctionReturn(0);
17154cb006feSStefano Zampini }
17164cb006feSStefano Zampini 
17175ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz, Vec zoz, Vec zzo)
17184cb006feSStefano Zampini {
17194cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
17204cb006feSStefano Zampini   PetscErrorCode     ierr;
17214cb006feSStefano Zampini 
17224cb006feSStefano Zampini   PetscFunctionBegin;
17234cb006feSStefano Zampini   /* throw away any vector if already set */
17246ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->constants[0]);CHKERRQ(ierr);
17256ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->constants[1]);CHKERRQ(ierr);
17266ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->constants[2]);CHKERRQ(ierr);
17276ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz->map,&jac->constants[0]);CHKERRQ(ierr);
17284cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
17296ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz->map,&jac->constants[1]);CHKERRQ(ierr);
17304cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
17315ac14e1cSStefano Zampini   jac->dim = 2;
17324cb006feSStefano Zampini   if (zzo) {
17336ea7df73SStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo->map,&jac->constants[2]);CHKERRQ(ierr);
17344cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
17355ac14e1cSStefano Zampini     jac->dim++;
17364cb006feSStefano Zampini   }
17374cb006feSStefano Zampini   PetscFunctionReturn(0);
17384cb006feSStefano Zampini }
17394cb006feSStefano Zampini 
17404cb006feSStefano Zampini /*@
17414cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
17424cb006feSStefano Zampini 
17434cb006feSStefano Zampini    Collective on PC
17444cb006feSStefano Zampini 
17454cb006feSStefano Zampini    Input Parameters:
17464cb006feSStefano Zampini +  pc - the preconditioning context
17474cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
17484cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
17494cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
17504cb006feSStefano Zampini 
17514cb006feSStefano Zampini    Level: intermediate
17524cb006feSStefano Zampini 
17534cb006feSStefano Zampini    Notes:
17544cb006feSStefano Zampini 
17554cb006feSStefano Zampini .seealso:
17564cb006feSStefano Zampini @*/
17574cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
17584cb006feSStefano Zampini {
17594cb006feSStefano Zampini   PetscErrorCode ierr;
17604cb006feSStefano Zampini 
17614cb006feSStefano Zampini   PetscFunctionBegin;
17624cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
17634cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
17644cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
17654cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
17664cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
17674cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
17684cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
17694cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
17704cb006feSStefano Zampini   PetscFunctionReturn(0);
17714cb006feSStefano Zampini }
17724cb006feSStefano Zampini 
1773863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
17744cb006feSStefano Zampini {
17754cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
17764cb006feSStefano Zampini   Vec             tv;
17774cb006feSStefano Zampini   PetscInt        i;
17784cb006feSStefano Zampini   PetscErrorCode  ierr;
17794cb006feSStefano Zampini 
17804cb006feSStefano Zampini   PetscFunctionBegin;
17814cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
17826ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->coords[0]);CHKERRQ(ierr);
17836ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->coords[1]);CHKERRQ(ierr);
17846ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->coords[2]);CHKERRQ(ierr);
17855ac14e1cSStefano Zampini   jac->dim = dim;
17865ac14e1cSStefano Zampini 
17874cb006feSStefano Zampini   /* compute IJ vector for coordinates */
17884cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
17894cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
17904cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
17914cb006feSStefano Zampini   for (i=0;i<dim;i++) {
17924cb006feSStefano Zampini     PetscScalar *array;
17934cb006feSStefano Zampini     PetscInt    j;
17944cb006feSStefano Zampini 
17956ea7df73SStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv->map,&jac->coords[i]);CHKERRQ(ierr);
1796589dcaf0SStefano Zampini     ierr = VecGetArrayWrite(tv,&array);CHKERRQ(ierr);
17976ea7df73SStefano Zampini     for (j=0;j<nloc;j++) array[j] = coords[j*dim+i];
1798589dcaf0SStefano Zampini     ierr = VecRestoreArrayWrite(tv,&array);CHKERRQ(ierr);
17996ea7df73SStefano Zampini     ierr = VecHYPRE_IJVectorCopy(tv,jac->coords[i]);CHKERRQ(ierr);
18004cb006feSStefano Zampini   }
18014cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
18024cb006feSStefano Zampini   PetscFunctionReturn(0);
18034cb006feSStefano Zampini }
18044cb006feSStefano Zampini 
180516d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
180616d9e3a6SLisandro Dalcin 
1807f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
180816d9e3a6SLisandro Dalcin {
180916d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
181016d9e3a6SLisandro Dalcin 
181116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
181216d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
181316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
181416d9e3a6SLisandro Dalcin }
181516d9e3a6SLisandro Dalcin 
1816f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
181716d9e3a6SLisandro Dalcin {
181816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
181916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1820ace3abfcSBarry Smith   PetscBool      flag;
182116d9e3a6SLisandro Dalcin 
182216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
182316d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
182416d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
18259ace16cdSJacob Faibussowitsch     PetscAssertFalse(!flag,PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
182616d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
182716d9e3a6SLisandro Dalcin   } else {
182816d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
182916d9e3a6SLisandro Dalcin   }
183016d9e3a6SLisandro Dalcin 
183116d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
183216d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
183316d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
183416d9e3a6SLisandro Dalcin 
183516d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
183616d9e3a6SLisandro Dalcin   if (flag) {
183757f21012SBarry Smith     ierr = PetscCommGetComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre);CHKERRQ(ierr);
1838*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,jac->comm_hypre,&jac->hsolver);
183916d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
184016d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
184116d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
184216d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
184316d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
184416d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
184516d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
184616d9e3a6SLisandro Dalcin   }
1847db966c6cSHong Zhang   ierr = PetscStrcmp("euclid",jac->hypre_type,&flag);CHKERRQ(ierr);
1848db966c6cSHong Zhang   if (flag) {
18498bf83915SBarry Smith #if defined(PETSC_HAVE_64BIT_INDICES)
18508bf83915SBarry Smith     SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Hypre Euclid not support with 64 bit indices");
18518bf83915SBarry Smith #endif
185257f21012SBarry Smith     ierr = PetscCommGetComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre);CHKERRQ(ierr);
1853*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_EuclidCreate,jac->comm_hypre,&jac->hsolver);
1854db966c6cSHong Zhang     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
1855db966c6cSHong Zhang     pc->ops->view           = PCView_HYPRE_Euclid;
1856db966c6cSHong Zhang     jac->destroy            = HYPRE_EuclidDestroy;
1857db966c6cSHong Zhang     jac->setup              = HYPRE_EuclidSetup;
1858db966c6cSHong Zhang     jac->solve              = HYPRE_EuclidSolve;
1859db966c6cSHong Zhang     jac->factorrowsize      = PETSC_DEFAULT;
1860db966c6cSHong Zhang     jac->eu_level           = PETSC_DEFAULT; /* default */
1861db966c6cSHong Zhang     PetscFunctionReturn(0);
1862db966c6cSHong Zhang   }
186316d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
186416d9e3a6SLisandro Dalcin   if (flag) {
186557f21012SBarry Smith     ierr = PetscCommGetComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre);CHKERRQ(ierr);
1866*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ParaSailsCreate,jac->comm_hypre,&jac->hsolver);
186716d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
186816d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
186916d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
187016d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
187116d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
187216d9e3a6SLisandro Dalcin     /* initialize */
187316d9e3a6SLisandro Dalcin     jac->nlevels   = 1;
18748966356dSPierre Jolivet     jac->threshold = .1;
187516d9e3a6SLisandro Dalcin     jac->filter    = .1;
187616d9e3a6SLisandro Dalcin     jac->loadbal   = 0;
18772fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
18782fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
18792fa5cd67SKarl Rupp 
188016d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
188116d9e3a6SLisandro Dalcin     jac->symt = 0;
1882*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ParaSailsSetParams,jac->hsolver,jac->threshold,jac->nlevels);
1883*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,jac->hsolver,jac->filter);
1884*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,jac->hsolver,jac->loadbal);
1885*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,jac->hsolver,jac->logging);
1886*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,jac->hsolver,jac->ruse);
1887*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ParaSailsSetSym,jac->hsolver,jac->symt);
188816d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
188916d9e3a6SLisandro Dalcin   }
189016d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
189116d9e3a6SLisandro Dalcin   if (flag) {
189216d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
189316d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
189416d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
189516d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
189616d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
1897fd2dd295SFande Kong     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",PCGetInterpolations_BoomerAMG);CHKERRQ(ierr);
1898fd2dd295SFande Kong     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",PCGetCoarseOperators_BoomerAMG);CHKERRQ(ierr);
189916d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
190016d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
190116d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
190216d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
190316d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
190416d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
190516d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
190616d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
19078f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
190816d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
190916d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
191016d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
191116d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
191216d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
19130f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
19146a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1915b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
19161810e44eSEike Mueller     jac->eu_level         = 0;
19171810e44eSEike Mueller     jac->eu_droptolerance = 0;
19181810e44eSEike Mueller     jac->eu_bj            = 0;
1919589dcaf0SStefano Zampini     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a PC - most likely with CG */
19200f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
192116d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
192216d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
192316d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
19240f1074feSSatish Balay     jac->interptype       = 0;
1925589dcaf0SStefano Zampini     jac->Rtype            = 0;
1926589dcaf0SStefano Zampini     jac->Rstrongthreshold = 0.25;
1927589dcaf0SStefano Zampini     jac->Rfilterthreshold = 0.0;
1928589dcaf0SStefano Zampini     jac->Adroptype        = -1;
1929589dcaf0SStefano Zampini     jac->Adroptol         = 0.0;
19300f1074feSSatish Balay     jac->agg_nl           = 0;
19316ea7df73SStefano Zampini     jac->agg_interptype   = 4;
19320f1074feSSatish Balay     jac->pmax             = 0;
19330f1074feSSatish Balay     jac->truncfactor      = 0.0;
19340f1074feSSatish Balay     jac->agg_num_paths    = 1;
1935589dcaf0SStefano Zampini     jac->maxc             = 9;
1936589dcaf0SStefano Zampini     jac->minc             = 1;
193722e51d31SStefano Zampini     jac->nodal_coarsening      = 0;
193822e51d31SStefano Zampini     jac->nodal_coarsening_diag = 0;
193922e51d31SStefano Zampini     jac->vec_interp_variant    = 0;
194022e51d31SStefano Zampini     jac->vec_interp_qmax       = 0;
194122e51d31SStefano Zampini     jac->vec_interp_smooth     = PETSC_FALSE;
194222e51d31SStefano Zampini     jac->interp_refine         = 0;
19438f87f92bSBarry Smith     jac->nodal_relax           = PETSC_FALSE;
19448f87f92bSBarry Smith     jac->nodal_relax_levels    = 1;
19456ea7df73SStefano Zampini     jac->rap2                  = 0;
19466ea7df73SStefano Zampini 
19476ea7df73SStefano Zampini     /* GPU defaults
19486ea7df73SStefano Zampini          from https://hypre.readthedocs.io/en/latest/solvers-boomeramg.html#gpu-supported-options
19496ea7df73SStefano Zampini          and /src/parcsr_ls/par_amg.c */
19506ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE)
19516ea7df73SStefano Zampini     jac->keeptranspose         = PETSC_TRUE;
19526ea7df73SStefano Zampini     jac->mod_rap2              = 1;
19536ea7df73SStefano Zampini     jac->coarsentype           = 8;
19546ea7df73SStefano Zampini     jac->relaxorder            = 0;
19556ea7df73SStefano Zampini     jac->interptype            = 6;
19566ea7df73SStefano Zampini     jac->relaxtype[0]          = 18;
19576ea7df73SStefano Zampini     jac->relaxtype[1]          = 18;
19586ea7df73SStefano Zampini     jac->agg_interptype        = 7;
19596ea7df73SStefano Zampini #else
19606ea7df73SStefano Zampini     jac->keeptranspose         = PETSC_FALSE;
19616ea7df73SStefano Zampini     jac->mod_rap2              = 0;
19626ea7df73SStefano Zampini #endif
1963*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,jac->hsolver,jac->cycletype);
1964*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,jac->hsolver,jac->maxlevels);
1965*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,jac->maxiter);
1966*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,jac->hsolver,jac->tol);
1967*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,jac->hsolver,jac->truncfactor);
1968*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,jac->hsolver,jac->strongthreshold);
1969*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,jac->hsolver,jac->maxrowsum);
1970*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,jac->hsolver,jac->coarsentype);
1971*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,jac->hsolver,jac->measuretype);
1972*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,jac->hsolver, jac->relaxorder);
1973*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,jac->hsolver,jac->interptype);
1974*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,jac->hsolver,jac->agg_nl);
1975*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetAggInterpType,jac->hsolver,jac->agg_interptype);
1976*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,jac->hsolver,jac->pmax);
1977*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,jac->hsolver,jac->agg_num_paths);
1978*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,jac->hsolver, jac->relaxtype[0]);  /* defaults coarse to 9 */
1979*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,jac->hsolver, jac->gridsweeps[0]); /* defaults coarse to 1 */
1980*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxCoarseSize,jac->hsolver, jac->maxc);
1981*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMinCoarseSize,jac->hsolver, jac->minc);
19826ea7df73SStefano Zampini     /* GPU */
19836ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0)
1984*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetKeepTranspose,jac->hsolver,jac->keeptranspose ? 1 : 0);
1985*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetRAP2,jac->hsolver, jac->rap2);
1986*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetModuleRAP2,jac->hsolver, jac->mod_rap2);
19876ea7df73SStefano Zampini #endif
19886ea7df73SStefano Zampini 
1989589dcaf0SStefano Zampini     /* AIR */
19906ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0)
1991*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetRestriction,jac->hsolver,jac->Rtype);
1992*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThresholdR,jac->hsolver,jac->Rstrongthreshold);
1993*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetFilterThresholdR,jac->hsolver,jac->Rfilterthreshold);
1994*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetADropTol,jac->hsolver,jac->Adroptol);
1995*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetADropType,jac->hsolver,jac->Adroptype);
19966ea7df73SStefano Zampini #endif
199716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
199816d9e3a6SLisandro Dalcin   }
19994cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
20004cb006feSStefano Zampini   if (flag) {
20014cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
20024cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
20034cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
20044cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
20054cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
20064cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
20074cb006feSStefano Zampini     jac->coords[0]           = NULL;
20084cb006feSStefano Zampini     jac->coords[1]           = NULL;
20094cb006feSStefano Zampini     jac->coords[2]           = NULL;
20104cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
2011863406b8SStefano Zampini     jac->as_print           = 0;
2012863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
2013863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
20144cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
20154cb006feSStefano Zampini     /* Smoothing options */
2016863406b8SStefano Zampini     jac->as_relax_type      = 2;
2017863406b8SStefano Zampini     jac->as_relax_times     = 1;
2018863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
2019863406b8SStefano Zampini     jac->as_omega           = 1.0;
20204cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
2021863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
2022863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
20230bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
2024863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
2025863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
2026863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
20274cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
2028863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
2029863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
20300bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
2031863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
2032863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
2033863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
2034*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,jac->hsolver,jac->as_print);
2035*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetMaxIter,jac->hsolver,jac->as_max_iter);
2036*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetCycleType,jac->hsolver,jac->ams_cycle_type);
2037*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetTol,jac->hsolver,jac->as_tol);
2038*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,jac->hsolver,jac->as_relax_type,
2039863406b8SStefano Zampini                                                                       jac->as_relax_times,
2040863406b8SStefano Zampini                                                                       jac->as_relax_weight,
2041*a74df02fSJacob Faibussowitsch                                                                       jac->as_omega);
2042*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
2043863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
2044863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
2045863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
2046863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
2047*a74df02fSJacob Faibussowitsch                                                                      jac->as_amg_alpha_opts[4]);     /* AMG Pmax */
2048*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
2049863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
2050863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
2051863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
2052863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
2053*a74df02fSJacob Faibussowitsch                                                                     jac->as_amg_beta_opts[4]);     /* AMG Pmax */
205423df4f25SStefano Zampini     /* Zero conductivity */
205523df4f25SStefano Zampini     jac->ams_beta_is_zero      = PETSC_FALSE;
205623df4f25SStefano Zampini     jac->ams_beta_is_zero_part = PETSC_FALSE;
20574cb006feSStefano Zampini     PetscFunctionReturn(0);
20584cb006feSStefano Zampini   }
2059863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
2060863406b8SStefano Zampini   if (flag) {
2061863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
2062863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
2063863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
2064863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
2065863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
2066863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
2067863406b8SStefano Zampini     jac->coords[0]           = NULL;
2068863406b8SStefano Zampini     jac->coords[1]           = NULL;
2069863406b8SStefano Zampini     jac->coords[2]           = NULL;
2070863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
2071863406b8SStefano Zampini     jac->as_print           = 0;
2072863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
2073863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
2074863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
2075863406b8SStefano Zampini     /* Smoothing options */
2076863406b8SStefano Zampini     jac->as_relax_type      = 2;
2077863406b8SStefano Zampini     jac->as_relax_times     = 1;
2078863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
2079863406b8SStefano Zampini     jac->as_omega           = 1.0;
2080863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
2081863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
2082863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
2083863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
2084863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
2085863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
2086863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
2087863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
2088863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
2089863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
2090863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
2091863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
2092863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
2093863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
2094863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
2095*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,jac->hsolver,jac->as_print);
2096*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetMaxIter,jac->hsolver,jac->as_max_iter);
2097*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetCycleType,jac->hsolver,jac->ams_cycle_type);
2098*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetTol,jac->hsolver,jac->as_tol);
2099*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,jac->hsolver,jac->as_relax_type,
2100863406b8SStefano Zampini                                                                       jac->as_relax_times,
2101863406b8SStefano Zampini                                                                       jac->as_relax_weight,
2102*a74df02fSJacob Faibussowitsch                                                                       jac->as_omega);
2103*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
2104863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
2105863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
2106863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
2107863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
2108863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
2109*a74df02fSJacob Faibussowitsch                                                                 jac->as_amg_alpha_opts[4]);     /* AMG Pmax */
2110*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
2111863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
2112863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
2113863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
2114863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
2115*a74df02fSJacob Faibussowitsch                                                                 jac->as_amg_beta_opts[4]);     /* AMG Pmax */
2116863406b8SStefano Zampini     PetscFunctionReturn(0);
2117863406b8SStefano Zampini   }
2118503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
21192fa5cd67SKarl Rupp 
21200298fd71SBarry Smith   jac->hypre_type = NULL;
212198921bdaSJacob Faibussowitsch   SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams",name);
212216d9e3a6SLisandro Dalcin }
212316d9e3a6SLisandro Dalcin 
212416d9e3a6SLisandro Dalcin /*
212516d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
212616d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
212716d9e3a6SLisandro Dalcin */
2128360ee056SFande Kong PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc)
212916d9e3a6SLisandro Dalcin {
213016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
21314ddd07fcSJed Brown   PetscInt       indx;
2132db966c6cSHong Zhang   const char     *type[] = {"euclid","pilut","parasails","boomeramg","ams","ads"};
2133ace3abfcSBarry Smith   PetscBool      flg;
213416d9e3a6SLisandro Dalcin 
213516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
21369fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
2137cab5ea25SPierre Jolivet   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,ALEN(type),"boomeramg",&indx,&flg);CHKERRQ(ierr);
213816d9e3a6SLisandro Dalcin   if (flg) {
213916d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
214002a17cd4SBarry Smith   } else {
214102a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
214216d9e3a6SLisandro Dalcin   }
214316d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
21443931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
214516d9e3a6SLisandro Dalcin   }
214616d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
214716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
214816d9e3a6SLisandro Dalcin }
214916d9e3a6SLisandro Dalcin 
215016d9e3a6SLisandro Dalcin /*@C
215116d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
215216d9e3a6SLisandro Dalcin 
215316d9e3a6SLisandro Dalcin    Input Parameters:
215416d9e3a6SLisandro Dalcin +     pc - the preconditioner context
2155db966c6cSHong Zhang -     name - either  euclid, pilut, parasails, boomeramg, ams, ads
215616d9e3a6SLisandro Dalcin 
215716d9e3a6SLisandro Dalcin    Options Database Keys:
2158db966c6cSHong Zhang    -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
215916d9e3a6SLisandro Dalcin 
216016d9e3a6SLisandro Dalcin    Level: intermediate
216116d9e3a6SLisandro Dalcin 
216216d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
216316d9e3a6SLisandro Dalcin            PCHYPRE
216416d9e3a6SLisandro Dalcin 
216516d9e3a6SLisandro Dalcin @*/
21667087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
216716d9e3a6SLisandro Dalcin {
21684ac538c5SBarry Smith   PetscErrorCode ierr;
216916d9e3a6SLisandro Dalcin 
217016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
21710700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
217216d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
21734ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
217416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
217516d9e3a6SLisandro Dalcin }
217616d9e3a6SLisandro Dalcin 
217716d9e3a6SLisandro Dalcin /*@C
217816d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
217916d9e3a6SLisandro Dalcin 
218016d9e3a6SLisandro Dalcin    Input Parameter:
218116d9e3a6SLisandro Dalcin .     pc - the preconditioner context
218216d9e3a6SLisandro Dalcin 
218316d9e3a6SLisandro Dalcin    Output Parameter:
2184db966c6cSHong Zhang .     name - either  euclid, pilut, parasails, boomeramg, ams, ads
218516d9e3a6SLisandro Dalcin 
218616d9e3a6SLisandro Dalcin    Level: intermediate
218716d9e3a6SLisandro Dalcin 
218816d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
218916d9e3a6SLisandro Dalcin            PCHYPRE
219016d9e3a6SLisandro Dalcin 
219116d9e3a6SLisandro Dalcin @*/
21927087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
219316d9e3a6SLisandro Dalcin {
21944ac538c5SBarry Smith   PetscErrorCode ierr;
219516d9e3a6SLisandro Dalcin 
219616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
21970700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
219816d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
21994ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
220016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
220116d9e3a6SLisandro Dalcin }
220216d9e3a6SLisandro Dalcin 
2203db6f9c32SMark Adams /*@C
2204db6f9c32SMark Adams    PCMGGalerkinSetMatProductAlgorithm - Set type of SpGEMM for hypre to use
2205db6f9c32SMark Adams 
2206db6f9c32SMark Adams    Logically Collective on PC
2207db6f9c32SMark Adams 
2208db6f9c32SMark Adams    Input Parameters:
2209db6f9c32SMark Adams +  pc - the hypre context
2210db6f9c32SMark Adams -  type - one of 'cusparse', 'hypre'
2211db6f9c32SMark Adams 
2212db6f9c32SMark Adams    Options Database Key:
2213db6f9c32SMark Adams .  -pc_mg_galerkin_mat_product_algorithm <"cusparse","hypre">
2214db6f9c32SMark Adams 
2215db6f9c32SMark Adams    Level: intermediate
2216db6f9c32SMark Adams 
2217db6f9c32SMark Adams .seealso: PCMGGalerkinGetMatProductAlgorithm()
2218db6f9c32SMark Adams 
2219db6f9c32SMark Adams @*/
2220db6f9c32SMark Adams PetscErrorCode PCMGGalerkinSetMatProductAlgorithm(PC pc,const char name[])
2221db6f9c32SMark Adams {
2222db6f9c32SMark Adams   PetscErrorCode ierr;
2223db6f9c32SMark Adams 
2224db6f9c32SMark Adams   PetscFunctionBegin;
2225db6f9c32SMark Adams   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
2226db6f9c32SMark Adams   ierr = PetscTryMethod(pc,"PCMGGalerkinSetMatProductAlgorithm_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
2227db6f9c32SMark Adams   PetscFunctionReturn(0);
2228db6f9c32SMark Adams }
2229db6f9c32SMark Adams 
2230db6f9c32SMark Adams /*@C
2231db6f9c32SMark Adams    PCMGGalerkinGetMatProductAlgorithm - Get type of SpGEMM for hypre
2232db6f9c32SMark Adams 
2233db6f9c32SMark Adams    Not Collective
2234db6f9c32SMark Adams 
2235db6f9c32SMark Adams    Input Parameter:
2236db6f9c32SMark Adams .  pc - the multigrid context
2237db6f9c32SMark Adams 
2238db6f9c32SMark Adams    Output Parameter:
2239db6f9c32SMark Adams .  name - one of 'cusparse', 'hypre'
2240db6f9c32SMark Adams 
2241db6f9c32SMark Adams    Level: intermediate
2242db6f9c32SMark Adams 
2243db6f9c32SMark Adams .seealso: PCMGGalerkinSetMatProductAlgorithm()
2244db6f9c32SMark Adams 
2245db6f9c32SMark Adams @*/
2246db6f9c32SMark Adams PetscErrorCode PCMGGalerkinGetMatProductAlgorithm(PC pc,const char *name[])
2247db6f9c32SMark Adams {
2248db6f9c32SMark Adams   PetscErrorCode ierr;
2249db6f9c32SMark Adams 
2250db6f9c32SMark Adams   PetscFunctionBegin;
2251db6f9c32SMark Adams   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
2252db6f9c32SMark Adams   ierr = PetscTryMethod(pc,"PCMGGalerkinGetMatProductAlgorithm_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
2253db6f9c32SMark Adams   PetscFunctionReturn(0);
2254db6f9c32SMark Adams }
2255db6f9c32SMark Adams 
225616d9e3a6SLisandro Dalcin /*MC
225716d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
225816d9e3a6SLisandro Dalcin 
225916d9e3a6SLisandro Dalcin    Options Database Keys:
2260db966c6cSHong Zhang +   -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
226116d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
226216d9e3a6SLisandro Dalcin           preconditioner
226316d9e3a6SLisandro Dalcin 
226416d9e3a6SLisandro Dalcin    Level: intermediate
226516d9e3a6SLisandro Dalcin 
226695452b02SPatrick Sanan    Notes:
226795452b02SPatrick Sanan     Apart from pc_hypre_type (for which there is PCHYPRESetType()),
226816d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
226916d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
227016d9e3a6SLisandro Dalcin 
2271c231f9e3SBarryFSmith           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_tol refer to the number of iterations
22720f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
22730f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
2274c231f9e3SBarryFSmith           (-pc_hypre_boomeramg_tol should be set to 0.0 - the default - to strictly use a fixed number of
22758f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
22760f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
22770f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
227816d9e3a6SLisandro Dalcin 
22790f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
22800f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
22810f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
228216d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
228316d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
228416d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
228516d9e3a6SLisandro Dalcin 
228616d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
228716d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
228816d9e3a6SLisandro Dalcin 
22895272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
2290fdd15c9aSJunchao Zhang           the following two options:
22910b1a5bd9SEric Chamberland 
2292fdd15c9aSJunchao Zhang    Options Database Keys:
22935272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
2294fdd15c9aSJunchao Zhang -   -pc_hypre_boomeramg_vec_interp_variant <v> - where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
22955272c319SBarry Smith 
22965272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
22975272c319SBarry Smith 
22989e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
22999e5bc791SBarry Smith 
230016d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
23019e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
230216d9e3a6SLisandro Dalcin 
230316d9e3a6SLisandro Dalcin M*/
230416d9e3a6SLisandro Dalcin 
23058cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
230616d9e3a6SLisandro Dalcin {
230716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
230816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
230916d9e3a6SLisandro Dalcin 
231016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
2311b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
23122fa5cd67SKarl Rupp 
231316d9e3a6SLisandro Dalcin   pc->data                = jac;
23148695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
231516d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
231616d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
231716d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
231816d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
231916d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
2320bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
2321bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
23225ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
23235ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
23245ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
23256bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",PCHYPRESetInterpolations_HYPRE);CHKERRQ(ierr);
23265ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE);CHKERRQ(ierr);
23275ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",PCHYPRESetPoissonMatrix_HYPRE);CHKERRQ(ierr);
2328db6f9c32SMark Adams   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinSetMatProductAlgorithm_C",PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG);CHKERRQ(ierr);
2329db6f9c32SMark Adams   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinGetMatProductAlgorithm_C",PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG);CHKERRQ(ierr);
23306ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE)
23316ea7df73SStefano Zampini #if defined(HYPRE_USING_HIP)
2332a4af0ceeSJacob Faibussowitsch   ierr = PetscDeviceInitialize(PETSC_DEVICE_HIP);CHKERRQ(ierr);
23336ea7df73SStefano Zampini #endif
23346ea7df73SStefano Zampini #if defined(HYPRE_USING_CUDA)
2335a4af0ceeSJacob Faibussowitsch   ierr = PetscDeviceInitialize(PETSC_DEVICE_CUDA);CHKERRQ(ierr);
23366ea7df73SStefano Zampini #endif
23376ea7df73SStefano Zampini #endif
233816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
233916d9e3a6SLisandro Dalcin }
2340ebc551c0SBarry Smith 
2341f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
2342f91d8e95SBarry Smith 
2343ebc551c0SBarry Smith typedef struct {
234468326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
2345f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
23469e5bc791SBarry Smith 
23479e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
23484ddd07fcSJed Brown   PetscInt its;
23499e5bc791SBarry Smith   double   tol;
23504ddd07fcSJed Brown   PetscInt relax_type;
23514ddd07fcSJed Brown   PetscInt rap_type;
23524ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
23534ddd07fcSJed Brown   PetscInt max_levels;
2354ebc551c0SBarry Smith } PC_PFMG;
2355ebc551c0SBarry Smith 
2356ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
2357ebc551c0SBarry Smith {
2358ebc551c0SBarry Smith   PetscErrorCode ierr;
2359f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2360ebc551c0SBarry Smith 
2361ebc551c0SBarry Smith   PetscFunctionBegin;
2362*a74df02fSJacob Faibussowitsch   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,ex->hsolver);
236357f21012SBarry Smith   ierr = PetscCommRestoreComm(PetscObjectComm((PetscObject)pc),&ex->hcomm);CHKERRQ(ierr);
2364c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2365ebc551c0SBarry Smith   PetscFunctionReturn(0);
2366ebc551c0SBarry Smith }
2367ebc551c0SBarry Smith 
23689e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
23699e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
23709e5bc791SBarry Smith 
2371ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
2372ebc551c0SBarry Smith {
2373ebc551c0SBarry Smith   PetscErrorCode ierr;
2374ace3abfcSBarry Smith   PetscBool      iascii;
2375f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2376ebc551c0SBarry Smith 
2377ebc551c0SBarry Smith   PetscFunctionBegin;
2378251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
23799e5bc791SBarry Smith   if (iascii) {
23809e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
2381efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max iterations %d\n",ex->its);CHKERRQ(ierr);
2382efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    tolerance %g\n",ex->tol);CHKERRQ(ierr);
2383efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2384efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
2385efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2386efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max levels %d\n",ex->max_levels);CHKERRQ(ierr);
23879e5bc791SBarry Smith   }
2388ebc551c0SBarry Smith   PetscFunctionReturn(0);
2389ebc551c0SBarry Smith }
2390ebc551c0SBarry Smith 
23914416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2392ebc551c0SBarry Smith {
2393ebc551c0SBarry Smith   PetscErrorCode ierr;
2394f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2395ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2396ebc551c0SBarry Smith 
2397ebc551c0SBarry Smith   PetscFunctionBegin;
2398e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
23990298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
240068326731SBarry Smith   if (flg) {
2401*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,ex->hsolver,3);
240268326731SBarry Smith   }
24030298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2404*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,ex->hsolver,ex->its);
24050298fd71SBarry 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);
2406*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,ex->hsolver,ex->num_pre_relax);
24070298fd71SBarry 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);
2408*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,ex->hsolver,ex->num_post_relax);
24099e5bc791SBarry Smith 
24100298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
2411*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,ex->hsolver,ex->max_levels);
24123b46a515SGlenn Hammond 
24130298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2414*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetTol,ex->hsolver,ex->tol);
24150298fd71SBarry 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);
2416*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,ex->hsolver, ex->relax_type);
24170298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
2418*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,ex->hsolver, ex->rap_type);
2419ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
2420ebc551c0SBarry Smith   PetscFunctionReturn(0);
2421ebc551c0SBarry Smith }
2422ebc551c0SBarry Smith 
2423f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
2424f91d8e95SBarry Smith {
2425f91d8e95SBarry Smith   PetscErrorCode    ierr;
2426f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
2427d9ca1df4SBarry Smith   PetscScalar       *yy;
2428d9ca1df4SBarry Smith   const PetscScalar *xx;
24294ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
24302cf14000SStefano Zampini   HYPRE_Int         hlower[3],hupper[3];
243168326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2432f91d8e95SBarry Smith 
2433f91d8e95SBarry Smith   PetscFunctionBegin;
2434dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2435aa219208SBarry Smith   ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
24362cf14000SStefano Zampini   /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
2437f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
2438f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
2439f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
24402cf14000SStefano Zampini   hlower[0]  = (HYPRE_Int)ilower[0];
24412cf14000SStefano Zampini   hlower[1]  = (HYPRE_Int)ilower[1];
24422cf14000SStefano Zampini   hlower[2]  = (HYPRE_Int)ilower[2];
24432cf14000SStefano Zampini   hupper[0]  = (HYPRE_Int)iupper[0];
24442cf14000SStefano Zampini   hupper[1]  = (HYPRE_Int)iupper[1];
24452cf14000SStefano Zampini   hupper[2]  = (HYPRE_Int)iupper[2];
2446f91d8e95SBarry Smith 
2447f91d8e95SBarry Smith   /* copy x values over to hypre */
2448*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,mx->hb,0.0);
2449d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2450*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,mx->hb,hlower,hupper,(HYPRE_Complex*)xx);
2451d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2452*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructVectorAssemble,mx->hb);
2453*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSolve,ex->hsolver,mx->hmat,mx->hb,mx->hx);
2454f91d8e95SBarry Smith 
2455f91d8e95SBarry Smith   /* copy solution values back to PETSc */
2456f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
2457*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,mx->hx,hlower,hupper,(HYPRE_Complex*)yy);
2458f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2459f91d8e95SBarry Smith   PetscFunctionReturn(0);
2460f91d8e95SBarry Smith }
2461f91d8e95SBarry Smith 
2462ace3abfcSBarry 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)
24639e5bc791SBarry Smith {
24649e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
24659e5bc791SBarry Smith   PetscErrorCode ierr;
24662cf14000SStefano Zampini   HYPRE_Int      oits;
24679e5bc791SBarry Smith 
24689e5bc791SBarry Smith   PetscFunctionBegin;
2469dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2470*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,jac->hsolver,its*jac->its);
2471*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetTol,jac->hsolver,rtol);
24729e5bc791SBarry Smith 
24739e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
2474*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,jac->hsolver,&oits);
24759e5bc791SBarry Smith   *outits = oits;
24769e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
24779e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2478*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetTol,jac->hsolver,jac->tol);
2479*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,jac->hsolver,jac->its);
24809e5bc791SBarry Smith   PetscFunctionReturn(0);
24819e5bc791SBarry Smith }
24829e5bc791SBarry Smith 
24833a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
24843a32d3dbSGlenn Hammond {
24853a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
24863a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
24873a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2488ace3abfcSBarry Smith   PetscBool       flg;
24893a32d3dbSGlenn Hammond 
24903a32d3dbSGlenn Hammond   PetscFunctionBegin;
2491251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
24929ace16cdSJacob Faibussowitsch   PetscAssertFalse(!flg,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
24933a32d3dbSGlenn Hammond 
24943a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
2495*a74df02fSJacob Faibussowitsch   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,ex->hsolver);
2496*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGCreate,ex->hcomm,&ex->hsolver);
2497*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetup,ex->hsolver,mx->hmat,mx->hb,mx->hx);
2498*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,ex->hsolver);
24993a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
25003a32d3dbSGlenn Hammond }
25013a32d3dbSGlenn Hammond 
2502ebc551c0SBarry Smith /*MC
2503ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
2504ebc551c0SBarry Smith 
2505ebc551c0SBarry Smith    Level: advanced
2506ebc551c0SBarry Smith 
25079e5bc791SBarry Smith    Options Database:
25089e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
25099e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
25109e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
25119e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
25129e5bc791SBarry 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
25139e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
2514f91d8e95SBarry Smith 
251595452b02SPatrick Sanan    Notes:
251695452b02SPatrick Sanan     This is for CELL-centered descretizations
25179e5bc791SBarry Smith 
25188e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
2519aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
25209e5bc791SBarry Smith 
25219e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
2522ebc551c0SBarry Smith M*/
2523ebc551c0SBarry Smith 
25248cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
2525ebc551c0SBarry Smith {
2526ebc551c0SBarry Smith   PetscErrorCode ierr;
2527ebc551c0SBarry Smith   PC_PFMG        *ex;
2528ebc551c0SBarry Smith 
2529ebc551c0SBarry Smith   PetscFunctionBegin;
2530b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
253168326731SBarry Smith   pc->data = ex;
2532ebc551c0SBarry Smith 
25339e5bc791SBarry Smith   ex->its            = 1;
25349e5bc791SBarry Smith   ex->tol            = 1.e-8;
25359e5bc791SBarry Smith   ex->relax_type     = 1;
25369e5bc791SBarry Smith   ex->rap_type       = 0;
25379e5bc791SBarry Smith   ex->num_pre_relax  = 1;
25389e5bc791SBarry Smith   ex->num_post_relax = 1;
25393b46a515SGlenn Hammond   ex->max_levels     = 0;
25409e5bc791SBarry Smith 
2541ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2542ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2543ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2544f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
25459e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
254668326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
25472fa5cd67SKarl Rupp 
254857f21012SBarry Smith   ierr = PetscCommGetComm(PetscObjectComm((PetscObject)pc),&ex->hcomm);CHKERRQ(ierr);
2549*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGCreate,ex->hcomm,&ex->hsolver);
2550ebc551c0SBarry Smith   PetscFunctionReturn(0);
2551ebc551c0SBarry Smith }
2552d851a50bSGlenn Hammond 
2553325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2554325fc9f4SBarry Smith 
2555d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2556d851a50bSGlenn Hammond typedef struct {
2557d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2558d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2559d851a50bSGlenn Hammond 
2560d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
25614ddd07fcSJed Brown   PetscInt its;
2562d851a50bSGlenn Hammond   double   tol;
25634ddd07fcSJed Brown   PetscInt relax_type;
25644ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2565d851a50bSGlenn Hammond } PC_SysPFMG;
2566d851a50bSGlenn Hammond 
2567d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2568d851a50bSGlenn Hammond {
2569d851a50bSGlenn Hammond   PetscErrorCode ierr;
2570d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2571d851a50bSGlenn Hammond 
2572d851a50bSGlenn Hammond   PetscFunctionBegin;
2573*a74df02fSJacob Faibussowitsch   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,ex->ss_solver);
257457f21012SBarry Smith   ierr = PetscCommRestoreComm(PetscObjectComm((PetscObject)pc),&ex->hcomm);CHKERRQ(ierr);
2575c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2576d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2577d851a50bSGlenn Hammond }
2578d851a50bSGlenn Hammond 
2579d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2580d851a50bSGlenn Hammond 
2581d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2582d851a50bSGlenn Hammond {
2583d851a50bSGlenn Hammond   PetscErrorCode ierr;
2584ace3abfcSBarry Smith   PetscBool      iascii;
2585d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2586d851a50bSGlenn Hammond 
2587d851a50bSGlenn Hammond   PetscFunctionBegin;
2588251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2589d851a50bSGlenn Hammond   if (iascii) {
2590d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2591efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  max iterations %d\n",ex->its);CHKERRQ(ierr);
2592efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerance %g\n",ex->tol);CHKERRQ(ierr);
2593efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2594efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2595d851a50bSGlenn Hammond   }
2596d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2597d851a50bSGlenn Hammond }
2598d851a50bSGlenn Hammond 
25994416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2600d851a50bSGlenn Hammond {
2601d851a50bSGlenn Hammond   PetscErrorCode ierr;
2602d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2603ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2604d851a50bSGlenn Hammond 
2605d851a50bSGlenn Hammond   PetscFunctionBegin;
2606e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
26070298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2608d851a50bSGlenn Hammond   if (flg) {
2609*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,ex->ss_solver,3);
2610d851a50bSGlenn Hammond   }
26110298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2612*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,ex->ss_solver,ex->its);
26130298fd71SBarry 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);
2614*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,ex->ss_solver,ex->num_pre_relax);
26150298fd71SBarry 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);
2616*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,ex->ss_solver,ex->num_post_relax);
2617d851a50bSGlenn Hammond 
26180298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2619*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,ex->ss_solver,ex->tol);
262061710fbeSStefano 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);
2621*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,ex->ss_solver, ex->relax_type);
2622d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2623d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2624d851a50bSGlenn Hammond }
2625d851a50bSGlenn Hammond 
2626d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2627d851a50bSGlenn Hammond {
2628d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2629d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2630d9ca1df4SBarry Smith   PetscScalar       *yy;
2631d9ca1df4SBarry Smith   const PetscScalar *xx;
26324ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
26332cf14000SStefano Zampini   HYPRE_Int         hlower[3],hupper[3];
2634d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
26354ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
26364ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
26374ddd07fcSJed Brown   PetscInt          part    = 0;
26384ddd07fcSJed Brown   PetscInt          size;
26394ddd07fcSJed Brown   PetscInt          i;
2640d851a50bSGlenn Hammond 
2641d851a50bSGlenn Hammond   PetscFunctionBegin;
2642dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2643aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
26442cf14000SStefano Zampini   /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
2645d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2646d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2647d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
26482cf14000SStefano Zampini   hlower[0]  = (HYPRE_Int)ilower[0];
26492cf14000SStefano Zampini   hlower[1]  = (HYPRE_Int)ilower[1];
26502cf14000SStefano Zampini   hlower[2]  = (HYPRE_Int)ilower[2];
26512cf14000SStefano Zampini   hupper[0]  = (HYPRE_Int)iupper[0];
26522cf14000SStefano Zampini   hupper[1]  = (HYPRE_Int)iupper[1];
26532cf14000SStefano Zampini   hupper[2]  = (HYPRE_Int)iupper[2];
2654d851a50bSGlenn Hammond 
2655d851a50bSGlenn Hammond   size = 1;
26562fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
26572fa5cd67SKarl Rupp 
2658d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2659d851a50bSGlenn Hammond   if (ordering) {
2660*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,mx->ss_b,0.0);
2661d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2662*a74df02fSJacob Faibussowitsch     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(xx+(size*i)));
2663d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2664*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SStructVectorAssemble,mx->ss_b);
2665*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x);
2666*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x);
2667d851a50bSGlenn Hammond 
2668d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2669d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
2670*a74df02fSJacob Faibussowitsch     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(yy+(size*i)));
2671d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2672a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2673d851a50bSGlenn Hammond     PetscScalar *z;
26744ddd07fcSJed Brown     PetscInt    j, k;
2675d851a50bSGlenn Hammond 
2676785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2677*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,mx->ss_b,0.0);
2678d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2679d851a50bSGlenn Hammond 
2680d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2681d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2682d851a50bSGlenn Hammond       k= i*nvars;
26832fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2684d851a50bSGlenn Hammond     }
2685*a74df02fSJacob Faibussowitsch     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i)));
2686d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2687*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SStructVectorAssemble,mx->ss_b);
2688*a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x);
2689d851a50bSGlenn Hammond 
2690d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2691d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
2692*a74df02fSJacob Faibussowitsch     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i)));
2693d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2694d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2695d851a50bSGlenn Hammond       k= i*nvars;
26962fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2697d851a50bSGlenn Hammond     }
2698d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2699d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2700d851a50bSGlenn Hammond   }
2701d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2702d851a50bSGlenn Hammond }
2703d851a50bSGlenn Hammond 
2704ace3abfcSBarry 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)
2705d851a50bSGlenn Hammond {
2706d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2707d851a50bSGlenn Hammond   PetscErrorCode ierr;
27082cf14000SStefano Zampini   HYPRE_Int      oits;
2709d851a50bSGlenn Hammond 
2710d851a50bSGlenn Hammond   PetscFunctionBegin;
2711dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2712*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,jac->ss_solver,its*jac->its);
2713*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,jac->ss_solver,rtol);
2714d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
2715*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,jac->ss_solver,&oits);
2716d851a50bSGlenn Hammond   *outits = oits;
2717d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2718d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2719*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,jac->ss_solver,jac->tol);
2720*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,jac->ss_solver,jac->its);
2721d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2722d851a50bSGlenn Hammond }
2723d851a50bSGlenn Hammond 
2724d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2725d851a50bSGlenn Hammond {
2726d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2727d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2728d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2729ace3abfcSBarry Smith   PetscBool        flg;
2730d851a50bSGlenn Hammond 
2731d851a50bSGlenn Hammond   PetscFunctionBegin;
2732251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
27339ace16cdSJacob Faibussowitsch   PetscAssertFalse(!flg,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2734d851a50bSGlenn Hammond 
2735d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
2736*a74df02fSJacob Faibussowitsch   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,ex->ss_solver);
2737*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,ex->hcomm,&ex->ss_solver);
2738*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,ex->ss_solver);
2739*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x);
2740d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2741d851a50bSGlenn Hammond }
2742d851a50bSGlenn Hammond 
2743d851a50bSGlenn Hammond /*MC
2744d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2745d851a50bSGlenn Hammond 
2746d851a50bSGlenn Hammond    Level: advanced
2747d851a50bSGlenn Hammond 
2748d851a50bSGlenn Hammond    Options Database:
2749d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2750d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2751d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2752d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2753a2b725a8SWilliam Gropp - -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2754d851a50bSGlenn Hammond 
275595452b02SPatrick Sanan    Notes:
275695452b02SPatrick Sanan     This is for CELL-centered descretizations
2757d851a50bSGlenn Hammond 
2758f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2759aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2760d851a50bSGlenn Hammond            Also, only cell-centered variables.
2761d851a50bSGlenn Hammond 
2762d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2763d851a50bSGlenn Hammond M*/
2764d851a50bSGlenn Hammond 
27658cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2766d851a50bSGlenn Hammond {
2767d851a50bSGlenn Hammond   PetscErrorCode ierr;
2768d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2769d851a50bSGlenn Hammond 
2770d851a50bSGlenn Hammond   PetscFunctionBegin;
2771b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2772d851a50bSGlenn Hammond   pc->data = ex;
2773d851a50bSGlenn Hammond 
2774d851a50bSGlenn Hammond   ex->its            = 1;
2775d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2776d851a50bSGlenn Hammond   ex->relax_type     = 1;
2777d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2778d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2779d851a50bSGlenn Hammond 
2780d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2781d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2782d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2783d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2784d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2785d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
27862fa5cd67SKarl Rupp 
278757f21012SBarry Smith   ierr = PetscCommGetComm(PetscObjectComm((PetscObject)pc),&ex->hcomm);CHKERRQ(ierr);
2788*a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,ex->hcomm,&ex->ss_solver);
2789d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2790d851a50bSGlenn Hammond }
2791