xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 28b400f66ebc7ae0049166a2294dfcd3df27e64b)
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   PetscInt             num_levels,l;
1648a2c336bSFande Kong   Mat                  *mattmp;
1658a2c336bSFande Kong   hypre_ParCSRMatrix   **A_array;
1668a2c336bSFande Kong 
1678a2c336bSFande Kong   PetscFunctionBegin;
1685f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscStrcmp(jac->hypre_type,"boomeramg",&same));
1695f80ce2aSJacob Faibussowitsch   PetscCheck(same,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_NOTSAMETYPE,"Hypre type is not BoomerAMG ");
1708a2c336bSFande Kong   num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData*) (jac->hsolver));
1715f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscMalloc1(num_levels,&mattmp));
1728a2c336bSFande Kong   A_array    = hypre_ParAMGDataAArray((hypre_ParAMGData*) (jac->hsolver));
1738a2c336bSFande Kong   for (l=1; l<num_levels; l++) {
1745f80ce2aSJacob Faibussowitsch     CHKERRQ(MatCreateFromParCSR(A_array[l],MATAIJ,PETSC_OWN_POINTER, &(mattmp[num_levels-1-l])));
1758a2c336bSFande Kong     /* We want to own the data, and HYPRE can not touch this matrix any more */
1768a2c336bSFande Kong     A_array[l] = NULL;
1778a2c336bSFande Kong   }
1788a2c336bSFande Kong   *nlevels = num_levels;
1798a2c336bSFande Kong   *operators = mattmp;
1808a2c336bSFande Kong   PetscFunctionReturn(0);
1818a2c336bSFande Kong }
1828a2c336bSFande Kong 
183fd2dd295SFande Kong /*
1848a2c336bSFande Kong   Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix
1858a2c336bSFande Kong   is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine.
1868a2c336bSFande Kong   It is used in PCHMG. Other users should avoid using this function.
187fd2dd295SFande Kong */
188fd2dd295SFande Kong static PetscErrorCode PCGetInterpolations_BoomerAMG(PC pc,PetscInt *nlevels,Mat *interpolations[])
1898a2c336bSFande Kong {
1908a2c336bSFande Kong   PC_HYPRE             *jac  = (PC_HYPRE*)pc->data;
1918a2c336bSFande Kong   PetscBool            same = PETSC_FALSE;
1928a2c336bSFande Kong   PetscInt             num_levels,l;
1938a2c336bSFande Kong   Mat                  *mattmp;
1948a2c336bSFande Kong   hypre_ParCSRMatrix   **P_array;
1958a2c336bSFande Kong 
1968a2c336bSFande Kong   PetscFunctionBegin;
1975f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscStrcmp(jac->hypre_type,"boomeramg",&same));
1985f80ce2aSJacob Faibussowitsch   PetscCheck(same,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_NOTSAMETYPE,"Hypre type is not BoomerAMG ");
1998a2c336bSFande Kong   num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData*) (jac->hsolver));
2005f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscMalloc1(num_levels,&mattmp));
2018a2c336bSFande Kong   P_array  = hypre_ParAMGDataPArray((hypre_ParAMGData*) (jac->hsolver));
2028a2c336bSFande Kong   for (l=1; l<num_levels; l++) {
2035f80ce2aSJacob Faibussowitsch     CHKERRQ(MatCreateFromParCSR(P_array[num_levels-1-l],MATAIJ,PETSC_OWN_POINTER, &(mattmp[l-1])));
2048a2c336bSFande Kong     /* We want to own the data, and HYPRE can not touch this matrix any more */
2058a2c336bSFande Kong     P_array[num_levels-1-l] = NULL;
2068a2c336bSFande Kong   }
2078a2c336bSFande Kong   *nlevels = num_levels;
2088a2c336bSFande Kong   *interpolations = mattmp;
2098a2c336bSFande Kong   PetscFunctionReturn(0);
2108a2c336bSFande Kong }
2118a2c336bSFande Kong 
212ce6a8a0dSJed Brown /* Resets (frees) Hypre's representation of the near null space */
213ce6a8a0dSJed Brown static PetscErrorCode PCHYPREResetNearNullSpace_Private(PC pc)
214ce6a8a0dSJed Brown {
215ce6a8a0dSJed Brown   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
216ce6a8a0dSJed Brown   PetscInt       i;
217ce6a8a0dSJed Brown 
2189d678128SJed Brown   PetscFunctionBegin;
219ce6a8a0dSJed Brown   for (i=0; i<jac->n_hmnull; i++) {
2205f80ce2aSJacob Faibussowitsch     CHKERRQ(VecHYPRE_IJVectorDestroy(&jac->hmnull[i]));
221ce6a8a0dSJed Brown   }
2225f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(jac->hmnull));
2235f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(jac->phmnull));
2245f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&jac->hmnull_constant));
2259d678128SJed Brown   jac->n_hmnull = 0;
226ce6a8a0dSJed Brown   PetscFunctionReturn(0);
227ce6a8a0dSJed Brown }
228ce6a8a0dSJed Brown 
22916d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
23016d9e3a6SLisandro Dalcin {
23116d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
23249a781f5SStefano Zampini   Mat_HYPRE          *hjac;
23316d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
23416d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
23549a781f5SStefano Zampini   PetscBool          ishypre;
23616d9e3a6SLisandro Dalcin 
23716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
23816d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
2395f80ce2aSJacob Faibussowitsch     CHKERRQ(PCHYPRESetType(pc,"boomeramg"));
24016d9e3a6SLisandro Dalcin   }
2415f5c5b43SBarry Smith 
2425f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRE,&ishypre));
24349a781f5SStefano Zampini   if (!ishypre) {
2445f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&jac->hpmat));
2455f80ce2aSJacob Faibussowitsch     CHKERRQ(MatConvert(pc->pmat,MATHYPRE,MAT_INITIAL_MATRIX,&jac->hpmat));
2465f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscLogObjectParent((PetscObject)pc,(PetscObject)jac->hpmat));
24749a781f5SStefano Zampini   } else {
2485f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscObjectReference((PetscObject)pc->pmat));
2495f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&jac->hpmat));
25049a781f5SStefano Zampini     jac->hpmat = pc->pmat;
25116d9e3a6SLisandro Dalcin   }
2526ea7df73SStefano Zampini   /* allow debug */
2535f80ce2aSJacob Faibussowitsch   CHKERRQ(MatViewFromOptions(jac->hpmat,NULL,"-pc_hypre_mat_view"));
25449a781f5SStefano Zampini   hjac = (Mat_HYPRE*)(jac->hpmat->data);
2555f5c5b43SBarry Smith 
25616d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
25716d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
2585272c319SBarry Smith     MatNullSpace mnull;
2595272c319SBarry Smith     PetscBool    has_const;
26049a781f5SStefano Zampini     PetscInt     bs,nvec,i;
2615272c319SBarry Smith     const Vec    *vecs;
2625272c319SBarry Smith 
2635f80ce2aSJacob Faibussowitsch     CHKERRQ(MatGetBlockSize(pc->pmat,&bs));
264a74df02fSJacob Faibussowitsch     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,jac->hsolver,bs);
2655f80ce2aSJacob Faibussowitsch     CHKERRQ(MatGetNearNullSpace(pc->mat, &mnull));
2665272c319SBarry Smith     if (mnull) {
2675f80ce2aSJacob Faibussowitsch       CHKERRQ(PCHYPREResetNearNullSpace_Private(pc));
2685f80ce2aSJacob Faibussowitsch       CHKERRQ(MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs));
2695f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscMalloc1(nvec+1,&jac->hmnull));
2705f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscMalloc1(nvec+1,&jac->phmnull));
2715272c319SBarry Smith       for (i=0; i<nvec; i++) {
2725f80ce2aSJacob Faibussowitsch         CHKERRQ(VecHYPRE_IJVectorCreate(vecs[i]->map,&jac->hmnull[i]));
2735f80ce2aSJacob Faibussowitsch         CHKERRQ(VecHYPRE_IJVectorCopy(vecs[i],jac->hmnull[i]));
274a74df02fSJacob Faibussowitsch         PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->hmnull[i]->ij,(void**)&jac->phmnull[i]);
2755272c319SBarry Smith       }
2765272c319SBarry Smith       if (has_const) {
2775f80ce2aSJacob Faibussowitsch         CHKERRQ(MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL));
2785f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscLogObjectParent((PetscObject)pc,(PetscObject)jac->hmnull_constant));
2795f80ce2aSJacob Faibussowitsch         CHKERRQ(VecSet(jac->hmnull_constant,1));
2805f80ce2aSJacob Faibussowitsch         CHKERRQ(VecNormalize(jac->hmnull_constant,NULL));
2815f80ce2aSJacob Faibussowitsch         CHKERRQ(VecHYPRE_IJVectorCreate(jac->hmnull_constant->map,&jac->hmnull[nvec]));
2825f80ce2aSJacob Faibussowitsch         CHKERRQ(VecHYPRE_IJVectorCopy(jac->hmnull_constant,jac->hmnull[nvec]));
283a74df02fSJacob Faibussowitsch         PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->hmnull[nvec]->ij,(void**)&jac->phmnull[nvec]);
2845272c319SBarry Smith         nvec++;
2855272c319SBarry Smith       }
286a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVectors,jac->hsolver,nvec,jac->phmnull);
2875272c319SBarry Smith       jac->n_hmnull = nvec;
2885272c319SBarry Smith     }
2894cb006feSStefano Zampini   }
290863406b8SStefano Zampini 
2914cb006feSStefano Zampini   /* special case for AMS */
2924cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
2935ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2945ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
2956bf688a0SCe Qin     if (!jac->coords[0] && !jac->constants[0] && !(jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
2966bf688a0SCe 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");
2976bf688a0SCe Qin     }
2985ac14e1cSStefano Zampini     if (jac->dim) {
299a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_AMSSetDimension,jac->hsolver,jac->dim);
3005ac14e1cSStefano Zampini     }
3015ac14e1cSStefano Zampini     if (jac->constants[0]) {
3025ac14e1cSStefano Zampini       HYPRE_ParVector ozz,zoz,zzo = NULL;
303a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->constants[0]->ij,(void**)(&ozz));
304a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->constants[1]->ij,(void**)(&zoz));
3055ac14e1cSStefano Zampini       if (jac->constants[2]) {
306a74df02fSJacob Faibussowitsch         PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->constants[2]->ij,(void**)(&zzo));
3075ac14e1cSStefano Zampini       }
308a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,jac->hsolver,ozz,zoz,zzo);
3095ac14e1cSStefano Zampini     }
3105ac14e1cSStefano Zampini     if (jac->coords[0]) {
3115ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
3125ac14e1cSStefano Zampini       coords[0] = NULL;
3135ac14e1cSStefano Zampini       coords[1] = NULL;
3145ac14e1cSStefano Zampini       coords[2] = NULL;
315a74df02fSJacob Faibussowitsch       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->coords[0]->ij,(void**)(&coords[0]));
316a74df02fSJacob Faibussowitsch       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->coords[1]->ij,(void**)(&coords[1]));
317a74df02fSJacob Faibussowitsch       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->coords[2]->ij,(void**)(&coords[2]));
318a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,jac->hsolver,coords[0],coords[1],coords[2]);
3195ac14e1cSStefano Zampini     }
3205f80ce2aSJacob Faibussowitsch     PetscCheck(jac->G,PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
3215ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
322a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr));
323a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,jac->hsolver,parcsr);
3245ac14e1cSStefano Zampini     if (jac->alpha_Poisson) {
3255ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->alpha_Poisson->data);
326a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr));
327a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,jac->hsolver,parcsr);
3285ac14e1cSStefano Zampini     }
3295ac14e1cSStefano Zampini     if (jac->ams_beta_is_zero) {
330a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,jac->hsolver,NULL);
3315ac14e1cSStefano Zampini     } else if (jac->beta_Poisson) {
3325ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->beta_Poisson->data);
333a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr));
334a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,jac->hsolver,parcsr);
3355ac14e1cSStefano Zampini     }
3366bf688a0SCe Qin     if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) {
3376bf688a0SCe Qin       PetscInt           i;
3386bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
3396bf688a0SCe Qin       if (jac->ND_PiFull) {
3406bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
341a74df02fSJacob Faibussowitsch         PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&nd_parcsrfull));
3426bf688a0SCe Qin       } else {
3436bf688a0SCe Qin         nd_parcsrfull = NULL;
3446bf688a0SCe Qin       }
3456bf688a0SCe Qin       for (i=0;i<3;++i) {
3466bf688a0SCe Qin         if (jac->ND_Pi[i]) {
3476bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
348a74df02fSJacob Faibussowitsch           PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&nd_parcsr[i]));
3496bf688a0SCe Qin         } else {
3506bf688a0SCe Qin           nd_parcsr[i] = NULL;
3516bf688a0SCe Qin         }
3526bf688a0SCe Qin       }
353a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_AMSSetInterpolations,jac->hsolver,nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]);
3546bf688a0SCe Qin     }
3554cb006feSStefano Zampini   }
356863406b8SStefano Zampini   /* special case for ADS */
357863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
3585ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
3595ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
3606bf688a0SCe 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])))) {
3616bf688a0SCe Qin       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations");
3626bf688a0SCe Qin     }
3632c71b3e2SJacob Faibussowitsch     else PetscCheckFalse(!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");
3645f80ce2aSJacob Faibussowitsch     PetscCheck(jac->G,PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
3655f80ce2aSJacob Faibussowitsch     PetscCheck(jac->C,PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient");
3665ac14e1cSStefano Zampini     if (jac->coords[0]) {
3675ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
3685ac14e1cSStefano Zampini       coords[0] = NULL;
3695ac14e1cSStefano Zampini       coords[1] = NULL;
3705ac14e1cSStefano Zampini       coords[2] = NULL;
371a74df02fSJacob Faibussowitsch       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->coords[0]->ij,(void**)(&coords[0]));
372a74df02fSJacob Faibussowitsch       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->coords[1]->ij,(void**)(&coords[1]));
373a74df02fSJacob Faibussowitsch       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,jac->coords[2]->ij,(void**)(&coords[2]));
374a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_ADSSetCoordinateVectors,jac->hsolver,coords[0],coords[1],coords[2]);
3755ac14e1cSStefano Zampini     }
3765ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
377a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr));
378a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetDiscreteGradient,jac->hsolver,parcsr);
3795ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->C->data);
380a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr));
381a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetDiscreteCurl,jac->hsolver,parcsr);
3826bf688a0SCe Qin     if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
3836bf688a0SCe Qin       PetscInt           i;
3846bf688a0SCe Qin       HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3];
3856bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
3866bf688a0SCe Qin       if (jac->RT_PiFull) {
3876bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->RT_PiFull->data);
388a74df02fSJacob Faibussowitsch         PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&rt_parcsrfull));
3896bf688a0SCe Qin       } else {
3906bf688a0SCe Qin         rt_parcsrfull = NULL;
3916bf688a0SCe Qin       }
3926bf688a0SCe Qin       for (i=0;i<3;++i) {
3936bf688a0SCe Qin         if (jac->RT_Pi[i]) {
3946bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->RT_Pi[i]->data);
395a74df02fSJacob Faibussowitsch           PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&rt_parcsr[i]));
3966bf688a0SCe Qin         } else {
3976bf688a0SCe Qin           rt_parcsr[i] = NULL;
3986bf688a0SCe Qin         }
3996bf688a0SCe Qin       }
4006bf688a0SCe Qin       if (jac->ND_PiFull) {
4016bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
402a74df02fSJacob Faibussowitsch         PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&nd_parcsrfull));
4036bf688a0SCe Qin       } else {
4046bf688a0SCe Qin         nd_parcsrfull = NULL;
4056bf688a0SCe Qin       }
4066bf688a0SCe Qin       for (i=0;i<3;++i) {
4076bf688a0SCe Qin         if (jac->ND_Pi[i]) {
4086bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
409a74df02fSJacob Faibussowitsch           PetscStackCallStandard(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&nd_parcsr[i]));
4106bf688a0SCe Qin         } else {
4116bf688a0SCe Qin           nd_parcsr[i] = NULL;
4126bf688a0SCe Qin         }
4136bf688a0SCe Qin       }
414a74df02fSJacob 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]);
4156bf688a0SCe Qin     }
416863406b8SStefano Zampini   }
417a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_IJMatrixGetObject,hjac->ij,(void**)&hmat);
418a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_IJVectorGetObject,hjac->b->ij,(void**)&bv);
419a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_IJVectorGetObject,hjac->x->ij,(void**)&xv);
420a74df02fSJacob Faibussowitsch   PetscStackCallStandard(jac->setup,jac->hsolver,hmat,bv,xv);
42116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
42216d9e3a6SLisandro Dalcin }
42316d9e3a6SLisandro Dalcin 
42416d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
42516d9e3a6SLisandro Dalcin {
42616d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
42749a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
42816d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
42916d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
43016d9e3a6SLisandro Dalcin 
43116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
4325f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCitationsRegister(hypreCitation,&cite));
4335f80ce2aSJacob Faibussowitsch   if (!jac->applyrichardson) CHKERRQ(VecSet(x,0.0));
4345f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorPushVecRead(hjac->b,b));
4355f80ce2aSJacob Faibussowitsch   if (jac->applyrichardson) CHKERRQ(VecHYPRE_IJVectorPushVec(hjac->x,x));
4365f80ce2aSJacob Faibussowitsch   else CHKERRQ(VecHYPRE_IJVectorPushVecWrite(hjac->x,x));
437a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_IJMatrixGetObject,hjac->ij,(void**)&hmat);
438a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_IJVectorGetObject,hjac->b->ij,(void**)&jbv);
439a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_IJVectorGetObject,hjac->x->ij,(void**)&jxv);
4405f80ce2aSJacob Faibussowitsch   PetscStackCall("Hypre solve",do {
4415f80ce2aSJacob Faibussowitsch       HYPRE_Int hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
4425f80ce2aSJacob Faibussowitsch       if (hierr) {
4435f80ce2aSJacob Faibussowitsch         PetscCheck(hierr == HYPRE_ERROR_CONV,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",(int)hierr);
4445f80ce2aSJacob Faibussowitsch         hypre__global_error = 0;
4455f80ce2aSJacob Faibussowitsch       }
4465f80ce2aSJacob Faibussowitsch     } while (0));
44716d9e3a6SLisandro Dalcin 
44823df4f25SStefano Zampini   if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) {
449a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSProjectOutGradients,jac->hsolver,jxv);
45021df291bSStefano Zampini   }
4515f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorPopVec(hjac->x));
4525f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorPopVec(hjac->b));
45316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
45416d9e3a6SLisandro Dalcin }
45516d9e3a6SLisandro Dalcin 
4568695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc)
4578695de01SBarry Smith {
4588695de01SBarry Smith   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
4598695de01SBarry Smith 
4608695de01SBarry Smith   PetscFunctionBegin;
4615f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&jac->hpmat));
4625f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&jac->G));
4635f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&jac->C));
4645f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&jac->alpha_Poisson));
4655f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&jac->beta_Poisson));
4665f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&jac->RT_PiFull));
4675f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&jac->RT_Pi[0]));
4685f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&jac->RT_Pi[1]));
4695f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&jac->RT_Pi[2]));
4705f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&jac->ND_PiFull));
4715f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&jac->ND_Pi[0]));
4725f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&jac->ND_Pi[1]));
4735f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&jac->ND_Pi[2]));
4745f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorDestroy(&jac->coords[0]));
4755f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorDestroy(&jac->coords[1]));
4765f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorDestroy(&jac->coords[2]));
4775f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorDestroy(&jac->constants[0]));
4785f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorDestroy(&jac->constants[1]));
4795f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorDestroy(&jac->constants[2]));
4805f80ce2aSJacob Faibussowitsch   CHKERRQ(PCHYPREResetNearNullSpace_Private(pc));
4815ac14e1cSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
4825ac14e1cSStefano Zampini   jac->dim = 0;
4838695de01SBarry Smith   PetscFunctionReturn(0);
4848695de01SBarry Smith }
4858695de01SBarry Smith 
48616d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
48716d9e3a6SLisandro Dalcin {
48816d9e3a6SLisandro Dalcin   PC_HYPRE                 *jac = (PC_HYPRE*)pc->data;
48916d9e3a6SLisandro Dalcin 
49016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
4915f80ce2aSJacob Faibussowitsch   CHKERRQ(PCReset_HYPRE(pc));
492a74df02fSJacob Faibussowitsch   if (jac->destroy) PetscStackCallStandard(jac->destroy,jac->hsolver);
4935f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(jac->hypre_type));
494db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0)
4955f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(jac->spgemm_type));
496db6f9c32SMark Adams #endif
4975f80ce2aSJacob Faibussowitsch   if (jac->comm_hypre != MPI_COMM_NULL) CHKERRQ(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre));
4985f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(pc->data));
49916d9e3a6SLisandro Dalcin 
5005f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectChangeTypeName((PetscObject)pc,0));
5015f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL));
5025f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL));
5035f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL));
5045f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL));
5055f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL));
5065f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",NULL));
5075f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL));
5085f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",NULL));
5095f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",NULL));
5105f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",NULL));
5115f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinSetMatProductAlgorithm_C",NULL));
5125f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinGetMatProductAlgorithm_C",NULL));
513db6f9c32SMark Adams 
51416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
51516d9e3a6SLisandro Dalcin }
51616d9e3a6SLisandro Dalcin 
51716d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
5184416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptionItems *PetscOptionsObject,PC pc)
51916d9e3a6SLisandro Dalcin {
52016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
521ace3abfcSBarry Smith   PetscBool      flag;
52216d9e3a6SLisandro Dalcin 
52316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
5245f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options"));
5255f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag));
526a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,jac->hsolver,jac->maxiter);
5275f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag));
528a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,jac->hsolver,jac->tol);
5295f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag));
530a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,jac->hsolver,jac->factorrowsize);
5315f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsTail());
53216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
53316d9e3a6SLisandro Dalcin }
53416d9e3a6SLisandro Dalcin 
53516d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
53616d9e3a6SLisandro Dalcin {
53716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
538ace3abfcSBarry Smith   PetscBool      iascii;
53916d9e3a6SLisandro Dalcin 
54016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
5415f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
54216d9e3a6SLisandro Dalcin   if (iascii) {
5435f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n"));
54416d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
5455f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    maximum number of iterations %d\n",jac->maxiter));
54616d9e3a6SLisandro Dalcin     } else {
5475f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    default maximum number of iterations \n"));
54816d9e3a6SLisandro Dalcin     }
54916d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
5505f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->tol));
55116d9e3a6SLisandro Dalcin     } else {
5525f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    default drop tolerance \n"));
55316d9e3a6SLisandro Dalcin     }
55416d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
5555f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    factor row size %d\n",jac->factorrowsize));
55616d9e3a6SLisandro Dalcin     } else {
5575f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    default factor row size \n"));
55816d9e3a6SLisandro Dalcin     }
55916d9e3a6SLisandro Dalcin   }
56016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
56116d9e3a6SLisandro Dalcin }
56216d9e3a6SLisandro Dalcin 
56316d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
564db966c6cSHong Zhang static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PetscOptionItems *PetscOptionsObject,PC pc)
565db966c6cSHong Zhang {
566db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
5678bf83915SBarry Smith   PetscBool      flag,eu_bj = jac->eu_bj ? PETSC_TRUE : PETSC_FALSE;
568db966c6cSHong Zhang 
569db966c6cSHong Zhang   PetscFunctionBegin;
5705f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsHead(PetscOptionsObject,"HYPRE Euclid Options"));
5715f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_euclid_level","Factorization levels","None",jac->eu_level,&jac->eu_level,&flag));
572a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_EuclidSetLevel,jac->hsolver,jac->eu_level);
5738bf83915SBarry Smith 
5745f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-pc_hypre_euclid_droptolerance","Drop tolerance for ILU(k) in Euclid","None",jac->eu_droptolerance,&jac->eu_droptolerance,&flag));
5758bf83915SBarry Smith   if (flag) {
5768bf83915SBarry Smith     PetscMPIInt size;
5778bf83915SBarry Smith 
5785f80ce2aSJacob Faibussowitsch     CHKERRMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size));
5792c71b3e2SJacob Faibussowitsch     PetscCheckFalse(size > 1,PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"hypre's Euclid does not support a parallel drop tolerance");
580a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_EuclidSetILUT,jac->hsolver,jac->eu_droptolerance);
5818bf83915SBarry Smith   }
5828bf83915SBarry Smith 
5835f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsBool("-pc_hypre_euclid_bj", "Use Block Jacobi for ILU in Euclid", "None", eu_bj,&eu_bj,&flag));
5848bf83915SBarry Smith   if (flag) {
5858bf83915SBarry Smith     jac->eu_bj = eu_bj ? 1 : 0;
586a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_EuclidSetBJ,jac->hsolver,jac->eu_bj);
5878bf83915SBarry Smith   }
5885f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsTail());
589db966c6cSHong Zhang   PetscFunctionReturn(0);
590db966c6cSHong Zhang }
591db966c6cSHong Zhang 
592db966c6cSHong Zhang static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer)
593db966c6cSHong Zhang {
594db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
595db966c6cSHong Zhang   PetscBool      iascii;
596db966c6cSHong Zhang 
597db966c6cSHong Zhang   PetscFunctionBegin;
5985f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
599db966c6cSHong Zhang   if (iascii) {
6005f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid preconditioning\n"));
601db966c6cSHong Zhang     if (jac->eu_level != PETSC_DEFAULT) {
6025f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    factorization levels %d\n",jac->eu_level));
603db966c6cSHong Zhang     } else {
6045f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    default factorization levels \n"));
605db966c6cSHong Zhang     }
6065f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->eu_droptolerance));
6075f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    use Block-Jacobi? %D\n",jac->eu_bj));
608db966c6cSHong Zhang   }
609db966c6cSHong Zhang   PetscFunctionReturn(0);
610db966c6cSHong Zhang }
611db966c6cSHong Zhang 
612db966c6cSHong Zhang /* --------------------------------------------------------------------------------------------*/
61316d9e3a6SLisandro Dalcin 
61416d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
61516d9e3a6SLisandro Dalcin {
61616d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
61749a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
61816d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
61916d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
62016d9e3a6SLisandro Dalcin 
62116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
6225f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCitationsRegister(hypreCitation,&cite));
6235f80ce2aSJacob Faibussowitsch   CHKERRQ(VecSet(x,0.0));
6245f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorPushVecRead(hjac->x,b));
6255f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorPushVecWrite(hjac->b,x));
62616d9e3a6SLisandro Dalcin 
627a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_IJMatrixGetObject,hjac->ij,(void**)&hmat);
628a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_IJVectorGetObject,hjac->b->ij,(void**)&jbv);
629a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_IJVectorGetObject,hjac->x->ij,(void**)&jxv);
63016d9e3a6SLisandro Dalcin 
6315f80ce2aSJacob Faibussowitsch   PetscStackCall("Hypre Transpose solve",do {
6325f80ce2aSJacob Faibussowitsch       HYPRE_Int hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
6335f80ce2aSJacob Faibussowitsch       if (hierr) {
63416d9e3a6SLisandro Dalcin         /* error code of 1 in BoomerAMG merely means convergence not achieved */
6355f80ce2aSJacob Faibussowitsch         PetscCheck(hierr == 1,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",(int)hierr);
6365f80ce2aSJacob Faibussowitsch         hypre__global_error = 0;
6375f80ce2aSJacob Faibussowitsch       }
6385f80ce2aSJacob Faibussowitsch     } while (0));
63916d9e3a6SLisandro Dalcin 
6405f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorPopVec(hjac->x));
6415f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorPopVec(hjac->b));
64216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
64316d9e3a6SLisandro Dalcin }
64416d9e3a6SLisandro Dalcin 
645a669f990SJed Brown /* static array length */
646a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
647a669f990SJed Brown 
648db6f9c32SMark Adams static PetscErrorCode PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc,const char name[])
649db6f9c32SMark Adams {
650db6f9c32SMark Adams   PC_HYPRE *jac  = (PC_HYPRE*)pc->data;
651db6f9c32SMark Adams   PetscBool      flag;
652db6f9c32SMark Adams 
653db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0)
654db6f9c32SMark Adams   PetscFunctionBegin;
655db6f9c32SMark Adams   if (jac->spgemm_type) {
6565f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrcmp(jac->spgemm_type,name,&flag));
657*28b400f6SJacob Faibussowitsch     PetscCheck(flag,PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE SpGEMM (really we can)");
658db6f9c32SMark Adams     PetscFunctionReturn(0);
659db6f9c32SMark Adams   } else {
6605f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrallocpy(name, &jac->spgemm_type));
661db6f9c32SMark Adams   }
6625f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscStrcmp("cusparse",jac->spgemm_type,&flag));
663db6f9c32SMark Adams   if (flag) {
664a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SetSpGemmUseCusparse,1);
665db6f9c32SMark Adams     PetscFunctionReturn(0);
666db6f9c32SMark Adams   }
6675f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscStrcmp("hypre",jac->spgemm_type,&flag));
668db6f9c32SMark Adams   if (flag) {
669a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SetSpGemmUseCusparse,0);
670db6f9c32SMark Adams     PetscFunctionReturn(0);
671db6f9c32SMark Adams   }
672db6f9c32SMark Adams   jac->spgemm_type = NULL;
67398921bdaSJacob Faibussowitsch   SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE SpGEM type %s; Choices are cusparse, hypre",name);
674db6f9c32SMark Adams #endif
675db6f9c32SMark Adams }
676db6f9c32SMark Adams 
677db6f9c32SMark Adams static PetscErrorCode PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc, const char *spgemm[])
678db6f9c32SMark Adams {
679db6f9c32SMark Adams   PC_HYPRE *jac  = (PC_HYPRE*)pc->data;
680db6f9c32SMark Adams 
681db6f9c32SMark Adams   PetscFunctionBegin;
682db6f9c32SMark Adams   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
683db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0)
684db6f9c32SMark Adams   *spgemm = jac->spgemm_type;
685db6f9c32SMark Adams #endif
686db6f9c32SMark Adams   PetscFunctionReturn(0);
687db6f9c32SMark Adams }
688db6f9c32SMark Adams 
68916d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
6900f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
69116d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
69265de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
6936a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]  = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
69465de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
69565de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
69665de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
6977b7fa87dSPierre Jolivet                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "l1-Gauss-Seidel" /* nonsymmetric */, "backward-l1-Gauss-Seidel" /* nonsymmetric */,
69865de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
6990f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
700589dcaf0SStefano Zampini                                                   "ext+i-cc", "standard", "standard-wts", "block", "block-wtd", "FF", "FF1",
701589dcaf0SStefano Zampini                                                   "ext", "ad-wts", "ext-mm", "ext+i-mm", "ext+e-mm"};
7024416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc)
70316d9e3a6SLisandro Dalcin {
70416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
70522e51d31SStefano Zampini   PetscInt       bs,n,indx,level;
706ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
70716d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
708589dcaf0SStefano Zampini   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
709db6f9c32SMark Adams   const char     *PCHYPRESpgemmTypes[] = {"cusparse","hypre"};
71016d9e3a6SLisandro Dalcin 
71116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
7125f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options"));
7135f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg));
71416d9e3a6SLisandro Dalcin   if (flg) {
7154336a9eeSBarry Smith     jac->cycletype = indx+1;
716a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,jac->hsolver,jac->cycletype);
71716d9e3a6SLisandro Dalcin   }
7185f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg));
71916d9e3a6SLisandro Dalcin   if (flg) {
7202c71b3e2SJacob Faibussowitsch     PetscCheckFalse(jac->maxlevels < 2,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
721a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,jac->hsolver,jac->maxlevels);
72216d9e3a6SLisandro Dalcin   }
7235f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg));
72416d9e3a6SLisandro Dalcin   if (flg) {
7252c71b3e2SJacob Faibussowitsch     PetscCheckFalse(jac->maxiter < 1,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
726a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,jac->maxiter);
72716d9e3a6SLisandro Dalcin   }
7285f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-pc_hypre_boomeramg_tol","Convergence tolerance PER hypre call (0.0 = use a fixed number of iterations)","None",jac->tol,&jac->tol,&flg));
72916d9e3a6SLisandro Dalcin   if (flg) {
7302c71b3e2SJacob Faibussowitsch     PetscCheckFalse(jac->tol < 0.0,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Tolerance %g must be greater than or equal to zero",(double)jac->tol);
731a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,jac->hsolver,jac->tol);
73216d9e3a6SLisandro Dalcin   }
73322e51d31SStefano Zampini   bs = 1;
73422e51d31SStefano Zampini   if (pc->pmat) {
7355f80ce2aSJacob Faibussowitsch     CHKERRQ(MatGetBlockSize(pc->pmat,&bs));
73622e51d31SStefano Zampini   }
7375f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_numfunctions","Number of functions","HYPRE_BoomerAMGSetNumFunctions",bs,&bs,&flg));
73822e51d31SStefano Zampini   if (flg) {
739a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,jac->hsolver,bs);
74022e51d31SStefano Zampini   }
74116d9e3a6SLisandro Dalcin 
7425f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg));
74316d9e3a6SLisandro Dalcin   if (flg) {
7442c71b3e2SJacob Faibussowitsch     PetscCheckFalse(jac->truncfactor < 0.0,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Truncation factor %g must be great than or equal zero",(double)jac->truncfactor);
745a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,jac->hsolver,jac->truncfactor);
74616d9e3a6SLisandro Dalcin   }
74716d9e3a6SLisandro Dalcin 
7485f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_P_max","Max elements per row for interpolation operator (0=unlimited)","None",jac->pmax,&jac->pmax,&flg));
7490f1074feSSatish Balay   if (flg) {
7502c71b3e2SJacob Faibussowitsch     PetscCheckFalse(jac->pmax < 0,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"P_max %D must be greater than or equal to zero",jac->pmax);
751a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,jac->hsolver,jac->pmax);
7520f1074feSSatish Balay   }
7530f1074feSSatish Balay 
7545f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsRangeInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg,0,jac->maxlevels));
755a74df02fSJacob Faibussowitsch   if (flg) PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,jac->hsolver,jac->agg_nl);
7560f1074feSSatish Balay 
7575f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_agg_num_paths","Number of paths for aggressive coarsening","None",jac->agg_num_paths,&jac->agg_num_paths,&flg));
7580f1074feSSatish Balay   if (flg) {
7592c71b3e2SJacob Faibussowitsch     PetscCheckFalse(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);
760a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,jac->hsolver,jac->agg_num_paths);
7610f1074feSSatish Balay   }
7620f1074feSSatish Balay 
7635f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg));
76416d9e3a6SLisandro Dalcin   if (flg) {
7652c71b3e2SJacob Faibussowitsch     PetscCheckFalse(jac->strongthreshold < 0.0,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Strong threshold %g must be great than or equal zero",(double)jac->strongthreshold);
766a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,jac->hsolver,jac->strongthreshold);
76716d9e3a6SLisandro Dalcin   }
7685f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg));
76916d9e3a6SLisandro Dalcin   if (flg) {
7702c71b3e2SJacob Faibussowitsch     PetscCheckFalse(jac->maxrowsum < 0.0,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Maximum row sum %g must be greater than zero",(double)jac->maxrowsum);
7712c71b3e2SJacob Faibussowitsch     PetscCheckFalse(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);
772a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,jac->hsolver,jac->maxrowsum);
77316d9e3a6SLisandro Dalcin   }
77416d9e3a6SLisandro Dalcin 
77516d9e3a6SLisandro Dalcin   /* Grid sweeps */
7765f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_all","Number of sweeps for the up and down grid levels","None",jac->gridsweeps[0],&indx,&flg));
77716d9e3a6SLisandro Dalcin   if (flg) {
778a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,jac->hsolver,indx);
77916d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
78016d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
7810f1074feSSatish Balay     jac->gridsweeps[1] = indx;
7820f1074feSSatish Balay     /*defaults coarse to 1 */
7830f1074feSSatish Balay     jac->gridsweeps[2] = 1;
78416d9e3a6SLisandro Dalcin   }
7855f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_nodal_coarsen","Use a nodal based coarsening 1-6","HYPRE_BoomerAMGSetNodal",jac->nodal_coarsening,&jac->nodal_coarsening,&flg));
7865272c319SBarry Smith   if (flg) {
787a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,jac->hsolver,jac->nodal_coarsening);
7885272c319SBarry Smith   }
7895f80ce2aSJacob Faibussowitsch   CHKERRQ(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));
79022e51d31SStefano Zampini   if (flg) {
791a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetNodalDiag,jac->hsolver,jac->nodal_coarsening_diag);
79222e51d31SStefano Zampini   }
7935f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_vec_interp_variant","Variant of algorithm 1-3","HYPRE_BoomerAMGSetInterpVecVariant",jac->vec_interp_variant, &jac->vec_interp_variant,&flg));
7945272c319SBarry Smith   if (flg) {
795a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,jac->hsolver,jac->vec_interp_variant);
7965272c319SBarry Smith   }
7975f80ce2aSJacob Faibussowitsch   CHKERRQ(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));
79822e51d31SStefano Zampini   if (flg) {
799a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecQMax,jac->hsolver,jac->vec_interp_qmax);
80022e51d31SStefano Zampini   }
8015f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsBool("-pc_hypre_boomeramg_vec_interp_smooth","Whether to smooth the interpolation vectors","HYPRE_BoomerAMGSetSmoothInterpVectors",jac->vec_interp_smooth, &jac->vec_interp_smooth,&flg));
80222e51d31SStefano Zampini   if (flg) {
803a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothInterpVectors,jac->hsolver,jac->vec_interp_smooth);
80422e51d31SStefano Zampini   }
8055f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_interp_refine","Preprocess the interpolation matrix through iterative weight refinement","HYPRE_BoomerAMGSetInterpRefine",jac->interp_refine, &jac->interp_refine,&flg));
80622e51d31SStefano Zampini   if (flg) {
807a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpRefine,jac->hsolver,jac->interp_refine);
80822e51d31SStefano Zampini   }
8095f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg));
81016d9e3a6SLisandro Dalcin   if (flg) {
811a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,jac->hsolver,indx, 1);
8120f1074feSSatish Balay     jac->gridsweeps[0] = indx;
81316d9e3a6SLisandro Dalcin   }
8145f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg));
81516d9e3a6SLisandro Dalcin   if (flg) {
816a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,jac->hsolver,indx, 2);
8170f1074feSSatish Balay     jac->gridsweeps[1] = indx;
81816d9e3a6SLisandro Dalcin   }
8195f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg));
82016d9e3a6SLisandro Dalcin   if (flg) {
821a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,jac->hsolver,indx, 3);
8220f1074feSSatish Balay     jac->gridsweeps[2] = indx;
82316d9e3a6SLisandro Dalcin   }
82416d9e3a6SLisandro Dalcin 
8256a251517SEike Mueller   /* Smooth type */
8265f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg));
8276a251517SEike Mueller   if (flg) {
8286a251517SEike Mueller     jac->smoothtype = indx;
829a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,jac->hsolver,indx+6);
8308131ecf7SEike Mueller     jac->smoothnumlevels = 25;
831a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,jac->hsolver,25);
8328131ecf7SEike Mueller   }
8338131ecf7SEike Mueller 
8348131ecf7SEike Mueller   /* Number of smoothing levels */
8355f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_smooth_num_levels","Number of levels on which more complex smoothers are used","None",25,&indx,&flg));
8368131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
8378131ecf7SEike Mueller     jac->smoothnumlevels = indx;
838a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,jac->hsolver,indx);
8396a251517SEike Mueller   }
8406a251517SEike Mueller 
8411810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
8425f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg));
8431810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8441810e44eSEike Mueller     jac->eu_level = indx;
845a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,jac->hsolver,indx);
8461810e44eSEike Mueller   }
8471810e44eSEike Mueller 
8481810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
8491810e44eSEike Mueller   double droptolerance;
8505f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg));
8511810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8521810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
853a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,jac->hsolver,droptolerance);
8541810e44eSEike Mueller   }
8551810e44eSEike Mueller 
8561810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
8575f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg));
8581810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8591810e44eSEike Mueller     jac->eu_bj = tmp_truth;
860a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,jac->hsolver,jac->eu_bj);
8611810e44eSEike Mueller   }
8621810e44eSEike Mueller 
86316d9e3a6SLisandro Dalcin   /* Relax type */
8645f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsEList("-pc_hypre_boomeramg_relax_type_all","Relax type for the up and down cycles","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg));
86516d9e3a6SLisandro Dalcin   if (flg) {
8660f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
867a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,jac->hsolver, indx);
8680f1074feSSatish Balay     /* by default, coarse type set to 9 */
8690f1074feSSatish Balay     jac->relaxtype[2] = 9;
870a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, 9, 3);
87116d9e3a6SLisandro Dalcin   }
8725f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsEList("-pc_hypre_boomeramg_relax_type_down","Relax type for the down cycles","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg));
87316d9e3a6SLisandro Dalcin   if (flg) {
87416d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
875a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, indx, 1);
87616d9e3a6SLisandro Dalcin   }
8775f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsEList("-pc_hypre_boomeramg_relax_type_up","Relax type for the up cycles","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg));
87816d9e3a6SLisandro Dalcin   if (flg) {
8790f1074feSSatish Balay     jac->relaxtype[1] = indx;
880a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, indx, 2);
88116d9e3a6SLisandro Dalcin   }
8825f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg));
88316d9e3a6SLisandro Dalcin   if (flg) {
8840f1074feSSatish Balay     jac->relaxtype[2] = indx;
885a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, indx, 3);
88616d9e3a6SLisandro Dalcin   }
88716d9e3a6SLisandro Dalcin 
88816d9e3a6SLisandro Dalcin   /* Relaxation Weight */
8895f80ce2aSJacob Faibussowitsch   CHKERRQ(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));
89016d9e3a6SLisandro Dalcin   if (flg) {
891a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,jac->hsolver,tmpdbl);
89216d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
89316d9e3a6SLisandro Dalcin   }
89416d9e3a6SLisandro Dalcin 
89516d9e3a6SLisandro Dalcin   n         = 2;
89616d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
8975f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsRealArray("-pc_hypre_boomeramg_relax_weight_level","Set the relaxation weight for a particular level (weight,level)","None",twodbl, &n, &flg));
89816d9e3a6SLisandro Dalcin   if (flg) {
89916d9e3a6SLisandro Dalcin     if (n == 2) {
90016d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
901a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,jac->hsolver,twodbl[0],indx);
90298921bdaSJacob 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);
90316d9e3a6SLisandro Dalcin   }
90416d9e3a6SLisandro Dalcin 
90516d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
9065f80ce2aSJacob Faibussowitsch   CHKERRQ(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));
90716d9e3a6SLisandro Dalcin   if (flg) {
908a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,jac->hsolver, tmpdbl);
90916d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
91016d9e3a6SLisandro Dalcin   }
91116d9e3a6SLisandro Dalcin 
91216d9e3a6SLisandro Dalcin   n         = 2;
91316d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
9145f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsRealArray("-pc_hypre_boomeramg_outer_relax_weight_level","Set the outer relaxation weight for a particular level (weight,level)","None",twodbl, &n, &flg));
91516d9e3a6SLisandro Dalcin   if (flg) {
91616d9e3a6SLisandro Dalcin     if (n == 2) {
91716d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
918a74df02fSJacob Faibussowitsch       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,jac->hsolver, twodbl[0], indx);
91998921bdaSJacob 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);
92016d9e3a6SLisandro Dalcin   }
92116d9e3a6SLisandro Dalcin 
92216d9e3a6SLisandro Dalcin   /* the Relax Order */
9235f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg));
92416d9e3a6SLisandro Dalcin 
9258afaa268SBarry Smith   if (flg && tmp_truth) {
92616d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
927a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,jac->hsolver, jac->relaxorder);
92816d9e3a6SLisandro Dalcin   }
9295f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg));
93016d9e3a6SLisandro Dalcin   if (flg) {
93116d9e3a6SLisandro Dalcin     jac->measuretype = indx;
932a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,jac->hsolver,jac->measuretype);
93316d9e3a6SLisandro Dalcin   }
9340f1074feSSatish Balay   /* update list length 3/07 */
9355f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg));
93616d9e3a6SLisandro Dalcin   if (flg) {
93716d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
938a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,jac->hsolver,jac->coarsentype);
93916d9e3a6SLisandro Dalcin   }
9400f1074feSSatish Balay 
9415f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_max_coarse_size", "Maximum size of coarsest grid", "None", jac->maxc, &jac->maxc, &flg));
942589dcaf0SStefano Zampini   if (flg) {
943a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxCoarseSize,jac->hsolver, jac->maxc);
944589dcaf0SStefano Zampini   }
9455f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_min_coarse_size", "Minimum size of coarsest grid", "None", jac->minc, &jac->minc, &flg));
946589dcaf0SStefano Zampini   if (flg) {
947a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMinCoarseSize,jac->hsolver, jac->minc);
948589dcaf0SStefano Zampini   }
949db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0)
950db6f9c32SMark Adams   // global parameter but is closely associated with BoomerAMG
9515f80ce2aSJacob Faibussowitsch   CHKERRQ(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));
952db6f9c32SMark Adams   if (!flg) indx = 0;
9535f80ce2aSJacob Faibussowitsch   CHKERRQ(PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(pc,PCHYPRESpgemmTypes[indx]));
954db6f9c32SMark Adams #endif
955589dcaf0SStefano Zampini   /* AIR */
956589dcaf0SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0)
9575f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_restriction_type", "Type of AIR method (distance 1 or 2, 0 means no AIR)", "None", jac->Rtype, &jac->Rtype, NULL));
958a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_BoomerAMGSetRestriction,jac->hsolver,jac->Rtype);
959589dcaf0SStefano Zampini   if (jac->Rtype) {
960589dcaf0SStefano 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 */
961589dcaf0SStefano Zampini 
9625f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscOptionsReal("-pc_hypre_boomeramg_strongthresholdR","Threshold for R","None",jac->Rstrongthreshold,&jac->Rstrongthreshold,NULL));
963a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThresholdR,jac->hsolver,jac->Rstrongthreshold);
964589dcaf0SStefano Zampini 
9655f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscOptionsReal("-pc_hypre_boomeramg_filterthresholdR","Filter threshold for R","None",jac->Rfilterthreshold,&jac->Rfilterthreshold,NULL));
966a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetFilterThresholdR,jac->hsolver,jac->Rfilterthreshold);
967589dcaf0SStefano Zampini 
9685f80ce2aSJacob Faibussowitsch     CHKERRQ(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));
969a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetADropTol,jac->hsolver,jac->Adroptol);
970589dcaf0SStefano Zampini 
9715f80ce2aSJacob Faibussowitsch     CHKERRQ(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));
972a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetADropType,jac->hsolver,jac->Adroptype);
973589dcaf0SStefano Zampini   }
974589dcaf0SStefano Zampini #endif
975589dcaf0SStefano Zampini 
976ecae95adSPierre Jolivet #if PETSC_PKG_HYPRE_VERSION_LE(9,9,9)
9772c71b3e2SJacob Faibussowitsch   PetscCheckFalse(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);
978ecae95adSPierre Jolivet #endif
979ecae95adSPierre Jolivet 
9800f1074feSSatish Balay   /* new 3/07 */
9815f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg));
982589dcaf0SStefano Zampini   if (flg || jac->Rtype) {
983589dcaf0SStefano Zampini     if (flg) jac->interptype = indx;
984a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,jac->hsolver,jac->interptype);
9850f1074feSSatish Balay   }
9860f1074feSSatish Balay 
9875f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg));
98816d9e3a6SLisandro Dalcin   if (flg) {
989b96a4a96SBarry Smith     level = 3;
9905f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL));
9912fa5cd67SKarl Rupp 
992b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
993a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,jac->hsolver,level);
9942ae77aedSBarry Smith   }
9952ae77aedSBarry Smith 
9965f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg));
9972ae77aedSBarry Smith   if (flg) {
998b96a4a96SBarry Smith     level = 3;
9995f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL));
10002fa5cd67SKarl Rupp 
1001b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
1002a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,jac->hsolver,level);
100316d9e3a6SLisandro Dalcin   }
10048f87f92bSBarry Smith 
10055f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg));
10068f87f92bSBarry Smith   if (flg && tmp_truth) {
10078f87f92bSBarry Smith     PetscInt tmp_int;
10085f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg));
10098f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
1010a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,jac->hsolver,6);
1011a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,jac->hsolver,1);
1012a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,jac->hsolver,0);
1013a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,jac->hsolver,jac->nodal_relax_levels);
10148f87f92bSBarry Smith   }
10158f87f92bSBarry Smith 
10165f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsBool("-pc_hypre_boomeramg_keeptranspose", "Avoid transpose matvecs in preconditioner application", "None", jac->keeptranspose, &jac->keeptranspose, NULL));
1017a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_BoomerAMGSetKeepTranspose,jac->hsolver,jac->keeptranspose ? 1 : 0);
1018589dcaf0SStefano Zampini 
1019589dcaf0SStefano Zampini   /* options for ParaSails solvers */
10205f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsEList("-pc_hypre_boomeramg_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flg));
1021589dcaf0SStefano Zampini   if (flg) {
1022589dcaf0SStefano Zampini     jac->symt = indx;
1023a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetSym,jac->hsolver,jac->symt);
1024589dcaf0SStefano Zampini   }
1025589dcaf0SStefano Zampini 
10265f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsTail());
102716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
102816d9e3a6SLisandro Dalcin }
102916d9e3a6SLisandro Dalcin 
1030ace3abfcSBarry 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)
103116d9e3a6SLisandro Dalcin {
103216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
10332cf14000SStefano Zampini   HYPRE_Int      oits;
103416d9e3a6SLisandro Dalcin 
103516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
10365f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCitationsRegister(hypreCitation,&cite));
1037a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,its*jac->maxiter);
1038a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,jac->hsolver,rtol);
103916d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
10405f80ce2aSJacob Faibussowitsch   CHKERRQ(PCApply_HYPRE(pc,b,y));
104116d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
1042a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,jac->hsolver,&oits);
10434d0a8057SBarry Smith   *outits = oits;
10444d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
10454d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1046a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,jac->hsolver,jac->tol);
1047a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,jac->maxiter);
104816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
104916d9e3a6SLisandro Dalcin }
105016d9e3a6SLisandro Dalcin 
105116d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
105216d9e3a6SLisandro Dalcin {
105316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1054ace3abfcSBarry Smith   PetscBool      iascii;
105516d9e3a6SLisandro Dalcin 
105616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
10575f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
105816d9e3a6SLisandro Dalcin   if (iascii) {
10595f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n"));
10605f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]));
10615f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Maximum number of levels %D\n",jac->maxlevels));
10625f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Maximum number of iterations PER hypre call %D\n",jac->maxiter));
10635f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Convergence tolerance PER hypre call %g\n",(double)jac->tol));
10645f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Threshold for strong coupling %g\n",(double)jac->strongthreshold));
10655f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Interpolation truncation factor %g\n",(double)jac->truncfactor));
10665f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Interpolation: max elements per row %D\n",jac->pmax));
106722e51d31SStefano Zampini     if (jac->interp_refine) {
10685f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Interpolation: number of steps of weighted refinement %D\n",jac->interp_refine));
106922e51d31SStefano Zampini     }
10705f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Number of levels of aggressive coarsening %D\n",jac->agg_nl));
10715f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Number of paths for aggressive coarsening %D\n",jac->agg_num_paths));
10720f1074feSSatish Balay 
10735f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Maximum row sums %g\n",(double)jac->maxrowsum));
107416d9e3a6SLisandro Dalcin 
10755f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Sweeps down         %D\n",jac->gridsweeps[0]));
10765f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Sweeps up           %D\n",jac->gridsweeps[1]));
10775f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Sweeps on coarse    %D\n",jac->gridsweeps[2]));
107816d9e3a6SLisandro Dalcin 
10795f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]));
10805f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]));
10815f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]));
108216d9e3a6SLisandro Dalcin 
10835f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Relax weight  (all)      %g\n",(double)jac->relaxweight));
10845f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Outer relax weight (all) %g\n",(double)jac->outerrelaxweight));
108516d9e3a6SLisandro Dalcin 
108616d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
10875f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Using CF-relaxation\n"));
108816d9e3a6SLisandro Dalcin     } else {
10895f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Not using CF-relaxation\n"));
109016d9e3a6SLisandro Dalcin     }
10916a251517SEike Mueller     if (jac->smoothtype!=-1) {
10925f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]));
10935f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Smooth num levels    %D\n",jac->smoothnumlevels));
10947e352d70SEike Mueller     } else {
10955f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Not using more complex smoothers.\n"));
10961810e44eSEike Mueller     }
10971810e44eSEike Mueller     if (jac->smoothtype==3) {
10985f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) levels %D\n",jac->eu_level));
10995f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) drop tolerance %g\n",(double)jac->eu_droptolerance));
11005f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Euclid ILU use Block-Jacobi? %D\n",jac->eu_bj));
11016a251517SEike Mueller     }
11025f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]));
11035f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]));
11045f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Interpolation type  %s\n",jac->interptype != 100 ? HYPREBoomerAMGInterpType[jac->interptype] : "1pt"));
11055272c319SBarry Smith     if (jac->nodal_coarsening) {
11065f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Using nodal coarsening with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening));
11075272c319SBarry Smith     }
11085272c319SBarry Smith     if (jac->vec_interp_variant) {
11095f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant));
11105f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecQMax() %D\n",jac->vec_interp_qmax));
11115f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n",jac->vec_interp_smooth));
11128f87f92bSBarry Smith     }
11138f87f92bSBarry Smith     if (jac->nodal_relax) {
11145f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Using nodal relaxation via Schwarz smoothing on levels %D\n",jac->nodal_relax_levels));
11158f87f92bSBarry Smith     }
1116db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0)
11175f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    SpGEMM type         %s\n",jac->spgemm_type));
1118db6f9c32SMark Adams #endif
1119589dcaf0SStefano Zampini     /* AIR */
1120589dcaf0SStefano Zampini     if (jac->Rtype) {
11215f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    Using approximate ideal restriction type %D\n",jac->Rtype));
11225f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"      Threshold for R %g\n",(double)jac->Rstrongthreshold));
11235f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"      Filter for R %g\n",(double)jac->Rfilterthreshold));
11245f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"      A drop tolerance %g\n",(double)jac->Adroptol));
11255f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"      A drop type %D\n",jac->Adroptype));
1126589dcaf0SStefano Zampini     }
112716d9e3a6SLisandro Dalcin   }
112816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
112916d9e3a6SLisandro Dalcin }
113016d9e3a6SLisandro Dalcin 
113116d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
11324416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc)
113316d9e3a6SLisandro Dalcin {
113416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
11354ddd07fcSJed Brown   PetscInt       indx;
1136ace3abfcSBarry Smith   PetscBool      flag;
113716d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
113816d9e3a6SLisandro Dalcin 
113916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
11405f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options"));
11415f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0));
11425f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshold,&jac->threshold,&flag));
1143a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,jac->hsolver,jac->threshold,jac->nlevels);
114416d9e3a6SLisandro Dalcin 
11455f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag));
1146a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,jac->hsolver,jac->filter);
114716d9e3a6SLisandro Dalcin 
11485f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag));
1149a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,jac->hsolver,jac->loadbal);
115016d9e3a6SLisandro Dalcin 
11515f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag));
1152a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,jac->hsolver,jac->logging);
115316d9e3a6SLisandro Dalcin 
11545f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag));
1155a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,jac->hsolver,jac->ruse);
115616d9e3a6SLisandro Dalcin 
11575f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag));
115816d9e3a6SLisandro Dalcin   if (flag) {
115916d9e3a6SLisandro Dalcin     jac->symt = indx;
1160a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ParaSailsSetSym,jac->hsolver,jac->symt);
116116d9e3a6SLisandro Dalcin   }
116216d9e3a6SLisandro Dalcin 
11635f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsTail());
116416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
116516d9e3a6SLisandro Dalcin }
116616d9e3a6SLisandro Dalcin 
116716d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
116816d9e3a6SLisandro Dalcin {
116916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1170ace3abfcSBarry Smith   PetscBool      iascii;
1171feb237baSPierre Jolivet   const char     *symt = 0;
117216d9e3a6SLisandro Dalcin 
117316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
11745f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
117516d9e3a6SLisandro Dalcin   if (iascii) {
11765f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n"));
11775f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    nlevels %d\n",jac->nlevels));
11785f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    threshold %g\n",(double)jac->threshold));
11795f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    filter %g\n",(double)jac->filter));
11805f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    load balance %g\n",(double)jac->loadbal));
11815f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    reuse nonzero structure %s\n",PetscBools[jac->ruse]));
11825f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    print info to screen %s\n",PetscBools[jac->logging]));
11832fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
11842fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
11852fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
118698921bdaSJacob Faibussowitsch     else SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
11875f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    %s\n",symt));
118816d9e3a6SLisandro Dalcin   }
118916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
119016d9e3a6SLisandro Dalcin }
11914cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
11924416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc)
11934cb006feSStefano Zampini {
11944cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
11954cb006feSStefano Zampini   PetscInt       n;
11964cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
11974cb006feSStefano Zampini 
11984cb006feSStefano Zampini   PetscFunctionBegin;
11995f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options"));
12005f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag));
1201a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,jac->hsolver,jac->as_print);
12025f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_ams_max_iter","Maximum number of AMS multigrid iterations within PCApply","None",jac->as_max_iter,&jac->as_max_iter,&flag));
1203a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,jac->hsolver,jac->as_max_iter);
12045f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_ams_cycle_type","Cycle type for AMS multigrid","None",jac->ams_cycle_type,&jac->ams_cycle_type,&flag));
1205a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,jac->hsolver,jac->ams_cycle_type);
12065f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag));
1207a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,jac->hsolver,jac->as_tol);
12085f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_ams_relax_type","Relaxation type for AMS smoother","None",jac->as_relax_type,&jac->as_relax_type,&flag));
12095f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_ams_relax_times","Number of relaxation steps for AMS smoother","None",jac->as_relax_times,&jac->as_relax_times,&flag2));
12105f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-pc_hypre_ams_relax_weight","Relaxation weight for AMS smoother","None",jac->as_relax_weight,&jac->as_relax_weight,&flag3));
12115f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4));
12124cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1213a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,jac->hsolver,jac->as_relax_type,
1214863406b8SStefano Zampini                                                                       jac->as_relax_times,
1215863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1216a74df02fSJacob Faibussowitsch                                                                       jac->as_omega);
12174cb006feSStefano Zampini   }
12185f80ce2aSJacob Faibussowitsch   CHKERRQ(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));
12194cb006feSStefano Zampini   n = 5;
12205f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2));
12214cb006feSStefano Zampini   if (flag || flag2) {
1222a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1223863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1224863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1225863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1226863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1227a74df02fSJacob Faibussowitsch                                                                      jac->as_amg_alpha_opts[4]);     /* AMG Pmax */
12284cb006feSStefano Zampini   }
12295f80ce2aSJacob Faibussowitsch   CHKERRQ(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));
12304cb006feSStefano Zampini   n = 5;
12315f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsIntArray("-pc_hypre_ams_amg_beta_options","AMG options for scalar Poisson solver","None",jac->as_amg_beta_opts,&n,&flag2));
12324cb006feSStefano Zampini   if (flag || flag2) {
1233a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1234863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1235863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1236863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1237863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1238a74df02fSJacob Faibussowitsch                                                                     jac->as_amg_beta_opts[4]);     /* AMG Pmax */
12394cb006feSStefano Zampini   }
12405f80ce2aSJacob Faibussowitsch   CHKERRQ(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));
124123df4f25SStefano Zampini   if (flag) { /* override HYPRE's default only if the options is used */
1242a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetProjectionFrequency,jac->hsolver,jac->ams_proj_freq);
124323df4f25SStefano Zampini   }
12445f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsTail());
12454cb006feSStefano Zampini   PetscFunctionReturn(0);
12464cb006feSStefano Zampini }
12474cb006feSStefano Zampini 
12484cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
12494cb006feSStefano Zampini {
12504cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12514cb006feSStefano Zampini   PetscBool      iascii;
12524cb006feSStefano Zampini 
12534cb006feSStefano Zampini   PetscFunctionBegin;
12545f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
12554cb006feSStefano Zampini   if (iascii) {
12565f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n"));
12575f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter));
12585f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ams_cycle_type));
12595f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol));
12605f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type));
12615f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times));
12625f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight));
12635f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega));
12644cb006feSStefano Zampini     if (jac->alpha_Poisson) {
12655f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (passed in by user)\n"));
12664cb006feSStefano Zampini     } else {
12675f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (computed) \n"));
12684cb006feSStefano Zampini     }
12695f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]));
12705f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]));
12715f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]));
12725f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]));
12735f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]));
12745f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta));
12754cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
12764cb006feSStefano Zampini       if (jac->beta_Poisson) {
12775f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (passed in by user)\n"));
12784cb006feSStefano Zampini       } else {
12795f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (computed) \n"));
12804cb006feSStefano Zampini       }
12815f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]));
12825f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]));
12835f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]));
12845f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]));
12855f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]));
12865f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_beta_theta));
128723df4f25SStefano Zampini       if (jac->ams_beta_is_zero_part) {
12885f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscViewerASCIIPrintf(viewer,"        compatible subspace projection frequency %d (-1 HYPRE uses default)\n",jac->ams_proj_freq));
128923df4f25SStefano Zampini       }
129023df4f25SStefano Zampini     } else {
12915f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver not used (zero-conductivity everywhere) \n"));
12924cb006feSStefano Zampini     }
12934cb006feSStefano Zampini   }
12944cb006feSStefano Zampini   PetscFunctionReturn(0);
12954cb006feSStefano Zampini }
12964cb006feSStefano Zampini 
12974416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc)
1298863406b8SStefano Zampini {
1299863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1300863406b8SStefano Zampini   PetscInt       n;
1301863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
1302863406b8SStefano Zampini 
1303863406b8SStefano Zampini   PetscFunctionBegin;
13045f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options"));
13055f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag));
1306a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,jac->hsolver,jac->as_print);
13075f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_ads_max_iter","Maximum number of ADS multigrid iterations within PCApply","None",jac->as_max_iter,&jac->as_max_iter,&flag));
1308a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,jac->hsolver,jac->as_max_iter);
13095f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_ads_cycle_type","Cycle type for ADS multigrid","None",jac->ads_cycle_type,&jac->ads_cycle_type,&flag));
1310a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,jac->hsolver,jac->ads_cycle_type);
13115f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag));
1312a74df02fSJacob Faibussowitsch   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,jac->hsolver,jac->as_tol);
13135f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_ads_relax_type","Relaxation type for ADS smoother","None",jac->as_relax_type,&jac->as_relax_type,&flag));
13145f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_ads_relax_times","Number of relaxation steps for ADS smoother","None",jac->as_relax_times,&jac->as_relax_times,&flag2));
13155f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-pc_hypre_ads_relax_weight","Relaxation weight for ADS smoother","None",jac->as_relax_weight,&jac->as_relax_weight,&flag3));
13165f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4));
1317863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1318a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,jac->hsolver,jac->as_relax_type,
1319863406b8SStefano Zampini                                                                       jac->as_relax_times,
1320863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1321a74df02fSJacob Faibussowitsch                                                                       jac->as_omega);
1322863406b8SStefano Zampini   }
13235f80ce2aSJacob Faibussowitsch   CHKERRQ(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));
1324863406b8SStefano Zampini   n = 5;
13255f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsIntArray("-pc_hypre_ads_ams_options","AMG options for AMS solver inside ADS","None",jac->as_amg_alpha_opts,&n,&flag2));
13265f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_hypre_ads_ams_cycle_type","Cycle type for AMS solver inside ADS","None",jac->ams_cycle_type,&jac->ams_cycle_type,&flag3));
1327863406b8SStefano Zampini   if (flag || flag2 || flag3) {
1328a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
1329863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1330863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1331863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1332863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1333863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1334a74df02fSJacob Faibussowitsch                                                                 jac->as_amg_alpha_opts[4]);     /* AMG Pmax */
1335863406b8SStefano Zampini   }
13365f80ce2aSJacob Faibussowitsch   CHKERRQ(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));
1337863406b8SStefano Zampini   n = 5;
13385f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsIntArray("-pc_hypre_ads_amg_options","AMG options for vector AMG solver inside ADS","None",jac->as_amg_beta_opts,&n,&flag2));
1339863406b8SStefano Zampini   if (flag || flag2) {
1340a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1341863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1342863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1343863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1344863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1345a74df02fSJacob Faibussowitsch                                                                 jac->as_amg_beta_opts[4]);     /* AMG Pmax */
1346863406b8SStefano Zampini   }
13475f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsTail());
1348863406b8SStefano Zampini   PetscFunctionReturn(0);
1349863406b8SStefano Zampini }
1350863406b8SStefano Zampini 
1351863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1352863406b8SStefano Zampini {
1353863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1354863406b8SStefano Zampini   PetscBool      iascii;
1355863406b8SStefano Zampini 
1356863406b8SStefano Zampini   PetscFunctionBegin;
13575f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
1358863406b8SStefano Zampini   if (iascii) {
13595f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n"));
13605f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter));
13615f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ads_cycle_type));
13625f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol));
13635f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type));
13645f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times));
13655f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight));
13665f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega));
13675f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    AMS solver using boomerAMG\n"));
13685f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"        subspace cycle type %d\n",jac->ams_cycle_type));
13695f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_alpha_opts[0]));
13705f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]));
13715f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_alpha_opts[2]));
13725f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_alpha_opts[3]));
13735f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]));
13745f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_alpha_theta));
13755f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    vector Poisson solver using boomerAMG\n"));
13765f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_beta_opts[0]));
13775f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]));
13785f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_beta_opts[2]));
13795f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_beta_opts[3]));
13805f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]));
13815f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_beta_theta));
1382863406b8SStefano Zampini   }
1383863406b8SStefano Zampini   PetscFunctionReturn(0);
1384863406b8SStefano Zampini }
1385863406b8SStefano Zampini 
1386863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
13874cb006feSStefano Zampini {
13884cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
13895ac14e1cSStefano Zampini   PetscBool      ishypre;
13904cb006feSStefano Zampini 
13914cb006feSStefano Zampini   PetscFunctionBegin;
13925f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)G,MATHYPRE,&ishypre));
13935ac14e1cSStefano Zampini   if (ishypre) {
13945f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscObjectReference((PetscObject)G));
13955f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&jac->G));
13965ac14e1cSStefano Zampini     jac->G = G;
13975ac14e1cSStefano Zampini   } else {
13985f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&jac->G));
13995f80ce2aSJacob Faibussowitsch     CHKERRQ(MatConvert(G,MATHYPRE,MAT_INITIAL_MATRIX,&jac->G));
14005ac14e1cSStefano Zampini   }
14014cb006feSStefano Zampini   PetscFunctionReturn(0);
14024cb006feSStefano Zampini }
14034cb006feSStefano Zampini 
14044cb006feSStefano Zampini /*@
14054cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
14064cb006feSStefano Zampini 
14074cb006feSStefano Zampini    Collective on PC
14084cb006feSStefano Zampini 
14094cb006feSStefano Zampini    Input Parameters:
14104cb006feSStefano Zampini +  pc - the preconditioning context
14114cb006feSStefano Zampini -  G - the discrete gradient
14124cb006feSStefano Zampini 
14134cb006feSStefano Zampini    Level: intermediate
14144cb006feSStefano Zampini 
141595452b02SPatrick Sanan    Notes:
141695452b02SPatrick Sanan     G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh
1417147403d9SBarry Smith 
1418863406b8SStefano 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
14194cb006feSStefano Zampini 
1420147403d9SBarry Smith .seealso: PCHYPRESetDiscreteCurl()
14214cb006feSStefano Zampini @*/
14224cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
14234cb006feSStefano Zampini {
14244cb006feSStefano Zampini   PetscFunctionBegin;
14254cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
14264cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
14274cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
14285f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G)));
14294cb006feSStefano Zampini   PetscFunctionReturn(0);
14304cb006feSStefano Zampini }
14314cb006feSStefano Zampini 
1432863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1433863406b8SStefano Zampini {
1434863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
14355ac14e1cSStefano Zampini   PetscBool      ishypre;
1436863406b8SStefano Zampini 
1437863406b8SStefano Zampini   PetscFunctionBegin;
14385f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)C,MATHYPRE,&ishypre));
14395ac14e1cSStefano Zampini   if (ishypre) {
14405f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscObjectReference((PetscObject)C));
14415f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&jac->C));
14425ac14e1cSStefano Zampini     jac->C = C;
14435ac14e1cSStefano Zampini   } else {
14445f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&jac->C));
14455f80ce2aSJacob Faibussowitsch     CHKERRQ(MatConvert(C,MATHYPRE,MAT_INITIAL_MATRIX,&jac->C));
14465ac14e1cSStefano Zampini   }
1447863406b8SStefano Zampini   PetscFunctionReturn(0);
1448863406b8SStefano Zampini }
1449863406b8SStefano Zampini 
1450863406b8SStefano Zampini /*@
1451863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1452863406b8SStefano Zampini 
1453863406b8SStefano Zampini    Collective on PC
1454863406b8SStefano Zampini 
1455863406b8SStefano Zampini    Input Parameters:
1456863406b8SStefano Zampini +  pc - the preconditioning context
1457863406b8SStefano Zampini -  C - the discrete curl
1458863406b8SStefano Zampini 
1459863406b8SStefano Zampini    Level: intermediate
1460863406b8SStefano Zampini 
146195452b02SPatrick Sanan    Notes:
146295452b02SPatrick Sanan     C should have as many rows as the number of faces and as many columns as the number of edges in the mesh
1463147403d9SBarry Smith 
1464863406b8SStefano 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
1465863406b8SStefano Zampini 
1466147403d9SBarry Smith .seealso: PCHYPRESetDiscreteGradient()
1467863406b8SStefano Zampini @*/
1468863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1469863406b8SStefano Zampini {
1470863406b8SStefano Zampini   PetscFunctionBegin;
1471863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1472863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1473863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
14745f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C)));
1475863406b8SStefano Zampini   PetscFunctionReturn(0);
1476863406b8SStefano Zampini }
1477863406b8SStefano Zampini 
14786bf688a0SCe Qin static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
14796bf688a0SCe Qin {
14806bf688a0SCe Qin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
14816bf688a0SCe Qin   PetscBool      ishypre;
14826bf688a0SCe Qin   PetscInt       i;
14836bf688a0SCe Qin   PetscFunctionBegin;
14846bf688a0SCe Qin 
14855f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&jac->RT_PiFull));
14865f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&jac->ND_PiFull));
14876bf688a0SCe Qin   for (i=0;i<3;++i) {
14885f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&jac->RT_Pi[i]));
14895f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&jac->ND_Pi[i]));
14906bf688a0SCe Qin   }
14916bf688a0SCe Qin 
14926bf688a0SCe Qin   jac->dim = dim;
14936bf688a0SCe Qin   if (RT_PiFull) {
14945f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscObjectTypeCompare((PetscObject)RT_PiFull,MATHYPRE,&ishypre));
14956bf688a0SCe Qin     if (ishypre) {
14965f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscObjectReference((PetscObject)RT_PiFull));
14976bf688a0SCe Qin       jac->RT_PiFull = RT_PiFull;
14986bf688a0SCe Qin     } else {
14995f80ce2aSJacob Faibussowitsch       CHKERRQ(MatConvert(RT_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_PiFull));
15006bf688a0SCe Qin     }
15016bf688a0SCe Qin   }
15026bf688a0SCe Qin   if (RT_Pi) {
15036bf688a0SCe Qin     for (i=0;i<dim;++i) {
15046bf688a0SCe Qin       if (RT_Pi[i]) {
15055f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscObjectTypeCompare((PetscObject)RT_Pi[i],MATHYPRE,&ishypre));
15066bf688a0SCe Qin         if (ishypre) {
15075f80ce2aSJacob Faibussowitsch           CHKERRQ(PetscObjectReference((PetscObject)RT_Pi[i]));
15086bf688a0SCe Qin           jac->RT_Pi[i] = RT_Pi[i];
15096bf688a0SCe Qin         } else {
15105f80ce2aSJacob Faibussowitsch           CHKERRQ(MatConvert(RT_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_Pi[i]));
15116bf688a0SCe Qin         }
15126bf688a0SCe Qin       }
15136bf688a0SCe Qin     }
15146bf688a0SCe Qin   }
15156bf688a0SCe Qin   if (ND_PiFull) {
15165f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscObjectTypeCompare((PetscObject)ND_PiFull,MATHYPRE,&ishypre));
15176bf688a0SCe Qin     if (ishypre) {
15185f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscObjectReference((PetscObject)ND_PiFull));
15196bf688a0SCe Qin       jac->ND_PiFull = ND_PiFull;
15206bf688a0SCe Qin     } else {
15215f80ce2aSJacob Faibussowitsch       CHKERRQ(MatConvert(ND_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_PiFull));
15226bf688a0SCe Qin     }
15236bf688a0SCe Qin   }
15246bf688a0SCe Qin   if (ND_Pi) {
15256bf688a0SCe Qin     for (i=0;i<dim;++i) {
15266bf688a0SCe Qin       if (ND_Pi[i]) {
15275f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscObjectTypeCompare((PetscObject)ND_Pi[i],MATHYPRE,&ishypre));
15286bf688a0SCe Qin         if (ishypre) {
15295f80ce2aSJacob Faibussowitsch           CHKERRQ(PetscObjectReference((PetscObject)ND_Pi[i]));
15306bf688a0SCe Qin           jac->ND_Pi[i] = ND_Pi[i];
15316bf688a0SCe Qin         } else {
15325f80ce2aSJacob Faibussowitsch           CHKERRQ(MatConvert(ND_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_Pi[i]));
15336bf688a0SCe Qin         }
15346bf688a0SCe Qin       }
15356bf688a0SCe Qin     }
15366bf688a0SCe Qin   }
15376bf688a0SCe Qin 
15386bf688a0SCe Qin   PetscFunctionReturn(0);
15396bf688a0SCe Qin }
15406bf688a0SCe Qin 
15416bf688a0SCe Qin /*@
15426bf688a0SCe Qin  PCHYPRESetInterpolations - Set interpolation matrices for AMS/ADS preconditioner
15436bf688a0SCe Qin 
15446bf688a0SCe Qin    Collective on PC
15456bf688a0SCe Qin 
15466bf688a0SCe Qin    Input Parameters:
15476bf688a0SCe Qin +  pc - the preconditioning context
15486bf688a0SCe Qin -  dim - the dimension of the problem, only used in AMS
15496bf688a0SCe Qin -  RT_PiFull - Raviart-Thomas interpolation matrix
15506bf688a0SCe Qin -  RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix
15516bf688a0SCe Qin -  ND_PiFull - Nedelec interpolation matrix
15526bf688a0SCe Qin -  ND_Pi - x/y/z component of Nedelec interpolation matrix
15536bf688a0SCe Qin 
155495452b02SPatrick Sanan    Notes:
155595452b02SPatrick Sanan     For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL.
1556147403d9SBarry Smith 
15576bf688a0SCe Qin     For ADS, both type of interpolation matrices are needed.
1558147403d9SBarry Smith 
15596bf688a0SCe Qin    Level: intermediate
15606bf688a0SCe Qin 
15616bf688a0SCe Qin @*/
15626bf688a0SCe Qin PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
15636bf688a0SCe Qin {
15646bf688a0SCe Qin   PetscInt       i;
15656bf688a0SCe Qin 
15666bf688a0SCe Qin   PetscFunctionBegin;
15676bf688a0SCe Qin   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15686bf688a0SCe Qin   if (RT_PiFull) {
15696bf688a0SCe Qin     PetscValidHeaderSpecific(RT_PiFull,MAT_CLASSID,3);
15706bf688a0SCe Qin     PetscCheckSameComm(pc,1,RT_PiFull,3);
15716bf688a0SCe Qin   }
15726bf688a0SCe Qin   if (RT_Pi) {
15736bf688a0SCe Qin     PetscValidPointer(RT_Pi,4);
15746bf688a0SCe Qin     for (i=0;i<dim;++i) {
15756bf688a0SCe Qin       if (RT_Pi[i]) {
15766bf688a0SCe Qin         PetscValidHeaderSpecific(RT_Pi[i],MAT_CLASSID,4);
15776bf688a0SCe Qin         PetscCheckSameComm(pc,1,RT_Pi[i],4);
15786bf688a0SCe Qin       }
15796bf688a0SCe Qin     }
15806bf688a0SCe Qin   }
15816bf688a0SCe Qin   if (ND_PiFull) {
15826bf688a0SCe Qin     PetscValidHeaderSpecific(ND_PiFull,MAT_CLASSID,5);
15836bf688a0SCe Qin     PetscCheckSameComm(pc,1,ND_PiFull,5);
15846bf688a0SCe Qin   }
15856bf688a0SCe Qin   if (ND_Pi) {
15866bf688a0SCe Qin     PetscValidPointer(ND_Pi,6);
15876bf688a0SCe Qin     for (i=0;i<dim;++i) {
15886bf688a0SCe Qin       if (ND_Pi[i]) {
15896bf688a0SCe Qin         PetscValidHeaderSpecific(ND_Pi[i],MAT_CLASSID,6);
15906bf688a0SCe Qin         PetscCheckSameComm(pc,1,ND_Pi[i],6);
15916bf688a0SCe Qin       }
15926bf688a0SCe Qin     }
15936bf688a0SCe Qin   }
15945f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscTryMethod(pc,"PCHYPRESetInterpolations_C",(PC,PetscInt,Mat,Mat[],Mat,Mat[]),(pc,dim,RT_PiFull,RT_Pi,ND_PiFull,ND_Pi)));
15956bf688a0SCe Qin   PetscFunctionReturn(0);
15966bf688a0SCe Qin }
15976bf688a0SCe Qin 
15985ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha)
15994cb006feSStefano Zampini {
16004cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
16015ac14e1cSStefano Zampini   PetscBool      ishypre;
16024cb006feSStefano Zampini 
16034cb006feSStefano Zampini   PetscFunctionBegin;
16045f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre));
16055ac14e1cSStefano Zampini   if (ishypre) {
16065ac14e1cSStefano Zampini     if (isalpha) {
16075f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscObjectReference((PetscObject)A));
16085f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&jac->alpha_Poisson));
16095ac14e1cSStefano Zampini       jac->alpha_Poisson = A;
16105ac14e1cSStefano Zampini     } else {
16115ac14e1cSStefano Zampini       if (A) {
16125f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscObjectReference((PetscObject)A));
16135ac14e1cSStefano Zampini       } else {
16145ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
16155ac14e1cSStefano Zampini       }
16165f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&jac->beta_Poisson));
16175ac14e1cSStefano Zampini       jac->beta_Poisson = A;
16185ac14e1cSStefano Zampini     }
16195ac14e1cSStefano Zampini   } else {
16205ac14e1cSStefano Zampini     if (isalpha) {
16215f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&jac->alpha_Poisson));
16225f80ce2aSJacob Faibussowitsch       CHKERRQ(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->alpha_Poisson));
16235ac14e1cSStefano Zampini     } else {
16245ac14e1cSStefano Zampini       if (A) {
16255f80ce2aSJacob Faibussowitsch         CHKERRQ(MatDestroy(&jac->beta_Poisson));
16265f80ce2aSJacob Faibussowitsch         CHKERRQ(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->beta_Poisson));
16275ac14e1cSStefano Zampini       } else {
16285f80ce2aSJacob Faibussowitsch         CHKERRQ(MatDestroy(&jac->beta_Poisson));
16295ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
16305ac14e1cSStefano Zampini       }
16315ac14e1cSStefano Zampini     }
16325ac14e1cSStefano Zampini   }
16334cb006feSStefano Zampini   PetscFunctionReturn(0);
16344cb006feSStefano Zampini }
16354cb006feSStefano Zampini 
16364cb006feSStefano Zampini /*@
16374cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
16384cb006feSStefano Zampini 
16394cb006feSStefano Zampini    Collective on PC
16404cb006feSStefano Zampini 
16414cb006feSStefano Zampini    Input Parameters:
16424cb006feSStefano Zampini +  pc - the preconditioning context
16434cb006feSStefano Zampini -  A - the matrix
16444cb006feSStefano Zampini 
16454cb006feSStefano Zampini    Level: intermediate
16464cb006feSStefano Zampini 
164795452b02SPatrick Sanan    Notes:
164895452b02SPatrick Sanan     A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
16494cb006feSStefano Zampini 
1650147403d9SBarry Smith .seealso: PCHYPRESetDiscreteGradient(), PCHYPRESetDiscreteCurl(), PCHYPRESetBetaPoissonMatrix()
16514cb006feSStefano Zampini @*/
16524cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
16534cb006feSStefano Zampini {
16544cb006feSStefano Zampini   PetscFunctionBegin;
16554cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
16564cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
16574cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
16585f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_TRUE)));
16594cb006feSStefano Zampini   PetscFunctionReturn(0);
16604cb006feSStefano Zampini }
16614cb006feSStefano Zampini 
16624cb006feSStefano Zampini /*@
16634cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
16644cb006feSStefano Zampini 
16654cb006feSStefano Zampini    Collective on PC
16664cb006feSStefano Zampini 
16674cb006feSStefano Zampini    Input Parameters:
16684cb006feSStefano Zampini +  pc - the preconditioning context
16694cb006feSStefano Zampini -  A - the matrix
16704cb006feSStefano Zampini 
16714cb006feSStefano Zampini    Level: intermediate
16724cb006feSStefano Zampini 
167395452b02SPatrick Sanan    Notes:
167495452b02SPatrick Sanan     A should be obtained by discretizing the Poisson problem with linear finite elements.
16754cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
16764cb006feSStefano Zampini 
1677147403d9SBarry Smith .seealso: PCHYPRESetDiscreteGradient(), PCHYPRESetDiscreteCurl(), PCHYPRESetAlphaPoissonMatrix()
16784cb006feSStefano Zampini @*/
16794cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
16804cb006feSStefano Zampini {
16814cb006feSStefano Zampini   PetscFunctionBegin;
16824cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
16834cb006feSStefano Zampini   if (A) {
16844cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
16854cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
16864cb006feSStefano Zampini   }
16875f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_FALSE)));
16884cb006feSStefano Zampini   PetscFunctionReturn(0);
16894cb006feSStefano Zampini }
16904cb006feSStefano Zampini 
16915ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz, Vec zoz, Vec zzo)
16924cb006feSStefano Zampini {
16934cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
16944cb006feSStefano Zampini 
16954cb006feSStefano Zampini   PetscFunctionBegin;
16964cb006feSStefano Zampini   /* throw away any vector if already set */
16975f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorDestroy(&jac->constants[0]));
16985f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorDestroy(&jac->constants[1]));
16995f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorDestroy(&jac->constants[2]));
17005f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorCreate(ozz->map,&jac->constants[0]));
17015f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorCopy(ozz,jac->constants[0]));
17025f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorCreate(zoz->map,&jac->constants[1]));
17035f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorCopy(zoz,jac->constants[1]));
17045ac14e1cSStefano Zampini   jac->dim = 2;
17054cb006feSStefano Zampini   if (zzo) {
17065f80ce2aSJacob Faibussowitsch     CHKERRQ(VecHYPRE_IJVectorCreate(zzo->map,&jac->constants[2]));
17075f80ce2aSJacob Faibussowitsch     CHKERRQ(VecHYPRE_IJVectorCopy(zzo,jac->constants[2]));
17085ac14e1cSStefano Zampini     jac->dim++;
17094cb006feSStefano Zampini   }
17104cb006feSStefano Zampini   PetscFunctionReturn(0);
17114cb006feSStefano Zampini }
17124cb006feSStefano Zampini 
17134cb006feSStefano Zampini /*@
1714147403d9SBarry Smith  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in the edge element basis
17154cb006feSStefano Zampini 
17164cb006feSStefano Zampini    Collective on PC
17174cb006feSStefano Zampini 
17184cb006feSStefano Zampini    Input Parameters:
17194cb006feSStefano Zampini +  pc - the preconditioning context
17204cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
17214cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
17224cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
17234cb006feSStefano Zampini 
17244cb006feSStefano Zampini    Level: intermediate
17254cb006feSStefano Zampini 
17264cb006feSStefano Zampini @*/
17274cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
17284cb006feSStefano Zampini {
17294cb006feSStefano Zampini   PetscFunctionBegin;
17304cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
17314cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
17324cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
17334cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
17344cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
17354cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
17364cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
17375f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo)));
17384cb006feSStefano Zampini   PetscFunctionReturn(0);
17394cb006feSStefano Zampini }
17404cb006feSStefano Zampini 
1741863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
17424cb006feSStefano Zampini {
17434cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
17444cb006feSStefano Zampini   Vec             tv;
17454cb006feSStefano Zampini   PetscInt        i;
17464cb006feSStefano Zampini 
17474cb006feSStefano Zampini   PetscFunctionBegin;
17484cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
17495f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorDestroy(&jac->coords[0]));
17505f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorDestroy(&jac->coords[1]));
17515f80ce2aSJacob Faibussowitsch   CHKERRQ(VecHYPRE_IJVectorDestroy(&jac->coords[2]));
17525ac14e1cSStefano Zampini   jac->dim = dim;
17535ac14e1cSStefano Zampini 
17544cb006feSStefano Zampini   /* compute IJ vector for coordinates */
17555f80ce2aSJacob Faibussowitsch   CHKERRQ(VecCreate(PetscObjectComm((PetscObject)pc),&tv));
17565f80ce2aSJacob Faibussowitsch   CHKERRQ(VecSetType(tv,VECSTANDARD));
17575f80ce2aSJacob Faibussowitsch   CHKERRQ(VecSetSizes(tv,nloc,PETSC_DECIDE));
17584cb006feSStefano Zampini   for (i=0;i<dim;i++) {
17594cb006feSStefano Zampini     PetscScalar *array;
17604cb006feSStefano Zampini     PetscInt    j;
17614cb006feSStefano Zampini 
17625f80ce2aSJacob Faibussowitsch     CHKERRQ(VecHYPRE_IJVectorCreate(tv->map,&jac->coords[i]));
17635f80ce2aSJacob Faibussowitsch     CHKERRQ(VecGetArrayWrite(tv,&array));
17646ea7df73SStefano Zampini     for (j=0;j<nloc;j++) array[j] = coords[j*dim+i];
17655f80ce2aSJacob Faibussowitsch     CHKERRQ(VecRestoreArrayWrite(tv,&array));
17665f80ce2aSJacob Faibussowitsch     CHKERRQ(VecHYPRE_IJVectorCopy(tv,jac->coords[i]));
17674cb006feSStefano Zampini   }
17685f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&tv));
17694cb006feSStefano Zampini   PetscFunctionReturn(0);
17704cb006feSStefano Zampini }
17714cb006feSStefano Zampini 
177216d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
177316d9e3a6SLisandro Dalcin 
1774f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
177516d9e3a6SLisandro Dalcin {
177616d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
177716d9e3a6SLisandro Dalcin 
177816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
177916d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
178016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
178116d9e3a6SLisandro Dalcin }
178216d9e3a6SLisandro Dalcin 
1783f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
178416d9e3a6SLisandro Dalcin {
178516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1786ace3abfcSBarry Smith   PetscBool      flag;
178716d9e3a6SLisandro Dalcin 
178816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
178916d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
17905f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrcmp(jac->hypre_type,name,&flag));
17915f80ce2aSJacob Faibussowitsch     PetscCheck(flag,PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
179216d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
179316d9e3a6SLisandro Dalcin   } else {
17945f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrallocpy(name, &jac->hypre_type));
179516d9e3a6SLisandro Dalcin   }
179616d9e3a6SLisandro Dalcin 
179716d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
179816d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
179916d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
180016d9e3a6SLisandro Dalcin 
18015f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscStrcmp("pilut",jac->hypre_type,&flag));
180216d9e3a6SLisandro Dalcin   if (flag) {
18035f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre));
1804a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,jac->comm_hypre,&jac->hsolver);
180516d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
180616d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
180716d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
180816d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
180916d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
181016d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
181116d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
181216d9e3a6SLisandro Dalcin   }
18135f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscStrcmp("euclid",jac->hypre_type,&flag));
1814db966c6cSHong Zhang   if (flag) {
18158bf83915SBarry Smith #if defined(PETSC_HAVE_64BIT_INDICES)
18168bf83915SBarry Smith     SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Hypre Euclid not support with 64 bit indices");
18178bf83915SBarry Smith #endif
18185f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre));
1819a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_EuclidCreate,jac->comm_hypre,&jac->hsolver);
1820db966c6cSHong Zhang     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
1821db966c6cSHong Zhang     pc->ops->view           = PCView_HYPRE_Euclid;
1822db966c6cSHong Zhang     jac->destroy            = HYPRE_EuclidDestroy;
1823db966c6cSHong Zhang     jac->setup              = HYPRE_EuclidSetup;
1824db966c6cSHong Zhang     jac->solve              = HYPRE_EuclidSolve;
1825db966c6cSHong Zhang     jac->factorrowsize      = PETSC_DEFAULT;
1826db966c6cSHong Zhang     jac->eu_level           = PETSC_DEFAULT; /* default */
1827db966c6cSHong Zhang     PetscFunctionReturn(0);
1828db966c6cSHong Zhang   }
18295f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscStrcmp("parasails",jac->hypre_type,&flag));
183016d9e3a6SLisandro Dalcin   if (flag) {
18315f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre));
1832a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ParaSailsCreate,jac->comm_hypre,&jac->hsolver);
183316d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
183416d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
183516d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
183616d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
183716d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
183816d9e3a6SLisandro Dalcin     /* initialize */
183916d9e3a6SLisandro Dalcin     jac->nlevels   = 1;
18408966356dSPierre Jolivet     jac->threshold = .1;
184116d9e3a6SLisandro Dalcin     jac->filter    = .1;
184216d9e3a6SLisandro Dalcin     jac->loadbal   = 0;
18432fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
18442fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
18452fa5cd67SKarl Rupp 
184616d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
184716d9e3a6SLisandro Dalcin     jac->symt = 0;
1848a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ParaSailsSetParams,jac->hsolver,jac->threshold,jac->nlevels);
1849a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,jac->hsolver,jac->filter);
1850a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,jac->hsolver,jac->loadbal);
1851a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,jac->hsolver,jac->logging);
1852a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,jac->hsolver,jac->ruse);
1853a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ParaSailsSetSym,jac->hsolver,jac->symt);
185416d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
185516d9e3a6SLisandro Dalcin   }
18565f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscStrcmp("boomeramg",jac->hypre_type,&flag));
185716d9e3a6SLisandro Dalcin   if (flag) {
18585f80ce2aSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGCreate,&jac->hsolver);
185916d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
186016d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
186116d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
186216d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
18635f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",PCGetInterpolations_BoomerAMG));
18645f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",PCGetCoarseOperators_BoomerAMG));
186516d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
186616d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
186716d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
186816d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
186916d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
187016d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
187116d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
187216d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
18738f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
187416d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
187516d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
187616d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
187716d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
187816d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
18790f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
18806a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1881b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
18821810e44eSEike Mueller     jac->eu_level         = 0;
18831810e44eSEike Mueller     jac->eu_droptolerance = 0;
18841810e44eSEike Mueller     jac->eu_bj            = 0;
1885589dcaf0SStefano Zampini     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a PC - most likely with CG */
18860f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
188716d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
188816d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
188916d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
18900f1074feSSatish Balay     jac->interptype       = 0;
1891589dcaf0SStefano Zampini     jac->Rtype            = 0;
1892589dcaf0SStefano Zampini     jac->Rstrongthreshold = 0.25;
1893589dcaf0SStefano Zampini     jac->Rfilterthreshold = 0.0;
1894589dcaf0SStefano Zampini     jac->Adroptype        = -1;
1895589dcaf0SStefano Zampini     jac->Adroptol         = 0.0;
18960f1074feSSatish Balay     jac->agg_nl           = 0;
18976ea7df73SStefano Zampini     jac->agg_interptype   = 4;
18980f1074feSSatish Balay     jac->pmax             = 0;
18990f1074feSSatish Balay     jac->truncfactor      = 0.0;
19000f1074feSSatish Balay     jac->agg_num_paths    = 1;
1901589dcaf0SStefano Zampini     jac->maxc             = 9;
1902589dcaf0SStefano Zampini     jac->minc             = 1;
190322e51d31SStefano Zampini     jac->nodal_coarsening      = 0;
190422e51d31SStefano Zampini     jac->nodal_coarsening_diag = 0;
190522e51d31SStefano Zampini     jac->vec_interp_variant    = 0;
190622e51d31SStefano Zampini     jac->vec_interp_qmax       = 0;
190722e51d31SStefano Zampini     jac->vec_interp_smooth     = PETSC_FALSE;
190822e51d31SStefano Zampini     jac->interp_refine         = 0;
19098f87f92bSBarry Smith     jac->nodal_relax           = PETSC_FALSE;
19108f87f92bSBarry Smith     jac->nodal_relax_levels    = 1;
19116ea7df73SStefano Zampini     jac->rap2                  = 0;
19126ea7df73SStefano Zampini 
19136ea7df73SStefano Zampini     /* GPU defaults
19146ea7df73SStefano Zampini          from https://hypre.readthedocs.io/en/latest/solvers-boomeramg.html#gpu-supported-options
19156ea7df73SStefano Zampini          and /src/parcsr_ls/par_amg.c */
19166ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE)
19176ea7df73SStefano Zampini     jac->keeptranspose         = PETSC_TRUE;
19186ea7df73SStefano Zampini     jac->mod_rap2              = 1;
19196ea7df73SStefano Zampini     jac->coarsentype           = 8;
19206ea7df73SStefano Zampini     jac->relaxorder            = 0;
19216ea7df73SStefano Zampini     jac->interptype            = 6;
19226ea7df73SStefano Zampini     jac->relaxtype[0]          = 18;
19236ea7df73SStefano Zampini     jac->relaxtype[1]          = 18;
19246ea7df73SStefano Zampini     jac->agg_interptype        = 7;
19256ea7df73SStefano Zampini #else
19266ea7df73SStefano Zampini     jac->keeptranspose         = PETSC_FALSE;
19276ea7df73SStefano Zampini     jac->mod_rap2              = 0;
19286ea7df73SStefano Zampini #endif
1929a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,jac->hsolver,jac->cycletype);
1930a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,jac->hsolver,jac->maxlevels);
1931a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,jac->maxiter);
1932a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,jac->hsolver,jac->tol);
1933a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,jac->hsolver,jac->truncfactor);
1934a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,jac->hsolver,jac->strongthreshold);
1935a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,jac->hsolver,jac->maxrowsum);
1936a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,jac->hsolver,jac->coarsentype);
1937a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,jac->hsolver,jac->measuretype);
1938a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,jac->hsolver, jac->relaxorder);
1939a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,jac->hsolver,jac->interptype);
1940a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,jac->hsolver,jac->agg_nl);
1941a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetAggInterpType,jac->hsolver,jac->agg_interptype);
1942a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,jac->hsolver,jac->pmax);
1943a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,jac->hsolver,jac->agg_num_paths);
1944a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,jac->hsolver, jac->relaxtype[0]);  /* defaults coarse to 9 */
1945a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,jac->hsolver, jac->gridsweeps[0]); /* defaults coarse to 1 */
1946a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxCoarseSize,jac->hsolver, jac->maxc);
1947a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetMinCoarseSize,jac->hsolver, jac->minc);
19486ea7df73SStefano Zampini     /* GPU */
19496ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0)
1950a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetKeepTranspose,jac->hsolver,jac->keeptranspose ? 1 : 0);
1951a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetRAP2,jac->hsolver, jac->rap2);
1952a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetModuleRAP2,jac->hsolver, jac->mod_rap2);
19536ea7df73SStefano Zampini #endif
19546ea7df73SStefano Zampini 
1955589dcaf0SStefano Zampini     /* AIR */
19566ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0)
1957a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetRestriction,jac->hsolver,jac->Rtype);
1958a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThresholdR,jac->hsolver,jac->Rstrongthreshold);
1959a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetFilterThresholdR,jac->hsolver,jac->Rfilterthreshold);
1960a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetADropTol,jac->hsolver,jac->Adroptol);
1961a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_BoomerAMGSetADropType,jac->hsolver,jac->Adroptype);
19626ea7df73SStefano Zampini #endif
196316d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
196416d9e3a6SLisandro Dalcin   }
19655f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscStrcmp("ams",jac->hypre_type,&flag));
19664cb006feSStefano Zampini   if (flag) {
19675f80ce2aSJacob Faibussowitsch     CHKERRQ(HYPRE_AMSCreate(&jac->hsolver));
19684cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
19694cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
19704cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
19714cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
19724cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
19734cb006feSStefano Zampini     jac->coords[0]           = NULL;
19744cb006feSStefano Zampini     jac->coords[1]           = NULL;
19754cb006feSStefano Zampini     jac->coords[2]           = NULL;
19764cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1977863406b8SStefano Zampini     jac->as_print           = 0;
1978863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1979863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
19804cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
19814cb006feSStefano Zampini     /* Smoothing options */
1982863406b8SStefano Zampini     jac->as_relax_type      = 2;
1983863406b8SStefano Zampini     jac->as_relax_times     = 1;
1984863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1985863406b8SStefano Zampini     jac->as_omega           = 1.0;
19864cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1987863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1988863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
19890bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1990863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1991863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1992863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
19934cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1994863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1995863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
19960bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1997863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1998863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1999863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
2000a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,jac->hsolver,jac->as_print);
2001a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetMaxIter,jac->hsolver,jac->as_max_iter);
2002a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetCycleType,jac->hsolver,jac->ams_cycle_type);
2003a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetTol,jac->hsolver,jac->as_tol);
2004a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,jac->hsolver,jac->as_relax_type,
2005863406b8SStefano Zampini                                                                       jac->as_relax_times,
2006863406b8SStefano Zampini                                                                       jac->as_relax_weight,
2007a74df02fSJacob Faibussowitsch                                                                       jac->as_omega);
2008a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
2009863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
2010863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
2011863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
2012863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
2013a74df02fSJacob Faibussowitsch                                                                      jac->as_amg_alpha_opts[4]);     /* AMG Pmax */
2014a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
2015863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
2016863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
2017863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
2018863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
2019a74df02fSJacob Faibussowitsch                                                                     jac->as_amg_beta_opts[4]);     /* AMG Pmax */
202023df4f25SStefano Zampini     /* Zero conductivity */
202123df4f25SStefano Zampini     jac->ams_beta_is_zero      = PETSC_FALSE;
202223df4f25SStefano Zampini     jac->ams_beta_is_zero_part = PETSC_FALSE;
20234cb006feSStefano Zampini     PetscFunctionReturn(0);
20244cb006feSStefano Zampini   }
20255f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscStrcmp("ads",jac->hypre_type,&flag));
2026863406b8SStefano Zampini   if (flag) {
20275f80ce2aSJacob Faibussowitsch     CHKERRQ(HYPRE_ADSCreate(&jac->hsolver));
2028863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
2029863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
2030863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
2031863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
2032863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
2033863406b8SStefano Zampini     jac->coords[0]           = NULL;
2034863406b8SStefano Zampini     jac->coords[1]           = NULL;
2035863406b8SStefano Zampini     jac->coords[2]           = NULL;
2036863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
2037863406b8SStefano Zampini     jac->as_print           = 0;
2038863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
2039863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
2040863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
2041863406b8SStefano Zampini     /* Smoothing options */
2042863406b8SStefano Zampini     jac->as_relax_type      = 2;
2043863406b8SStefano Zampini     jac->as_relax_times     = 1;
2044863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
2045863406b8SStefano Zampini     jac->as_omega           = 1.0;
2046863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
2047863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
2048863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
2049863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
2050863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
2051863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
2052863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
2053863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
2054863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
2055863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
2056863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
2057863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
2058863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
2059863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
2060863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
2061a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,jac->hsolver,jac->as_print);
2062a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetMaxIter,jac->hsolver,jac->as_max_iter);
2063a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetCycleType,jac->hsolver,jac->ams_cycle_type);
2064a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetTol,jac->hsolver,jac->as_tol);
2065a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,jac->hsolver,jac->as_relax_type,
2066863406b8SStefano Zampini                                                                       jac->as_relax_times,
2067863406b8SStefano Zampini                                                                       jac->as_relax_weight,
2068a74df02fSJacob Faibussowitsch                                                                       jac->as_omega);
2069a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
2070863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
2071863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
2072863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
2073863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
2074863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
2075a74df02fSJacob Faibussowitsch                                                                 jac->as_amg_alpha_opts[4]);     /* AMG Pmax */
2076a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
2077863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
2078863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
2079863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
2080863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
2081a74df02fSJacob Faibussowitsch                                                                 jac->as_amg_beta_opts[4]);     /* AMG Pmax */
2082863406b8SStefano Zampini     PetscFunctionReturn(0);
2083863406b8SStefano Zampini   }
20845f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(jac->hypre_type));
20852fa5cd67SKarl Rupp 
20860298fd71SBarry Smith   jac->hypre_type = NULL;
208798921bdaSJacob Faibussowitsch   SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams",name);
208816d9e3a6SLisandro Dalcin }
208916d9e3a6SLisandro Dalcin 
209016d9e3a6SLisandro Dalcin /*
209116d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
209216d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
209316d9e3a6SLisandro Dalcin */
2094360ee056SFande Kong PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc)
209516d9e3a6SLisandro Dalcin {
20964ddd07fcSJed Brown   PetscInt       indx;
2097db966c6cSHong Zhang   const char     *type[] = {"euclid","pilut","parasails","boomeramg","ams","ads"};
2098ace3abfcSBarry Smith   PetscBool      flg;
209916d9e3a6SLisandro Dalcin 
210016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
21015f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options"));
21025f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,ALEN(type),"boomeramg",&indx,&flg));
210316d9e3a6SLisandro Dalcin   if (flg) {
21045f80ce2aSJacob Faibussowitsch     CHKERRQ(PCHYPRESetType_HYPRE(pc,type[indx]));
210502a17cd4SBarry Smith   } else {
21065f80ce2aSJacob Faibussowitsch     CHKERRQ(PCHYPRESetType_HYPRE(pc,"boomeramg"));
210716d9e3a6SLisandro Dalcin   }
210816d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
21095f80ce2aSJacob Faibussowitsch     CHKERRQ(pc->ops->setfromoptions(PetscOptionsObject,pc));
211016d9e3a6SLisandro Dalcin   }
21115f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsTail());
211216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
211316d9e3a6SLisandro Dalcin }
211416d9e3a6SLisandro Dalcin 
211516d9e3a6SLisandro Dalcin /*@C
211616d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
211716d9e3a6SLisandro Dalcin 
211816d9e3a6SLisandro Dalcin    Input Parameters:
211916d9e3a6SLisandro Dalcin +     pc - the preconditioner context
2120db966c6cSHong Zhang -     name - either  euclid, pilut, parasails, boomeramg, ams, ads
212116d9e3a6SLisandro Dalcin 
212216d9e3a6SLisandro Dalcin    Options Database Keys:
2123db966c6cSHong Zhang    -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
212416d9e3a6SLisandro Dalcin 
212516d9e3a6SLisandro Dalcin    Level: intermediate
212616d9e3a6SLisandro Dalcin 
212716d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
212816d9e3a6SLisandro Dalcin            PCHYPRE
212916d9e3a6SLisandro Dalcin 
213016d9e3a6SLisandro Dalcin @*/
21317087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
213216d9e3a6SLisandro Dalcin {
213316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
21340700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
213516d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
21365f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name)));
213716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
213816d9e3a6SLisandro Dalcin }
213916d9e3a6SLisandro Dalcin 
214016d9e3a6SLisandro Dalcin /*@C
214116d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
214216d9e3a6SLisandro Dalcin 
214316d9e3a6SLisandro Dalcin    Input Parameter:
214416d9e3a6SLisandro Dalcin .     pc - the preconditioner context
214516d9e3a6SLisandro Dalcin 
214616d9e3a6SLisandro Dalcin    Output Parameter:
2147db966c6cSHong Zhang .     name - either  euclid, pilut, parasails, boomeramg, ams, ads
214816d9e3a6SLisandro Dalcin 
214916d9e3a6SLisandro Dalcin    Level: intermediate
215016d9e3a6SLisandro Dalcin 
215116d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
215216d9e3a6SLisandro Dalcin            PCHYPRE
215316d9e3a6SLisandro Dalcin 
215416d9e3a6SLisandro Dalcin @*/
21557087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
215616d9e3a6SLisandro Dalcin {
215716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
21580700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
215916d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
21605f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name)));
216116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
216216d9e3a6SLisandro Dalcin }
216316d9e3a6SLisandro Dalcin 
2164db6f9c32SMark Adams /*@C
2165db6f9c32SMark Adams    PCMGGalerkinSetMatProductAlgorithm - Set type of SpGEMM for hypre to use
2166db6f9c32SMark Adams 
2167db6f9c32SMark Adams    Logically Collective on PC
2168db6f9c32SMark Adams 
2169db6f9c32SMark Adams    Input Parameters:
2170db6f9c32SMark Adams +  pc - the hypre context
2171db6f9c32SMark Adams -  type - one of 'cusparse', 'hypre'
2172db6f9c32SMark Adams 
2173db6f9c32SMark Adams    Options Database Key:
217467b8a455SSatish Balay .  -pc_mg_galerkin_mat_product_algorithm <cusparse,hypre> - Type of SpGEMM to use in hypre
2175db6f9c32SMark Adams 
2176db6f9c32SMark Adams    Level: intermediate
2177db6f9c32SMark Adams 
2178db6f9c32SMark Adams .seealso: PCMGGalerkinGetMatProductAlgorithm()
2179db6f9c32SMark Adams 
2180db6f9c32SMark Adams @*/
2181db6f9c32SMark Adams PetscErrorCode PCMGGalerkinSetMatProductAlgorithm(PC pc,const char name[])
2182db6f9c32SMark Adams {
2183db6f9c32SMark Adams   PetscFunctionBegin;
2184db6f9c32SMark Adams   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
21855f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscTryMethod(pc,"PCMGGalerkinSetMatProductAlgorithm_C",(PC,const char[]),(pc,name)));
2186db6f9c32SMark Adams   PetscFunctionReturn(0);
2187db6f9c32SMark Adams }
2188db6f9c32SMark Adams 
2189db6f9c32SMark Adams /*@C
2190db6f9c32SMark Adams    PCMGGalerkinGetMatProductAlgorithm - Get type of SpGEMM for hypre
2191db6f9c32SMark Adams 
2192db6f9c32SMark Adams    Not Collective
2193db6f9c32SMark Adams 
2194db6f9c32SMark Adams    Input Parameter:
2195db6f9c32SMark Adams .  pc - the multigrid context
2196db6f9c32SMark Adams 
2197db6f9c32SMark Adams    Output Parameter:
2198db6f9c32SMark Adams .  name - one of 'cusparse', 'hypre'
2199db6f9c32SMark Adams 
2200db6f9c32SMark Adams    Level: intermediate
2201db6f9c32SMark Adams 
2202db6f9c32SMark Adams .seealso: PCMGGalerkinSetMatProductAlgorithm()
2203db6f9c32SMark Adams 
2204db6f9c32SMark Adams @*/
2205db6f9c32SMark Adams PetscErrorCode PCMGGalerkinGetMatProductAlgorithm(PC pc,const char *name[])
2206db6f9c32SMark Adams {
2207db6f9c32SMark Adams   PetscFunctionBegin;
2208db6f9c32SMark Adams   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
22095f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscTryMethod(pc,"PCMGGalerkinGetMatProductAlgorithm_C",(PC,const char*[]),(pc,name)));
2210db6f9c32SMark Adams   PetscFunctionReturn(0);
2211db6f9c32SMark Adams }
2212db6f9c32SMark Adams 
221316d9e3a6SLisandro Dalcin /*MC
221416d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
221516d9e3a6SLisandro Dalcin 
221616d9e3a6SLisandro Dalcin    Options Database Keys:
2217db966c6cSHong Zhang +   -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
2218ead8c081SBarry Smith .   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
2219ead8c081SBarry Smith .   -pc_hypre_boomeramg_vec_interp_variant <v> - where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
2220ead8c081SBarry Smith -   Many others, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX preconditioner
222116d9e3a6SLisandro Dalcin 
222216d9e3a6SLisandro Dalcin    Level: intermediate
222316d9e3a6SLisandro Dalcin 
222495452b02SPatrick Sanan    Notes:
222595452b02SPatrick Sanan     Apart from pc_hypre_type (for which there is PCHYPRESetType()),
222616d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
222716d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
222816d9e3a6SLisandro Dalcin 
2229c231f9e3SBarryFSmith           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_tol refer to the number of iterations
22300f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
22310f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
2232c231f9e3SBarryFSmith           (-pc_hypre_boomeramg_tol should be set to 0.0 - the default - to strictly use a fixed number of
22338f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
22340f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
22350f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
223616d9e3a6SLisandro Dalcin 
22370f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
22380f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
22390f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
224016d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
224116d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
224216d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
224316d9e3a6SLisandro Dalcin 
224416d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
224516d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
224616d9e3a6SLisandro Dalcin 
22475272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
2248fdd15c9aSJunchao Zhang           the following two options:
22490b1a5bd9SEric Chamberland 
22509e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
22519e5bc791SBarry Smith 
2252ead8c081SBarry Smith    GPU Notes:
2253ead8c081SBarry Smith      To configure hypre BoomerAMG so that it can utilize NVIDIA GPUs run ./configure --download-hypre --with-cuda
2254ead8c081SBarry Smith      Then pass VECCUDA vectors and MATAIJCUSPARSE matrices to the solvers and PETSc will automatically utilize hypre's GPU solvers.
2255ead8c081SBarry Smith 
2256ead8c081SBarry Smith      To configure hypre BoomerAMG so that it can utilize AMD GPUs run ./configure --download-hypre --with-hip
2257ead8c081SBarry Smith      Then pass VECHIP vectors to the solvers and PETSc will automatically utilize hypre's GPU solvers.
2258ead8c081SBarry Smith 
225916d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
22609e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
226116d9e3a6SLisandro Dalcin 
226216d9e3a6SLisandro Dalcin M*/
226316d9e3a6SLisandro Dalcin 
22648cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
226516d9e3a6SLisandro Dalcin {
226616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
226716d9e3a6SLisandro Dalcin 
226816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
22695f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscNewLog(pc,&jac));
22702fa5cd67SKarl Rupp 
227116d9e3a6SLisandro Dalcin   pc->data                = jac;
22728695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
227316d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
227416d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
227516d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
227616d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
227716d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
22785f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE));
22795f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE));
22805f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE));
22815f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE));
22825f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE));
22835f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",PCHYPRESetInterpolations_HYPRE));
22845f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE));
22855f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",PCHYPRESetPoissonMatrix_HYPRE));
22865f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinSetMatProductAlgorithm_C",PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG));
22875f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinGetMatProductAlgorithm_C",PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG));
22886ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE)
22896ea7df73SStefano Zampini #if defined(HYPRE_USING_HIP)
22905f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscDeviceInitialize(PETSC_DEVICE_HIP));
22916ea7df73SStefano Zampini #endif
22926ea7df73SStefano Zampini #if defined(HYPRE_USING_CUDA)
22935f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscDeviceInitialize(PETSC_DEVICE_CUDA));
22946ea7df73SStefano Zampini #endif
22956ea7df73SStefano Zampini #endif
229616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
229716d9e3a6SLisandro Dalcin }
2298ebc551c0SBarry Smith 
2299f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
2300f91d8e95SBarry Smith 
2301ebc551c0SBarry Smith typedef struct {
230268326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
2303f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
23049e5bc791SBarry Smith 
23059e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
23064ddd07fcSJed Brown   PetscInt its;
23079e5bc791SBarry Smith   double   tol;
23084ddd07fcSJed Brown   PetscInt relax_type;
23094ddd07fcSJed Brown   PetscInt rap_type;
23104ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
23114ddd07fcSJed Brown   PetscInt max_levels;
2312ebc551c0SBarry Smith } PC_PFMG;
2313ebc551c0SBarry Smith 
2314ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
2315ebc551c0SBarry Smith {
2316f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2317ebc551c0SBarry Smith 
2318ebc551c0SBarry Smith   PetscFunctionBegin;
2319a74df02fSJacob Faibussowitsch   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,ex->hsolver);
23205f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc),&ex->hcomm));
23215f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(pc->data));
2322ebc551c0SBarry Smith   PetscFunctionReturn(0);
2323ebc551c0SBarry Smith }
2324ebc551c0SBarry Smith 
23259e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
23269e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
23279e5bc791SBarry Smith 
2328ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
2329ebc551c0SBarry Smith {
2330ace3abfcSBarry Smith   PetscBool      iascii;
2331f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2332ebc551c0SBarry Smith 
2333ebc551c0SBarry Smith   PetscFunctionBegin;
23345f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
23359e5bc791SBarry Smith   if (iascii) {
23365f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n"));
23375f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    max iterations %d\n",ex->its));
23385f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    tolerance %g\n",ex->tol));
23395f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    relax type %s\n",PFMGRelaxType[ex->relax_type]));
23405f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    RAP type %s\n",PFMGRAPType[ex->rap_type]));
23415f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax));
23425f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"    max levels %d\n",ex->max_levels));
23439e5bc791SBarry Smith   }
2344ebc551c0SBarry Smith   PetscFunctionReturn(0);
2345ebc551c0SBarry Smith }
2346ebc551c0SBarry Smith 
23474416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2348ebc551c0SBarry Smith {
2349f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2350ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2351ebc551c0SBarry Smith 
2352ebc551c0SBarry Smith   PetscFunctionBegin;
23535f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsHead(PetscOptionsObject,"PFMG options"));
23545f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL));
235568326731SBarry Smith   if (flg) {
2356a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,ex->hsolver,3);
235768326731SBarry Smith   }
23585f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL));
2359a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,ex->hsolver,ex->its);
23605f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_pfmg_num_pre_relax","Number of smoothing steps before coarse grid","HYPRE_StructPFMGSetNumPreRelax",ex->num_pre_relax,&ex->num_pre_relax,NULL));
2361a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,ex->hsolver,ex->num_pre_relax);
23625f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_pfmg_num_post_relax","Number of smoothing steps after coarse grid","HYPRE_StructPFMGSetNumPostRelax",ex->num_post_relax,&ex->num_post_relax,NULL));
2363a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,ex->hsolver,ex->num_post_relax);
23649e5bc791SBarry Smith 
23655f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL));
2366a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,ex->hsolver,ex->max_levels);
23673b46a515SGlenn Hammond 
23685f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL));
2369a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetTol,ex->hsolver,ex->tol);
23705f80ce2aSJacob Faibussowitsch   CHKERRQ(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));
2371a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,ex->hsolver, ex->relax_type);
23725f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL));
2373a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,ex->hsolver, ex->rap_type);
23745f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsTail());
2375ebc551c0SBarry Smith   PetscFunctionReturn(0);
2376ebc551c0SBarry Smith }
2377ebc551c0SBarry Smith 
2378f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
2379f91d8e95SBarry Smith {
2380f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
2381d9ca1df4SBarry Smith   PetscScalar       *yy;
2382d9ca1df4SBarry Smith   const PetscScalar *xx;
23834ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
23842cf14000SStefano Zampini   HYPRE_Int         hlower[3],hupper[3];
238568326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2386f91d8e95SBarry Smith 
2387f91d8e95SBarry Smith   PetscFunctionBegin;
23885f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCitationsRegister(hypreCitation,&cite));
23895f80ce2aSJacob Faibussowitsch   CHKERRQ(DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]));
23902cf14000SStefano Zampini   /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
2391f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
2392f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
2393f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
23942cf14000SStefano Zampini   hlower[0]  = (HYPRE_Int)ilower[0];
23952cf14000SStefano Zampini   hlower[1]  = (HYPRE_Int)ilower[1];
23962cf14000SStefano Zampini   hlower[2]  = (HYPRE_Int)ilower[2];
23972cf14000SStefano Zampini   hupper[0]  = (HYPRE_Int)iupper[0];
23982cf14000SStefano Zampini   hupper[1]  = (HYPRE_Int)iupper[1];
23992cf14000SStefano Zampini   hupper[2]  = (HYPRE_Int)iupper[2];
2400f91d8e95SBarry Smith 
2401f91d8e95SBarry Smith   /* copy x values over to hypre */
2402a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,mx->hb,0.0);
24035f80ce2aSJacob Faibussowitsch   CHKERRQ(VecGetArrayRead(x,&xx));
2404a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,mx->hb,hlower,hupper,(HYPRE_Complex*)xx);
24055f80ce2aSJacob Faibussowitsch   CHKERRQ(VecRestoreArrayRead(x,&xx));
2406a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructVectorAssemble,mx->hb);
2407a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSolve,ex->hsolver,mx->hmat,mx->hb,mx->hx);
2408f91d8e95SBarry Smith 
2409f91d8e95SBarry Smith   /* copy solution values back to PETSc */
24105f80ce2aSJacob Faibussowitsch   CHKERRQ(VecGetArray(y,&yy));
2411a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,mx->hx,hlower,hupper,(HYPRE_Complex*)yy);
24125f80ce2aSJacob Faibussowitsch   CHKERRQ(VecRestoreArray(y,&yy));
2413f91d8e95SBarry Smith   PetscFunctionReturn(0);
2414f91d8e95SBarry Smith }
2415f91d8e95SBarry Smith 
2416ace3abfcSBarry 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)
24179e5bc791SBarry Smith {
24189e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
24192cf14000SStefano Zampini   HYPRE_Int      oits;
24209e5bc791SBarry Smith 
24219e5bc791SBarry Smith   PetscFunctionBegin;
24225f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCitationsRegister(hypreCitation,&cite));
2423a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,jac->hsolver,its*jac->its);
2424a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetTol,jac->hsolver,rtol);
24259e5bc791SBarry Smith 
24265f80ce2aSJacob Faibussowitsch   CHKERRQ(PCApply_PFMG(pc,b,y));
2427a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,jac->hsolver,&oits);
24289e5bc791SBarry Smith   *outits = oits;
24299e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
24309e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2431a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetTol,jac->hsolver,jac->tol);
2432a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,jac->hsolver,jac->its);
24339e5bc791SBarry Smith   PetscFunctionReturn(0);
24349e5bc791SBarry Smith }
24359e5bc791SBarry Smith 
24363a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
24373a32d3dbSGlenn Hammond {
24383a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
24393a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2440ace3abfcSBarry Smith   PetscBool       flg;
24413a32d3dbSGlenn Hammond 
24423a32d3dbSGlenn Hammond   PetscFunctionBegin;
24435f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg));
2444*28b400f6SJacob Faibussowitsch   PetscCheck(flg,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
24453a32d3dbSGlenn Hammond 
24463a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
2447a74df02fSJacob Faibussowitsch   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,ex->hsolver);
2448a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGCreate,ex->hcomm,&ex->hsolver);
2449a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetup,ex->hsolver,mx->hmat,mx->hb,mx->hx);
2450a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,ex->hsolver);
24513a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
24523a32d3dbSGlenn Hammond }
24533a32d3dbSGlenn Hammond 
2454ebc551c0SBarry Smith /*MC
2455ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
2456ebc551c0SBarry Smith 
2457ebc551c0SBarry Smith    Level: advanced
2458ebc551c0SBarry Smith 
24599e5bc791SBarry Smith    Options Database:
246067b8a455SSatish Balay + -pc_pfmg_its <its> - number of iterations of PFMG to use as preconditioner
246167b8a455SSatish Balay . -pc_pfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid solve
246267b8a455SSatish Balay . -pc_pfmg_num_post_relax <steps> - number of smoothing steps after coarse grid solve
246367b8a455SSatish Balay . -pc_pfmg_tol <tol> - tolerance of PFMG
24649e5bc791SBarry 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
24659e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
2466f91d8e95SBarry Smith 
246795452b02SPatrick Sanan    Notes:
246895452b02SPatrick Sanan     This is for CELL-centered descretizations
24699e5bc791SBarry Smith 
24708e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
2471aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
24729e5bc791SBarry Smith 
24739e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
2474ebc551c0SBarry Smith M*/
2475ebc551c0SBarry Smith 
24768cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
2477ebc551c0SBarry Smith {
2478ebc551c0SBarry Smith   PC_PFMG        *ex;
2479ebc551c0SBarry Smith 
2480ebc551c0SBarry Smith   PetscFunctionBegin;
24815f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscNew(&ex)); \
248268326731SBarry Smith   pc->data = ex;
2483ebc551c0SBarry Smith 
24849e5bc791SBarry Smith   ex->its            = 1;
24859e5bc791SBarry Smith   ex->tol            = 1.e-8;
24869e5bc791SBarry Smith   ex->relax_type     = 1;
24879e5bc791SBarry Smith   ex->rap_type       = 0;
24889e5bc791SBarry Smith   ex->num_pre_relax  = 1;
24899e5bc791SBarry Smith   ex->num_post_relax = 1;
24903b46a515SGlenn Hammond   ex->max_levels     = 0;
24919e5bc791SBarry Smith 
2492ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2493ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2494ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2495f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
24969e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
249768326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
24982fa5cd67SKarl Rupp 
24995f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&ex->hcomm));
2500a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_StructPFMGCreate,ex->hcomm,&ex->hsolver);
2501ebc551c0SBarry Smith   PetscFunctionReturn(0);
2502ebc551c0SBarry Smith }
2503d851a50bSGlenn Hammond 
2504325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2505325fc9f4SBarry Smith 
2506d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2507d851a50bSGlenn Hammond typedef struct {
2508d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2509d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2510d851a50bSGlenn Hammond 
2511d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
25124ddd07fcSJed Brown   PetscInt its;
2513d851a50bSGlenn Hammond   double   tol;
25144ddd07fcSJed Brown   PetscInt relax_type;
25154ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2516d851a50bSGlenn Hammond } PC_SysPFMG;
2517d851a50bSGlenn Hammond 
2518d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2519d851a50bSGlenn Hammond {
2520d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2521d851a50bSGlenn Hammond 
2522d851a50bSGlenn Hammond   PetscFunctionBegin;
2523a74df02fSJacob Faibussowitsch   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,ex->ss_solver);
25245f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc),&ex->hcomm));
25255f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(pc->data));
2526d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2527d851a50bSGlenn Hammond }
2528d851a50bSGlenn Hammond 
2529d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2530d851a50bSGlenn Hammond 
2531d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2532d851a50bSGlenn Hammond {
2533ace3abfcSBarry Smith   PetscBool      iascii;
2534d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2535d851a50bSGlenn Hammond 
2536d851a50bSGlenn Hammond   PetscFunctionBegin;
25375f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
2538d851a50bSGlenn Hammond   if (iascii) {
25395f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n"));
25405f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"  max iterations %d\n",ex->its));
25415f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"  tolerance %g\n",ex->tol));
25425f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"  relax type %s\n",PFMGRelaxType[ex->relax_type]));
25435f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"  number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax));
2544d851a50bSGlenn Hammond   }
2545d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2546d851a50bSGlenn Hammond }
2547d851a50bSGlenn Hammond 
25484416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2549d851a50bSGlenn Hammond {
2550d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2551ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2552d851a50bSGlenn Hammond 
2553d851a50bSGlenn Hammond   PetscFunctionBegin;
25545f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsHead(PetscOptionsObject,"SysPFMG options"));
25555f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL));
2556d851a50bSGlenn Hammond   if (flg) {
2557a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,ex->ss_solver,3);
2558d851a50bSGlenn Hammond   }
25595f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL));
2560a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,ex->ss_solver,ex->its);
25615f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_syspfmg_num_pre_relax","Number of smoothing steps before coarse grid","HYPRE_SStructSysPFMGSetNumPreRelax",ex->num_pre_relax,&ex->num_pre_relax,NULL));
2562a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,ex->ss_solver,ex->num_pre_relax);
25635f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInt("-pc_syspfmg_num_post_relax","Number of smoothing steps after coarse grid","HYPRE_SStructSysPFMGSetNumPostRelax",ex->num_post_relax,&ex->num_post_relax,NULL));
2564a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,ex->ss_solver,ex->num_post_relax);
2565d851a50bSGlenn Hammond 
25665f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL));
2567a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,ex->ss_solver,ex->tol);
25685f80ce2aSJacob Faibussowitsch   CHKERRQ(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));
2569a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,ex->ss_solver, ex->relax_type);
25705f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsTail());
2571d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2572d851a50bSGlenn Hammond }
2573d851a50bSGlenn Hammond 
2574d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2575d851a50bSGlenn Hammond {
2576d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2577d9ca1df4SBarry Smith   PetscScalar       *yy;
2578d9ca1df4SBarry Smith   const PetscScalar *xx;
25794ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
25802cf14000SStefano Zampini   HYPRE_Int         hlower[3],hupper[3];
2581d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
25824ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
25834ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
25844ddd07fcSJed Brown   PetscInt          part    = 0;
25854ddd07fcSJed Brown   PetscInt          size;
25864ddd07fcSJed Brown   PetscInt          i;
2587d851a50bSGlenn Hammond 
2588d851a50bSGlenn Hammond   PetscFunctionBegin;
25895f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCitationsRegister(hypreCitation,&cite));
25905f80ce2aSJacob Faibussowitsch   CHKERRQ(DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]));
25912cf14000SStefano Zampini   /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
2592d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2593d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2594d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
25952cf14000SStefano Zampini   hlower[0]  = (HYPRE_Int)ilower[0];
25962cf14000SStefano Zampini   hlower[1]  = (HYPRE_Int)ilower[1];
25972cf14000SStefano Zampini   hlower[2]  = (HYPRE_Int)ilower[2];
25982cf14000SStefano Zampini   hupper[0]  = (HYPRE_Int)iupper[0];
25992cf14000SStefano Zampini   hupper[1]  = (HYPRE_Int)iupper[1];
26002cf14000SStefano Zampini   hupper[2]  = (HYPRE_Int)iupper[2];
2601d851a50bSGlenn Hammond 
2602d851a50bSGlenn Hammond   size = 1;
26032fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
26042fa5cd67SKarl Rupp 
2605d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2606d851a50bSGlenn Hammond   if (ordering) {
2607a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,mx->ss_b,0.0);
26085f80ce2aSJacob Faibussowitsch     CHKERRQ(VecGetArrayRead(x,&xx));
2609a74df02fSJacob Faibussowitsch     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(xx+(size*i)));
26105f80ce2aSJacob Faibussowitsch     CHKERRQ(VecRestoreArrayRead(x,&xx));
2611a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SStructVectorAssemble,mx->ss_b);
2612a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x);
2613a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x);
2614d851a50bSGlenn Hammond 
2615d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
26165f80ce2aSJacob Faibussowitsch     CHKERRQ(VecGetArray(y,&yy));
2617a74df02fSJacob Faibussowitsch     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(yy+(size*i)));
26185f80ce2aSJacob Faibussowitsch     CHKERRQ(VecRestoreArray(y,&yy));
2619a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2620d851a50bSGlenn Hammond     PetscScalar *z;
26214ddd07fcSJed Brown     PetscInt    j, k;
2622d851a50bSGlenn Hammond 
26235f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscMalloc1(nvars*size,&z));
2624a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,mx->ss_b,0.0);
26255f80ce2aSJacob Faibussowitsch     CHKERRQ(VecGetArrayRead(x,&xx));
2626d851a50bSGlenn Hammond 
2627d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2628d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2629d851a50bSGlenn Hammond       k= i*nvars;
26302fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2631d851a50bSGlenn Hammond     }
2632a74df02fSJacob Faibussowitsch     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i)));
26335f80ce2aSJacob Faibussowitsch     CHKERRQ(VecRestoreArrayRead(x,&xx));
2634a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SStructVectorAssemble,mx->ss_b);
2635a74df02fSJacob Faibussowitsch     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x);
2636d851a50bSGlenn Hammond 
2637d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
26385f80ce2aSJacob Faibussowitsch     CHKERRQ(VecGetArray(y,&yy));
2639a74df02fSJacob Faibussowitsch     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i)));
2640d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2641d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2642d851a50bSGlenn Hammond       k= i*nvars;
26432fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2644d851a50bSGlenn Hammond     }
26455f80ce2aSJacob Faibussowitsch     CHKERRQ(VecRestoreArray(y,&yy));
26465f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscFree(z));
2647d851a50bSGlenn Hammond   }
2648d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2649d851a50bSGlenn Hammond }
2650d851a50bSGlenn Hammond 
2651ace3abfcSBarry 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)
2652d851a50bSGlenn Hammond {
2653d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
26542cf14000SStefano Zampini   HYPRE_Int      oits;
2655d851a50bSGlenn Hammond 
2656d851a50bSGlenn Hammond   PetscFunctionBegin;
26575f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCitationsRegister(hypreCitation,&cite));
2658a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,jac->ss_solver,its*jac->its);
2659a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,jac->ss_solver,rtol);
26605f80ce2aSJacob Faibussowitsch   CHKERRQ(PCApply_SysPFMG(pc,b,y));
2661a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,jac->ss_solver,&oits);
2662d851a50bSGlenn Hammond   *outits = oits;
2663d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2664d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2665a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,jac->ss_solver,jac->tol);
2666a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,jac->ss_solver,jac->its);
2667d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2668d851a50bSGlenn Hammond }
2669d851a50bSGlenn Hammond 
2670d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2671d851a50bSGlenn Hammond {
2672d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2673d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2674ace3abfcSBarry Smith   PetscBool        flg;
2675d851a50bSGlenn Hammond 
2676d851a50bSGlenn Hammond   PetscFunctionBegin;
26775f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg));
2678*28b400f6SJacob Faibussowitsch   PetscCheck(flg,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2679d851a50bSGlenn Hammond 
2680d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
2681a74df02fSJacob Faibussowitsch   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,ex->ss_solver);
2682a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,ex->hcomm,&ex->ss_solver);
2683a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,ex->ss_solver);
2684a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x);
2685d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2686d851a50bSGlenn Hammond }
2687d851a50bSGlenn Hammond 
2688d851a50bSGlenn Hammond /*MC
2689d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2690d851a50bSGlenn Hammond 
2691d851a50bSGlenn Hammond    Level: advanced
2692d851a50bSGlenn Hammond 
2693d851a50bSGlenn Hammond    Options Database:
269467b8a455SSatish Balay + -pc_syspfmg_its <its> - number of iterations of SysPFMG to use as preconditioner
269567b8a455SSatish Balay . -pc_syspfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid
269667b8a455SSatish Balay . -pc_syspfmg_num_post_relax <steps> - number of smoothing steps after coarse grid
269767b8a455SSatish Balay . -pc_syspfmg_tol <tol> - tolerance of SysPFMG
269867b8a455SSatish Balay - -pc_syspfmg_relax_type <Weighted-Jacobi,Red/Black-Gauss-Seidel> - relaxation type for the up and down cycles
2699d851a50bSGlenn Hammond 
270095452b02SPatrick Sanan    Notes:
270195452b02SPatrick Sanan     This is for CELL-centered descretizations
2702d851a50bSGlenn Hammond 
2703f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2704aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2705d851a50bSGlenn Hammond            Also, only cell-centered variables.
2706d851a50bSGlenn Hammond 
2707d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2708d851a50bSGlenn Hammond M*/
2709d851a50bSGlenn Hammond 
27108cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2711d851a50bSGlenn Hammond {
2712d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2713d851a50bSGlenn Hammond 
2714d851a50bSGlenn Hammond   PetscFunctionBegin;
27155f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscNew(&ex)); \
2716d851a50bSGlenn Hammond   pc->data = ex;
2717d851a50bSGlenn Hammond 
2718d851a50bSGlenn Hammond   ex->its            = 1;
2719d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2720d851a50bSGlenn Hammond   ex->relax_type     = 1;
2721d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2722d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2723d851a50bSGlenn Hammond 
2724d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2725d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2726d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2727d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2728d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2729d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
27302fa5cd67SKarl Rupp 
27315f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&ex->hcomm));
2732a74df02fSJacob Faibussowitsch   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,ex->hcomm,&ex->ss_solver);
2733d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2734d851a50bSGlenn Hammond }
2735