xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision e77caa6d1afedf4ba8955df060e5170dedd79f24)
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;
1689566063dSJacob Faibussowitsch   PetscCall(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));
1719566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(num_levels,&mattmp));
1728a2c336bSFande Kong   A_array    = hypre_ParAMGDataAArray((hypre_ParAMGData*) (jac->hsolver));
1738a2c336bSFande Kong   for (l=1; l<num_levels; l++) {
1749566063dSJacob Faibussowitsch     PetscCall(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;
1979566063dSJacob Faibussowitsch   PetscCall(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));
2009566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(num_levels,&mattmp));
2018a2c336bSFande Kong   P_array  = hypre_ParAMGDataPArray((hypre_ParAMGData*) (jac->hsolver));
2028a2c336bSFande Kong   for (l=1; l<num_levels; l++) {
2039566063dSJacob Faibussowitsch     PetscCall(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++) {
2209566063dSJacob Faibussowitsch     PetscCall(VecHYPRE_IJVectorDestroy(&jac->hmnull[i]));
221ce6a8a0dSJed Brown   }
2229566063dSJacob Faibussowitsch   PetscCall(PetscFree(jac->hmnull));
2239566063dSJacob Faibussowitsch   PetscCall(PetscFree(jac->phmnull));
2249566063dSJacob Faibussowitsch   PetscCall(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) {
2399566063dSJacob Faibussowitsch     PetscCall(PCHYPRESetType(pc,"boomeramg"));
24016d9e3a6SLisandro Dalcin   }
2415f5c5b43SBarry Smith 
2429566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRE,&ishypre));
24349a781f5SStefano Zampini   if (!ishypre) {
2449566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&jac->hpmat));
2459566063dSJacob Faibussowitsch     PetscCall(MatConvert(pc->pmat,MATHYPRE,MAT_INITIAL_MATRIX,&jac->hpmat));
2469566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)pc,(PetscObject)jac->hpmat));
24749a781f5SStefano Zampini   } else {
2489566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)pc->pmat));
2499566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&jac->hpmat));
25049a781f5SStefano Zampini     jac->hpmat = pc->pmat;
25116d9e3a6SLisandro Dalcin   }
2526ea7df73SStefano Zampini   /* allow debug */
2539566063dSJacob Faibussowitsch   PetscCall(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 
2639566063dSJacob Faibussowitsch     PetscCall(MatGetBlockSize(pc->pmat,&bs));
264792fecdfSBarry Smith     if (bs > 1) PetscCallExternal(HYPRE_BoomerAMGSetNumFunctions,jac->hsolver,bs);
2659566063dSJacob Faibussowitsch     PetscCall(MatGetNearNullSpace(pc->mat, &mnull));
2665272c319SBarry Smith     if (mnull) {
2679566063dSJacob Faibussowitsch       PetscCall(PCHYPREResetNearNullSpace_Private(pc));
2689566063dSJacob Faibussowitsch       PetscCall(MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs));
2699566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(nvec+1,&jac->hmnull));
2709566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(nvec+1,&jac->phmnull));
2715272c319SBarry Smith       for (i=0; i<nvec; i++) {
2729566063dSJacob Faibussowitsch         PetscCall(VecHYPRE_IJVectorCreate(vecs[i]->map,&jac->hmnull[i]));
2739566063dSJacob Faibussowitsch         PetscCall(VecHYPRE_IJVectorCopy(vecs[i],jac->hmnull[i]));
274792fecdfSBarry Smith         PetscCallExternal(HYPRE_IJVectorGetObject,jac->hmnull[i]->ij,(void**)&jac->phmnull[i]);
2755272c319SBarry Smith       }
2765272c319SBarry Smith       if (has_const) {
2779566063dSJacob Faibussowitsch         PetscCall(MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL));
2789566063dSJacob Faibussowitsch         PetscCall(PetscLogObjectParent((PetscObject)pc,(PetscObject)jac->hmnull_constant));
2799566063dSJacob Faibussowitsch         PetscCall(VecSet(jac->hmnull_constant,1));
2809566063dSJacob Faibussowitsch         PetscCall(VecNormalize(jac->hmnull_constant,NULL));
2819566063dSJacob Faibussowitsch         PetscCall(VecHYPRE_IJVectorCreate(jac->hmnull_constant->map,&jac->hmnull[nvec]));
2829566063dSJacob Faibussowitsch         PetscCall(VecHYPRE_IJVectorCopy(jac->hmnull_constant,jac->hmnull[nvec]));
283792fecdfSBarry Smith         PetscCallExternal(HYPRE_IJVectorGetObject,jac->hmnull[nvec]->ij,(void**)&jac->phmnull[nvec]);
2845272c319SBarry Smith         nvec++;
2855272c319SBarry Smith       }
286792fecdfSBarry Smith       PetscCallExternal(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) {
299792fecdfSBarry Smith       PetscCallExternal(HYPRE_AMSSetDimension,jac->hsolver,jac->dim);
3005ac14e1cSStefano Zampini     }
3015ac14e1cSStefano Zampini     if (jac->constants[0]) {
3025ac14e1cSStefano Zampini       HYPRE_ParVector ozz,zoz,zzo = NULL;
303792fecdfSBarry Smith       PetscCallExternal(HYPRE_IJVectorGetObject,jac->constants[0]->ij,(void**)(&ozz));
304792fecdfSBarry Smith       PetscCallExternal(HYPRE_IJVectorGetObject,jac->constants[1]->ij,(void**)(&zoz));
3055ac14e1cSStefano Zampini       if (jac->constants[2]) {
306792fecdfSBarry Smith         PetscCallExternal(HYPRE_IJVectorGetObject,jac->constants[2]->ij,(void**)(&zzo));
3075ac14e1cSStefano Zampini       }
308792fecdfSBarry Smith       PetscCallExternal(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;
315792fecdfSBarry Smith       if (jac->coords[0]) PetscCallExternal(HYPRE_IJVectorGetObject,jac->coords[0]->ij,(void**)(&coords[0]));
316792fecdfSBarry Smith       if (jac->coords[1]) PetscCallExternal(HYPRE_IJVectorGetObject,jac->coords[1]->ij,(void**)(&coords[1]));
317792fecdfSBarry Smith       if (jac->coords[2]) PetscCallExternal(HYPRE_IJVectorGetObject,jac->coords[2]->ij,(void**)(&coords[2]));
318792fecdfSBarry Smith       PetscCallExternal(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);
322792fecdfSBarry Smith     PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr));
323792fecdfSBarry Smith     PetscCallExternal(HYPRE_AMSSetDiscreteGradient,jac->hsolver,parcsr);
3245ac14e1cSStefano Zampini     if (jac->alpha_Poisson) {
3255ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->alpha_Poisson->data);
326792fecdfSBarry Smith       PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr));
327792fecdfSBarry Smith       PetscCallExternal(HYPRE_AMSSetAlphaPoissonMatrix,jac->hsolver,parcsr);
3285ac14e1cSStefano Zampini     }
3295ac14e1cSStefano Zampini     if (jac->ams_beta_is_zero) {
330792fecdfSBarry Smith       PetscCallExternal(HYPRE_AMSSetBetaPoissonMatrix,jac->hsolver,NULL);
3315ac14e1cSStefano Zampini     } else if (jac->beta_Poisson) {
3325ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->beta_Poisson->data);
333792fecdfSBarry Smith       PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr));
334792fecdfSBarry Smith       PetscCallExternal(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);
341792fecdfSBarry Smith         PetscCallExternal(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);
348792fecdfSBarry Smith           PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&nd_parcsr[i]));
3496bf688a0SCe Qin         } else {
3506bf688a0SCe Qin           nd_parcsr[i] = NULL;
3516bf688a0SCe Qin         }
3526bf688a0SCe Qin       }
353792fecdfSBarry Smith       PetscCallExternal(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     }
3637827d75bSBarry Smith     else PetscCheck(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;
371792fecdfSBarry Smith       if (jac->coords[0]) PetscCallExternal(HYPRE_IJVectorGetObject,jac->coords[0]->ij,(void**)(&coords[0]));
372792fecdfSBarry Smith       if (jac->coords[1]) PetscCallExternal(HYPRE_IJVectorGetObject,jac->coords[1]->ij,(void**)(&coords[1]));
373792fecdfSBarry Smith       if (jac->coords[2]) PetscCallExternal(HYPRE_IJVectorGetObject,jac->coords[2]->ij,(void**)(&coords[2]));
374792fecdfSBarry Smith       PetscCallExternal(HYPRE_ADSSetCoordinateVectors,jac->hsolver,coords[0],coords[1],coords[2]);
3755ac14e1cSStefano Zampini     }
3765ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
377792fecdfSBarry Smith     PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr));
378792fecdfSBarry Smith     PetscCallExternal(HYPRE_ADSSetDiscreteGradient,jac->hsolver,parcsr);
3795ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->C->data);
380792fecdfSBarry Smith     PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&parcsr));
381792fecdfSBarry Smith     PetscCallExternal(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);
388792fecdfSBarry Smith         PetscCallExternal(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);
395792fecdfSBarry Smith           PetscCallExternal(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);
402792fecdfSBarry Smith         PetscCallExternal(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);
409792fecdfSBarry Smith           PetscCallExternal(HYPRE_IJMatrixGetObject,hm->ij,(void**)(&nd_parcsr[i]));
4106bf688a0SCe Qin         } else {
4116bf688a0SCe Qin           nd_parcsr[i] = NULL;
4126bf688a0SCe Qin         }
4136bf688a0SCe Qin       }
414792fecdfSBarry Smith       PetscCallExternal(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   }
417792fecdfSBarry Smith   PetscCallExternal(HYPRE_IJMatrixGetObject,hjac->ij,(void**)&hmat);
418792fecdfSBarry Smith   PetscCallExternal(HYPRE_IJVectorGetObject,hjac->b->ij,(void**)&bv);
419792fecdfSBarry Smith   PetscCallExternal(HYPRE_IJVectorGetObject,hjac->x->ij,(void**)&xv);
420792fecdfSBarry Smith   PetscCallExternal(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;
4329566063dSJacob Faibussowitsch   PetscCall(PetscCitationsRegister(hypreCitation,&cite));
4339566063dSJacob Faibussowitsch   if (!jac->applyrichardson) PetscCall(VecSet(x,0.0));
4349566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorPushVecRead(hjac->b,b));
4359566063dSJacob Faibussowitsch   if (jac->applyrichardson) PetscCall(VecHYPRE_IJVectorPushVec(hjac->x,x));
4369566063dSJacob Faibussowitsch   else PetscCall(VecHYPRE_IJVectorPushVecWrite(hjac->x,x));
437792fecdfSBarry Smith   PetscCallExternal(HYPRE_IJMatrixGetObject,hjac->ij,(void**)&hmat);
438792fecdfSBarry Smith   PetscCallExternal(HYPRE_IJVectorGetObject,hjac->b->ij,(void**)&jbv);
439792fecdfSBarry Smith   PetscCallExternal(HYPRE_IJVectorGetObject,hjac->x->ij,(void**)&jxv);
440*e77caa6dSBarry Smith   PetscStackCallExternalVoid("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) {
449792fecdfSBarry Smith     PetscCallExternal(HYPRE_AMSProjectOutGradients,jac->hsolver,jxv);
45021df291bSStefano Zampini   }
4519566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorPopVec(hjac->x));
4529566063dSJacob Faibussowitsch   PetscCall(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;
4619566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&jac->hpmat));
4629566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&jac->G));
4639566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&jac->C));
4649566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&jac->alpha_Poisson));
4659566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&jac->beta_Poisson));
4669566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&jac->RT_PiFull));
4679566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&jac->RT_Pi[0]));
4689566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&jac->RT_Pi[1]));
4699566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&jac->RT_Pi[2]));
4709566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&jac->ND_PiFull));
4719566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&jac->ND_Pi[0]));
4729566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&jac->ND_Pi[1]));
4739566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&jac->ND_Pi[2]));
4749566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[0]));
4759566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[1]));
4769566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[2]));
4779566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[0]));
4789566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[1]));
4799566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[2]));
4809566063dSJacob Faibussowitsch   PetscCall(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;
4919566063dSJacob Faibussowitsch   PetscCall(PCReset_HYPRE(pc));
492792fecdfSBarry Smith   if (jac->destroy) PetscCallExternal(jac->destroy,jac->hsolver);
4939566063dSJacob Faibussowitsch   PetscCall(PetscFree(jac->hypre_type));
494db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0)
4959566063dSJacob Faibussowitsch   PetscCall(PetscFree(jac->spgemm_type));
496db6f9c32SMark Adams #endif
4979566063dSJacob Faibussowitsch   if (jac->comm_hypre != MPI_COMM_NULL) PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre));
4989566063dSJacob Faibussowitsch   PetscCall(PetscFree(pc->data));
49916d9e3a6SLisandro Dalcin 
5009566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)pc,0));
5019566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL));
5029566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL));
5039566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL));
5049566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL));
5059566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",NULL));
5069566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL));
5079566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",NULL));
5082e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",NULL));
5099566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",NULL));
5109566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",NULL));
5119566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinSetMatProductAlgorithm_C",NULL));
5129566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinGetMatProductAlgorithm_C",NULL));
5132e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",NULL));
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;
524d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE Pilut Options");
5259566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag));
526792fecdfSBarry Smith   if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetMaxIter,jac->hsolver,jac->maxiter);
5279566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag));
528792fecdfSBarry Smith   if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetDropTolerance,jac->hsolver,jac->tol);
5299566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag));
530792fecdfSBarry Smith   if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetFactorRowSize,jac->hsolver,jac->factorrowsize);
531d0609cedSBarry Smith   PetscOptionsHeadEnd();
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;
5419566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
54216d9e3a6SLisandro Dalcin   if (iascii) {
5439566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n"));
54416d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
54563a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    maximum number of iterations %" PetscInt_FMT "\n",jac->maxiter));
54616d9e3a6SLisandro Dalcin     } else {
5479566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    default maximum number of iterations \n"));
54816d9e3a6SLisandro Dalcin     }
54916d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
5509566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->tol));
55116d9e3a6SLisandro Dalcin     } else {
5529566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    default drop tolerance \n"));
55316d9e3a6SLisandro Dalcin     }
55416d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
55563a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    factor row size %" PetscInt_FMT "\n",jac->factorrowsize));
55616d9e3a6SLisandro Dalcin     } else {
5579566063dSJacob Faibussowitsch       PetscCall(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;
570d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE Euclid Options");
5719566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_euclid_level","Factorization levels","None",jac->eu_level,&jac->eu_level,&flag));
572792fecdfSBarry Smith   if (flag) PetscCallExternal(HYPRE_EuclidSetLevel,jac->hsolver,jac->eu_level);
5738bf83915SBarry Smith 
5749566063dSJacob Faibussowitsch   PetscCall(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 
5789566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size));
5797827d75bSBarry Smith     PetscCheck(size == 1,PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"hypre's Euclid does not support a parallel drop tolerance");
580792fecdfSBarry Smith     PetscCallExternal(HYPRE_EuclidSetILUT,jac->hsolver,jac->eu_droptolerance);
5818bf83915SBarry Smith   }
5828bf83915SBarry Smith 
5839566063dSJacob Faibussowitsch   PetscCall(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;
586792fecdfSBarry Smith     PetscCallExternal(HYPRE_EuclidSetBJ,jac->hsolver,jac->eu_bj);
5878bf83915SBarry Smith   }
588d0609cedSBarry Smith   PetscOptionsHeadEnd();
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;
5989566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
599db966c6cSHong Zhang   if (iascii) {
6009566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid preconditioning\n"));
601db966c6cSHong Zhang     if (jac->eu_level != PETSC_DEFAULT) {
60263a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    factorization levels %" PetscInt_FMT "\n",jac->eu_level));
603db966c6cSHong Zhang     } else {
6049566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    default factorization levels \n"));
605db966c6cSHong Zhang     }
6069566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->eu_droptolerance));
60763a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    use Block-Jacobi? %" PetscInt_FMT "\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;
6229566063dSJacob Faibussowitsch   PetscCall(PetscCitationsRegister(hypreCitation,&cite));
6239566063dSJacob Faibussowitsch   PetscCall(VecSet(x,0.0));
6249566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorPushVecRead(hjac->x,b));
6259566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorPushVecWrite(hjac->b,x));
62616d9e3a6SLisandro Dalcin 
627792fecdfSBarry Smith   PetscCallExternal(HYPRE_IJMatrixGetObject,hjac->ij,(void**)&hmat);
628792fecdfSBarry Smith   PetscCallExternal(HYPRE_IJVectorGetObject,hjac->b->ij,(void**)&jbv);
629792fecdfSBarry Smith   PetscCallExternal(HYPRE_IJVectorGetObject,hjac->x->ij,(void**)&jxv);
63016d9e3a6SLisandro Dalcin 
631*e77caa6dSBarry Smith   PetscStackCallExternalVoid("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 
6409566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorPopVec(hjac->x));
6419566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorPopVec(hjac->b));
64216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
64316d9e3a6SLisandro Dalcin }
64416d9e3a6SLisandro Dalcin 
645db6f9c32SMark Adams static PetscErrorCode PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc,const char name[])
646db6f9c32SMark Adams {
647db6f9c32SMark Adams   PC_HYPRE *jac  = (PC_HYPRE*)pc->data;
648db6f9c32SMark Adams   PetscBool      flag;
649db6f9c32SMark Adams 
650db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0)
651db6f9c32SMark Adams   PetscFunctionBegin;
652db6f9c32SMark Adams   if (jac->spgemm_type) {
6539566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(jac->spgemm_type,name,&flag));
65428b400f6SJacob Faibussowitsch     PetscCheck(flag,PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE SpGEMM (really we can)");
655db6f9c32SMark Adams     PetscFunctionReturn(0);
656db6f9c32SMark Adams   } else {
6579566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, &jac->spgemm_type));
658db6f9c32SMark Adams   }
6599566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp("cusparse",jac->spgemm_type,&flag));
660db6f9c32SMark Adams   if (flag) {
661792fecdfSBarry Smith     PetscCallExternal(HYPRE_SetSpGemmUseCusparse,1);
662db6f9c32SMark Adams     PetscFunctionReturn(0);
663db6f9c32SMark Adams   }
6649566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp("hypre",jac->spgemm_type,&flag));
665db6f9c32SMark Adams   if (flag) {
666792fecdfSBarry Smith     PetscCallExternal(HYPRE_SetSpGemmUseCusparse,0);
667db6f9c32SMark Adams     PetscFunctionReturn(0);
668db6f9c32SMark Adams   }
669db6f9c32SMark Adams   jac->spgemm_type = NULL;
67098921bdaSJacob Faibussowitsch   SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE SpGEM type %s; Choices are cusparse, hypre",name);
671db6f9c32SMark Adams #endif
672db6f9c32SMark Adams }
673db6f9c32SMark Adams 
674db6f9c32SMark Adams static PetscErrorCode PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc, const char *spgemm[])
675db6f9c32SMark Adams {
676db6f9c32SMark Adams   PC_HYPRE *jac  = (PC_HYPRE*)pc->data;
677db6f9c32SMark Adams 
678db6f9c32SMark Adams   PetscFunctionBegin;
679db6f9c32SMark Adams   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
680db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0)
681db6f9c32SMark Adams   *spgemm = jac->spgemm_type;
682db6f9c32SMark Adams #endif
683db6f9c32SMark Adams   PetscFunctionReturn(0);
684db6f9c32SMark Adams }
685db6f9c32SMark Adams 
68616d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
6870f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
68816d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
68965de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
6906a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]  = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
69165de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
69265de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
69365de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
6947b7fa87dSPierre Jolivet                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "l1-Gauss-Seidel" /* nonsymmetric */, "backward-l1-Gauss-Seidel" /* nonsymmetric */,
69565de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
6960f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
697589dcaf0SStefano Zampini                                                   "ext+i-cc", "standard", "standard-wts", "block", "block-wtd", "FF", "FF1",
698589dcaf0SStefano Zampini                                                   "ext", "ad-wts", "ext-mm", "ext+i-mm", "ext+e-mm"};
6994416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc)
70016d9e3a6SLisandro Dalcin {
70116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
70222e51d31SStefano Zampini   PetscInt       bs,n,indx,level;
703ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
70416d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
705589dcaf0SStefano Zampini   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
706db6f9c32SMark Adams   const char     *PCHYPRESpgemmTypes[] = {"cusparse","hypre"};
70716d9e3a6SLisandro Dalcin 
70816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
709d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE BoomerAMG Options");
7109566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg));
71116d9e3a6SLisandro Dalcin   if (flg) {
7124336a9eeSBarry Smith     jac->cycletype = indx+1;
713792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetCycleType,jac->hsolver,jac->cycletype);
71416d9e3a6SLisandro Dalcin   }
7159566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg));
71616d9e3a6SLisandro Dalcin   if (flg) {
71763a3b9bcSJacob Faibussowitsch     PetscCheck(jac->maxlevels >= 2,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %" PetscInt_FMT " must be at least two",jac->maxlevels);
718792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetMaxLevels,jac->hsolver,jac->maxlevels);
71916d9e3a6SLisandro Dalcin   }
7209566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg));
72116d9e3a6SLisandro Dalcin   if (flg) {
72263a3b9bcSJacob Faibussowitsch     PetscCheck(jac->maxiter >= 1,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %" PetscInt_FMT " must be at least one",jac->maxiter);
723792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,jac->maxiter);
72416d9e3a6SLisandro Dalcin   }
7259566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_tol","Convergence tolerance PER hypre call (0.0 = use a fixed number of iterations)","None",jac->tol,&jac->tol,&flg));
72616d9e3a6SLisandro Dalcin   if (flg) {
72708401ef6SPierre Jolivet     PetscCheck(jac->tol >= 0.0,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Tolerance %g must be greater than or equal to zero",(double)jac->tol);
728792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetTol,jac->hsolver,jac->tol);
72916d9e3a6SLisandro Dalcin   }
73022e51d31SStefano Zampini   bs = 1;
73122e51d31SStefano Zampini   if (pc->pmat) {
7329566063dSJacob Faibussowitsch     PetscCall(MatGetBlockSize(pc->pmat,&bs));
73322e51d31SStefano Zampini   }
7349566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_numfunctions","Number of functions","HYPRE_BoomerAMGSetNumFunctions",bs,&bs,&flg));
73522e51d31SStefano Zampini   if (flg) {
736792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetNumFunctions,jac->hsolver,bs);
73722e51d31SStefano Zampini   }
73816d9e3a6SLisandro Dalcin 
7399566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg));
74016d9e3a6SLisandro Dalcin   if (flg) {
74108401ef6SPierre Jolivet     PetscCheck(jac->truncfactor >= 0.0,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Truncation factor %g must be great than or equal zero",(double)jac->truncfactor);
742792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetTruncFactor,jac->hsolver,jac->truncfactor);
74316d9e3a6SLisandro Dalcin   }
74416d9e3a6SLisandro Dalcin 
7459566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_P_max","Max elements per row for interpolation operator (0=unlimited)","None",jac->pmax,&jac->pmax,&flg));
7460f1074feSSatish Balay   if (flg) {
74763a3b9bcSJacob Faibussowitsch     PetscCheck(jac->pmax >= 0,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"P_max %" PetscInt_FMT " must be greater than or equal to zero",jac->pmax);
748792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetPMaxElmts,jac->hsolver,jac->pmax);
7490f1074feSSatish Balay   }
7500f1074feSSatish Balay 
7519566063dSJacob Faibussowitsch   PetscCall(PetscOptionsRangeInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg,0,jac->maxlevels));
752792fecdfSBarry Smith   if (flg) PetscCallExternal(HYPRE_BoomerAMGSetAggNumLevels,jac->hsolver,jac->agg_nl);
7530f1074feSSatish Balay 
7549566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_agg_num_paths","Number of paths for aggressive coarsening","None",jac->agg_num_paths,&jac->agg_num_paths,&flg));
7550f1074feSSatish Balay   if (flg) {
75663a3b9bcSJacob Faibussowitsch     PetscCheck(jac->agg_num_paths >= 1,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of paths %" PetscInt_FMT " must be greater than or equal to 1",jac->agg_num_paths);
757792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetNumPaths,jac->hsolver,jac->agg_num_paths);
7580f1074feSSatish Balay   }
7590f1074feSSatish Balay 
7609566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg));
76116d9e3a6SLisandro Dalcin   if (flg) {
76208401ef6SPierre Jolivet     PetscCheck(jac->strongthreshold >= 0.0,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Strong threshold %g must be great than or equal zero",(double)jac->strongthreshold);
763792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetStrongThreshold,jac->hsolver,jac->strongthreshold);
76416d9e3a6SLisandro Dalcin   }
7659566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg));
76616d9e3a6SLisandro Dalcin   if (flg) {
76708401ef6SPierre Jolivet     PetscCheck(jac->maxrowsum >= 0.0,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Maximum row sum %g must be greater than zero",(double)jac->maxrowsum);
76808401ef6SPierre Jolivet     PetscCheck(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);
769792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetMaxRowSum,jac->hsolver,jac->maxrowsum);
77016d9e3a6SLisandro Dalcin   }
77116d9e3a6SLisandro Dalcin 
77216d9e3a6SLisandro Dalcin   /* Grid sweeps */
7739566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_all","Number of sweeps for the up and down grid levels","None",jac->gridsweeps[0],&indx,&flg));
77416d9e3a6SLisandro Dalcin   if (flg) {
775792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetNumSweeps,jac->hsolver,indx);
77616d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
77716d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
7780f1074feSSatish Balay     jac->gridsweeps[1] = indx;
7790f1074feSSatish Balay     /*defaults coarse to 1 */
7800f1074feSSatish Balay     jac->gridsweeps[2] = 1;
78116d9e3a6SLisandro Dalcin   }
7829566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_nodal_coarsen","Use a nodal based coarsening 1-6","HYPRE_BoomerAMGSetNodal",jac->nodal_coarsening,&jac->nodal_coarsening,&flg));
7835272c319SBarry Smith   if (flg) {
784792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetNodal,jac->hsolver,jac->nodal_coarsening);
7855272c319SBarry Smith   }
7869566063dSJacob Faibussowitsch   PetscCall(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));
78722e51d31SStefano Zampini   if (flg) {
788792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetNodalDiag,jac->hsolver,jac->nodal_coarsening_diag);
78922e51d31SStefano Zampini   }
7909566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_vec_interp_variant","Variant of algorithm 1-3","HYPRE_BoomerAMGSetInterpVecVariant",jac->vec_interp_variant, &jac->vec_interp_variant,&flg));
7915272c319SBarry Smith   if (flg) {
792792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetInterpVecVariant,jac->hsolver,jac->vec_interp_variant);
7935272c319SBarry Smith   }
7949566063dSJacob Faibussowitsch   PetscCall(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));
79522e51d31SStefano Zampini   if (flg) {
796792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetInterpVecQMax,jac->hsolver,jac->vec_interp_qmax);
79722e51d31SStefano Zampini   }
7989566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_vec_interp_smooth","Whether to smooth the interpolation vectors","HYPRE_BoomerAMGSetSmoothInterpVectors",jac->vec_interp_smooth, &jac->vec_interp_smooth,&flg));
79922e51d31SStefano Zampini   if (flg) {
800792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetSmoothInterpVectors,jac->hsolver,jac->vec_interp_smooth);
80122e51d31SStefano Zampini   }
8029566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_interp_refine","Preprocess the interpolation matrix through iterative weight refinement","HYPRE_BoomerAMGSetInterpRefine",jac->interp_refine, &jac->interp_refine,&flg));
80322e51d31SStefano Zampini   if (flg) {
804792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetInterpRefine,jac->hsolver,jac->interp_refine);
80522e51d31SStefano Zampini   }
8069566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg));
80716d9e3a6SLisandro Dalcin   if (flg) {
808792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps,jac->hsolver,indx, 1);
8090f1074feSSatish Balay     jac->gridsweeps[0] = indx;
81016d9e3a6SLisandro Dalcin   }
8119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg));
81216d9e3a6SLisandro Dalcin   if (flg) {
813792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps,jac->hsolver,indx, 2);
8140f1074feSSatish Balay     jac->gridsweeps[1] = indx;
81516d9e3a6SLisandro Dalcin   }
8169566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg));
81716d9e3a6SLisandro Dalcin   if (flg) {
818792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps,jac->hsolver,indx, 3);
8190f1074feSSatish Balay     jac->gridsweeps[2] = indx;
82016d9e3a6SLisandro Dalcin   }
82116d9e3a6SLisandro Dalcin 
8226a251517SEike Mueller   /* Smooth type */
823dd39110bSPierre Jolivet   PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg));
8246a251517SEike Mueller   if (flg) {
8256a251517SEike Mueller     jac->smoothtype = indx;
826792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetSmoothType,jac->hsolver,indx+6);
8278131ecf7SEike Mueller     jac->smoothnumlevels = 25;
828792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels,jac->hsolver,25);
8298131ecf7SEike Mueller   }
8308131ecf7SEike Mueller 
8318131ecf7SEike Mueller   /* Number of smoothing levels */
8329566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_smooth_num_levels","Number of levels on which more complex smoothers are used","None",25,&indx,&flg));
8338131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
8348131ecf7SEike Mueller     jac->smoothnumlevels = indx;
835792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels,jac->hsolver,indx);
8366a251517SEike Mueller   }
8376a251517SEike Mueller 
8381810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
8399566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg));
8401810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8411810e44eSEike Mueller     jac->eu_level = indx;
842792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetEuLevel,jac->hsolver,indx);
8431810e44eSEike Mueller   }
8441810e44eSEike Mueller 
8451810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
8461810e44eSEike Mueller   double droptolerance;
8479566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg));
8481810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8491810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
850792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetEuLevel,jac->hsolver,droptolerance);
8511810e44eSEike Mueller   }
8521810e44eSEike Mueller 
8531810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
8549566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg));
8551810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8561810e44eSEike Mueller     jac->eu_bj = tmp_truth;
857792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetEuBJ,jac->hsolver,jac->eu_bj);
8581810e44eSEike Mueller   }
8591810e44eSEike Mueller 
86016d9e3a6SLisandro Dalcin   /* Relax type */
861dd39110bSPierre Jolivet   PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_relax_type_all","Relax type for the up and down cycles","None",HYPREBoomerAMGRelaxType,PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg));
86216d9e3a6SLisandro Dalcin   if (flg) {
8630f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
864792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetRelaxType,jac->hsolver, indx);
8650f1074feSSatish Balay     /* by default, coarse type set to 9 */
8660f1074feSSatish Balay     jac->relaxtype[2] = 9;
867792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, 9, 3);
86816d9e3a6SLisandro Dalcin   }
869dd39110bSPierre Jolivet   PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_relax_type_down","Relax type for the down cycles","None",HYPREBoomerAMGRelaxType,PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg));
87016d9e3a6SLisandro Dalcin   if (flg) {
87116d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
872792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, indx, 1);
87316d9e3a6SLisandro Dalcin   }
874dd39110bSPierre Jolivet   PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_relax_type_up","Relax type for the up cycles","None",HYPREBoomerAMGRelaxType,PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg));
87516d9e3a6SLisandro Dalcin   if (flg) {
8760f1074feSSatish Balay     jac->relaxtype[1] = indx;
877792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, indx, 2);
87816d9e3a6SLisandro Dalcin   }
879dd39110bSPierre Jolivet   PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg));
88016d9e3a6SLisandro Dalcin   if (flg) {
8810f1074feSSatish Balay     jac->relaxtype[2] = indx;
882792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType,jac->hsolver, indx, 3);
88316d9e3a6SLisandro Dalcin   }
88416d9e3a6SLisandro Dalcin 
88516d9e3a6SLisandro Dalcin   /* Relaxation Weight */
8869566063dSJacob Faibussowitsch   PetscCall(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));
88716d9e3a6SLisandro Dalcin   if (flg) {
888792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetRelaxWt,jac->hsolver,tmpdbl);
88916d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
89016d9e3a6SLisandro Dalcin   }
89116d9e3a6SLisandro Dalcin 
89216d9e3a6SLisandro Dalcin   n         = 2;
89316d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
8949566063dSJacob Faibussowitsch   PetscCall(PetscOptionsRealArray("-pc_hypre_boomeramg_relax_weight_level","Set the relaxation weight for a particular level (weight,level)","None",twodbl, &n, &flg));
89516d9e3a6SLisandro Dalcin   if (flg) {
89616d9e3a6SLisandro Dalcin     if (n == 2) {
89716d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
898792fecdfSBarry Smith       PetscCallExternal(HYPRE_BoomerAMGSetLevelRelaxWt,jac->hsolver,twodbl[0],indx);
89963a3b9bcSJacob 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 %" PetscInt_FMT,n);
90016d9e3a6SLisandro Dalcin   }
90116d9e3a6SLisandro Dalcin 
90216d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
9039566063dSJacob Faibussowitsch   PetscCall(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));
90416d9e3a6SLisandro Dalcin   if (flg) {
905792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetOuterWt,jac->hsolver, tmpdbl);
90616d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
90716d9e3a6SLisandro Dalcin   }
90816d9e3a6SLisandro Dalcin 
90916d9e3a6SLisandro Dalcin   n         = 2;
91016d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
9119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsRealArray("-pc_hypre_boomeramg_outer_relax_weight_level","Set the outer relaxation weight for a particular level (weight,level)","None",twodbl, &n, &flg));
91216d9e3a6SLisandro Dalcin   if (flg) {
91316d9e3a6SLisandro Dalcin     if (n == 2) {
91416d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
915792fecdfSBarry Smith       PetscCallExternal(HYPRE_BoomerAMGSetLevelOuterWt,jac->hsolver, twodbl[0], indx);
91663a3b9bcSJacob 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 %" PetscInt_FMT,n);
91716d9e3a6SLisandro Dalcin   }
91816d9e3a6SLisandro Dalcin 
91916d9e3a6SLisandro Dalcin   /* the Relax Order */
9209566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg));
92116d9e3a6SLisandro Dalcin 
9228afaa268SBarry Smith   if (flg && tmp_truth) {
92316d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
924792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetRelaxOrder,jac->hsolver, jac->relaxorder);
92516d9e3a6SLisandro Dalcin   }
926dd39110bSPierre Jolivet   PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg));
92716d9e3a6SLisandro Dalcin   if (flg) {
92816d9e3a6SLisandro Dalcin     jac->measuretype = indx;
929792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetMeasureType,jac->hsolver,jac->measuretype);
93016d9e3a6SLisandro Dalcin   }
9310f1074feSSatish Balay   /* update list length 3/07 */
932dd39110bSPierre Jolivet   PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg));
93316d9e3a6SLisandro Dalcin   if (flg) {
93416d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
935792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetCoarsenType,jac->hsolver,jac->coarsentype);
93616d9e3a6SLisandro Dalcin   }
9370f1074feSSatish Balay 
9389566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_max_coarse_size", "Maximum size of coarsest grid", "None", jac->maxc, &jac->maxc, &flg));
939589dcaf0SStefano Zampini   if (flg) {
940792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetMaxCoarseSize,jac->hsolver, jac->maxc);
941589dcaf0SStefano Zampini   }
9429566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_min_coarse_size", "Minimum size of coarsest grid", "None", jac->minc, &jac->minc, &flg));
943589dcaf0SStefano Zampini   if (flg) {
944792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetMinCoarseSize,jac->hsolver, jac->minc);
945589dcaf0SStefano Zampini   }
946db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0)
947db6f9c32SMark Adams   // global parameter but is closely associated with BoomerAMG
948dd39110bSPierre Jolivet   PetscCall(PetscOptionsEList("-pc_mg_galerkin_mat_product_algorithm","Type of SpGEMM to use in hypre (only for now)","PCMGGalerkinSetMatProductAlgorithm",PCHYPRESpgemmTypes,PETSC_STATIC_ARRAY_LENGTH(PCHYPRESpgemmTypes),PCHYPRESpgemmTypes[0],&indx,&flg));
949db6f9c32SMark Adams   if (!flg) indx = 0;
9509566063dSJacob Faibussowitsch   PetscCall(PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(pc,PCHYPRESpgemmTypes[indx]));
951db6f9c32SMark Adams #endif
952589dcaf0SStefano Zampini   /* AIR */
953589dcaf0SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0)
9549566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_restriction_type", "Type of AIR method (distance 1 or 2, 0 means no AIR)", "None", jac->Rtype, &jac->Rtype, NULL));
955792fecdfSBarry Smith   PetscCallExternal(HYPRE_BoomerAMGSetRestriction,jac->hsolver,jac->Rtype);
956589dcaf0SStefano Zampini   if (jac->Rtype) {
957589dcaf0SStefano 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 */
958589dcaf0SStefano Zampini 
9599566063dSJacob Faibussowitsch     PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_strongthresholdR","Threshold for R","None",jac->Rstrongthreshold,&jac->Rstrongthreshold,NULL));
960792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetStrongThresholdR,jac->hsolver,jac->Rstrongthreshold);
961589dcaf0SStefano Zampini 
9629566063dSJacob Faibussowitsch     PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_filterthresholdR","Filter threshold for R","None",jac->Rfilterthreshold,&jac->Rfilterthreshold,NULL));
963792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetFilterThresholdR,jac->hsolver,jac->Rfilterthreshold);
964589dcaf0SStefano Zampini 
9659566063dSJacob Faibussowitsch     PetscCall(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));
966792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetADropTol,jac->hsolver,jac->Adroptol);
967589dcaf0SStefano Zampini 
9689566063dSJacob Faibussowitsch     PetscCall(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));
969792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetADropType,jac->hsolver,jac->Adroptype);
970589dcaf0SStefano Zampini   }
971589dcaf0SStefano Zampini #endif
972589dcaf0SStefano Zampini 
973ecae95adSPierre Jolivet #if PETSC_PKG_HYPRE_VERSION_LE(9,9,9)
97463a3b9bcSJacob Faibussowitsch   PetscCheck(!jac->Rtype || !jac->agg_nl,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"-pc_hypre_boomeramg_restriction_type (%" PetscInt_FMT ") and -pc_hypre_boomeramg_agg_nl (%" PetscInt_FMT ")",jac->Rtype,jac->agg_nl);
975ecae95adSPierre Jolivet #endif
976ecae95adSPierre Jolivet 
9770f1074feSSatish Balay   /* new 3/07 */
978dd39110bSPierre Jolivet   PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg));
979589dcaf0SStefano Zampini   if (flg || jac->Rtype) {
980589dcaf0SStefano Zampini     if (flg) jac->interptype = indx;
981792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetInterpType,jac->hsolver,jac->interptype);
9820f1074feSSatish Balay   }
9830f1074feSSatish Balay 
9849566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg));
98516d9e3a6SLisandro Dalcin   if (flg) {
986b96a4a96SBarry Smith     level = 3;
9879566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL));
9882fa5cd67SKarl Rupp 
989b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
990792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetPrintLevel,jac->hsolver,level);
9912ae77aedSBarry Smith   }
9922ae77aedSBarry Smith 
9939566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg));
9942ae77aedSBarry Smith   if (flg) {
995b96a4a96SBarry Smith     level = 3;
9969566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL));
9972fa5cd67SKarl Rupp 
998b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
999792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetDebugFlag,jac->hsolver,level);
100016d9e3a6SLisandro Dalcin   }
10018f87f92bSBarry Smith 
10029566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg));
10038f87f92bSBarry Smith   if (flg && tmp_truth) {
10048f87f92bSBarry Smith     PetscInt tmp_int;
10059566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg));
10068f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
1007792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetSmoothType,jac->hsolver,6);
1008792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetDomainType,jac->hsolver,1);
1009792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetOverlap,jac->hsolver,0);
1010792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels,jac->hsolver,jac->nodal_relax_levels);
10118f87f92bSBarry Smith   }
10128f87f92bSBarry Smith 
10139566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_keeptranspose", "Avoid transpose matvecs in preconditioner application", "None", jac->keeptranspose, &jac->keeptranspose, NULL));
1014792fecdfSBarry Smith   PetscCallExternal(HYPRE_BoomerAMGSetKeepTranspose,jac->hsolver,jac->keeptranspose ? 1 : 0);
1015589dcaf0SStefano Zampini 
1016589dcaf0SStefano Zampini   /* options for ParaSails solvers */
1017dd39110bSPierre Jolivet   PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,PETSC_STATIC_ARRAY_LENGTH(symtlist),symtlist[0],&indx,&flg));
1018589dcaf0SStefano Zampini   if (flg) {
1019589dcaf0SStefano Zampini     jac->symt = indx;
1020792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetSym,jac->hsolver,jac->symt);
1021589dcaf0SStefano Zampini   }
1022589dcaf0SStefano Zampini 
1023d0609cedSBarry Smith   PetscOptionsHeadEnd();
102416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
102516d9e3a6SLisandro Dalcin }
102616d9e3a6SLisandro Dalcin 
1027ace3abfcSBarry 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)
102816d9e3a6SLisandro Dalcin {
102916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
10302cf14000SStefano Zampini   HYPRE_Int      oits;
103116d9e3a6SLisandro Dalcin 
103216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
10339566063dSJacob Faibussowitsch   PetscCall(PetscCitationsRegister(hypreCitation,&cite));
1034792fecdfSBarry Smith   PetscCallExternal(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,its*jac->maxiter);
1035792fecdfSBarry Smith   PetscCallExternal(HYPRE_BoomerAMGSetTol,jac->hsolver,rtol);
103616d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
10379566063dSJacob Faibussowitsch   PetscCall(PCApply_HYPRE(pc,b,y));
103816d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
1039792fecdfSBarry Smith   PetscCallExternal(HYPRE_BoomerAMGGetNumIterations,jac->hsolver,&oits);
10404d0a8057SBarry Smith   *outits = oits;
10414d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
10424d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1043792fecdfSBarry Smith   PetscCallExternal(HYPRE_BoomerAMGSetTol,jac->hsolver,jac->tol);
1044792fecdfSBarry Smith   PetscCallExternal(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,jac->maxiter);
104516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
104616d9e3a6SLisandro Dalcin }
104716d9e3a6SLisandro Dalcin 
104816d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
104916d9e3a6SLisandro Dalcin {
105016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1051ace3abfcSBarry Smith   PetscBool      iascii;
105216d9e3a6SLisandro Dalcin 
105316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
10549566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
105516d9e3a6SLisandro Dalcin   if (iascii) {
10569566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n"));
10579566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]));
105863a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Maximum number of levels %" PetscInt_FMT "\n",jac->maxlevels));
105963a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Maximum number of iterations PER hypre call %" PetscInt_FMT "\n",jac->maxiter));
10609566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Convergence tolerance PER hypre call %g\n",(double)jac->tol));
10619566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Threshold for strong coupling %g\n",(double)jac->strongthreshold));
10629566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Interpolation truncation factor %g\n",(double)jac->truncfactor));
106363a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Interpolation: max elements per row %" PetscInt_FMT "\n",jac->pmax));
106422e51d31SStefano Zampini     if (jac->interp_refine) {
106563a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    Interpolation: number of steps of weighted refinement %" PetscInt_FMT "\n",jac->interp_refine));
106622e51d31SStefano Zampini     }
106763a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Number of levels of aggressive coarsening %" PetscInt_FMT "\n",jac->agg_nl));
106863a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Number of paths for aggressive coarsening %" PetscInt_FMT "\n",jac->agg_num_paths));
10690f1074feSSatish Balay 
10709566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Maximum row sums %g\n",(double)jac->maxrowsum));
107116d9e3a6SLisandro Dalcin 
107263a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Sweeps down         %" PetscInt_FMT "\n",jac->gridsweeps[0]));
107363a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Sweeps up           %" PetscInt_FMT "\n",jac->gridsweeps[1]));
107463a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Sweeps on coarse    %" PetscInt_FMT "\n",jac->gridsweeps[2]));
107516d9e3a6SLisandro Dalcin 
10769566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]));
10779566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]));
10789566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]));
107916d9e3a6SLisandro Dalcin 
10809566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Relax weight  (all)      %g\n",(double)jac->relaxweight));
10819566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Outer relax weight (all) %g\n",(double)jac->outerrelaxweight));
108216d9e3a6SLisandro Dalcin 
108316d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
10849566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    Using CF-relaxation\n"));
108516d9e3a6SLisandro Dalcin     } else {
10869566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    Not using CF-relaxation\n"));
108716d9e3a6SLisandro Dalcin     }
10886a251517SEike Mueller     if (jac->smoothtype!=-1) {
10899566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]));
109063a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    Smooth num levels    %" PetscInt_FMT "\n",jac->smoothnumlevels));
10917e352d70SEike Mueller     } else {
10929566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    Not using more complex smoothers.\n"));
10931810e44eSEike Mueller     }
10941810e44eSEike Mueller     if (jac->smoothtype==3) {
109563a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) levels %" PetscInt_FMT "\n",jac->eu_level));
10969566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) drop tolerance %g\n",(double)jac->eu_droptolerance));
109763a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    Euclid ILU use Block-Jacobi? %" PetscInt_FMT "\n",jac->eu_bj));
10986a251517SEike Mueller     }
10999566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]));
11009566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]));
11019566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    Interpolation type  %s\n",jac->interptype != 100 ? HYPREBoomerAMGInterpType[jac->interptype] : "1pt"));
11025272c319SBarry Smith     if (jac->nodal_coarsening) {
110363a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    Using nodal coarsening with HYPRE_BOOMERAMGSetNodal() %" PetscInt_FMT "\n",jac->nodal_coarsening));
11045272c319SBarry Smith     }
11055272c319SBarry Smith     if (jac->vec_interp_variant) {
110663a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecVariant() %" PetscInt_FMT "\n",jac->vec_interp_variant));
110763a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecQMax() %" PetscInt_FMT "\n",jac->vec_interp_qmax));
11089566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n",jac->vec_interp_smooth));
11098f87f92bSBarry Smith     }
11108f87f92bSBarry Smith     if (jac->nodal_relax) {
111163a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    Using nodal relaxation via Schwarz smoothing on levels %" PetscInt_FMT "\n",jac->nodal_relax_levels));
11128f87f92bSBarry Smith     }
1113db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2,23,0)
11149566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    SpGEMM type         %s\n",jac->spgemm_type));
1115db6f9c32SMark Adams #endif
1116589dcaf0SStefano Zampini     /* AIR */
1117589dcaf0SStefano Zampini     if (jac->Rtype) {
111863a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    Using approximate ideal restriction type %" PetscInt_FMT "\n",jac->Rtype));
11199566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"      Threshold for R %g\n",(double)jac->Rstrongthreshold));
11209566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"      Filter for R %g\n",(double)jac->Rfilterthreshold));
11219566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"      A drop tolerance %g\n",(double)jac->Adroptol));
112263a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"      A drop type %" PetscInt_FMT "\n",jac->Adroptype));
1123589dcaf0SStefano Zampini     }
112416d9e3a6SLisandro Dalcin   }
112516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
112616d9e3a6SLisandro Dalcin }
112716d9e3a6SLisandro Dalcin 
112816d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
11294416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc)
113016d9e3a6SLisandro Dalcin {
113116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
11324ddd07fcSJed Brown   PetscInt       indx;
1133ace3abfcSBarry Smith   PetscBool      flag;
113416d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
113516d9e3a6SLisandro Dalcin 
113616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1137d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE ParaSails Options");
11389566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0));
11399566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshold,&jac->threshold,&flag));
1140792fecdfSBarry Smith   if (flag) PetscCallExternal(HYPRE_ParaSailsSetParams,jac->hsolver,jac->threshold,jac->nlevels);
114116d9e3a6SLisandro Dalcin 
11429566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag));
1143792fecdfSBarry Smith   if (flag) PetscCallExternal(HYPRE_ParaSailsSetFilter,jac->hsolver,jac->filter);
114416d9e3a6SLisandro Dalcin 
11459566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag));
1146792fecdfSBarry Smith   if (flag) PetscCallExternal(HYPRE_ParaSailsSetLoadbal,jac->hsolver,jac->loadbal);
114716d9e3a6SLisandro Dalcin 
11489566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag));
1149792fecdfSBarry Smith   if (flag) PetscCallExternal(HYPRE_ParaSailsSetLogging,jac->hsolver,jac->logging);
115016d9e3a6SLisandro Dalcin 
11519566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag));
1152792fecdfSBarry Smith   if (flag) PetscCallExternal(HYPRE_ParaSailsSetReuse,jac->hsolver,jac->ruse);
115316d9e3a6SLisandro Dalcin 
1154dd39110bSPierre Jolivet   PetscCall(PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,PETSC_STATIC_ARRAY_LENGTH(symtlist),symtlist[0],&indx,&flag));
115516d9e3a6SLisandro Dalcin   if (flag) {
115616d9e3a6SLisandro Dalcin     jac->symt = indx;
1157792fecdfSBarry Smith     PetscCallExternal(HYPRE_ParaSailsSetSym,jac->hsolver,jac->symt);
115816d9e3a6SLisandro Dalcin   }
115916d9e3a6SLisandro Dalcin 
1160d0609cedSBarry Smith   PetscOptionsHeadEnd();
116116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
116216d9e3a6SLisandro Dalcin }
116316d9e3a6SLisandro Dalcin 
116416d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
116516d9e3a6SLisandro Dalcin {
116616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1167ace3abfcSBarry Smith   PetscBool      iascii;
1168feb237baSPierre Jolivet   const char     *symt = 0;
116916d9e3a6SLisandro Dalcin 
117016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
11719566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
117216d9e3a6SLisandro Dalcin   if (iascii) {
11739566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n"));
117463a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    nlevels %" PetscInt_FMT "\n",jac->nlevels));
11759566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    threshold %g\n",(double)jac->threshold));
11769566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    filter %g\n",(double)jac->filter));
11779566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    load balance %g\n",(double)jac->loadbal));
11789566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    reuse nonzero structure %s\n",PetscBools[jac->ruse]));
11799566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    print info to screen %s\n",PetscBools[jac->logging]));
11802fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
11812fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
11822fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
118363a3b9bcSJacob Faibussowitsch     else SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %" PetscInt_FMT,jac->symt);
11849566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    %s\n",symt));
118516d9e3a6SLisandro Dalcin   }
118616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
118716d9e3a6SLisandro Dalcin }
11884cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
11894416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc)
11904cb006feSStefano Zampini {
11914cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
11924cb006feSStefano Zampini   PetscInt       n;
11934cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
11944cb006feSStefano Zampini 
11954cb006feSStefano Zampini   PetscFunctionBegin;
1196d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE AMS Options");
11979566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag));
1198792fecdfSBarry Smith   if (flag) PetscCallExternal(HYPRE_AMSSetPrintLevel,jac->hsolver,jac->as_print);
11999566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_ams_max_iter","Maximum number of AMS multigrid iterations within PCApply","None",jac->as_max_iter,&jac->as_max_iter,&flag));
1200792fecdfSBarry Smith   if (flag) PetscCallExternal(HYPRE_AMSSetMaxIter,jac->hsolver,jac->as_max_iter);
12019566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_ams_cycle_type","Cycle type for AMS multigrid","None",jac->ams_cycle_type,&jac->ams_cycle_type,&flag));
1202792fecdfSBarry Smith   if (flag) PetscCallExternal(HYPRE_AMSSetCycleType,jac->hsolver,jac->ams_cycle_type);
12039566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag));
1204792fecdfSBarry Smith   if (flag) PetscCallExternal(HYPRE_AMSSetTol,jac->hsolver,jac->as_tol);
12059566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_ams_relax_type","Relaxation type for AMS smoother","None",jac->as_relax_type,&jac->as_relax_type,&flag));
12069566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_ams_relax_times","Number of relaxation steps for AMS smoother","None",jac->as_relax_times,&jac->as_relax_times,&flag2));
12079566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_hypre_ams_relax_weight","Relaxation weight for AMS smoother","None",jac->as_relax_weight,&jac->as_relax_weight,&flag3));
12089566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4));
12094cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1210792fecdfSBarry Smith     PetscCallExternal(HYPRE_AMSSetSmoothingOptions,jac->hsolver,jac->as_relax_type,
1211863406b8SStefano Zampini                                                                       jac->as_relax_times,
1212863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1213a74df02fSJacob Faibussowitsch                                                                       jac->as_omega);
12144cb006feSStefano Zampini   }
12159566063dSJacob Faibussowitsch   PetscCall(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));
12164cb006feSStefano Zampini   n = 5;
12179566063dSJacob Faibussowitsch   PetscCall(PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2));
12184cb006feSStefano Zampini   if (flag || flag2) {
1219792fecdfSBarry Smith     PetscCallExternal(HYPRE_AMSSetAlphaAMGOptions,jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1220863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1221863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1222863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1223863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1224a74df02fSJacob Faibussowitsch                                                                      jac->as_amg_alpha_opts[4]);     /* AMG Pmax */
12254cb006feSStefano Zampini   }
12269566063dSJacob Faibussowitsch   PetscCall(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));
12274cb006feSStefano Zampini   n = 5;
12289566063dSJacob Faibussowitsch   PetscCall(PetscOptionsIntArray("-pc_hypre_ams_amg_beta_options","AMG options for scalar Poisson solver","None",jac->as_amg_beta_opts,&n,&flag2));
12294cb006feSStefano Zampini   if (flag || flag2) {
1230792fecdfSBarry Smith     PetscCallExternal(HYPRE_AMSSetBetaAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1231863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1232863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1233863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1234863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1235a74df02fSJacob Faibussowitsch                                                                     jac->as_amg_beta_opts[4]);     /* AMG Pmax */
12364cb006feSStefano Zampini   }
12379566063dSJacob Faibussowitsch   PetscCall(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));
123823df4f25SStefano Zampini   if (flag) { /* override HYPRE's default only if the options is used */
1239792fecdfSBarry Smith     PetscCallExternal(HYPRE_AMSSetProjectionFrequency,jac->hsolver,jac->ams_proj_freq);
124023df4f25SStefano Zampini   }
1241d0609cedSBarry Smith   PetscOptionsHeadEnd();
12424cb006feSStefano Zampini   PetscFunctionReturn(0);
12434cb006feSStefano Zampini }
12444cb006feSStefano Zampini 
12454cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
12464cb006feSStefano Zampini {
12474cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12484cb006feSStefano Zampini   PetscBool      iascii;
12494cb006feSStefano Zampini 
12504cb006feSStefano Zampini   PetscFunctionBegin;
12519566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
12524cb006feSStefano Zampini   if (iascii) {
12539566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n"));
125463a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %" PetscInt_FMT "\n",jac->as_max_iter));
125563a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    subspace cycle type %" PetscInt_FMT "\n",jac->ams_cycle_type));
125663a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",(double)jac->as_tol));
125763a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    smoother type %" PetscInt_FMT "\n",jac->as_relax_type));
125863a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %" PetscInt_FMT "\n",jac->as_relax_times));
125963a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",(double)jac->as_relax_weight));
126063a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",(double)jac->as_omega));
12614cb006feSStefano Zampini     if (jac->alpha_Poisson) {
12629566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (passed in by user)\n"));
12634cb006feSStefano Zampini     } else {
12649566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (computed) \n"));
12654cb006feSStefano Zampini     }
126663a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[0]));
126763a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[1]));
126863a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[2]));
126963a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[3]));
127063a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[4]));
127163a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",(double)jac->as_amg_alpha_theta));
12724cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
12734cb006feSStefano Zampini       if (jac->beta_Poisson) {
12749566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (passed in by user)\n"));
12754cb006feSStefano Zampini       } else {
12769566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (computed) \n"));
12774cb006feSStefano Zampini       }
127863a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %" PetscInt_FMT "\n",jac->as_amg_beta_opts[0]));
127963a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %" PetscInt_FMT "\n",jac->as_amg_beta_opts[1]));
128063a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %" PetscInt_FMT "\n",jac->as_amg_beta_opts[2]));
128163a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %" PetscInt_FMT "\n",jac->as_amg_beta_opts[3]));
128263a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %" PetscInt_FMT "\n",jac->as_amg_beta_opts[4]));
128363a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",(double)jac->as_amg_beta_theta));
128423df4f25SStefano Zampini       if (jac->ams_beta_is_zero_part) {
128563a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"        compatible subspace projection frequency %" PetscInt_FMT " (-1 HYPRE uses default)\n",jac->ams_proj_freq));
128623df4f25SStefano Zampini       }
128723df4f25SStefano Zampini     } else {
12889566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver not used (zero-conductivity everywhere) \n"));
12894cb006feSStefano Zampini     }
12904cb006feSStefano Zampini   }
12914cb006feSStefano Zampini   PetscFunctionReturn(0);
12924cb006feSStefano Zampini }
12934cb006feSStefano Zampini 
12944416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc)
1295863406b8SStefano Zampini {
1296863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1297863406b8SStefano Zampini   PetscInt       n;
1298863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
1299863406b8SStefano Zampini 
1300863406b8SStefano Zampini   PetscFunctionBegin;
1301d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE ADS Options");
13029566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag));
1303792fecdfSBarry Smith   if (flag) PetscCallExternal(HYPRE_ADSSetPrintLevel,jac->hsolver,jac->as_print);
13049566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_ads_max_iter","Maximum number of ADS multigrid iterations within PCApply","None",jac->as_max_iter,&jac->as_max_iter,&flag));
1305792fecdfSBarry Smith   if (flag) PetscCallExternal(HYPRE_ADSSetMaxIter,jac->hsolver,jac->as_max_iter);
13069566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_ads_cycle_type","Cycle type for ADS multigrid","None",jac->ads_cycle_type,&jac->ads_cycle_type,&flag));
1307792fecdfSBarry Smith   if (flag) PetscCallExternal(HYPRE_ADSSetCycleType,jac->hsolver,jac->ads_cycle_type);
13089566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag));
1309792fecdfSBarry Smith   if (flag) PetscCallExternal(HYPRE_ADSSetTol,jac->hsolver,jac->as_tol);
13109566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_ads_relax_type","Relaxation type for ADS smoother","None",jac->as_relax_type,&jac->as_relax_type,&flag));
13119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_ads_relax_times","Number of relaxation steps for ADS smoother","None",jac->as_relax_times,&jac->as_relax_times,&flag2));
13129566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_hypre_ads_relax_weight","Relaxation weight for ADS smoother","None",jac->as_relax_weight,&jac->as_relax_weight,&flag3));
13139566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4));
1314863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1315792fecdfSBarry Smith     PetscCallExternal(HYPRE_ADSSetSmoothingOptions,jac->hsolver,jac->as_relax_type,
1316863406b8SStefano Zampini                                                                       jac->as_relax_times,
1317863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1318a74df02fSJacob Faibussowitsch                                                                       jac->as_omega);
1319863406b8SStefano Zampini   }
13209566063dSJacob Faibussowitsch   PetscCall(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));
1321863406b8SStefano Zampini   n = 5;
13229566063dSJacob Faibussowitsch   PetscCall(PetscOptionsIntArray("-pc_hypre_ads_ams_options","AMG options for AMS solver inside ADS","None",jac->as_amg_alpha_opts,&n,&flag2));
13239566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_hypre_ads_ams_cycle_type","Cycle type for AMS solver inside ADS","None",jac->ams_cycle_type,&jac->ams_cycle_type,&flag3));
1324863406b8SStefano Zampini   if (flag || flag2 || flag3) {
1325792fecdfSBarry Smith     PetscCallExternal(HYPRE_ADSSetAMSOptions,jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
1326863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1327863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1328863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1329863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1330863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1331a74df02fSJacob Faibussowitsch                                                                 jac->as_amg_alpha_opts[4]);     /* AMG Pmax */
1332863406b8SStefano Zampini   }
13339566063dSJacob Faibussowitsch   PetscCall(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));
1334863406b8SStefano Zampini   n = 5;
13359566063dSJacob Faibussowitsch   PetscCall(PetscOptionsIntArray("-pc_hypre_ads_amg_options","AMG options for vector AMG solver inside ADS","None",jac->as_amg_beta_opts,&n,&flag2));
1336863406b8SStefano Zampini   if (flag || flag2) {
1337792fecdfSBarry Smith     PetscCallExternal(HYPRE_ADSSetAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1338863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1339863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1340863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1341863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1342a74df02fSJacob Faibussowitsch                                                                 jac->as_amg_beta_opts[4]);     /* AMG Pmax */
1343863406b8SStefano Zampini   }
1344d0609cedSBarry Smith   PetscOptionsHeadEnd();
1345863406b8SStefano Zampini   PetscFunctionReturn(0);
1346863406b8SStefano Zampini }
1347863406b8SStefano Zampini 
1348863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1349863406b8SStefano Zampini {
1350863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1351863406b8SStefano Zampini   PetscBool      iascii;
1352863406b8SStefano Zampini 
1353863406b8SStefano Zampini   PetscFunctionBegin;
13549566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
1355863406b8SStefano Zampini   if (iascii) {
13569566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n"));
135763a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %" PetscInt_FMT "\n",jac->as_max_iter));
135863a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    subspace cycle type %" PetscInt_FMT "\n",jac->ads_cycle_type));
135963a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",(double)jac->as_tol));
136063a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    smoother type %" PetscInt_FMT "\n",jac->as_relax_type));
136163a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %" PetscInt_FMT "\n",jac->as_relax_times));
136263a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",(double)jac->as_relax_weight));
136363a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",(double)jac->as_omega));
13649566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    AMS solver using boomerAMG\n"));
136563a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"        subspace cycle type %" PetscInt_FMT "\n",jac->ams_cycle_type));
136663a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"        coarsening type %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[0]));
136763a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[1]));
136863a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"        relaxation type %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[2]));
136963a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"        interpolation type %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[3]));
137063a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %" PetscInt_FMT "\n",jac->as_amg_alpha_opts[4]));
137163a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",(double)jac->as_amg_alpha_theta));
13729566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    vector Poisson solver using boomerAMG\n"));
137363a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"        coarsening type %" PetscInt_FMT "\n",jac->as_amg_beta_opts[0]));
137463a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %" PetscInt_FMT "\n",jac->as_amg_beta_opts[1]));
137563a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"        relaxation type %" PetscInt_FMT "\n",jac->as_amg_beta_opts[2]));
137663a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"        interpolation type %" PetscInt_FMT "\n",jac->as_amg_beta_opts[3]));
137763a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %" PetscInt_FMT "\n",jac->as_amg_beta_opts[4]));
137863a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",(double)jac->as_amg_beta_theta));
1379863406b8SStefano Zampini   }
1380863406b8SStefano Zampini   PetscFunctionReturn(0);
1381863406b8SStefano Zampini }
1382863406b8SStefano Zampini 
1383863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
13844cb006feSStefano Zampini {
13854cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
13865ac14e1cSStefano Zampini   PetscBool      ishypre;
13874cb006feSStefano Zampini 
13884cb006feSStefano Zampini   PetscFunctionBegin;
13899566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)G,MATHYPRE,&ishypre));
13905ac14e1cSStefano Zampini   if (ishypre) {
13919566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)G));
13929566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&jac->G));
13935ac14e1cSStefano Zampini     jac->G = G;
13945ac14e1cSStefano Zampini   } else {
13959566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&jac->G));
13969566063dSJacob Faibussowitsch     PetscCall(MatConvert(G,MATHYPRE,MAT_INITIAL_MATRIX,&jac->G));
13975ac14e1cSStefano Zampini   }
13984cb006feSStefano Zampini   PetscFunctionReturn(0);
13994cb006feSStefano Zampini }
14004cb006feSStefano Zampini 
14014cb006feSStefano Zampini /*@
14024cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
14034cb006feSStefano Zampini 
14044cb006feSStefano Zampini    Collective on PC
14054cb006feSStefano Zampini 
14064cb006feSStefano Zampini    Input Parameters:
14074cb006feSStefano Zampini +  pc - the preconditioning context
14084cb006feSStefano Zampini -  G - the discrete gradient
14094cb006feSStefano Zampini 
14104cb006feSStefano Zampini    Level: intermediate
14114cb006feSStefano Zampini 
141295452b02SPatrick Sanan    Notes:
141395452b02SPatrick Sanan     G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh
1414147403d9SBarry Smith 
1415863406b8SStefano 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
14164cb006feSStefano Zampini 
1417db781477SPatrick Sanan .seealso: `PCHYPRESetDiscreteCurl()`
14184cb006feSStefano Zampini @*/
14194cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
14204cb006feSStefano Zampini {
14214cb006feSStefano Zampini   PetscFunctionBegin;
14224cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
14234cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
14244cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
1425cac4c232SBarry Smith   PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));
14264cb006feSStefano Zampini   PetscFunctionReturn(0);
14274cb006feSStefano Zampini }
14284cb006feSStefano Zampini 
1429863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1430863406b8SStefano Zampini {
1431863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
14325ac14e1cSStefano Zampini   PetscBool      ishypre;
1433863406b8SStefano Zampini 
1434863406b8SStefano Zampini   PetscFunctionBegin;
14359566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)C,MATHYPRE,&ishypre));
14365ac14e1cSStefano Zampini   if (ishypre) {
14379566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)C));
14389566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&jac->C));
14395ac14e1cSStefano Zampini     jac->C = C;
14405ac14e1cSStefano Zampini   } else {
14419566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&jac->C));
14429566063dSJacob Faibussowitsch     PetscCall(MatConvert(C,MATHYPRE,MAT_INITIAL_MATRIX,&jac->C));
14435ac14e1cSStefano Zampini   }
1444863406b8SStefano Zampini   PetscFunctionReturn(0);
1445863406b8SStefano Zampini }
1446863406b8SStefano Zampini 
1447863406b8SStefano Zampini /*@
1448863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1449863406b8SStefano Zampini 
1450863406b8SStefano Zampini    Collective on PC
1451863406b8SStefano Zampini 
1452863406b8SStefano Zampini    Input Parameters:
1453863406b8SStefano Zampini +  pc - the preconditioning context
1454863406b8SStefano Zampini -  C - the discrete curl
1455863406b8SStefano Zampini 
1456863406b8SStefano Zampini    Level: intermediate
1457863406b8SStefano Zampini 
145895452b02SPatrick Sanan    Notes:
145995452b02SPatrick Sanan     C should have as many rows as the number of faces and as many columns as the number of edges in the mesh
1460147403d9SBarry Smith 
1461863406b8SStefano 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
1462863406b8SStefano Zampini 
1463db781477SPatrick Sanan .seealso: `PCHYPRESetDiscreteGradient()`
1464863406b8SStefano Zampini @*/
1465863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1466863406b8SStefano Zampini {
1467863406b8SStefano Zampini   PetscFunctionBegin;
1468863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1469863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1470863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1471cac4c232SBarry Smith   PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));
1472863406b8SStefano Zampini   PetscFunctionReturn(0);
1473863406b8SStefano Zampini }
1474863406b8SStefano Zampini 
14756bf688a0SCe Qin static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
14766bf688a0SCe Qin {
14776bf688a0SCe Qin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
14786bf688a0SCe Qin   PetscBool      ishypre;
14796bf688a0SCe Qin   PetscInt       i;
14806bf688a0SCe Qin   PetscFunctionBegin;
14816bf688a0SCe Qin 
14829566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&jac->RT_PiFull));
14839566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&jac->ND_PiFull));
14846bf688a0SCe Qin   for (i=0;i<3;++i) {
14859566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&jac->RT_Pi[i]));
14869566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&jac->ND_Pi[i]));
14876bf688a0SCe Qin   }
14886bf688a0SCe Qin 
14896bf688a0SCe Qin   jac->dim = dim;
14906bf688a0SCe Qin   if (RT_PiFull) {
14919566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)RT_PiFull,MATHYPRE,&ishypre));
14926bf688a0SCe Qin     if (ishypre) {
14939566063dSJacob Faibussowitsch       PetscCall(PetscObjectReference((PetscObject)RT_PiFull));
14946bf688a0SCe Qin       jac->RT_PiFull = RT_PiFull;
14956bf688a0SCe Qin     } else {
14969566063dSJacob Faibussowitsch       PetscCall(MatConvert(RT_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_PiFull));
14976bf688a0SCe Qin     }
14986bf688a0SCe Qin   }
14996bf688a0SCe Qin   if (RT_Pi) {
15006bf688a0SCe Qin     for (i=0;i<dim;++i) {
15016bf688a0SCe Qin       if (RT_Pi[i]) {
15029566063dSJacob Faibussowitsch         PetscCall(PetscObjectTypeCompare((PetscObject)RT_Pi[i],MATHYPRE,&ishypre));
15036bf688a0SCe Qin         if (ishypre) {
15049566063dSJacob Faibussowitsch           PetscCall(PetscObjectReference((PetscObject)RT_Pi[i]));
15056bf688a0SCe Qin           jac->RT_Pi[i] = RT_Pi[i];
15066bf688a0SCe Qin         } else {
15079566063dSJacob Faibussowitsch           PetscCall(MatConvert(RT_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_Pi[i]));
15086bf688a0SCe Qin         }
15096bf688a0SCe Qin       }
15106bf688a0SCe Qin     }
15116bf688a0SCe Qin   }
15126bf688a0SCe Qin   if (ND_PiFull) {
15139566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)ND_PiFull,MATHYPRE,&ishypre));
15146bf688a0SCe Qin     if (ishypre) {
15159566063dSJacob Faibussowitsch       PetscCall(PetscObjectReference((PetscObject)ND_PiFull));
15166bf688a0SCe Qin       jac->ND_PiFull = ND_PiFull;
15176bf688a0SCe Qin     } else {
15189566063dSJacob Faibussowitsch       PetscCall(MatConvert(ND_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_PiFull));
15196bf688a0SCe Qin     }
15206bf688a0SCe Qin   }
15216bf688a0SCe Qin   if (ND_Pi) {
15226bf688a0SCe Qin     for (i=0;i<dim;++i) {
15236bf688a0SCe Qin       if (ND_Pi[i]) {
15249566063dSJacob Faibussowitsch         PetscCall(PetscObjectTypeCompare((PetscObject)ND_Pi[i],MATHYPRE,&ishypre));
15256bf688a0SCe Qin         if (ishypre) {
15269566063dSJacob Faibussowitsch           PetscCall(PetscObjectReference((PetscObject)ND_Pi[i]));
15276bf688a0SCe Qin           jac->ND_Pi[i] = ND_Pi[i];
15286bf688a0SCe Qin         } else {
15299566063dSJacob Faibussowitsch           PetscCall(MatConvert(ND_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_Pi[i]));
15306bf688a0SCe Qin         }
15316bf688a0SCe Qin       }
15326bf688a0SCe Qin     }
15336bf688a0SCe Qin   }
15346bf688a0SCe Qin 
15356bf688a0SCe Qin   PetscFunctionReturn(0);
15366bf688a0SCe Qin }
15376bf688a0SCe Qin 
15386bf688a0SCe Qin /*@
15396bf688a0SCe Qin  PCHYPRESetInterpolations - Set interpolation matrices for AMS/ADS preconditioner
15406bf688a0SCe Qin 
15416bf688a0SCe Qin    Collective on PC
15426bf688a0SCe Qin 
15436bf688a0SCe Qin    Input Parameters:
15446bf688a0SCe Qin +  pc - the preconditioning context
15456bf688a0SCe Qin -  dim - the dimension of the problem, only used in AMS
15466bf688a0SCe Qin -  RT_PiFull - Raviart-Thomas interpolation matrix
15476bf688a0SCe Qin -  RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix
15486bf688a0SCe Qin -  ND_PiFull - Nedelec interpolation matrix
15496bf688a0SCe Qin -  ND_Pi - x/y/z component of Nedelec interpolation matrix
15506bf688a0SCe Qin 
155195452b02SPatrick Sanan    Notes:
155295452b02SPatrick Sanan     For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL.
1553147403d9SBarry Smith 
15546bf688a0SCe Qin     For ADS, both type of interpolation matrices are needed.
1555147403d9SBarry Smith 
15566bf688a0SCe Qin    Level: intermediate
15576bf688a0SCe Qin 
15586bf688a0SCe Qin @*/
15596bf688a0SCe Qin PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
15606bf688a0SCe Qin {
15616bf688a0SCe Qin   PetscInt       i;
15626bf688a0SCe Qin 
15636bf688a0SCe Qin   PetscFunctionBegin;
15646bf688a0SCe Qin   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15656bf688a0SCe Qin   if (RT_PiFull) {
15666bf688a0SCe Qin     PetscValidHeaderSpecific(RT_PiFull,MAT_CLASSID,3);
15676bf688a0SCe Qin     PetscCheckSameComm(pc,1,RT_PiFull,3);
15686bf688a0SCe Qin   }
15696bf688a0SCe Qin   if (RT_Pi) {
15706bf688a0SCe Qin     PetscValidPointer(RT_Pi,4);
15716bf688a0SCe Qin     for (i=0;i<dim;++i) {
15726bf688a0SCe Qin       if (RT_Pi[i]) {
15736bf688a0SCe Qin         PetscValidHeaderSpecific(RT_Pi[i],MAT_CLASSID,4);
15746bf688a0SCe Qin         PetscCheckSameComm(pc,1,RT_Pi[i],4);
15756bf688a0SCe Qin       }
15766bf688a0SCe Qin     }
15776bf688a0SCe Qin   }
15786bf688a0SCe Qin   if (ND_PiFull) {
15796bf688a0SCe Qin     PetscValidHeaderSpecific(ND_PiFull,MAT_CLASSID,5);
15806bf688a0SCe Qin     PetscCheckSameComm(pc,1,ND_PiFull,5);
15816bf688a0SCe Qin   }
15826bf688a0SCe Qin   if (ND_Pi) {
15836bf688a0SCe Qin     PetscValidPointer(ND_Pi,6);
15846bf688a0SCe Qin     for (i=0;i<dim;++i) {
15856bf688a0SCe Qin       if (ND_Pi[i]) {
15866bf688a0SCe Qin         PetscValidHeaderSpecific(ND_Pi[i],MAT_CLASSID,6);
15876bf688a0SCe Qin         PetscCheckSameComm(pc,1,ND_Pi[i],6);
15886bf688a0SCe Qin       }
15896bf688a0SCe Qin     }
15906bf688a0SCe Qin   }
1591cac4c232SBarry Smith   PetscTryMethod(pc,"PCHYPRESetInterpolations_C",(PC,PetscInt,Mat,Mat[],Mat,Mat[]),(pc,dim,RT_PiFull,RT_Pi,ND_PiFull,ND_Pi));
15926bf688a0SCe Qin   PetscFunctionReturn(0);
15936bf688a0SCe Qin }
15946bf688a0SCe Qin 
15955ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha)
15964cb006feSStefano Zampini {
15974cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
15985ac14e1cSStefano Zampini   PetscBool      ishypre;
15994cb006feSStefano Zampini 
16004cb006feSStefano Zampini   PetscFunctionBegin;
16019566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre));
16025ac14e1cSStefano Zampini   if (ishypre) {
16035ac14e1cSStefano Zampini     if (isalpha) {
16049566063dSJacob Faibussowitsch       PetscCall(PetscObjectReference((PetscObject)A));
16059566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&jac->alpha_Poisson));
16065ac14e1cSStefano Zampini       jac->alpha_Poisson = A;
16075ac14e1cSStefano Zampini     } else {
16085ac14e1cSStefano Zampini       if (A) {
16099566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)A));
16105ac14e1cSStefano Zampini       } else {
16115ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
16125ac14e1cSStefano Zampini       }
16139566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&jac->beta_Poisson));
16145ac14e1cSStefano Zampini       jac->beta_Poisson = A;
16155ac14e1cSStefano Zampini     }
16165ac14e1cSStefano Zampini   } else {
16175ac14e1cSStefano Zampini     if (isalpha) {
16189566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&jac->alpha_Poisson));
16199566063dSJacob Faibussowitsch       PetscCall(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->alpha_Poisson));
16205ac14e1cSStefano Zampini     } else {
16215ac14e1cSStefano Zampini       if (A) {
16229566063dSJacob Faibussowitsch         PetscCall(MatDestroy(&jac->beta_Poisson));
16239566063dSJacob Faibussowitsch         PetscCall(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->beta_Poisson));
16245ac14e1cSStefano Zampini       } else {
16259566063dSJacob Faibussowitsch         PetscCall(MatDestroy(&jac->beta_Poisson));
16265ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
16275ac14e1cSStefano Zampini       }
16285ac14e1cSStefano Zampini     }
16295ac14e1cSStefano Zampini   }
16304cb006feSStefano Zampini   PetscFunctionReturn(0);
16314cb006feSStefano Zampini }
16324cb006feSStefano Zampini 
16334cb006feSStefano Zampini /*@
16344cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
16354cb006feSStefano Zampini 
16364cb006feSStefano Zampini    Collective on PC
16374cb006feSStefano Zampini 
16384cb006feSStefano Zampini    Input Parameters:
16394cb006feSStefano Zampini +  pc - the preconditioning context
16404cb006feSStefano Zampini -  A - the matrix
16414cb006feSStefano Zampini 
16424cb006feSStefano Zampini    Level: intermediate
16434cb006feSStefano Zampini 
164495452b02SPatrick Sanan    Notes:
164595452b02SPatrick Sanan     A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
16464cb006feSStefano Zampini 
1647db781477SPatrick Sanan .seealso: `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetBetaPoissonMatrix()`
16484cb006feSStefano Zampini @*/
16494cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
16504cb006feSStefano Zampini {
16514cb006feSStefano Zampini   PetscFunctionBegin;
16524cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
16534cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
16544cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
1655cac4c232SBarry Smith   PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_TRUE));
16564cb006feSStefano Zampini   PetscFunctionReturn(0);
16574cb006feSStefano Zampini }
16584cb006feSStefano Zampini 
16594cb006feSStefano Zampini /*@
16604cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
16614cb006feSStefano Zampini 
16624cb006feSStefano Zampini    Collective on PC
16634cb006feSStefano Zampini 
16644cb006feSStefano Zampini    Input Parameters:
16654cb006feSStefano Zampini +  pc - the preconditioning context
16664cb006feSStefano Zampini -  A - the matrix
16674cb006feSStefano Zampini 
16684cb006feSStefano Zampini    Level: intermediate
16694cb006feSStefano Zampini 
167095452b02SPatrick Sanan    Notes:
167195452b02SPatrick Sanan     A should be obtained by discretizing the Poisson problem with linear finite elements.
16724cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
16734cb006feSStefano Zampini 
1674db781477SPatrick Sanan .seealso: `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()`
16754cb006feSStefano Zampini @*/
16764cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
16774cb006feSStefano Zampini {
16784cb006feSStefano Zampini   PetscFunctionBegin;
16794cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
16804cb006feSStefano Zampini   if (A) {
16814cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
16824cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
16834cb006feSStefano Zampini   }
1684cac4c232SBarry Smith   PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_FALSE));
16854cb006feSStefano Zampini   PetscFunctionReturn(0);
16864cb006feSStefano Zampini }
16874cb006feSStefano Zampini 
16885ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz, Vec zoz, Vec zzo)
16894cb006feSStefano Zampini {
16904cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
16914cb006feSStefano Zampini 
16924cb006feSStefano Zampini   PetscFunctionBegin;
16934cb006feSStefano Zampini   /* throw away any vector if already set */
16949566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[0]));
16959566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[1]));
16969566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[2]));
16979566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorCreate(ozz->map,&jac->constants[0]));
16989566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorCopy(ozz,jac->constants[0]));
16999566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorCreate(zoz->map,&jac->constants[1]));
17009566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorCopy(zoz,jac->constants[1]));
17015ac14e1cSStefano Zampini   jac->dim = 2;
17024cb006feSStefano Zampini   if (zzo) {
17039566063dSJacob Faibussowitsch     PetscCall(VecHYPRE_IJVectorCreate(zzo->map,&jac->constants[2]));
17049566063dSJacob Faibussowitsch     PetscCall(VecHYPRE_IJVectorCopy(zzo,jac->constants[2]));
17055ac14e1cSStefano Zampini     jac->dim++;
17064cb006feSStefano Zampini   }
17074cb006feSStefano Zampini   PetscFunctionReturn(0);
17084cb006feSStefano Zampini }
17094cb006feSStefano Zampini 
17104cb006feSStefano Zampini /*@
1711147403d9SBarry Smith  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in the edge element basis
17124cb006feSStefano Zampini 
17134cb006feSStefano Zampini    Collective on PC
17144cb006feSStefano Zampini 
17154cb006feSStefano Zampini    Input Parameters:
17164cb006feSStefano Zampini +  pc - the preconditioning context
17174cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
17184cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
17194cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
17204cb006feSStefano Zampini 
17214cb006feSStefano Zampini    Level: intermediate
17224cb006feSStefano Zampini 
17234cb006feSStefano Zampini @*/
17244cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
17254cb006feSStefano Zampini {
17264cb006feSStefano Zampini   PetscFunctionBegin;
17274cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
17284cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
17294cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
17304cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
17314cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
17324cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
17334cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
1734cac4c232SBarry Smith   PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));
17354cb006feSStefano Zampini   PetscFunctionReturn(0);
17364cb006feSStefano Zampini }
17374cb006feSStefano Zampini 
1738863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
17394cb006feSStefano Zampini {
17404cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
17414cb006feSStefano Zampini   Vec             tv;
17424cb006feSStefano Zampini   PetscInt        i;
17434cb006feSStefano Zampini 
17444cb006feSStefano Zampini   PetscFunctionBegin;
17454cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
17469566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[0]));
17479566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[1]));
17489566063dSJacob Faibussowitsch   PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[2]));
17495ac14e1cSStefano Zampini   jac->dim = dim;
17505ac14e1cSStefano Zampini 
17514cb006feSStefano Zampini   /* compute IJ vector for coordinates */
17529566063dSJacob Faibussowitsch   PetscCall(VecCreate(PetscObjectComm((PetscObject)pc),&tv));
17539566063dSJacob Faibussowitsch   PetscCall(VecSetType(tv,VECSTANDARD));
17549566063dSJacob Faibussowitsch   PetscCall(VecSetSizes(tv,nloc,PETSC_DECIDE));
17554cb006feSStefano Zampini   for (i=0;i<dim;i++) {
17564cb006feSStefano Zampini     PetscScalar *array;
17574cb006feSStefano Zampini     PetscInt    j;
17584cb006feSStefano Zampini 
17599566063dSJacob Faibussowitsch     PetscCall(VecHYPRE_IJVectorCreate(tv->map,&jac->coords[i]));
17609566063dSJacob Faibussowitsch     PetscCall(VecGetArrayWrite(tv,&array));
17616ea7df73SStefano Zampini     for (j=0;j<nloc;j++) array[j] = coords[j*dim+i];
17629566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayWrite(tv,&array));
17639566063dSJacob Faibussowitsch     PetscCall(VecHYPRE_IJVectorCopy(tv,jac->coords[i]));
17644cb006feSStefano Zampini   }
17659566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&tv));
17664cb006feSStefano Zampini   PetscFunctionReturn(0);
17674cb006feSStefano Zampini }
17684cb006feSStefano Zampini 
176916d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
177016d9e3a6SLisandro Dalcin 
1771f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
177216d9e3a6SLisandro Dalcin {
177316d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
177416d9e3a6SLisandro Dalcin 
177516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
177616d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
177716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
177816d9e3a6SLisandro Dalcin }
177916d9e3a6SLisandro Dalcin 
1780f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
178116d9e3a6SLisandro Dalcin {
178216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1783ace3abfcSBarry Smith   PetscBool      flag;
178416d9e3a6SLisandro Dalcin 
178516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
178616d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
17879566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(jac->hypre_type,name,&flag));
17885f80ce2aSJacob Faibussowitsch     PetscCheck(flag,PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
178916d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
179016d9e3a6SLisandro Dalcin   } else {
17919566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, &jac->hypre_type));
179216d9e3a6SLisandro Dalcin   }
179316d9e3a6SLisandro Dalcin 
179416d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
179516d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
179616d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
179716d9e3a6SLisandro Dalcin 
17989566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp("pilut",jac->hypre_type,&flag));
179916d9e3a6SLisandro Dalcin   if (flag) {
18009566063dSJacob Faibussowitsch     PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre));
1801792fecdfSBarry Smith     PetscCallExternal(HYPRE_ParCSRPilutCreate,jac->comm_hypre,&jac->hsolver);
180216d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
180316d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
180416d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
180516d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
180616d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
180716d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
180816d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
180916d9e3a6SLisandro Dalcin   }
18109566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp("euclid",jac->hypre_type,&flag));
1811db966c6cSHong Zhang   if (flag) {
18124e3c431bSBarry Smith #if defined(PETSC_USE_64BIT_INDICES)
18134e3c431bSBarry Smith     SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Hypre Euclid does not support 64 bit indices");
18148bf83915SBarry Smith #endif
18159566063dSJacob Faibussowitsch     PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre));
1816792fecdfSBarry Smith     PetscCallExternal(HYPRE_EuclidCreate,jac->comm_hypre,&jac->hsolver);
1817db966c6cSHong Zhang     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
1818db966c6cSHong Zhang     pc->ops->view           = PCView_HYPRE_Euclid;
1819db966c6cSHong Zhang     jac->destroy            = HYPRE_EuclidDestroy;
1820db966c6cSHong Zhang     jac->setup              = HYPRE_EuclidSetup;
1821db966c6cSHong Zhang     jac->solve              = HYPRE_EuclidSolve;
1822db966c6cSHong Zhang     jac->factorrowsize      = PETSC_DEFAULT;
1823db966c6cSHong Zhang     jac->eu_level           = PETSC_DEFAULT; /* default */
1824db966c6cSHong Zhang     PetscFunctionReturn(0);
1825db966c6cSHong Zhang   }
18269566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp("parasails",jac->hypre_type,&flag));
182716d9e3a6SLisandro Dalcin   if (flag) {
18289566063dSJacob Faibussowitsch     PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&jac->comm_hypre));
1829792fecdfSBarry Smith     PetscCallExternal(HYPRE_ParaSailsCreate,jac->comm_hypre,&jac->hsolver);
183016d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
183116d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
183216d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
183316d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
183416d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
183516d9e3a6SLisandro Dalcin     /* initialize */
183616d9e3a6SLisandro Dalcin     jac->nlevels   = 1;
18378966356dSPierre Jolivet     jac->threshold = .1;
183816d9e3a6SLisandro Dalcin     jac->filter    = .1;
183916d9e3a6SLisandro Dalcin     jac->loadbal   = 0;
18402fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
18412fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
18422fa5cd67SKarl Rupp 
184316d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
184416d9e3a6SLisandro Dalcin     jac->symt = 0;
1845792fecdfSBarry Smith     PetscCallExternal(HYPRE_ParaSailsSetParams,jac->hsolver,jac->threshold,jac->nlevels);
1846792fecdfSBarry Smith     PetscCallExternal(HYPRE_ParaSailsSetFilter,jac->hsolver,jac->filter);
1847792fecdfSBarry Smith     PetscCallExternal(HYPRE_ParaSailsSetLoadbal,jac->hsolver,jac->loadbal);
1848792fecdfSBarry Smith     PetscCallExternal(HYPRE_ParaSailsSetLogging,jac->hsolver,jac->logging);
1849792fecdfSBarry Smith     PetscCallExternal(HYPRE_ParaSailsSetReuse,jac->hsolver,jac->ruse);
1850792fecdfSBarry Smith     PetscCallExternal(HYPRE_ParaSailsSetSym,jac->hsolver,jac->symt);
185116d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
185216d9e3a6SLisandro Dalcin   }
18539566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp("boomeramg",jac->hypre_type,&flag));
185416d9e3a6SLisandro Dalcin   if (flag) {
1855792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGCreate,&jac->hsolver);
185616d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
185716d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
185816d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
185916d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
18609566063dSJacob Faibussowitsch     PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",PCGetInterpolations_BoomerAMG));
18619566063dSJacob Faibussowitsch     PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",PCGetCoarseOperators_BoomerAMG));
186216d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
186316d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
186416d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
186516d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
186616d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
186716d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
186816d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
186916d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
18708f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
187116d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
187216d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
187316d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
187416d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
187516d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
18760f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
18776a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1878b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
18791810e44eSEike Mueller     jac->eu_level         = 0;
18801810e44eSEike Mueller     jac->eu_droptolerance = 0;
18811810e44eSEike Mueller     jac->eu_bj            = 0;
1882589dcaf0SStefano Zampini     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a PC - most likely with CG */
18830f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
188416d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
188516d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
188616d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
18870f1074feSSatish Balay     jac->interptype       = 0;
1888589dcaf0SStefano Zampini     jac->Rtype            = 0;
1889589dcaf0SStefano Zampini     jac->Rstrongthreshold = 0.25;
1890589dcaf0SStefano Zampini     jac->Rfilterthreshold = 0.0;
1891589dcaf0SStefano Zampini     jac->Adroptype        = -1;
1892589dcaf0SStefano Zampini     jac->Adroptol         = 0.0;
18930f1074feSSatish Balay     jac->agg_nl           = 0;
18946ea7df73SStefano Zampini     jac->agg_interptype   = 4;
18950f1074feSSatish Balay     jac->pmax             = 0;
18960f1074feSSatish Balay     jac->truncfactor      = 0.0;
18970f1074feSSatish Balay     jac->agg_num_paths    = 1;
1898589dcaf0SStefano Zampini     jac->maxc             = 9;
1899589dcaf0SStefano Zampini     jac->minc             = 1;
190022e51d31SStefano Zampini     jac->nodal_coarsening      = 0;
190122e51d31SStefano Zampini     jac->nodal_coarsening_diag = 0;
190222e51d31SStefano Zampini     jac->vec_interp_variant    = 0;
190322e51d31SStefano Zampini     jac->vec_interp_qmax       = 0;
190422e51d31SStefano Zampini     jac->vec_interp_smooth     = PETSC_FALSE;
190522e51d31SStefano Zampini     jac->interp_refine         = 0;
19068f87f92bSBarry Smith     jac->nodal_relax           = PETSC_FALSE;
19078f87f92bSBarry Smith     jac->nodal_relax_levels    = 1;
19086ea7df73SStefano Zampini     jac->rap2                  = 0;
19096ea7df73SStefano Zampini 
19106ea7df73SStefano Zampini     /* GPU defaults
19116ea7df73SStefano Zampini          from https://hypre.readthedocs.io/en/latest/solvers-boomeramg.html#gpu-supported-options
19126ea7df73SStefano Zampini          and /src/parcsr_ls/par_amg.c */
19136ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE)
19146ea7df73SStefano Zampini     jac->keeptranspose         = PETSC_TRUE;
19156ea7df73SStefano Zampini     jac->mod_rap2              = 1;
19166ea7df73SStefano Zampini     jac->coarsentype           = 8;
19176ea7df73SStefano Zampini     jac->relaxorder            = 0;
19186ea7df73SStefano Zampini     jac->interptype            = 6;
19196ea7df73SStefano Zampini     jac->relaxtype[0]          = 18;
19206ea7df73SStefano Zampini     jac->relaxtype[1]          = 18;
19216ea7df73SStefano Zampini     jac->agg_interptype        = 7;
19226ea7df73SStefano Zampini #else
19236ea7df73SStefano Zampini     jac->keeptranspose         = PETSC_FALSE;
19246ea7df73SStefano Zampini     jac->mod_rap2              = 0;
19256ea7df73SStefano Zampini #endif
1926792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetCycleType,jac->hsolver,jac->cycletype);
1927792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetMaxLevels,jac->hsolver,jac->maxlevels);
1928792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetMaxIter,jac->hsolver,jac->maxiter);
1929792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetTol,jac->hsolver,jac->tol);
1930792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetTruncFactor,jac->hsolver,jac->truncfactor);
1931792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetStrongThreshold,jac->hsolver,jac->strongthreshold);
1932792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetMaxRowSum,jac->hsolver,jac->maxrowsum);
1933792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetCoarsenType,jac->hsolver,jac->coarsentype);
1934792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetMeasureType,jac->hsolver,jac->measuretype);
1935792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetRelaxOrder,jac->hsolver, jac->relaxorder);
1936792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetInterpType,jac->hsolver,jac->interptype);
1937792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetAggNumLevels,jac->hsolver,jac->agg_nl);
1938792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetAggInterpType,jac->hsolver,jac->agg_interptype);
1939792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetPMaxElmts,jac->hsolver,jac->pmax);
1940792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetNumPaths,jac->hsolver,jac->agg_num_paths);
1941792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetRelaxType,jac->hsolver, jac->relaxtype[0]);  /* defaults coarse to 9 */
1942792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetNumSweeps,jac->hsolver, jac->gridsweeps[0]); /* defaults coarse to 1 */
1943792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetMaxCoarseSize,jac->hsolver, jac->maxc);
1944792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetMinCoarseSize,jac->hsolver, jac->minc);
19456ea7df73SStefano Zampini     /* GPU */
19466ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0)
1947792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetKeepTranspose,jac->hsolver,jac->keeptranspose ? 1 : 0);
1948792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetRAP2,jac->hsolver, jac->rap2);
1949792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetModuleRAP2,jac->hsolver, jac->mod_rap2);
19506ea7df73SStefano Zampini #endif
19516ea7df73SStefano Zampini 
1952589dcaf0SStefano Zampini     /* AIR */
19536ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0)
1954792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetRestriction,jac->hsolver,jac->Rtype);
1955792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetStrongThresholdR,jac->hsolver,jac->Rstrongthreshold);
1956792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetFilterThresholdR,jac->hsolver,jac->Rfilterthreshold);
1957792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetADropTol,jac->hsolver,jac->Adroptol);
1958792fecdfSBarry Smith     PetscCallExternal(HYPRE_BoomerAMGSetADropType,jac->hsolver,jac->Adroptype);
19596ea7df73SStefano Zampini #endif
196016d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
196116d9e3a6SLisandro Dalcin   }
19629566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp("ams",jac->hypre_type,&flag));
19634cb006feSStefano Zampini   if (flag) {
19649566063dSJacob Faibussowitsch     PetscCall(HYPRE_AMSCreate(&jac->hsolver));
19654cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
19664cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
19674cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
19684cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
19694cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
19704cb006feSStefano Zampini     jac->coords[0]           = NULL;
19714cb006feSStefano Zampini     jac->coords[1]           = NULL;
19724cb006feSStefano Zampini     jac->coords[2]           = NULL;
19734cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1974863406b8SStefano Zampini     jac->as_print           = 0;
1975863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1976863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
19774cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
19784cb006feSStefano Zampini     /* Smoothing options */
1979863406b8SStefano Zampini     jac->as_relax_type      = 2;
1980863406b8SStefano Zampini     jac->as_relax_times     = 1;
1981863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1982863406b8SStefano Zampini     jac->as_omega           = 1.0;
19834cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1984863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1985863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
19860bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1987863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1988863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1989863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
19904cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1991863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1992863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
19930bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1994863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1995863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1996863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1997792fecdfSBarry Smith     PetscCallExternal(HYPRE_AMSSetPrintLevel,jac->hsolver,jac->as_print);
1998792fecdfSBarry Smith     PetscCallExternal(HYPRE_AMSSetMaxIter,jac->hsolver,jac->as_max_iter);
1999792fecdfSBarry Smith     PetscCallExternal(HYPRE_AMSSetCycleType,jac->hsolver,jac->ams_cycle_type);
2000792fecdfSBarry Smith     PetscCallExternal(HYPRE_AMSSetTol,jac->hsolver,jac->as_tol);
2001792fecdfSBarry Smith     PetscCallExternal(HYPRE_AMSSetSmoothingOptions,jac->hsolver,jac->as_relax_type,
2002863406b8SStefano Zampini                                                                       jac->as_relax_times,
2003863406b8SStefano Zampini                                                                       jac->as_relax_weight,
2004a74df02fSJacob Faibussowitsch                                                                       jac->as_omega);
2005792fecdfSBarry Smith     PetscCallExternal(HYPRE_AMSSetAlphaAMGOptions,jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
2006863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
2007863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
2008863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
2009863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
2010a74df02fSJacob Faibussowitsch                                                                      jac->as_amg_alpha_opts[4]);     /* AMG Pmax */
2011792fecdfSBarry Smith     PetscCallExternal(HYPRE_AMSSetBetaAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
2012863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
2013863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
2014863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
2015863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
2016a74df02fSJacob Faibussowitsch                                                                     jac->as_amg_beta_opts[4]);     /* AMG Pmax */
201723df4f25SStefano Zampini     /* Zero conductivity */
201823df4f25SStefano Zampini     jac->ams_beta_is_zero      = PETSC_FALSE;
201923df4f25SStefano Zampini     jac->ams_beta_is_zero_part = PETSC_FALSE;
20204cb006feSStefano Zampini     PetscFunctionReturn(0);
20214cb006feSStefano Zampini   }
20229566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp("ads",jac->hypre_type,&flag));
2023863406b8SStefano Zampini   if (flag) {
20249566063dSJacob Faibussowitsch     PetscCall(HYPRE_ADSCreate(&jac->hsolver));
2025863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
2026863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
2027863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
2028863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
2029863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
2030863406b8SStefano Zampini     jac->coords[0]           = NULL;
2031863406b8SStefano Zampini     jac->coords[1]           = NULL;
2032863406b8SStefano Zampini     jac->coords[2]           = NULL;
2033863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
2034863406b8SStefano Zampini     jac->as_print           = 0;
2035863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
2036863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
2037863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
2038863406b8SStefano Zampini     /* Smoothing options */
2039863406b8SStefano Zampini     jac->as_relax_type      = 2;
2040863406b8SStefano Zampini     jac->as_relax_times     = 1;
2041863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
2042863406b8SStefano Zampini     jac->as_omega           = 1.0;
2043863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
2044863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
2045863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
2046863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
2047863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
2048863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
2049863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
2050863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
2051863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
2052863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
2053863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
2054863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
2055863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
2056863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
2057863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
2058792fecdfSBarry Smith     PetscCallExternal(HYPRE_ADSSetPrintLevel,jac->hsolver,jac->as_print);
2059792fecdfSBarry Smith     PetscCallExternal(HYPRE_ADSSetMaxIter,jac->hsolver,jac->as_max_iter);
2060792fecdfSBarry Smith     PetscCallExternal(HYPRE_ADSSetCycleType,jac->hsolver,jac->ams_cycle_type);
2061792fecdfSBarry Smith     PetscCallExternal(HYPRE_ADSSetTol,jac->hsolver,jac->as_tol);
2062792fecdfSBarry Smith     PetscCallExternal(HYPRE_ADSSetSmoothingOptions,jac->hsolver,jac->as_relax_type,
2063863406b8SStefano Zampini                                                                       jac->as_relax_times,
2064863406b8SStefano Zampini                                                                       jac->as_relax_weight,
2065a74df02fSJacob Faibussowitsch                                                                       jac->as_omega);
2066792fecdfSBarry Smith     PetscCallExternal(HYPRE_ADSSetAMSOptions,jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
2067863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
2068863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
2069863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
2070863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
2071863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
2072a74df02fSJacob Faibussowitsch                                                                 jac->as_amg_alpha_opts[4]);     /* AMG Pmax */
2073792fecdfSBarry Smith     PetscCallExternal(HYPRE_ADSSetAMGOptions,jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
2074863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
2075863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
2076863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
2077863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
2078a74df02fSJacob Faibussowitsch                                                                 jac->as_amg_beta_opts[4]);     /* AMG Pmax */
2079863406b8SStefano Zampini     PetscFunctionReturn(0);
2080863406b8SStefano Zampini   }
20819566063dSJacob Faibussowitsch   PetscCall(PetscFree(jac->hypre_type));
20822fa5cd67SKarl Rupp 
20830298fd71SBarry Smith   jac->hypre_type = NULL;
208498921bdaSJacob Faibussowitsch   SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams",name);
208516d9e3a6SLisandro Dalcin }
208616d9e3a6SLisandro Dalcin 
208716d9e3a6SLisandro Dalcin /*
208816d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
208916d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
209016d9e3a6SLisandro Dalcin */
2091360ee056SFande Kong PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc)
209216d9e3a6SLisandro Dalcin {
20934ddd07fcSJed Brown   PetscInt       indx;
2094db966c6cSHong Zhang   const char     *type[] = {"euclid","pilut","parasails","boomeramg","ams","ads"};
2095ace3abfcSBarry Smith   PetscBool      flg;
209616d9e3a6SLisandro Dalcin 
209716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
2098d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject,"HYPRE preconditioner options");
2099dd39110bSPierre Jolivet   PetscCall(PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,PETSC_STATIC_ARRAY_LENGTH(type),"boomeramg",&indx,&flg));
210016d9e3a6SLisandro Dalcin   if (flg) {
21019566063dSJacob Faibussowitsch     PetscCall(PCHYPRESetType_HYPRE(pc,type[indx]));
210202a17cd4SBarry Smith   } else {
21039566063dSJacob Faibussowitsch     PetscCall(PCHYPRESetType_HYPRE(pc,"boomeramg"));
210416d9e3a6SLisandro Dalcin   }
21051baa6e33SBarry Smith   if (pc->ops->setfromoptions) PetscCall(pc->ops->setfromoptions(PetscOptionsObject,pc));
2106d0609cedSBarry Smith   PetscOptionsHeadEnd();
210716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
210816d9e3a6SLisandro Dalcin }
210916d9e3a6SLisandro Dalcin 
211016d9e3a6SLisandro Dalcin /*@C
211116d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
211216d9e3a6SLisandro Dalcin 
211316d9e3a6SLisandro Dalcin    Input Parameters:
211416d9e3a6SLisandro Dalcin +     pc - the preconditioner context
2115db966c6cSHong Zhang -     name - either  euclid, pilut, parasails, boomeramg, ams, ads
211616d9e3a6SLisandro Dalcin 
211716d9e3a6SLisandro Dalcin    Options Database Keys:
2118db966c6cSHong Zhang    -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
211916d9e3a6SLisandro Dalcin 
212016d9e3a6SLisandro Dalcin    Level: intermediate
212116d9e3a6SLisandro Dalcin 
2122db781477SPatrick Sanan .seealso: `PCCreate()`, `PCSetType()`, `PCType`, `PC`,
2123db781477SPatrick Sanan           `PCHYPRE`
212416d9e3a6SLisandro Dalcin 
212516d9e3a6SLisandro Dalcin @*/
21267087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
212716d9e3a6SLisandro Dalcin {
212816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
21290700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
213016d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
2131cac4c232SBarry Smith   PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));
213216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
213316d9e3a6SLisandro Dalcin }
213416d9e3a6SLisandro Dalcin 
213516d9e3a6SLisandro Dalcin /*@C
213616d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
213716d9e3a6SLisandro Dalcin 
213816d9e3a6SLisandro Dalcin    Input Parameter:
213916d9e3a6SLisandro Dalcin .     pc - the preconditioner context
214016d9e3a6SLisandro Dalcin 
214116d9e3a6SLisandro Dalcin    Output Parameter:
2142db966c6cSHong Zhang .     name - either  euclid, pilut, parasails, boomeramg, ams, ads
214316d9e3a6SLisandro Dalcin 
214416d9e3a6SLisandro Dalcin    Level: intermediate
214516d9e3a6SLisandro Dalcin 
2146db781477SPatrick Sanan .seealso: `PCCreate()`, `PCHYPRESetType()`, `PCType`, `PC`,
2147db781477SPatrick Sanan           `PCHYPRE`
214816d9e3a6SLisandro Dalcin 
214916d9e3a6SLisandro Dalcin @*/
21507087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
215116d9e3a6SLisandro Dalcin {
215216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
21530700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
215416d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
2155cac4c232SBarry Smith   PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));
215616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
215716d9e3a6SLisandro Dalcin }
215816d9e3a6SLisandro Dalcin 
2159db6f9c32SMark Adams /*@C
2160db6f9c32SMark Adams    PCMGGalerkinSetMatProductAlgorithm - Set type of SpGEMM for hypre to use
2161db6f9c32SMark Adams 
2162db6f9c32SMark Adams    Logically Collective on PC
2163db6f9c32SMark Adams 
2164db6f9c32SMark Adams    Input Parameters:
2165db6f9c32SMark Adams +  pc - the hypre context
2166db6f9c32SMark Adams -  type - one of 'cusparse', 'hypre'
2167db6f9c32SMark Adams 
2168db6f9c32SMark Adams    Options Database Key:
216967b8a455SSatish Balay .  -pc_mg_galerkin_mat_product_algorithm <cusparse,hypre> - Type of SpGEMM to use in hypre
2170db6f9c32SMark Adams 
2171db6f9c32SMark Adams    Level: intermediate
2172db6f9c32SMark Adams 
2173db781477SPatrick Sanan .seealso: `PCMGGalerkinGetMatProductAlgorithm()`
2174db6f9c32SMark Adams 
2175db6f9c32SMark Adams @*/
2176db6f9c32SMark Adams PetscErrorCode PCMGGalerkinSetMatProductAlgorithm(PC pc,const char name[])
2177db6f9c32SMark Adams {
2178db6f9c32SMark Adams   PetscFunctionBegin;
2179db6f9c32SMark Adams   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
2180cac4c232SBarry Smith   PetscTryMethod(pc,"PCMGGalerkinSetMatProductAlgorithm_C",(PC,const char[]),(pc,name));
2181db6f9c32SMark Adams   PetscFunctionReturn(0);
2182db6f9c32SMark Adams }
2183db6f9c32SMark Adams 
2184db6f9c32SMark Adams /*@C
2185db6f9c32SMark Adams    PCMGGalerkinGetMatProductAlgorithm - Get type of SpGEMM for hypre
2186db6f9c32SMark Adams 
2187db6f9c32SMark Adams    Not Collective
2188db6f9c32SMark Adams 
2189db6f9c32SMark Adams    Input Parameter:
2190db6f9c32SMark Adams .  pc - the multigrid context
2191db6f9c32SMark Adams 
2192db6f9c32SMark Adams    Output Parameter:
2193db6f9c32SMark Adams .  name - one of 'cusparse', 'hypre'
2194db6f9c32SMark Adams 
2195db6f9c32SMark Adams    Level: intermediate
2196db6f9c32SMark Adams 
2197db781477SPatrick Sanan .seealso: `PCMGGalerkinSetMatProductAlgorithm()`
2198db6f9c32SMark Adams 
2199db6f9c32SMark Adams @*/
2200db6f9c32SMark Adams PetscErrorCode PCMGGalerkinGetMatProductAlgorithm(PC pc,const char *name[])
2201db6f9c32SMark Adams {
2202db6f9c32SMark Adams   PetscFunctionBegin;
2203db6f9c32SMark Adams   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
2204cac4c232SBarry Smith   PetscTryMethod(pc,"PCMGGalerkinGetMatProductAlgorithm_C",(PC,const char*[]),(pc,name));
2205db6f9c32SMark Adams   PetscFunctionReturn(0);
2206db6f9c32SMark Adams }
2207db6f9c32SMark Adams 
220816d9e3a6SLisandro Dalcin /*MC
220916d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
221016d9e3a6SLisandro Dalcin 
221116d9e3a6SLisandro Dalcin    Options Database Keys:
2212db966c6cSHong Zhang +   -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
2213ead8c081SBarry Smith .   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
2214ead8c081SBarry Smith .   -pc_hypre_boomeramg_vec_interp_variant <v> - where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
2215ead8c081SBarry Smith -   Many others, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX preconditioner
221616d9e3a6SLisandro Dalcin 
221716d9e3a6SLisandro Dalcin    Level: intermediate
221816d9e3a6SLisandro Dalcin 
221995452b02SPatrick Sanan    Notes:
222095452b02SPatrick Sanan     Apart from pc_hypre_type (for which there is PCHYPRESetType()),
222116d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
222216d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
222316d9e3a6SLisandro Dalcin 
2224c231f9e3SBarryFSmith           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_tol refer to the number of iterations
22250f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
22260f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
2227c231f9e3SBarryFSmith           (-pc_hypre_boomeramg_tol should be set to 0.0 - the default - to strictly use a fixed number of
22288f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
22290f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
22300f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
223116d9e3a6SLisandro Dalcin 
22320f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
22330f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
22340f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
223516d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
223616d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
223716d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
223816d9e3a6SLisandro Dalcin 
223916d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
224016d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
224116d9e3a6SLisandro Dalcin 
22425272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
2243fdd15c9aSJunchao Zhang           the following two options:
22440b1a5bd9SEric Chamberland 
22459e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
22469e5bc791SBarry Smith 
2247ead8c081SBarry Smith    GPU Notes:
2248ead8c081SBarry Smith      To configure hypre BoomerAMG so that it can utilize NVIDIA GPUs run ./configure --download-hypre --with-cuda
2249ead8c081SBarry Smith      Then pass VECCUDA vectors and MATAIJCUSPARSE matrices to the solvers and PETSc will automatically utilize hypre's GPU solvers.
2250ead8c081SBarry Smith 
2251ead8c081SBarry Smith      To configure hypre BoomerAMG so that it can utilize AMD GPUs run ./configure --download-hypre --with-hip
2252ead8c081SBarry Smith      Then pass VECHIP vectors to the solvers and PETSc will automatically utilize hypre's GPU solvers.
2253ead8c081SBarry Smith 
2254db781477SPatrick Sanan .seealso: `PCCreate()`, `PCSetType()`, `PCType`, `PC`,
2255db781477SPatrick Sanan           `PCHYPRESetType()`, `PCPFMG`
225616d9e3a6SLisandro Dalcin 
225716d9e3a6SLisandro Dalcin M*/
225816d9e3a6SLisandro Dalcin 
22598cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
226016d9e3a6SLisandro Dalcin {
226116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
226216d9e3a6SLisandro Dalcin 
226316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
22649566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(pc,&jac));
22652fa5cd67SKarl Rupp 
226616d9e3a6SLisandro Dalcin   pc->data                = jac;
22678695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
226816d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
226916d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
227016d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
227116d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
227216d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
22739566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE));
22749566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE));
22759566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE));
22769566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE));
22779566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE));
22789566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",PCHYPRESetInterpolations_HYPRE));
22799566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE));
22809566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",PCHYPRESetPoissonMatrix_HYPRE));
22819566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinSetMatProductAlgorithm_C",PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG));
22829566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc,"PCMGGalerkinGetMatProductAlgorithm_C",PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG));
22836ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE)
22846ea7df73SStefano Zampini #if defined(HYPRE_USING_HIP)
22859566063dSJacob Faibussowitsch   PetscCall(PetscDeviceInitialize(PETSC_DEVICE_HIP));
22866ea7df73SStefano Zampini #endif
22876ea7df73SStefano Zampini #if defined(HYPRE_USING_CUDA)
22889566063dSJacob Faibussowitsch   PetscCall(PetscDeviceInitialize(PETSC_DEVICE_CUDA));
22896ea7df73SStefano Zampini #endif
22906ea7df73SStefano Zampini #endif
229116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
229216d9e3a6SLisandro Dalcin }
2293ebc551c0SBarry Smith 
2294f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
2295f91d8e95SBarry Smith 
2296ebc551c0SBarry Smith typedef struct {
229768326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
2298f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
22999e5bc791SBarry Smith 
23009e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
23014ddd07fcSJed Brown   PetscInt its;
23029e5bc791SBarry Smith   double   tol;
23034ddd07fcSJed Brown   PetscInt relax_type;
23044ddd07fcSJed Brown   PetscInt rap_type;
23054ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
23064ddd07fcSJed Brown   PetscInt max_levels;
2307ebc551c0SBarry Smith } PC_PFMG;
2308ebc551c0SBarry Smith 
2309ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
2310ebc551c0SBarry Smith {
2311f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2312ebc551c0SBarry Smith 
2313ebc551c0SBarry Smith   PetscFunctionBegin;
2314792fecdfSBarry Smith   if (ex->hsolver) PetscCallExternal(HYPRE_StructPFMGDestroy,ex->hsolver);
23159566063dSJacob Faibussowitsch   PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc),&ex->hcomm));
23169566063dSJacob Faibussowitsch   PetscCall(PetscFree(pc->data));
2317ebc551c0SBarry Smith   PetscFunctionReturn(0);
2318ebc551c0SBarry Smith }
2319ebc551c0SBarry Smith 
23209e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
23219e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
23229e5bc791SBarry Smith 
2323ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
2324ebc551c0SBarry Smith {
2325ace3abfcSBarry Smith   PetscBool      iascii;
2326f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2327ebc551c0SBarry Smith 
2328ebc551c0SBarry Smith   PetscFunctionBegin;
23299566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
23309e5bc791SBarry Smith   if (iascii) {
23319566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n"));
233263a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    max iterations %" PetscInt_FMT "\n",ex->its));
23339566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    tolerance %g\n",ex->tol));
23349566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    relax type %s\n",PFMGRelaxType[ex->relax_type]));
23359566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    RAP type %s\n",PFMGRAPType[ex->rap_type]));
233663a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n",ex->num_pre_relax,ex->num_post_relax));
233763a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    max levels %" PetscInt_FMT "\n",ex->max_levels));
23389e5bc791SBarry Smith   }
2339ebc551c0SBarry Smith   PetscFunctionReturn(0);
2340ebc551c0SBarry Smith }
2341ebc551c0SBarry Smith 
23424416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2343ebc551c0SBarry Smith {
2344f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2345ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2346ebc551c0SBarry Smith 
2347ebc551c0SBarry Smith   PetscFunctionBegin;
2348d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject,"PFMG options");
23499566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL));
235068326731SBarry Smith   if (flg) {
2351792fecdfSBarry Smith     PetscCallExternal(HYPRE_StructPFMGSetPrintLevel,ex->hsolver,3);
235268326731SBarry Smith   }
23539566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL));
2354792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructPFMGSetMaxIter,ex->hsolver,ex->its);
23559566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_pfmg_num_pre_relax","Number of smoothing steps before coarse grid","HYPRE_StructPFMGSetNumPreRelax",ex->num_pre_relax,&ex->num_pre_relax,NULL));
2356792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructPFMGSetNumPreRelax,ex->hsolver,ex->num_pre_relax);
23579566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_pfmg_num_post_relax","Number of smoothing steps after coarse grid","HYPRE_StructPFMGSetNumPostRelax",ex->num_post_relax,&ex->num_post_relax,NULL));
2358792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructPFMGSetNumPostRelax,ex->hsolver,ex->num_post_relax);
23599e5bc791SBarry Smith 
23609566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL));
2361792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructPFMGSetMaxLevels,ex->hsolver,ex->max_levels);
23623b46a515SGlenn Hammond 
23639566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL));
2364792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructPFMGSetTol,ex->hsolver,ex->tol);
2365dd39110bSPierre Jolivet   PetscCall(PetscOptionsEList("-pc_pfmg_relax_type","Relax type for the up and down cycles","HYPRE_StructPFMGSetRelaxType",PFMGRelaxType,PETSC_STATIC_ARRAY_LENGTH(PFMGRelaxType),PFMGRelaxType[ex->relax_type],&ex->relax_type,NULL));
2366792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructPFMGSetRelaxType,ex->hsolver, ex->relax_type);
2367dd39110bSPierre Jolivet   PetscCall(PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,PETSC_STATIC_ARRAY_LENGTH(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL));
2368792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructPFMGSetRAPType,ex->hsolver, ex->rap_type);
2369d0609cedSBarry Smith   PetscOptionsHeadEnd();
2370ebc551c0SBarry Smith   PetscFunctionReturn(0);
2371ebc551c0SBarry Smith }
2372ebc551c0SBarry Smith 
2373f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
2374f91d8e95SBarry Smith {
2375f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
2376d9ca1df4SBarry Smith   PetscScalar       *yy;
2377d9ca1df4SBarry Smith   const PetscScalar *xx;
23784ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
23792cf14000SStefano Zampini   HYPRE_Int         hlower[3],hupper[3];
238068326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2381f91d8e95SBarry Smith 
2382f91d8e95SBarry Smith   PetscFunctionBegin;
23839566063dSJacob Faibussowitsch   PetscCall(PetscCitationsRegister(hypreCitation,&cite));
23849566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]));
23852cf14000SStefano Zampini   /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
2386f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
2387f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
2388f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
23892cf14000SStefano Zampini   hlower[0]  = (HYPRE_Int)ilower[0];
23902cf14000SStefano Zampini   hlower[1]  = (HYPRE_Int)ilower[1];
23912cf14000SStefano Zampini   hlower[2]  = (HYPRE_Int)ilower[2];
23922cf14000SStefano Zampini   hupper[0]  = (HYPRE_Int)iupper[0];
23932cf14000SStefano Zampini   hupper[1]  = (HYPRE_Int)iupper[1];
23942cf14000SStefano Zampini   hupper[2]  = (HYPRE_Int)iupper[2];
2395f91d8e95SBarry Smith 
2396f91d8e95SBarry Smith   /* copy x values over to hypre */
2397792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructVectorSetConstantValues,mx->hb,0.0);
23989566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(x,&xx));
2399792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructVectorSetBoxValues,mx->hb,hlower,hupper,(HYPRE_Complex*)xx);
24009566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(x,&xx));
2401792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructVectorAssemble,mx->hb);
2402792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructPFMGSolve,ex->hsolver,mx->hmat,mx->hb,mx->hx);
2403f91d8e95SBarry Smith 
2404f91d8e95SBarry Smith   /* copy solution values back to PETSc */
24059566063dSJacob Faibussowitsch   PetscCall(VecGetArray(y,&yy));
2406792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructVectorGetBoxValues,mx->hx,hlower,hupper,(HYPRE_Complex*)yy);
24079566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(y,&yy));
2408f91d8e95SBarry Smith   PetscFunctionReturn(0);
2409f91d8e95SBarry Smith }
2410f91d8e95SBarry Smith 
2411ace3abfcSBarry 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)
24129e5bc791SBarry Smith {
24139e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
24142cf14000SStefano Zampini   HYPRE_Int      oits;
24159e5bc791SBarry Smith 
24169e5bc791SBarry Smith   PetscFunctionBegin;
24179566063dSJacob Faibussowitsch   PetscCall(PetscCitationsRegister(hypreCitation,&cite));
2418792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructPFMGSetMaxIter,jac->hsolver,its*jac->its);
2419792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructPFMGSetTol,jac->hsolver,rtol);
24209e5bc791SBarry Smith 
24219566063dSJacob Faibussowitsch   PetscCall(PCApply_PFMG(pc,b,y));
2422792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructPFMGGetNumIterations,jac->hsolver,&oits);
24239e5bc791SBarry Smith   *outits = oits;
24249e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
24259e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2426792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructPFMGSetTol,jac->hsolver,jac->tol);
2427792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructPFMGSetMaxIter,jac->hsolver,jac->its);
24289e5bc791SBarry Smith   PetscFunctionReturn(0);
24299e5bc791SBarry Smith }
24309e5bc791SBarry Smith 
24313a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
24323a32d3dbSGlenn Hammond {
24333a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
24343a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2435ace3abfcSBarry Smith   PetscBool       flg;
24363a32d3dbSGlenn Hammond 
24373a32d3dbSGlenn Hammond   PetscFunctionBegin;
24389566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg));
243928b400f6SJacob Faibussowitsch   PetscCheck(flg,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
24403a32d3dbSGlenn Hammond 
24413a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
2442792fecdfSBarry Smith   if (ex->hsolver) PetscCallExternal(HYPRE_StructPFMGDestroy,ex->hsolver);
2443792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructPFMGCreate,ex->hcomm,&ex->hsolver);
2444792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructPFMGSetup,ex->hsolver,mx->hmat,mx->hb,mx->hx);
2445792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructPFMGSetZeroGuess,ex->hsolver);
24463a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
24473a32d3dbSGlenn Hammond }
24483a32d3dbSGlenn Hammond 
2449ebc551c0SBarry Smith /*MC
2450ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
2451ebc551c0SBarry Smith 
2452ebc551c0SBarry Smith    Level: advanced
2453ebc551c0SBarry Smith 
24549e5bc791SBarry Smith    Options Database:
245567b8a455SSatish Balay + -pc_pfmg_its <its> - number of iterations of PFMG to use as preconditioner
245667b8a455SSatish Balay . -pc_pfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid solve
245767b8a455SSatish Balay . -pc_pfmg_num_post_relax <steps> - number of smoothing steps after coarse grid solve
245867b8a455SSatish Balay . -pc_pfmg_tol <tol> - tolerance of PFMG
24599e5bc791SBarry 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
24609e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
2461f91d8e95SBarry Smith 
246295452b02SPatrick Sanan    Notes:
246395452b02SPatrick Sanan     This is for CELL-centered descretizations
24649e5bc791SBarry Smith 
24658e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
2466aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
24679e5bc791SBarry Smith 
2468db781477SPatrick Sanan .seealso: `PCMG`, `MATHYPRESTRUCT`
2469ebc551c0SBarry Smith M*/
2470ebc551c0SBarry Smith 
24718cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
2472ebc551c0SBarry Smith {
2473ebc551c0SBarry Smith   PC_PFMG        *ex;
2474ebc551c0SBarry Smith 
2475ebc551c0SBarry Smith   PetscFunctionBegin;
24769566063dSJacob Faibussowitsch   PetscCall(PetscNew(&ex)); \
247768326731SBarry Smith   pc->data = ex;
2478ebc551c0SBarry Smith 
24799e5bc791SBarry Smith   ex->its            = 1;
24809e5bc791SBarry Smith   ex->tol            = 1.e-8;
24819e5bc791SBarry Smith   ex->relax_type     = 1;
24829e5bc791SBarry Smith   ex->rap_type       = 0;
24839e5bc791SBarry Smith   ex->num_pre_relax  = 1;
24849e5bc791SBarry Smith   ex->num_post_relax = 1;
24853b46a515SGlenn Hammond   ex->max_levels     = 0;
24869e5bc791SBarry Smith 
2487ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2488ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2489ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2490f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
24919e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
249268326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
24932fa5cd67SKarl Rupp 
24949566063dSJacob Faibussowitsch   PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&ex->hcomm));
2495792fecdfSBarry Smith   PetscCallExternal(HYPRE_StructPFMGCreate,ex->hcomm,&ex->hsolver);
2496ebc551c0SBarry Smith   PetscFunctionReturn(0);
2497ebc551c0SBarry Smith }
2498d851a50bSGlenn Hammond 
2499325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2500325fc9f4SBarry Smith 
2501d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2502d851a50bSGlenn Hammond typedef struct {
2503d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2504d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2505d851a50bSGlenn Hammond 
2506d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
25074ddd07fcSJed Brown   PetscInt its;
2508d851a50bSGlenn Hammond   double   tol;
25094ddd07fcSJed Brown   PetscInt relax_type;
25104ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2511d851a50bSGlenn Hammond } PC_SysPFMG;
2512d851a50bSGlenn Hammond 
2513d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2514d851a50bSGlenn Hammond {
2515d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2516d851a50bSGlenn Hammond 
2517d851a50bSGlenn Hammond   PetscFunctionBegin;
2518792fecdfSBarry Smith   if (ex->ss_solver) PetscCallExternal(HYPRE_SStructSysPFMGDestroy,ex->ss_solver);
25199566063dSJacob Faibussowitsch   PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc),&ex->hcomm));
25209566063dSJacob Faibussowitsch   PetscCall(PetscFree(pc->data));
2521d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2522d851a50bSGlenn Hammond }
2523d851a50bSGlenn Hammond 
2524d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2525d851a50bSGlenn Hammond 
2526d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2527d851a50bSGlenn Hammond {
2528ace3abfcSBarry Smith   PetscBool      iascii;
2529d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2530d851a50bSGlenn Hammond 
2531d851a50bSGlenn Hammond   PetscFunctionBegin;
25329566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
2533d851a50bSGlenn Hammond   if (iascii) {
25349566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n"));
253563a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  max iterations %" PetscInt_FMT "\n",ex->its));
25369566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  tolerance %g\n",ex->tol));
25379566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  relax type %s\n",PFMGRelaxType[ex->relax_type]));
253863a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n",ex->num_pre_relax,ex->num_post_relax));
2539d851a50bSGlenn Hammond   }
2540d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2541d851a50bSGlenn Hammond }
2542d851a50bSGlenn Hammond 
25434416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2544d851a50bSGlenn Hammond {
2545d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2546ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2547d851a50bSGlenn Hammond 
2548d851a50bSGlenn Hammond   PetscFunctionBegin;
2549d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject,"SysPFMG options");
25509566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL));
2551d851a50bSGlenn Hammond   if (flg) {
2552792fecdfSBarry Smith     PetscCallExternal(HYPRE_SStructSysPFMGSetPrintLevel,ex->ss_solver,3);
2553d851a50bSGlenn Hammond   }
25549566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL));
2555792fecdfSBarry Smith   PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter,ex->ss_solver,ex->its);
25569566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_syspfmg_num_pre_relax","Number of smoothing steps before coarse grid","HYPRE_SStructSysPFMGSetNumPreRelax",ex->num_pre_relax,&ex->num_pre_relax,NULL));
2557792fecdfSBarry Smith   PetscCallExternal(HYPRE_SStructSysPFMGSetNumPreRelax,ex->ss_solver,ex->num_pre_relax);
25589566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_syspfmg_num_post_relax","Number of smoothing steps after coarse grid","HYPRE_SStructSysPFMGSetNumPostRelax",ex->num_post_relax,&ex->num_post_relax,NULL));
2559792fecdfSBarry Smith   PetscCallExternal(HYPRE_SStructSysPFMGSetNumPostRelax,ex->ss_solver,ex->num_post_relax);
2560d851a50bSGlenn Hammond 
25619566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL));
2562792fecdfSBarry Smith   PetscCallExternal(HYPRE_SStructSysPFMGSetTol,ex->ss_solver,ex->tol);
2563dd39110bSPierre Jolivet   PetscCall(PetscOptionsEList("-pc_syspfmg_relax_type","Relax type for the up and down cycles","HYPRE_SStructSysPFMGSetRelaxType",SysPFMGRelaxType,PETSC_STATIC_ARRAY_LENGTH(SysPFMGRelaxType),SysPFMGRelaxType[ex->relax_type],&ex->relax_type,NULL));
2564792fecdfSBarry Smith   PetscCallExternal(HYPRE_SStructSysPFMGSetRelaxType,ex->ss_solver, ex->relax_type);
2565d0609cedSBarry Smith   PetscOptionsHeadEnd();
2566d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2567d851a50bSGlenn Hammond }
2568d851a50bSGlenn Hammond 
2569d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2570d851a50bSGlenn Hammond {
2571d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2572d9ca1df4SBarry Smith   PetscScalar       *yy;
2573d9ca1df4SBarry Smith   const PetscScalar *xx;
25744ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
25752cf14000SStefano Zampini   HYPRE_Int         hlower[3],hupper[3];
2576d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
25774ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
25784ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
25794ddd07fcSJed Brown   PetscInt          part    = 0;
25804ddd07fcSJed Brown   PetscInt          size;
25814ddd07fcSJed Brown   PetscInt          i;
2582d851a50bSGlenn Hammond 
2583d851a50bSGlenn Hammond   PetscFunctionBegin;
25849566063dSJacob Faibussowitsch   PetscCall(PetscCitationsRegister(hypreCitation,&cite));
25859566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]));
25862cf14000SStefano Zampini   /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
2587d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2588d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2589d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
25902cf14000SStefano Zampini   hlower[0]  = (HYPRE_Int)ilower[0];
25912cf14000SStefano Zampini   hlower[1]  = (HYPRE_Int)ilower[1];
25922cf14000SStefano Zampini   hlower[2]  = (HYPRE_Int)ilower[2];
25932cf14000SStefano Zampini   hupper[0]  = (HYPRE_Int)iupper[0];
25942cf14000SStefano Zampini   hupper[1]  = (HYPRE_Int)iupper[1];
25952cf14000SStefano Zampini   hupper[2]  = (HYPRE_Int)iupper[2];
2596d851a50bSGlenn Hammond 
2597d851a50bSGlenn Hammond   size = 1;
25982fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
25992fa5cd67SKarl Rupp 
2600d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2601d851a50bSGlenn Hammond   if (ordering) {
2602792fecdfSBarry Smith     PetscCallExternal(HYPRE_SStructVectorSetConstantValues,mx->ss_b,0.0);
26039566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x,&xx));
2604792fecdfSBarry Smith     for (i= 0; i< nvars; i++) PetscCallExternal(HYPRE_SStructVectorSetBoxValues,mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(xx+(size*i)));
26059566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x,&xx));
2606792fecdfSBarry Smith     PetscCallExternal(HYPRE_SStructVectorAssemble,mx->ss_b);
2607792fecdfSBarry Smith     PetscCallExternal(HYPRE_SStructMatrixMatvec,1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x);
2608792fecdfSBarry Smith     PetscCallExternal(HYPRE_SStructSysPFMGSolve,ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x);
2609d851a50bSGlenn Hammond 
2610d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
26119566063dSJacob Faibussowitsch     PetscCall(VecGetArray(y,&yy));
2612792fecdfSBarry Smith     for (i= 0; i< nvars; i++) PetscCallExternal(HYPRE_SStructVectorGetBoxValues,mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(yy+(size*i)));
26139566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(y,&yy));
2614a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2615d851a50bSGlenn Hammond     PetscScalar *z;
26164ddd07fcSJed Brown     PetscInt    j, k;
2617d851a50bSGlenn Hammond 
26189566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nvars*size,&z));
2619792fecdfSBarry Smith     PetscCallExternal(HYPRE_SStructVectorSetConstantValues,mx->ss_b,0.0);
26209566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x,&xx));
2621d851a50bSGlenn Hammond 
2622d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2623d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2624d851a50bSGlenn Hammond       k= i*nvars;
26252fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2626d851a50bSGlenn Hammond     }
2627792fecdfSBarry Smith     for (i= 0; i< nvars; i++) PetscCallExternal(HYPRE_SStructVectorSetBoxValues,mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i)));
26289566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x,&xx));
2629792fecdfSBarry Smith     PetscCallExternal(HYPRE_SStructVectorAssemble,mx->ss_b);
2630792fecdfSBarry Smith     PetscCallExternal(HYPRE_SStructSysPFMGSolve,ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x);
2631d851a50bSGlenn Hammond 
2632d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
26339566063dSJacob Faibussowitsch     PetscCall(VecGetArray(y,&yy));
2634792fecdfSBarry Smith     for (i= 0; i< nvars; i++) PetscCallExternal(HYPRE_SStructVectorGetBoxValues,mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i)));
2635d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2636d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2637d851a50bSGlenn Hammond       k= i*nvars;
26382fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2639d851a50bSGlenn Hammond     }
26409566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(y,&yy));
26419566063dSJacob Faibussowitsch     PetscCall(PetscFree(z));
2642d851a50bSGlenn Hammond   }
2643d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2644d851a50bSGlenn Hammond }
2645d851a50bSGlenn Hammond 
2646ace3abfcSBarry 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)
2647d851a50bSGlenn Hammond {
2648d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
26492cf14000SStefano Zampini   HYPRE_Int      oits;
2650d851a50bSGlenn Hammond 
2651d851a50bSGlenn Hammond   PetscFunctionBegin;
26529566063dSJacob Faibussowitsch   PetscCall(PetscCitationsRegister(hypreCitation,&cite));
2653792fecdfSBarry Smith   PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter,jac->ss_solver,its*jac->its);
2654792fecdfSBarry Smith   PetscCallExternal(HYPRE_SStructSysPFMGSetTol,jac->ss_solver,rtol);
26559566063dSJacob Faibussowitsch   PetscCall(PCApply_SysPFMG(pc,b,y));
2656792fecdfSBarry Smith   PetscCallExternal(HYPRE_SStructSysPFMGGetNumIterations,jac->ss_solver,&oits);
2657d851a50bSGlenn Hammond   *outits = oits;
2658d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2659d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2660792fecdfSBarry Smith   PetscCallExternal(HYPRE_SStructSysPFMGSetTol,jac->ss_solver,jac->tol);
2661792fecdfSBarry Smith   PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter,jac->ss_solver,jac->its);
2662d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2663d851a50bSGlenn Hammond }
2664d851a50bSGlenn Hammond 
2665d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2666d851a50bSGlenn Hammond {
2667d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2668d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2669ace3abfcSBarry Smith   PetscBool        flg;
2670d851a50bSGlenn Hammond 
2671d851a50bSGlenn Hammond   PetscFunctionBegin;
26729566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg));
267328b400f6SJacob Faibussowitsch   PetscCheck(flg,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2674d851a50bSGlenn Hammond 
2675d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
2676792fecdfSBarry Smith   if (ex->ss_solver) PetscCallExternal(HYPRE_SStructSysPFMGDestroy,ex->ss_solver);
2677792fecdfSBarry Smith   PetscCallExternal(HYPRE_SStructSysPFMGCreate,ex->hcomm,&ex->ss_solver);
2678792fecdfSBarry Smith   PetscCallExternal(HYPRE_SStructSysPFMGSetZeroGuess,ex->ss_solver);
2679792fecdfSBarry Smith   PetscCallExternal(HYPRE_SStructSysPFMGSetup,ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x);
2680d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2681d851a50bSGlenn Hammond }
2682d851a50bSGlenn Hammond 
2683d851a50bSGlenn Hammond /*MC
2684d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2685d851a50bSGlenn Hammond 
2686d851a50bSGlenn Hammond    Level: advanced
2687d851a50bSGlenn Hammond 
2688d851a50bSGlenn Hammond    Options Database:
268967b8a455SSatish Balay + -pc_syspfmg_its <its> - number of iterations of SysPFMG to use as preconditioner
269067b8a455SSatish Balay . -pc_syspfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid
269167b8a455SSatish Balay . -pc_syspfmg_num_post_relax <steps> - number of smoothing steps after coarse grid
269267b8a455SSatish Balay . -pc_syspfmg_tol <tol> - tolerance of SysPFMG
269367b8a455SSatish Balay - -pc_syspfmg_relax_type <Weighted-Jacobi,Red/Black-Gauss-Seidel> - relaxation type for the up and down cycles
2694d851a50bSGlenn Hammond 
269595452b02SPatrick Sanan    Notes:
269695452b02SPatrick Sanan     This is for CELL-centered descretizations
2697d851a50bSGlenn Hammond 
2698f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2699aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2700d851a50bSGlenn Hammond            Also, only cell-centered variables.
2701d851a50bSGlenn Hammond 
2702db781477SPatrick Sanan .seealso: `PCMG`, `MATHYPRESSTRUCT`
2703d851a50bSGlenn Hammond M*/
2704d851a50bSGlenn Hammond 
27058cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2706d851a50bSGlenn Hammond {
2707d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2708d851a50bSGlenn Hammond 
2709d851a50bSGlenn Hammond   PetscFunctionBegin;
27109566063dSJacob Faibussowitsch   PetscCall(PetscNew(&ex)); \
2711d851a50bSGlenn Hammond   pc->data = ex;
2712d851a50bSGlenn Hammond 
2713d851a50bSGlenn Hammond   ex->its            = 1;
2714d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2715d851a50bSGlenn Hammond   ex->relax_type     = 1;
2716d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2717d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2718d851a50bSGlenn Hammond 
2719d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2720d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2721d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2722d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2723d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2724d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
27252fa5cd67SKarl Rupp 
27269566063dSJacob Faibussowitsch   PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc),&ex->hcomm));
2727792fecdfSBarry Smith   PetscCallExternal(HYPRE_SStructSysPFMGCreate,ex->hcomm,&ex->ss_solver);
2728d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2729d851a50bSGlenn Hammond }
2730