xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 6ea7df73cca75adecc2aef0b2f4d0c18ef6de222)
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>
9*6ea7df73SStefano 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 
16dff31646SBarry Smith static PetscBool cite = PETSC_FALSE;
17a8d69d7bSBarry 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";
181f817a21SBarry Smith 
1916d9e3a6SLisandro Dalcin /*
2016d9e3a6SLisandro Dalcin    Private context (data structure) for the  preconditioner.
2116d9e3a6SLisandro Dalcin */
2216d9e3a6SLisandro Dalcin typedef struct {
2316d9e3a6SLisandro Dalcin   HYPRE_Solver   hsolver;
2449a781f5SStefano Zampini   Mat            hpmat; /* MatHYPRE */
2516d9e3a6SLisandro Dalcin 
264ddd07fcSJed Brown   HYPRE_Int (*destroy)(HYPRE_Solver);
274ddd07fcSJed Brown   HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
284ddd07fcSJed Brown   HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
2916d9e3a6SLisandro Dalcin 
3016d9e3a6SLisandro Dalcin   MPI_Comm comm_hypre;
3116d9e3a6SLisandro Dalcin   char     *hypre_type;
3216d9e3a6SLisandro Dalcin 
3316d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
344ddd07fcSJed Brown   PetscInt  maxiter;
3539accc25SStefano Zampini   PetscReal tol;
3616d9e3a6SLisandro Dalcin 
3716d9e3a6SLisandro Dalcin   /* options for Pilut */
384ddd07fcSJed Brown   PetscInt factorrowsize;
3916d9e3a6SLisandro Dalcin 
4016d9e3a6SLisandro Dalcin   /* options for ParaSails */
414ddd07fcSJed Brown   PetscInt  nlevels;
428966356dSPierre Jolivet   PetscReal threshold;
4339accc25SStefano Zampini   PetscReal filter;
4439accc25SStefano Zampini   PetscReal loadbal;
454ddd07fcSJed Brown   PetscInt  logging;
464ddd07fcSJed Brown   PetscInt  ruse;
474ddd07fcSJed Brown   PetscInt  symt;
4816d9e3a6SLisandro Dalcin 
4922b6d1caSBarry Smith   /* options for BoomerAMG */
50ace3abfcSBarry Smith   PetscBool printstatistics;
5116d9e3a6SLisandro Dalcin 
5216d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
534ddd07fcSJed Brown   PetscInt  cycletype;
544ddd07fcSJed Brown   PetscInt  maxlevels;
5539accc25SStefano Zampini   PetscReal strongthreshold;
5639accc25SStefano Zampini   PetscReal maxrowsum;
574ddd07fcSJed Brown   PetscInt  gridsweeps[3];
584ddd07fcSJed Brown   PetscInt  coarsentype;
594ddd07fcSJed Brown   PetscInt  measuretype;
606a251517SEike Mueller   PetscInt  smoothtype;
618131ecf7SEike Mueller   PetscInt  smoothnumlevels;
62ec64516dSEike Mueller   PetscInt  eu_level;   /* Number of levels for ILU(k) in Euclid */
6339accc25SStefano Zampini   PetscReal eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */
64ec64516dSEike Mueller   PetscInt  eu_bj;      /* Defines use of Block Jacobi ILU in Euclid */
654ddd07fcSJed Brown   PetscInt  relaxtype[3];
6639accc25SStefano Zampini   PetscReal relaxweight;
6739accc25SStefano Zampini   PetscReal outerrelaxweight;
684ddd07fcSJed Brown   PetscInt  relaxorder;
6939accc25SStefano Zampini   PetscReal truncfactor;
70ace3abfcSBarry Smith   PetscBool applyrichardson;
714ddd07fcSJed Brown   PetscInt  pmax;
724ddd07fcSJed Brown   PetscInt  interptype;
73589dcaf0SStefano Zampini   PetscInt  maxc;
74589dcaf0SStefano Zampini   PetscInt  minc;
75589dcaf0SStefano Zampini 
76*6ea7df73SStefano Zampini   /* GPU */
77*6ea7df73SStefano Zampini   PetscBool keeptranspose;
78*6ea7df73SStefano Zampini   PetscInt  rap2;
79*6ea7df73SStefano Zampini   PetscInt  mod_rap2;
80*6ea7df73SStefano Zampini 
81589dcaf0SStefano Zampini   /* AIR */
82589dcaf0SStefano Zampini   PetscInt  Rtype;
83589dcaf0SStefano Zampini   PetscReal Rstrongthreshold;
84589dcaf0SStefano Zampini   PetscReal Rfilterthreshold;
85589dcaf0SStefano Zampini   PetscInt  Adroptype;
86589dcaf0SStefano Zampini   PetscReal Adroptol;
87589dcaf0SStefano Zampini 
884ddd07fcSJed Brown   PetscInt  agg_nl;
89*6ea7df73SStefano Zampini   PetscInt  agg_interptype;
904ddd07fcSJed Brown   PetscInt  agg_num_paths;
91ace3abfcSBarry Smith   PetscBool nodal_relax;
924ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
934cb006feSStefano Zampini 
945272c319SBarry Smith   PetscInt  nodal_coarsening;
9522e51d31SStefano Zampini   PetscInt  nodal_coarsening_diag;
965272c319SBarry Smith   PetscInt  vec_interp_variant;
9722e51d31SStefano Zampini   PetscInt  vec_interp_qmax;
9822e51d31SStefano Zampini   PetscBool vec_interp_smooth;
9922e51d31SStefano Zampini   PetscInt  interp_refine;
10022e51d31SStefano Zampini 
101*6ea7df73SStefano Zampini   /* NearNullSpace support */
102*6ea7df73SStefano Zampini   VecHYPRE_IJVector *hmnull;
103*6ea7df73SStefano Zampini   HYPRE_ParVector   *phmnull;
1045272c319SBarry Smith   PetscInt          n_hmnull;
1055272c319SBarry Smith   Vec               hmnull_constant;
1065272c319SBarry Smith 
107863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
108863406b8SStefano Zampini   PetscInt  as_print;
109863406b8SStefano Zampini   PetscInt  as_max_iter;
110863406b8SStefano Zampini   PetscReal as_tol;
111863406b8SStefano Zampini   PetscInt  as_relax_type;
112863406b8SStefano Zampini   PetscInt  as_relax_times;
113863406b8SStefano Zampini   PetscReal as_relax_weight;
114863406b8SStefano Zampini   PetscReal as_omega;
115863406b8SStefano 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) */
116863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
117863406b8SStefano 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) */
118863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
1194cb006feSStefano Zampini   PetscInt  ams_cycle_type;
120863406b8SStefano Zampini   PetscInt  ads_cycle_type;
1214cb006feSStefano Zampini 
1224cb006feSStefano Zampini   /* additional data */
1235ac14e1cSStefano Zampini   Mat G;             /* MatHYPRE */
1245ac14e1cSStefano Zampini   Mat C;             /* MatHYPRE */
1255ac14e1cSStefano Zampini   Mat alpha_Poisson; /* MatHYPRE */
1265ac14e1cSStefano Zampini   Mat beta_Poisson;  /* MatHYPRE */
1275ac14e1cSStefano Zampini 
1285ac14e1cSStefano Zampini   /* extra information for AMS */
1295ac14e1cSStefano Zampini   PetscInt          dim; /* geometrical dimension */
130*6ea7df73SStefano Zampini   VecHYPRE_IJVector coords[3];
131*6ea7df73SStefano Zampini   VecHYPRE_IJVector constants[3];
1326bf688a0SCe Qin   Mat               RT_PiFull, RT_Pi[3];
1336bf688a0SCe Qin   Mat               ND_PiFull, ND_Pi[3];
1344cb006feSStefano Zampini   PetscBool         ams_beta_is_zero;
13523df4f25SStefano Zampini   PetscBool         ams_beta_is_zero_part;
13623df4f25SStefano Zampini   PetscInt          ams_proj_freq;
13716d9e3a6SLisandro Dalcin } PC_HYPRE;
13816d9e3a6SLisandro Dalcin 
139d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
140d2128fa2SBarry Smith {
141d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
142d2128fa2SBarry Smith 
143d2128fa2SBarry Smith   PetscFunctionBegin;
144d2128fa2SBarry Smith   *hsolver = jac->hsolver;
145d2128fa2SBarry Smith   PetscFunctionReturn(0);
146d2128fa2SBarry Smith }
14716d9e3a6SLisandro Dalcin 
148fd2dd295SFande Kong /*
1498a2c336bSFande Kong   Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix
1508a2c336bSFande Kong   is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine.
1518a2c336bSFande Kong   It is used in PCHMG. Other users should avoid using this function.
152fd2dd295SFande Kong */
153fd2dd295SFande Kong static PetscErrorCode PCGetCoarseOperators_BoomerAMG(PC pc,PetscInt *nlevels,Mat *operators[])
1548a2c336bSFande Kong {
1558a2c336bSFande Kong   PC_HYPRE             *jac  = (PC_HYPRE*)pc->data;
1568a2c336bSFande Kong   PetscBool            same = PETSC_FALSE;
1578a2c336bSFande Kong   PetscErrorCode       ierr;
1588a2c336bSFande Kong   PetscInt             num_levels,l;
1598a2c336bSFande Kong   Mat                  *mattmp;
1608a2c336bSFande Kong   hypre_ParCSRMatrix   **A_array;
1618a2c336bSFande Kong 
1628a2c336bSFande Kong   PetscFunctionBegin;
1638a2c336bSFande Kong   ierr = PetscStrcmp(jac->hypre_type,"boomeramg",&same);CHKERRQ(ierr);
1648a2c336bSFande Kong   if (!same) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_NOTSAMETYPE,"Hypre type is not BoomerAMG \n");
1658a2c336bSFande Kong   num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData*) (jac->hsolver));
1668a2c336bSFande Kong   ierr = PetscMalloc1(num_levels,&mattmp);CHKERRQ(ierr);
1678a2c336bSFande Kong   A_array    = hypre_ParAMGDataAArray((hypre_ParAMGData*) (jac->hsolver));
1688a2c336bSFande Kong   for (l=1; l<num_levels; l++) {
1698a2c336bSFande Kong     ierr = MatCreateFromParCSR(A_array[l],MATAIJ,PETSC_OWN_POINTER, &(mattmp[num_levels-1-l]));CHKERRQ(ierr);
1708a2c336bSFande Kong     /* We want to own the data, and HYPRE can not touch this matrix any more */
1718a2c336bSFande Kong     A_array[l] = NULL;
1728a2c336bSFande Kong   }
1738a2c336bSFande Kong   *nlevels = num_levels;
1748a2c336bSFande Kong   *operators = mattmp;
1758a2c336bSFande Kong   PetscFunctionReturn(0);
1768a2c336bSFande Kong }
1778a2c336bSFande Kong 
178fd2dd295SFande Kong /*
1798a2c336bSFande Kong   Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix
1808a2c336bSFande Kong   is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine.
1818a2c336bSFande Kong   It is used in PCHMG. Other users should avoid using this function.
182fd2dd295SFande Kong */
183fd2dd295SFande Kong static PetscErrorCode PCGetInterpolations_BoomerAMG(PC pc,PetscInt *nlevels,Mat *interpolations[])
1848a2c336bSFande Kong {
1858a2c336bSFande Kong   PC_HYPRE             *jac  = (PC_HYPRE*)pc->data;
1868a2c336bSFande Kong   PetscBool            same = PETSC_FALSE;
1878a2c336bSFande Kong   PetscErrorCode       ierr;
1888a2c336bSFande Kong   PetscInt             num_levels,l;
1898a2c336bSFande Kong   Mat                  *mattmp;
1908a2c336bSFande Kong   hypre_ParCSRMatrix   **P_array;
1918a2c336bSFande Kong 
1928a2c336bSFande Kong   PetscFunctionBegin;
1938a2c336bSFande Kong   ierr = PetscStrcmp(jac->hypre_type,"boomeramg",&same);CHKERRQ(ierr);
1948a2c336bSFande Kong   if (!same) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_NOTSAMETYPE,"Hypre type is not BoomerAMG \n");
1958a2c336bSFande Kong   num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData*) (jac->hsolver));
1968a2c336bSFande Kong   ierr = PetscMalloc1(num_levels,&mattmp);CHKERRQ(ierr);
1978a2c336bSFande Kong   P_array  = hypre_ParAMGDataPArray((hypre_ParAMGData*) (jac->hsolver));
1988a2c336bSFande Kong   for (l=1; l<num_levels; l++) {
1998a2c336bSFande Kong     ierr = MatCreateFromParCSR(P_array[num_levels-1-l],MATAIJ,PETSC_OWN_POINTER, &(mattmp[l-1]));CHKERRQ(ierr);
2008a2c336bSFande Kong     /* We want to own the data, and HYPRE can not touch this matrix any more */
2018a2c336bSFande Kong     P_array[num_levels-1-l] = NULL;
2028a2c336bSFande Kong   }
2038a2c336bSFande Kong   *nlevels = num_levels;
2048a2c336bSFande Kong   *interpolations = mattmp;
2058a2c336bSFande Kong   PetscFunctionReturn(0);
2068a2c336bSFande Kong }
2078a2c336bSFande Kong 
208ce6a8a0dSJed Brown /* Resets (frees) Hypre's representation of the near null space */
209ce6a8a0dSJed Brown static PetscErrorCode PCHYPREResetNearNullSpace_Private(PC pc)
210ce6a8a0dSJed Brown {
211ce6a8a0dSJed Brown   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
212ce6a8a0dSJed Brown   PetscInt       i;
2139d678128SJed Brown   PetscErrorCode ierr;
214ce6a8a0dSJed Brown 
2159d678128SJed Brown   PetscFunctionBegin;
216ce6a8a0dSJed Brown   for (i=0; i<jac->n_hmnull; i++) {
217*6ea7df73SStefano Zampini     ierr = VecHYPRE_IJVectorDestroy(&jac->hmnull[i]);CHKERRQ(ierr);
218ce6a8a0dSJed Brown   }
219ce6a8a0dSJed Brown   ierr = PetscFree(jac->hmnull);CHKERRQ(ierr);
220ce6a8a0dSJed Brown   ierr = PetscFree(jac->phmnull);CHKERRQ(ierr);
221ce6a8a0dSJed Brown   ierr = VecDestroy(&jac->hmnull_constant);CHKERRQ(ierr);
2229d678128SJed Brown   jac->n_hmnull = 0;
223ce6a8a0dSJed Brown   PetscFunctionReturn(0);
224ce6a8a0dSJed Brown }
225ce6a8a0dSJed Brown 
22616d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
22716d9e3a6SLisandro Dalcin {
22816d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
22949a781f5SStefano Zampini   Mat_HYPRE          *hjac;
23016d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
23116d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
23249a781f5SStefano Zampini   PetscBool          ishypre;
23349a781f5SStefano Zampini   PetscErrorCode     ierr;
23416d9e3a6SLisandro Dalcin 
23516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
23616d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
23702a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
23816d9e3a6SLisandro Dalcin   }
2395f5c5b43SBarry Smith 
24049a781f5SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRE,&ishypre);CHKERRQ(ierr);
24149a781f5SStefano Zampini   if (!ishypre) {
2426bf688a0SCe Qin     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
2436bf688a0SCe Qin     ierr = MatConvert(pc->pmat,MATHYPRE,MAT_INITIAL_MATRIX,&jac->hpmat);CHKERRQ(ierr);
244589dcaf0SStefano Zampini     ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)jac->hpmat);CHKERRQ(ierr);
24549a781f5SStefano Zampini   } else {
24649a781f5SStefano Zampini     ierr = PetscObjectReference((PetscObject)pc->pmat);CHKERRQ(ierr);
24749a781f5SStefano Zampini     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
24849a781f5SStefano Zampini     jac->hpmat = pc->pmat;
24916d9e3a6SLisandro Dalcin   }
250*6ea7df73SStefano Zampini   /* allow debug */
251*6ea7df73SStefano Zampini   ierr = MatViewFromOptions(jac->hpmat,NULL,"-pc_hypre_mat_view");CHKERRQ(ierr);
25249a781f5SStefano Zampini   hjac = (Mat_HYPRE*)(jac->hpmat->data);
2535f5c5b43SBarry Smith 
25416d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
25516d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
2565272c319SBarry Smith     MatNullSpace mnull;
2575272c319SBarry Smith     PetscBool    has_const;
25849a781f5SStefano Zampini     PetscInt     bs,nvec,i;
2595272c319SBarry Smith     const Vec    *vecs;
2605272c319SBarry Smith 
26116d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
2622fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
2635272c319SBarry Smith     ierr = MatGetNearNullSpace(pc->mat, &mnull);CHKERRQ(ierr);
2645272c319SBarry Smith     if (mnull) {
265ce6a8a0dSJed Brown       ierr = PCHYPREResetNearNullSpace_Private(pc);CHKERRQ(ierr);
2665272c319SBarry Smith       ierr = MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs);CHKERRQ(ierr);
2675272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull);CHKERRQ(ierr);
2685272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->phmnull);CHKERRQ(ierr);
2695272c319SBarry Smith       for (i=0; i<nvec; i++) {
270*6ea7df73SStefano Zampini         ierr = VecHYPRE_IJVectorCreate(vecs[i]->map,&jac->hmnull[i]);CHKERRQ(ierr);
271*6ea7df73SStefano Zampini         ierr = VecHYPRE_IJVectorCopy(vecs[i],jac->hmnull[i]);CHKERRQ(ierr);
272*6ea7df73SStefano Zampini         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[i]->ij,(void**)&jac->phmnull[i]));
2735272c319SBarry Smith       }
2745272c319SBarry Smith       if (has_const) {
2755272c319SBarry Smith         ierr = MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL);CHKERRQ(ierr);
276589dcaf0SStefano Zampini         ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)jac->hmnull_constant);CHKERRQ(ierr);
2775272c319SBarry Smith         ierr = VecSet(jac->hmnull_constant,1);CHKERRQ(ierr);
2781e1ea65dSPierre Jolivet         ierr = VecNormalize(jac->hmnull_constant,NULL);CHKERRQ(ierr);
279*6ea7df73SStefano Zampini         ierr = VecHYPRE_IJVectorCreate(jac->hmnull_constant->map,&jac->hmnull[nvec]);CHKERRQ(ierr);
280*6ea7df73SStefano Zampini         ierr = VecHYPRE_IJVectorCopy(jac->hmnull_constant,jac->hmnull[nvec]);CHKERRQ(ierr);
281*6ea7df73SStefano Zampini         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[nvec]->ij,(void**)&jac->phmnull[nvec]));
2825272c319SBarry Smith         nvec++;
2835272c319SBarry Smith       }
2845272c319SBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVectors,(jac->hsolver,nvec,jac->phmnull));
2855272c319SBarry Smith       jac->n_hmnull = nvec;
2865272c319SBarry Smith     }
2874cb006feSStefano Zampini   }
288863406b8SStefano Zampini 
2894cb006feSStefano Zampini   /* special case for AMS */
2904cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
2915ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2925ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
2936bf688a0SCe Qin     if (!jac->coords[0] && !jac->constants[0] && !(jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
2946bf688a0SCe 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");
2956bf688a0SCe Qin     }
2965ac14e1cSStefano Zampini     if (jac->dim) {
2975ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,jac->dim));
2985ac14e1cSStefano Zampini     }
2995ac14e1cSStefano Zampini     if (jac->constants[0]) {
3005ac14e1cSStefano Zampini       HYPRE_ParVector ozz,zoz,zzo = NULL;
301*6ea7df73SStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0]->ij,(void**)(&ozz)));
302*6ea7df73SStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1]->ij,(void**)(&zoz)));
3035ac14e1cSStefano Zampini       if (jac->constants[2]) {
304*6ea7df73SStefano Zampini         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2]->ij,(void**)(&zzo)));
3055ac14e1cSStefano Zampini       }
3065ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,ozz,zoz,zzo));
3075ac14e1cSStefano Zampini     }
3085ac14e1cSStefano Zampini     if (jac->coords[0]) {
3095ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
3105ac14e1cSStefano Zampini       coords[0] = NULL;
3115ac14e1cSStefano Zampini       coords[1] = NULL;
3125ac14e1cSStefano Zampini       coords[2] = NULL;
313*6ea7df73SStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0]->ij,(void**)(&coords[0])));
314*6ea7df73SStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1]->ij,(void**)(&coords[1])));
315*6ea7df73SStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2]->ij,(void**)(&coords[2])));
3165ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
3175ac14e1cSStefano Zampini     }
31849a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
3195ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
3205ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3215ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr));
3225ac14e1cSStefano Zampini     if (jac->alpha_Poisson) {
3235ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->alpha_Poisson->data);
3245ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3255ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr));
3265ac14e1cSStefano Zampini     }
3275ac14e1cSStefano Zampini     if (jac->ams_beta_is_zero) {
3285ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
3295ac14e1cSStefano Zampini     } else if (jac->beta_Poisson) {
3305ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->beta_Poisson->data);
3315ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3325ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr));
3335ac14e1cSStefano Zampini     }
3346bf688a0SCe Qin     if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) {
3356bf688a0SCe Qin       PetscInt           i;
3366bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
3376bf688a0SCe Qin       if (jac->ND_PiFull) {
3386bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
3396bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
3406bf688a0SCe Qin       } else {
3416bf688a0SCe Qin         nd_parcsrfull = NULL;
3426bf688a0SCe Qin       }
3436bf688a0SCe Qin       for (i=0;i<3;++i) {
3446bf688a0SCe Qin         if (jac->ND_Pi[i]) {
3456bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
3466bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
3476bf688a0SCe Qin         } else {
3486bf688a0SCe Qin           nd_parcsr[i] = NULL;
3496bf688a0SCe Qin         }
3506bf688a0SCe Qin       }
3516bf688a0SCe Qin       PetscStackCallStandard(HYPRE_AMSSetInterpolations,(jac->hsolver,nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]));
3526bf688a0SCe Qin     }
3534cb006feSStefano Zampini   }
354863406b8SStefano Zampini   /* special case for ADS */
355863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
3565ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
3575ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
3586bf688a0SCe 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])))) {
3596bf688a0SCe Qin       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations");
3606bf688a0SCe Qin     }
36137096e45SBarry Smith     else if (!jac->coords[1] || !jac->coords[2]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner has been designed for three dimensional problems! For two dimensional problems, use HYPRE AMS instead");
36249a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
36349a781f5SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient");
3645ac14e1cSStefano Zampini     if (jac->coords[0]) {
3655ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
3665ac14e1cSStefano Zampini       coords[0] = NULL;
3675ac14e1cSStefano Zampini       coords[1] = NULL;
3685ac14e1cSStefano Zampini       coords[2] = NULL;
369*6ea7df73SStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0]->ij,(void**)(&coords[0])));
370*6ea7df73SStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1]->ij,(void**)(&coords[1])));
371*6ea7df73SStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2]->ij,(void**)(&coords[2])));
3725ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_ADSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
3735ac14e1cSStefano Zampini     }
3745ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
3755ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3765ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteGradient,(jac->hsolver,parcsr));
3775ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->C->data);
3785ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3795ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteCurl,(jac->hsolver,parcsr));
3806bf688a0SCe Qin     if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
3816bf688a0SCe Qin       PetscInt           i;
3826bf688a0SCe Qin       HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3];
3836bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
3846bf688a0SCe Qin       if (jac->RT_PiFull) {
3856bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->RT_PiFull->data);
3866bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsrfull)));
3876bf688a0SCe Qin       } else {
3886bf688a0SCe Qin         rt_parcsrfull = NULL;
3896bf688a0SCe Qin       }
3906bf688a0SCe Qin       for (i=0;i<3;++i) {
3916bf688a0SCe Qin         if (jac->RT_Pi[i]) {
3926bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->RT_Pi[i]->data);
3936bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsr[i])));
3946bf688a0SCe Qin         } else {
3956bf688a0SCe Qin           rt_parcsr[i] = NULL;
3966bf688a0SCe Qin         }
3976bf688a0SCe Qin       }
3986bf688a0SCe Qin       if (jac->ND_PiFull) {
3996bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
4006bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
4016bf688a0SCe Qin       } else {
4026bf688a0SCe Qin         nd_parcsrfull = NULL;
4036bf688a0SCe Qin       }
4046bf688a0SCe Qin       for (i=0;i<3;++i) {
4056bf688a0SCe Qin         if (jac->ND_Pi[i]) {
4066bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
4076bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
4086bf688a0SCe Qin         } else {
4096bf688a0SCe Qin           nd_parcsr[i] = NULL;
4106bf688a0SCe Qin         }
4116bf688a0SCe Qin       }
4126bf688a0SCe Qin       PetscStackCallStandard(HYPRE_ADSSetInterpolations,(jac->hsolver,rt_parcsrfull,rt_parcsr[0],rt_parcsr[1],rt_parcsr[2],nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]));
4136bf688a0SCe Qin     }
414863406b8SStefano Zampini   }
41549a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
416*6ea7df73SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b->ij,(void**)&bv));
417*6ea7df73SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x->ij,(void**)&xv));
41822e51d31SStefano Zampini   PetscStackCallStandard(jac->setup,(jac->hsolver,hmat,bv,xv));
41916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
42016d9e3a6SLisandro Dalcin }
42116d9e3a6SLisandro Dalcin 
42216d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
42316d9e3a6SLisandro Dalcin {
42416d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
42549a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
42616d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
42716d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
42816d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
4294ddd07fcSJed Brown   PetscInt           hierr;
43016d9e3a6SLisandro Dalcin 
43116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
432dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
43316d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
434*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPushVecRead(hjac->b,b);CHKERRQ(ierr);
435*6ea7df73SStefano Zampini   if (jac->applyrichardson) { ierr = VecHYPRE_IJVectorPushVec(hjac->x,x);CHKERRQ(ierr); }
436*6ea7df73SStefano Zampini   else { ierr = VecHYPRE_IJVectorPushVecWrite(hjac->x,x);CHKERRQ(ierr); }
43749a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
438*6ea7df73SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b->ij,(void**)&jbv));
439*6ea7df73SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x->ij,(void**)&jxv));
440fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
44165e19b50SBarry Smith   if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
442fd3f9acdSBarry Smith   if (hierr) hypre__global_error = 0;);
44316d9e3a6SLisandro Dalcin 
44423df4f25SStefano Zampini   if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) {
4455ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSProjectOutGradients,(jac->hsolver,jxv));
44621df291bSStefano Zampini   }
447*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPopVec(hjac->x);CHKERRQ(ierr);
448*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPopVec(hjac->b);CHKERRQ(ierr);
44916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
45016d9e3a6SLisandro Dalcin }
45116d9e3a6SLisandro Dalcin 
4528695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc)
4538695de01SBarry Smith {
4548695de01SBarry Smith   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
4558695de01SBarry Smith   PetscErrorCode ierr;
4568695de01SBarry Smith 
4578695de01SBarry Smith   PetscFunctionBegin;
45849a781f5SStefano Zampini   ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
4595ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
4605ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
4615ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
4625ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
4636bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
4646bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[0]);CHKERRQ(ierr);
4656bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[1]);CHKERRQ(ierr);
4666bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[2]);CHKERRQ(ierr);
4676bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
4686bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[0]);CHKERRQ(ierr);
4696bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[1]);CHKERRQ(ierr);
4706bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[2]);CHKERRQ(ierr);
471*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->coords[0]);CHKERRQ(ierr);
472*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->coords[1]);CHKERRQ(ierr);
473*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->coords[2]);CHKERRQ(ierr);
474*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->constants[0]);CHKERRQ(ierr);
475*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->constants[1]);CHKERRQ(ierr);
476*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->constants[2]);CHKERRQ(ierr);
477ce6a8a0dSJed Brown   ierr = PCHYPREResetNearNullSpace_Private(pc);CHKERRQ(ierr);
4785ac14e1cSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
4795ac14e1cSStefano Zampini   jac->dim = 0;
4808695de01SBarry Smith   PetscFunctionReturn(0);
4818695de01SBarry Smith }
4828695de01SBarry Smith 
48316d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
48416d9e3a6SLisandro Dalcin {
48516d9e3a6SLisandro Dalcin   PC_HYPRE                 *jac = (PC_HYPRE*)pc->data;
48616d9e3a6SLisandro Dalcin   PetscErrorCode           ierr;
48716d9e3a6SLisandro Dalcin 
48816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
4898695de01SBarry Smith   ierr = PCReset_HYPRE(pc);CHKERRQ(ierr);
49022e51d31SStefano Zampini   if (jac->destroy) PetscStackCallStandard(jac->destroy,(jac->hsolver));
491503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
492ffc4695bSBarry Smith   if (jac->comm_hypre != MPI_COMM_NULL) {ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRMPI(ierr);}
493c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
49416d9e3a6SLisandro Dalcin 
49516d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
496bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
497bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
4984cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
4994cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
500863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
5016bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",NULL);CHKERRQ(ierr);
5024cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
5035ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",NULL);CHKERRQ(ierr);
504fd2dd295SFande Kong   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",NULL);CHKERRQ(ierr);
505fd2dd295SFande Kong   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",NULL);CHKERRQ(ierr);
50616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
50716d9e3a6SLisandro Dalcin }
50816d9e3a6SLisandro Dalcin 
50916d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
5104416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptionItems *PetscOptionsObject,PC pc)
51116d9e3a6SLisandro Dalcin {
51216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
51316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
514ace3abfcSBarry Smith   PetscBool      flag;
51516d9e3a6SLisandro Dalcin 
51616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
517e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
51816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
519fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
52016d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
521fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
52216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
523fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
52416d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
52516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
52616d9e3a6SLisandro Dalcin }
52716d9e3a6SLisandro Dalcin 
52816d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
52916d9e3a6SLisandro Dalcin {
53016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
53116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
532ace3abfcSBarry Smith   PetscBool      iascii;
53316d9e3a6SLisandro Dalcin 
53416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
535251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
53616d9e3a6SLisandro Dalcin   if (iascii) {
53716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
53816d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
539efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
54016d9e3a6SLisandro Dalcin     } else {
541efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default maximum number of iterations \n");CHKERRQ(ierr);
54216d9e3a6SLisandro Dalcin     }
54316d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
544efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
54516d9e3a6SLisandro Dalcin     } else {
546efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default drop tolerance \n");CHKERRQ(ierr);
54716d9e3a6SLisandro Dalcin     }
54816d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
549efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
55016d9e3a6SLisandro Dalcin     } else {
551efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default factor row size \n");CHKERRQ(ierr);
55216d9e3a6SLisandro Dalcin     }
55316d9e3a6SLisandro Dalcin   }
55416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
55516d9e3a6SLisandro Dalcin }
55616d9e3a6SLisandro Dalcin 
55716d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
558db966c6cSHong Zhang static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PetscOptionItems *PetscOptionsObject,PC pc)
559db966c6cSHong Zhang {
560db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
561db966c6cSHong Zhang   PetscErrorCode ierr;
5628bf83915SBarry Smith   PetscBool      flag,eu_bj = jac->eu_bj ? PETSC_TRUE : PETSC_FALSE;
563db966c6cSHong Zhang 
564db966c6cSHong Zhang   PetscFunctionBegin;
565db966c6cSHong Zhang   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Euclid Options");CHKERRQ(ierr);
566db966c6cSHong Zhang   ierr = PetscOptionsInt("-pc_hypre_euclid_level","Factorization levels","None",jac->eu_level,&jac->eu_level,&flag);CHKERRQ(ierr);
567db966c6cSHong Zhang   if (flag) PetscStackCallStandard(HYPRE_EuclidSetLevel,(jac->hsolver,jac->eu_level));
5688bf83915SBarry Smith 
5698bf83915SBarry Smith   ierr = PetscOptionsReal("-pc_hypre_euclid_droptolerance","Drop tolerance for ILU(k) in Euclid","None",jac->eu_droptolerance,&jac->eu_droptolerance,&flag);CHKERRQ(ierr);
5708bf83915SBarry Smith   if (flag) {
5718bf83915SBarry Smith     PetscMPIInt size;
5728bf83915SBarry Smith 
57355b25c41SPierre Jolivet     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRMPI(ierr);
5748bf83915SBarry Smith     if (size > 1) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"hypre's Euclid does not support a parallel drop tolerance");
5758bf83915SBarry Smith     PetscStackCallStandard(HYPRE_EuclidSetILUT,(jac->hsolver,jac->eu_droptolerance));
5768bf83915SBarry Smith   }
5778bf83915SBarry Smith 
5788bf83915SBarry Smith   ierr = PetscOptionsBool("-pc_hypre_euclid_bj", "Use Block Jacobi for ILU in Euclid", "None", eu_bj,&eu_bj,&flag);CHKERRQ(ierr);
5798bf83915SBarry Smith   if (flag) {
5808bf83915SBarry Smith     jac->eu_bj = eu_bj ? 1 : 0;
5818bf83915SBarry Smith     PetscStackCallStandard(HYPRE_EuclidSetBJ,(jac->hsolver,jac->eu_bj));
5828bf83915SBarry Smith   }
583db966c6cSHong Zhang   ierr = PetscOptionsTail();CHKERRQ(ierr);
584db966c6cSHong Zhang   PetscFunctionReturn(0);
585db966c6cSHong Zhang }
586db966c6cSHong Zhang 
587db966c6cSHong Zhang static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer)
588db966c6cSHong Zhang {
589db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
590db966c6cSHong Zhang   PetscErrorCode ierr;
591db966c6cSHong Zhang   PetscBool      iascii;
592db966c6cSHong Zhang 
593db966c6cSHong Zhang   PetscFunctionBegin;
594db966c6cSHong Zhang   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
595db966c6cSHong Zhang   if (iascii) {
596db966c6cSHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid preconditioning\n");CHKERRQ(ierr);
597db966c6cSHong Zhang     if (jac->eu_level != PETSC_DEFAULT) {
598db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    factorization levels %d\n",jac->eu_level);CHKERRQ(ierr);
599db966c6cSHong Zhang     } else {
600db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    default factorization levels \n");CHKERRQ(ierr);
601db966c6cSHong Zhang     }
6028bf83915SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->eu_droptolerance);CHKERRQ(ierr);
6038bf83915SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    use Block-Jacobi? %D\n",jac->eu_bj);CHKERRQ(ierr);
604db966c6cSHong Zhang   }
605db966c6cSHong Zhang   PetscFunctionReturn(0);
606db966c6cSHong Zhang }
607db966c6cSHong Zhang 
608db966c6cSHong Zhang /* --------------------------------------------------------------------------------------------*/
60916d9e3a6SLisandro Dalcin 
61016d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
61116d9e3a6SLisandro Dalcin {
61216d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
61349a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
61416d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
61516d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
61616d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
6174ddd07fcSJed Brown   PetscInt           hierr;
61816d9e3a6SLisandro Dalcin 
61916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
620dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
62116d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
622*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPushVecRead(hjac->x,b);CHKERRQ(ierr);
623*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPushVecWrite(hjac->b,x);CHKERRQ(ierr);
62416d9e3a6SLisandro Dalcin 
62549a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
626*6ea7df73SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b->ij,(void**)&jbv));
627*6ea7df73SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x->ij,(void**)&jxv));
62816d9e3a6SLisandro Dalcin 
629*6ea7df73SStefano Zampini   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jxv,jbv);
63016d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
631e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
63216d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
63316d9e3a6SLisandro Dalcin 
634*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPopVec(hjac->x);CHKERRQ(ierr);
635*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPopVec(hjac->b);CHKERRQ(ierr);
63616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
63716d9e3a6SLisandro Dalcin }
63816d9e3a6SLisandro Dalcin 
639a669f990SJed Brown /* static array length */
640a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
641a669f990SJed Brown 
64216d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
6430f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
64416d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
64565de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
6466a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]  = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
64765de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
64865de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
64965de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
6507b7fa87dSPierre Jolivet                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "l1-Gauss-Seidel" /* nonsymmetric */, "backward-l1-Gauss-Seidel" /* nonsymmetric */,
65165de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
6520f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
653589dcaf0SStefano Zampini                                                   "ext+i-cc", "standard", "standard-wts", "block", "block-wtd", "FF", "FF1",
654589dcaf0SStefano Zampini                                                   "ext", "ad-wts", "ext-mm", "ext+i-mm", "ext+e-mm"};
6554416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc)
65616d9e3a6SLisandro Dalcin {
65716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
65816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
65922e51d31SStefano Zampini   PetscInt       bs,n,indx,level;
660ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
66116d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
662589dcaf0SStefano Zampini   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
66316d9e3a6SLisandro Dalcin 
66416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
665e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
6664336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
66716d9e3a6SLisandro Dalcin   if (flg) {
6684336a9eeSBarry Smith     jac->cycletype = indx+1;
669fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
67016d9e3a6SLisandro Dalcin   }
67116d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
67216d9e3a6SLisandro Dalcin   if (flg) {
673ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
674fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
67516d9e3a6SLisandro Dalcin   }
67616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
67716d9e3a6SLisandro Dalcin   if (flg) {
678ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
679fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
68016d9e3a6SLisandro Dalcin   }
68139accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_tol","Convergence tolerance PER hypre call (0.0 = use a fixed number of iterations)","None",jac->tol,&jac->tol,&flg);CHKERRQ(ierr);
68216d9e3a6SLisandro Dalcin   if (flg) {
68357622a8eSBarry Smith     if (jac->tol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Tolerance %g must be greater than or equal to zero",(double)jac->tol);
684fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
68516d9e3a6SLisandro Dalcin   }
68622e51d31SStefano Zampini   bs = 1;
68722e51d31SStefano Zampini   if (pc->pmat) {
68822e51d31SStefano Zampini     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
68922e51d31SStefano Zampini   }
69022e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_numfunctions","Number of functions","HYPRE_BoomerAMGSetNumFunctions",bs,&bs,&flg);CHKERRQ(ierr);
69122e51d31SStefano Zampini   if (flg) {
69222e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
69322e51d31SStefano Zampini   }
69416d9e3a6SLisandro Dalcin 
69539accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
69616d9e3a6SLisandro Dalcin   if (flg) {
69757622a8eSBarry Smith     if (jac->truncfactor < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Truncation factor %g must be great than or equal zero",(double)jac->truncfactor);
698fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
69916d9e3a6SLisandro Dalcin   }
70016d9e3a6SLisandro Dalcin 
7010f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_P_max","Max elements per row for interpolation operator (0=unlimited)","None",jac->pmax,&jac->pmax,&flg);CHKERRQ(ierr);
7020f1074feSSatish Balay   if (flg) {
70357622a8eSBarry Smith     if (jac->pmax < 0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"P_max %g must be greater than or equal to zero",(double)jac->pmax);
704fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
7050f1074feSSatish Balay   }
7060f1074feSSatish Balay 
7070f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
7080f1074feSSatish Balay   if (flg) {
70957622a8eSBarry Smith     if (jac->agg_nl < 0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %g must be greater than or equal to zero",(double)jac->agg_nl);
7100f1074feSSatish Balay 
711fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
7120f1074feSSatish Balay   }
7130f1074feSSatish Balay 
7140f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_num_paths","Number of paths for aggressive coarsening","None",jac->agg_num_paths,&jac->agg_num_paths,&flg);CHKERRQ(ierr);
7150f1074feSSatish Balay   if (flg) {
71657622a8eSBarry Smith     if (jac->agg_num_paths < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of paths %g must be greater than or equal to 1",(double)jac->agg_num_paths);
7170f1074feSSatish Balay 
718fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
7190f1074feSSatish Balay   }
7200f1074feSSatish Balay 
72139accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
72216d9e3a6SLisandro Dalcin   if (flg) {
72357622a8eSBarry Smith     if (jac->strongthreshold < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Strong threshold %g must be great than or equal zero",(double)jac->strongthreshold);
724fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
72516d9e3a6SLisandro Dalcin   }
72639accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
72716d9e3a6SLisandro Dalcin   if (flg) {
72857622a8eSBarry Smith     if (jac->maxrowsum < 0.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Maximum row sum %g must be greater than zero",(double)jac->maxrowsum);
72957622a8eSBarry Smith     if (jac->maxrowsum > 1.0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Maximum row sum %g must be less than or equal one",(double)jac->maxrowsum);
730fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
73116d9e3a6SLisandro Dalcin   }
73216d9e3a6SLisandro Dalcin 
73316d9e3a6SLisandro Dalcin   /* Grid sweeps */
7340f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_all","Number of sweeps for the up and down grid levels","None",jac->gridsweeps[0],&indx,&flg);CHKERRQ(ierr);
73516d9e3a6SLisandro Dalcin   if (flg) {
736fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
73716d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
73816d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
7390f1074feSSatish Balay     jac->gridsweeps[1] = indx;
7400f1074feSSatish Balay     /*defaults coarse to 1 */
7410f1074feSSatish Balay     jac->gridsweeps[2] = 1;
74216d9e3a6SLisandro Dalcin   }
7435272c319SBarry Smith   ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_coarsen","Use a nodal based coarsening 1-6","HYPRE_BoomerAMGSetNodal",jac->nodal_coarsening,&jac->nodal_coarsening,&flg);CHKERRQ(ierr);
7445272c319SBarry Smith   if (flg) {
7455272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,jac->nodal_coarsening));
7465272c319SBarry Smith   }
74722e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_coarsen_diag","Diagonal in strength matrix for nodal based coarsening 0-2","HYPRE_BoomerAMGSetNodalDiag",jac->nodal_coarsening_diag,&jac->nodal_coarsening_diag,&flg);CHKERRQ(ierr);
74822e51d31SStefano Zampini   if (flg) {
74922e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNodalDiag,(jac->hsolver,jac->nodal_coarsening_diag));
75022e51d31SStefano Zampini   }
751cbc39033SBarry Smith   ierr = PetscOptionsInt("-pc_hypre_boomeramg_vec_interp_variant","Variant of algorithm 1-3","HYPRE_BoomerAMGSetInterpVecVariant",jac->vec_interp_variant, &jac->vec_interp_variant,&flg);CHKERRQ(ierr);
7525272c319SBarry Smith   if (flg) {
7535272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,(jac->hsolver,jac->vec_interp_variant));
7545272c319SBarry Smith   }
75522e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_vec_interp_qmax","Max elements per row for each Q","HYPRE_BoomerAMGSetInterpVecQMax",jac->vec_interp_qmax, &jac->vec_interp_qmax,&flg);CHKERRQ(ierr);
75622e51d31SStefano Zampini   if (flg) {
75722e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecQMax,(jac->hsolver,jac->vec_interp_qmax));
75822e51d31SStefano Zampini   }
75922e51d31SStefano Zampini   ierr = PetscOptionsBool("-pc_hypre_boomeramg_vec_interp_smooth","Whether to smooth the interpolation vectors","HYPRE_BoomerAMGSetSmoothInterpVectors",jac->vec_interp_smooth, &jac->vec_interp_smooth,&flg);CHKERRQ(ierr);
76022e51d31SStefano Zampini   if (flg) {
76122e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothInterpVectors,(jac->hsolver,jac->vec_interp_smooth));
76222e51d31SStefano Zampini   }
76322e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_interp_refine","Preprocess the interpolation matrix through iterative weight refinement","HYPRE_BoomerAMGSetInterpRefine",jac->interp_refine, &jac->interp_refine,&flg);CHKERRQ(ierr);
76422e51d31SStefano Zampini   if (flg) {
76522e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpRefine,(jac->hsolver,jac->interp_refine));
76622e51d31SStefano Zampini   }
7670f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
76816d9e3a6SLisandro Dalcin   if (flg) {
769fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
7700f1074feSSatish Balay     jac->gridsweeps[0] = indx;
77116d9e3a6SLisandro Dalcin   }
77216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
77316d9e3a6SLisandro Dalcin   if (flg) {
774fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
7750f1074feSSatish Balay     jac->gridsweeps[1] = indx;
77616d9e3a6SLisandro Dalcin   }
7770f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
77816d9e3a6SLisandro Dalcin   if (flg) {
779fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
7800f1074feSSatish Balay     jac->gridsweeps[2] = indx;
78116d9e3a6SLisandro Dalcin   }
78216d9e3a6SLisandro Dalcin 
7836a251517SEike Mueller   /* Smooth type */
7841e1ea65dSPierre Jolivet   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);CHKERRQ(ierr);
7856a251517SEike Mueller   if (flg) {
7866a251517SEike Mueller     jac->smoothtype = indx;
7876a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
7888131ecf7SEike Mueller     jac->smoothnumlevels = 25;
7898131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
7908131ecf7SEike Mueller   }
7918131ecf7SEike Mueller 
7928131ecf7SEike Mueller   /* Number of smoothing levels */
7938131ecf7SEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_smooth_num_levels","Number of levels on which more complex smoothers are used","None",25,&indx,&flg);CHKERRQ(ierr);
7948131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
7958131ecf7SEike Mueller     jac->smoothnumlevels = indx;
7968131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
7976a251517SEike Mueller   }
7986a251517SEike Mueller 
7991810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
8001810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
8011810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8021810e44eSEike Mueller     jac->eu_level = indx;
8031810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
8041810e44eSEike Mueller   }
8051810e44eSEike Mueller 
8061810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
8071810e44eSEike Mueller   double droptolerance;
80839accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
8091810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8101810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
8111810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
8121810e44eSEike Mueller   }
8131810e44eSEike Mueller 
8141810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
8151810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
8161810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8171810e44eSEike Mueller     jac->eu_bj = tmp_truth;
818493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
8191810e44eSEike Mueller   }
8201810e44eSEike Mueller 
82116d9e3a6SLisandro Dalcin   /* Relax type */
822a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_all","Relax type for the up and down cycles","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr);
82316d9e3a6SLisandro Dalcin   if (flg) {
8240f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
825fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
8260f1074feSSatish Balay     /* by default, coarse type set to 9 */
8270f1074feSSatish Balay     jac->relaxtype[2] = 9;
828ddbeb582SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, 9, 3));
82916d9e3a6SLisandro Dalcin   }
830a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_down","Relax type for the down cycles","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr);
83116d9e3a6SLisandro Dalcin   if (flg) {
83216d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
833fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
83416d9e3a6SLisandro Dalcin   }
835a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_up","Relax type for the up cycles","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[6],&indx,&flg);CHKERRQ(ierr);
83616d9e3a6SLisandro Dalcin   if (flg) {
8370f1074feSSatish Balay     jac->relaxtype[1] = indx;
838fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
83916d9e3a6SLisandro Dalcin   }
840a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
84116d9e3a6SLisandro Dalcin   if (flg) {
8420f1074feSSatish Balay     jac->relaxtype[2] = indx;
843fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
84416d9e3a6SLisandro Dalcin   }
84516d9e3a6SLisandro Dalcin 
84616d9e3a6SLisandro Dalcin   /* Relaxation Weight */
84716d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_boomeramg_relax_weight_all","Relaxation weight for all levels (0 = hypre estimates, -k = determined with k CG steps)","None",jac->relaxweight, &tmpdbl,&flg);CHKERRQ(ierr);
84816d9e3a6SLisandro Dalcin   if (flg) {
849fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
85016d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
85116d9e3a6SLisandro Dalcin   }
85216d9e3a6SLisandro Dalcin 
85316d9e3a6SLisandro Dalcin   n         = 2;
85416d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
85516d9e3a6SLisandro Dalcin   ierr      = PetscOptionsRealArray("-pc_hypre_boomeramg_relax_weight_level","Set the relaxation weight for a particular level (weight,level)","None",twodbl, &n, &flg);CHKERRQ(ierr);
85616d9e3a6SLisandro Dalcin   if (flg) {
85716d9e3a6SLisandro Dalcin     if (n == 2) {
85816d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
859fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
860ce94432eSBarry Smith     } else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Relax weight level: you must provide 2 values separated by a comma (and no space), you provided %d",n);
86116d9e3a6SLisandro Dalcin   }
86216d9e3a6SLisandro Dalcin 
86316d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
86416d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_boomeramg_outer_relax_weight_all","Outer relaxation weight for all levels (-k = determined with k CG steps)","None",jac->outerrelaxweight, &tmpdbl,&flg);CHKERRQ(ierr);
86516d9e3a6SLisandro Dalcin   if (flg) {
866fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
86716d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
86816d9e3a6SLisandro Dalcin   }
86916d9e3a6SLisandro Dalcin 
87016d9e3a6SLisandro Dalcin   n         = 2;
87116d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
87216d9e3a6SLisandro Dalcin   ierr      = PetscOptionsRealArray("-pc_hypre_boomeramg_outer_relax_weight_level","Set the outer relaxation weight for a particular level (weight,level)","None",twodbl, &n, &flg);CHKERRQ(ierr);
87316d9e3a6SLisandro Dalcin   if (flg) {
87416d9e3a6SLisandro Dalcin     if (n == 2) {
87516d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
876fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
877ce94432eSBarry Smith     } else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Relax weight outer level: You must provide 2 values separated by a comma (and no space), you provided %d",n);
87816d9e3a6SLisandro Dalcin   }
87916d9e3a6SLisandro Dalcin 
88016d9e3a6SLisandro Dalcin   /* the Relax Order */
881acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
88216d9e3a6SLisandro Dalcin 
8838afaa268SBarry Smith   if (flg && tmp_truth) {
88416d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
885fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
88616d9e3a6SLisandro Dalcin   }
887a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
88816d9e3a6SLisandro Dalcin   if (flg) {
88916d9e3a6SLisandro Dalcin     jac->measuretype = indx;
890fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
89116d9e3a6SLisandro Dalcin   }
8920f1074feSSatish Balay   /* update list length 3/07 */
893a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
89416d9e3a6SLisandro Dalcin   if (flg) {
89516d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
896fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
89716d9e3a6SLisandro Dalcin   }
8980f1074feSSatish Balay 
899589dcaf0SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_coarse_size", "Maximum size of coarsest grid", "None", jac->maxc, &jac->maxc, &flg);CHKERRQ(ierr);
900589dcaf0SStefano Zampini   if (flg) {
901589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxCoarseSize,(jac->hsolver, jac->maxc));
902589dcaf0SStefano Zampini   }
903589dcaf0SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_min_coarse_size", "Minimum size of coarsest grid", "None", jac->minc, &jac->minc, &flg);CHKERRQ(ierr);
904589dcaf0SStefano Zampini   if (flg) {
905589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetMinCoarseSize,(jac->hsolver, jac->minc));
906589dcaf0SStefano Zampini   }
907589dcaf0SStefano Zampini 
908589dcaf0SStefano Zampini   /* AIR */
909589dcaf0SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0)
910589dcaf0SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_restriction_type", "Type of AIR method (distance 1 or 2, 0 means no AIR)", "None", jac->Rtype, &jac->Rtype, NULL);CHKERRQ(ierr);
911589dcaf0SStefano Zampini   PetscStackCallStandard(HYPRE_BoomerAMGSetRestriction,(jac->hsolver,jac->Rtype));
912589dcaf0SStefano Zampini   if (jac->Rtype) {
913589dcaf0SStefano 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 */
914589dcaf0SStefano Zampini 
915589dcaf0SStefano Zampini     ierr = PetscOptionsReal("-pc_hypre_boomeramg_strongthresholdR","Threshold for R","None",jac->Rstrongthreshold,&jac->Rstrongthreshold,NULL);CHKERRQ(ierr);
916589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThresholdR,(jac->hsolver,jac->Rstrongthreshold));
917589dcaf0SStefano Zampini 
918589dcaf0SStefano Zampini     ierr = PetscOptionsReal("-pc_hypre_boomeramg_filterthresholdR","Filter threshold for R","None",jac->Rfilterthreshold,&jac->Rfilterthreshold,NULL);CHKERRQ(ierr);
919589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetFilterThresholdR,(jac->hsolver,jac->Rfilterthreshold));
920589dcaf0SStefano Zampini 
921589dcaf0SStefano Zampini     ierr = PetscOptionsReal("-pc_hypre_boomeramg_Adroptol","Defines the drop tolerance for the A-matrices from the 2nd level of AMG","None",jac->Adroptol,&jac->Adroptol,NULL);CHKERRQ(ierr);
922589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetADropTol,(jac->hsolver,jac->Adroptol));
923589dcaf0SStefano Zampini 
924589dcaf0SStefano Zampini     ierr = PetscOptionsInt("-pc_hypre_boomeramg_Adroptype","Drops the entries that are not on the diagonal and smaller than its row norm: type 1: 1-norm, 2: 2-norm, -1: infinity norm","None",jac->Adroptype,&jac->Adroptype,NULL);CHKERRQ(ierr);
925589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetADropType,(jac->hsolver,jac->Adroptype));
926589dcaf0SStefano Zampini   }
927589dcaf0SStefano Zampini #endif
928589dcaf0SStefano Zampini 
9290f1074feSSatish Balay   /* new 3/07 */
930a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
931589dcaf0SStefano Zampini   if (flg || jac->Rtype) {
932589dcaf0SStefano Zampini     if (flg) jac->interptype = indx;
933fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
9340f1074feSSatish Balay   }
9350f1074feSSatish Balay 
936b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
93716d9e3a6SLisandro Dalcin   if (flg) {
938b96a4a96SBarry Smith     level = 3;
9390298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
9402fa5cd67SKarl Rupp 
941b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
942fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
9432ae77aedSBarry Smith   }
9442ae77aedSBarry Smith 
945b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
9462ae77aedSBarry Smith   if (flg) {
947b96a4a96SBarry Smith     level = 3;
9480298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
9492fa5cd67SKarl Rupp 
950b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
951fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
95216d9e3a6SLisandro Dalcin   }
9538f87f92bSBarry Smith 
954acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
9558f87f92bSBarry Smith   if (flg && tmp_truth) {
9568f87f92bSBarry Smith     PetscInt tmp_int;
9578f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
9588f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
959fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
960fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
961fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
962fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
9638f87f92bSBarry Smith   }
9648f87f92bSBarry Smith 
965589dcaf0SStefano Zampini   ierr = PetscOptionsBool("-pc_hypre_boomeramg_keeptranspose", "Avoid transpose matvecs in preconditioner application", "None", jac->keeptranspose, &jac->keeptranspose, NULL);CHKERRQ(ierr);
966589dcaf0SStefano Zampini   PetscStackCallStandard(HYPRE_BoomerAMGSetKeepTranspose,(jac->hsolver,jac->keeptranspose ? 1 : 0));
967589dcaf0SStefano Zampini 
968589dcaf0SStefano Zampini   /* options for ParaSails solvers */
969589dcaf0SStefano Zampini   ierr = PetscOptionsEList("-pc_hypre_boomeramg_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flg);CHKERRQ(ierr);
970589dcaf0SStefano Zampini   if (flg) {
971589dcaf0SStefano Zampini     jac->symt = indx;
972589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetSym,(jac->hsolver,jac->symt));
973589dcaf0SStefano Zampini   }
974589dcaf0SStefano Zampini 
97516d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
97616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
97716d9e3a6SLisandro Dalcin }
97816d9e3a6SLisandro Dalcin 
979ace3abfcSBarry 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)
98016d9e3a6SLisandro Dalcin {
98116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
98216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
9832cf14000SStefano Zampini   HYPRE_Int      oits;
98416d9e3a6SLisandro Dalcin 
98516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
986dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
987fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
988fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
98916d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
99016d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
99116d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
9922cf14000SStefano Zampini   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,&oits));
9934d0a8057SBarry Smith   *outits = oits;
9944d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
9954d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
996fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
997fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
99816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
99916d9e3a6SLisandro Dalcin }
100016d9e3a6SLisandro Dalcin 
100116d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
100216d9e3a6SLisandro Dalcin {
100316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
100416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1005ace3abfcSBarry Smith   PetscBool      iascii;
100616d9e3a6SLisandro Dalcin 
100716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1008251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
100916d9e3a6SLisandro Dalcin   if (iascii) {
101016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
1011efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
101222e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of levels %D\n",jac->maxlevels);CHKERRQ(ierr);
101322e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of iterations PER hypre call %D\n",jac->maxiter);CHKERRQ(ierr);
1014efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
1015efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
1016efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
101722e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: max elements per row %D\n",jac->pmax);CHKERRQ(ierr);
101822e51d31SStefano Zampini     if (jac->interp_refine) {
101922e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: number of steps of weighted refinement %D\n",jac->interp_refine);CHKERRQ(ierr);
102022e51d31SStefano Zampini     }
102122e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of levels of aggressive coarsening %D\n",jac->agg_nl);CHKERRQ(ierr);
102222e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of paths for aggressive coarsening %D\n",jac->agg_num_paths);CHKERRQ(ierr);
10230f1074feSSatish Balay 
1024efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
102516d9e3a6SLisandro Dalcin 
102622e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps down         %D\n",jac->gridsweeps[0]);CHKERRQ(ierr);
102722e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps up           %D\n",jac->gridsweeps[1]);CHKERRQ(ierr);
102822e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps on coarse    %D\n",jac->gridsweeps[2]);CHKERRQ(ierr);
102916d9e3a6SLisandro Dalcin 
1030efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
1031efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
1032efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
103316d9e3a6SLisandro Dalcin 
1034efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
1035efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
103616d9e3a6SLisandro Dalcin 
103716d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
1038efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using CF-relaxation\n");CHKERRQ(ierr);
103916d9e3a6SLisandro Dalcin     } else {
1040efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using CF-relaxation\n");CHKERRQ(ierr);
104116d9e3a6SLisandro Dalcin     }
10426a251517SEike Mueller     if (jac->smoothtype!=-1) {
1043efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
104422e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth num levels    %D\n",jac->smoothnumlevels);CHKERRQ(ierr);
10457e352d70SEike Mueller     } else {
1046efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using more complex smoothers.\n");CHKERRQ(ierr);
10471810e44eSEike Mueller     }
10481810e44eSEike Mueller     if (jac->smoothtype==3) {
104922e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) levels %D\n",jac->eu_level);CHKERRQ(ierr);
105022e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) drop tolerance %g\n",(double)jac->eu_droptolerance);CHKERRQ(ierr);
105122e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU use Block-Jacobi? %D\n",jac->eu_bj);CHKERRQ(ierr);
10526a251517SEike Mueller     }
1053efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
1054efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
1055589dcaf0SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation type  %s\n",jac->interptype != 100 ? HYPREBoomerAMGInterpType[jac->interptype] : "1pt");CHKERRQ(ierr);
10565272c319SBarry Smith     if (jac->nodal_coarsening) {
105784c7a2fdSPierre Jolivet       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal coarsening with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
10585272c319SBarry Smith     }
10595272c319SBarry Smith     if (jac->vec_interp_variant) {
1060efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
106122e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecQMax() %D\n",jac->vec_interp_qmax);CHKERRQ(ierr);
106222e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n",jac->vec_interp_smooth);CHKERRQ(ierr);
10638f87f92bSBarry Smith     }
10648f87f92bSBarry Smith     if (jac->nodal_relax) {
106522e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal relaxation via Schwarz smoothing on levels %D\n",jac->nodal_relax_levels);CHKERRQ(ierr);
10668f87f92bSBarry Smith     }
1067589dcaf0SStefano Zampini 
1068589dcaf0SStefano Zampini     /* AIR */
1069589dcaf0SStefano Zampini     if (jac->Rtype) {
1070589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Using approximate ideal restriction type %D\n",jac->Rtype);CHKERRQ(ierr);
1071589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"      Threshold for R %g\n",(double)jac->Rstrongthreshold);CHKERRQ(ierr);
1072589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"      Filter for R %g\n",(double)jac->Rfilterthreshold);CHKERRQ(ierr);
1073589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"      A drop tolerance %g\n",(double)jac->Adroptol);CHKERRQ(ierr);
1074589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"      A drop type %D\n",jac->Adroptype);CHKERRQ(ierr);
1075589dcaf0SStefano Zampini     }
107616d9e3a6SLisandro Dalcin   }
107716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
107816d9e3a6SLisandro Dalcin }
107916d9e3a6SLisandro Dalcin 
108016d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
10814416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc)
108216d9e3a6SLisandro Dalcin {
108316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
108416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
10854ddd07fcSJed Brown   PetscInt       indx;
1086ace3abfcSBarry Smith   PetscBool      flag;
108716d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
108816d9e3a6SLisandro Dalcin 
108916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1090e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
109116d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
10928966356dSPierre Jolivet   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshold,&jac->threshold,&flag);CHKERRQ(ierr);
10938966356dSPierre Jolivet   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshold,jac->nlevels));
109416d9e3a6SLisandro Dalcin 
109516d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
10962fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
109716d9e3a6SLisandro Dalcin 
109816d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
10992fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
110016d9e3a6SLisandro Dalcin 
1101acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
11022fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
110316d9e3a6SLisandro Dalcin 
1104acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
11052fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
110616d9e3a6SLisandro Dalcin 
1107a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
110816d9e3a6SLisandro Dalcin   if (flag) {
110916d9e3a6SLisandro Dalcin     jac->symt = indx;
1110fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
111116d9e3a6SLisandro Dalcin   }
111216d9e3a6SLisandro Dalcin 
111316d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
111416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
111516d9e3a6SLisandro Dalcin }
111616d9e3a6SLisandro Dalcin 
111716d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
111816d9e3a6SLisandro Dalcin {
111916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
112016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1121ace3abfcSBarry Smith   PetscBool      iascii;
1122feb237baSPierre Jolivet   const char     *symt = 0;
112316d9e3a6SLisandro Dalcin 
112416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1125251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
112616d9e3a6SLisandro Dalcin   if (iascii) {
112716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
1128efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
11298966356dSPierre Jolivet     ierr = PetscViewerASCIIPrintf(viewer,"    threshold %g\n",(double)jac->threshold);CHKERRQ(ierr);
1130efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    filter %g\n",(double)jac->filter);CHKERRQ(ierr);
1131efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
1132efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
1133efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
11342fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
11352fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
11362fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
1137ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
1138efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    %s\n",symt);CHKERRQ(ierr);
113916d9e3a6SLisandro Dalcin   }
114016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
114116d9e3a6SLisandro Dalcin }
11424cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
11434416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc)
11444cb006feSStefano Zampini {
11454cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
11464cb006feSStefano Zampini   PetscErrorCode ierr;
11474cb006feSStefano Zampini   PetscInt       n;
11484cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
11494cb006feSStefano Zampini 
11504cb006feSStefano Zampini   PetscFunctionBegin;
11519fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
1152863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1153863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1154863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_max_iter","Maximum number of AMS multigrid iterations within PCApply","None",jac->as_max_iter,&jac->as_max_iter,&flag);CHKERRQ(ierr);
1155863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
11564cb006feSStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_cycle_type","Cycle type for AMS multigrid","None",jac->ams_cycle_type,&jac->ams_cycle_type,&flag);CHKERRQ(ierr);
11574cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1158863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1159863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1160863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_relax_type","Relaxation type for AMS smoother","None",jac->as_relax_type,&jac->as_relax_type,&flag);CHKERRQ(ierr);
1161863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_relax_times","Number of relaxation steps for AMS smoother","None",jac->as_relax_times,&jac->as_relax_times,&flag2);CHKERRQ(ierr);
1162863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_relax_weight","Relaxation weight for AMS smoother","None",jac->as_relax_weight,&jac->as_relax_weight,&flag3);CHKERRQ(ierr);
1163863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
11644cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1165863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1166863406b8SStefano Zampini                                                                       jac->as_relax_times,
1167863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1168863406b8SStefano Zampini                                                                       jac->as_omega));
11694cb006feSStefano Zampini   }
1170863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_amg_alpha_theta","Threshold for strong coupling of vector Poisson AMG solver","None",jac->as_amg_alpha_theta,&jac->as_amg_alpha_theta,&flag);CHKERRQ(ierr);
11714cb006feSStefano Zampini   n = 5;
1172863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
11734cb006feSStefano Zampini   if (flag || flag2) {
1174863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1175863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1176863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1177863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1178863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1179863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
11804cb006feSStefano Zampini   }
1181863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_amg_beta_theta","Threshold for strong coupling of scalar Poisson AMG solver","None",jac->as_amg_beta_theta,&jac->as_amg_beta_theta,&flag);CHKERRQ(ierr);
11824cb006feSStefano Zampini   n = 5;
1183863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_beta_options","AMG options for scalar Poisson solver","None",jac->as_amg_beta_opts,&n,&flag2);CHKERRQ(ierr);
11844cb006feSStefano Zampini   if (flag || flag2) {
1185863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1186863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1187863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1188863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1189863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1190863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
11914cb006feSStefano Zampini   }
119223df4f25SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_projection_frequency","Frequency at which a projection onto the compatible subspace for problems with zero conductivity regions is performed","None",jac->ams_proj_freq,&jac->ams_proj_freq,&flag);CHKERRQ(ierr);
119323df4f25SStefano Zampini   if (flag) { /* override HYPRE's default only if the options is used */
119423df4f25SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetProjectionFrequency,(jac->hsolver,jac->ams_proj_freq));
119523df4f25SStefano Zampini   }
11964cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
11974cb006feSStefano Zampini   PetscFunctionReturn(0);
11984cb006feSStefano Zampini }
11994cb006feSStefano Zampini 
12004cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
12014cb006feSStefano Zampini {
12024cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12034cb006feSStefano Zampini   PetscErrorCode ierr;
12044cb006feSStefano Zampini   PetscBool      iascii;
12054cb006feSStefano Zampini 
12064cb006feSStefano Zampini   PetscFunctionBegin;
12074cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
12084cb006feSStefano Zampini   if (iascii) {
12094cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
1210efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1211efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1212efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1213efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1214efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1215efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1216efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
12174cb006feSStefano Zampini     if (jac->alpha_Poisson) {
1218efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
12194cb006feSStefano Zampini     } else {
1220efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (computed) \n");CHKERRQ(ierr);
12214cb006feSStefano Zampini     }
1222efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1223efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1224efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1225efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1226efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1227efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
12284cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
12294cb006feSStefano Zampini       if (jac->beta_Poisson) {
1230efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
12314cb006feSStefano Zampini       } else {
1232efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (computed) \n");CHKERRQ(ierr);
12334cb006feSStefano Zampini       }
1234efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1235efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1236efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1237efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1238efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1239efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
124023df4f25SStefano Zampini       if (jac->ams_beta_is_zero_part) {
1241efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"        compatible subspace projection frequency %d (-1 HYPRE uses default)\n",jac->ams_proj_freq);CHKERRQ(ierr);
124223df4f25SStefano Zampini       }
124323df4f25SStefano Zampini     } else {
1244efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver not used (zero-conductivity everywhere) \n");CHKERRQ(ierr);
12454cb006feSStefano Zampini     }
12464cb006feSStefano Zampini   }
12474cb006feSStefano Zampini   PetscFunctionReturn(0);
12484cb006feSStefano Zampini }
12494cb006feSStefano Zampini 
12504416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc)
1251863406b8SStefano Zampini {
1252863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1253863406b8SStefano Zampini   PetscErrorCode ierr;
1254863406b8SStefano Zampini   PetscInt       n;
1255863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
1256863406b8SStefano Zampini 
1257863406b8SStefano Zampini   PetscFunctionBegin;
1258863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
1259863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1260863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1261863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_max_iter","Maximum number of ADS multigrid iterations within PCApply","None",jac->as_max_iter,&jac->as_max_iter,&flag);CHKERRQ(ierr);
1262863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1263863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_cycle_type","Cycle type for ADS multigrid","None",jac->ads_cycle_type,&jac->ads_cycle_type,&flag);CHKERRQ(ierr);
1264863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
1265863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1266863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1267863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_relax_type","Relaxation type for ADS smoother","None",jac->as_relax_type,&jac->as_relax_type,&flag);CHKERRQ(ierr);
1268863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_relax_times","Number of relaxation steps for ADS smoother","None",jac->as_relax_times,&jac->as_relax_times,&flag2);CHKERRQ(ierr);
1269863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_relax_weight","Relaxation weight for ADS smoother","None",jac->as_relax_weight,&jac->as_relax_weight,&flag3);CHKERRQ(ierr);
1270863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
1271863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1272863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1273863406b8SStefano Zampini                                                                       jac->as_relax_times,
1274863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1275863406b8SStefano Zampini                                                                       jac->as_omega));
1276863406b8SStefano Zampini   }
1277863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_ams_theta","Threshold for strong coupling of AMS solver inside ADS","None",jac->as_amg_alpha_theta,&jac->as_amg_alpha_theta,&flag);CHKERRQ(ierr);
1278863406b8SStefano Zampini   n = 5;
1279863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ads_ams_options","AMG options for AMS solver inside ADS","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
1280863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_ams_cycle_type","Cycle type for AMS solver inside ADS","None",jac->ams_cycle_type,&jac->ams_cycle_type,&flag3);CHKERRQ(ierr);
1281863406b8SStefano Zampini   if (flag || flag2 || flag3) {
1282863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
1283863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1284863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1285863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1286863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1287863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1288863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1289863406b8SStefano Zampini   }
1290863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_amg_theta","Threshold for strong coupling of vector AMG solver inside ADS","None",jac->as_amg_beta_theta,&jac->as_amg_beta_theta,&flag);CHKERRQ(ierr);
1291863406b8SStefano Zampini   n = 5;
1292863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ads_amg_options","AMG options for vector AMG solver inside ADS","None",jac->as_amg_beta_opts,&n,&flag2);CHKERRQ(ierr);
1293863406b8SStefano Zampini   if (flag || flag2) {
1294863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1295863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1296863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1297863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1298863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1299863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1300863406b8SStefano Zampini   }
1301863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
1302863406b8SStefano Zampini   PetscFunctionReturn(0);
1303863406b8SStefano Zampini }
1304863406b8SStefano Zampini 
1305863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1306863406b8SStefano Zampini {
1307863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1308863406b8SStefano Zampini   PetscErrorCode ierr;
1309863406b8SStefano Zampini   PetscBool      iascii;
1310863406b8SStefano Zampini 
1311863406b8SStefano Zampini   PetscFunctionBegin;
1312863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1313863406b8SStefano Zampini   if (iascii) {
1314863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
1315efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1316efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
1317efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1318efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1319efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1320efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1321efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
1322efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    AMS solver using boomerAMG\n");CHKERRQ(ierr);
1323efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1324efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1325efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1326efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1327efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1328efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1329efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
1330efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver using boomerAMG\n");CHKERRQ(ierr);
1331efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1332efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1333efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1334efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1335efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1336efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
1337863406b8SStefano Zampini   }
1338863406b8SStefano Zampini   PetscFunctionReturn(0);
1339863406b8SStefano Zampini }
1340863406b8SStefano Zampini 
1341863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
13424cb006feSStefano Zampini {
13434cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
13445ac14e1cSStefano Zampini   PetscBool      ishypre;
13454cb006feSStefano Zampini   PetscErrorCode ierr;
13464cb006feSStefano Zampini 
13474cb006feSStefano Zampini   PetscFunctionBegin;
13485ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)G,MATHYPRE,&ishypre);CHKERRQ(ierr);
13495ac14e1cSStefano Zampini   if (ishypre) {
13505ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr);
13515ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
13525ac14e1cSStefano Zampini     jac->G = G;
13535ac14e1cSStefano Zampini   } else {
13546bf688a0SCe Qin     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
13556bf688a0SCe Qin     ierr = MatConvert(G,MATHYPRE,MAT_INITIAL_MATRIX,&jac->G);CHKERRQ(ierr);
13565ac14e1cSStefano Zampini   }
13574cb006feSStefano Zampini   PetscFunctionReturn(0);
13584cb006feSStefano Zampini }
13594cb006feSStefano Zampini 
13604cb006feSStefano Zampini /*@
13614cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
13624cb006feSStefano Zampini 
13634cb006feSStefano Zampini    Collective on PC
13644cb006feSStefano Zampini 
13654cb006feSStefano Zampini    Input Parameters:
13664cb006feSStefano Zampini +  pc - the preconditioning context
13674cb006feSStefano Zampini -  G - the discrete gradient
13684cb006feSStefano Zampini 
13694cb006feSStefano Zampini    Level: intermediate
13704cb006feSStefano Zampini 
137195452b02SPatrick Sanan    Notes:
137295452b02SPatrick Sanan     G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh
1373863406b8SStefano 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
13744cb006feSStefano Zampini 
13754cb006feSStefano Zampini .seealso:
13764cb006feSStefano Zampini @*/
13774cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
13784cb006feSStefano Zampini {
13794cb006feSStefano Zampini   PetscErrorCode ierr;
13804cb006feSStefano Zampini 
13814cb006feSStefano Zampini   PetscFunctionBegin;
13824cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
13834cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
13844cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
13854cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
13864cb006feSStefano Zampini   PetscFunctionReturn(0);
13874cb006feSStefano Zampini }
13884cb006feSStefano Zampini 
1389863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1390863406b8SStefano Zampini {
1391863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
13925ac14e1cSStefano Zampini   PetscBool      ishypre;
1393863406b8SStefano Zampini   PetscErrorCode ierr;
1394863406b8SStefano Zampini 
1395863406b8SStefano Zampini   PetscFunctionBegin;
13965ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)C,MATHYPRE,&ishypre);CHKERRQ(ierr);
13975ac14e1cSStefano Zampini   if (ishypre) {
13985ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr);
13995ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
14005ac14e1cSStefano Zampini     jac->C = C;
14015ac14e1cSStefano Zampini   } else {
14026bf688a0SCe Qin     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
14036bf688a0SCe Qin     ierr = MatConvert(C,MATHYPRE,MAT_INITIAL_MATRIX,&jac->C);CHKERRQ(ierr);
14045ac14e1cSStefano Zampini   }
1405863406b8SStefano Zampini   PetscFunctionReturn(0);
1406863406b8SStefano Zampini }
1407863406b8SStefano Zampini 
1408863406b8SStefano Zampini /*@
1409863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1410863406b8SStefano Zampini 
1411863406b8SStefano Zampini    Collective on PC
1412863406b8SStefano Zampini 
1413863406b8SStefano Zampini    Input Parameters:
1414863406b8SStefano Zampini +  pc - the preconditioning context
1415863406b8SStefano Zampini -  C - the discrete curl
1416863406b8SStefano Zampini 
1417863406b8SStefano Zampini    Level: intermediate
1418863406b8SStefano Zampini 
141995452b02SPatrick Sanan    Notes:
142095452b02SPatrick Sanan     C should have as many rows as the number of faces and as many columns as the number of edges in the mesh
1421863406b8SStefano 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
1422863406b8SStefano Zampini 
1423863406b8SStefano Zampini .seealso:
1424863406b8SStefano Zampini @*/
1425863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1426863406b8SStefano Zampini {
1427863406b8SStefano Zampini   PetscErrorCode ierr;
1428863406b8SStefano Zampini 
1429863406b8SStefano Zampini   PetscFunctionBegin;
1430863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1431863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1432863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1433863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1434863406b8SStefano Zampini   PetscFunctionReturn(0);
1435863406b8SStefano Zampini }
1436863406b8SStefano Zampini 
14376bf688a0SCe Qin static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
14386bf688a0SCe Qin {
14396bf688a0SCe Qin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
14406bf688a0SCe Qin   PetscBool      ishypre;
14416bf688a0SCe Qin   PetscErrorCode ierr;
14426bf688a0SCe Qin   PetscInt       i;
14436bf688a0SCe Qin   PetscFunctionBegin;
14446bf688a0SCe Qin 
14456bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
14466bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
14476bf688a0SCe Qin   for (i=0;i<3;++i) {
14486bf688a0SCe Qin     ierr = MatDestroy(&jac->RT_Pi[i]);CHKERRQ(ierr);
14496bf688a0SCe Qin     ierr = MatDestroy(&jac->ND_Pi[i]);CHKERRQ(ierr);
14506bf688a0SCe Qin   }
14516bf688a0SCe Qin 
14526bf688a0SCe Qin   jac->dim = dim;
14536bf688a0SCe Qin   if (RT_PiFull) {
14546bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)RT_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
14556bf688a0SCe Qin     if (ishypre) {
14566bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)RT_PiFull);CHKERRQ(ierr);
14576bf688a0SCe Qin       jac->RT_PiFull = RT_PiFull;
14586bf688a0SCe Qin     } else {
14596bf688a0SCe Qin       ierr = MatConvert(RT_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_PiFull);CHKERRQ(ierr);
14606bf688a0SCe Qin     }
14616bf688a0SCe Qin   }
14626bf688a0SCe Qin   if (RT_Pi) {
14636bf688a0SCe Qin     for (i=0;i<dim;++i) {
14646bf688a0SCe Qin       if (RT_Pi[i]) {
14656bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)RT_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
14666bf688a0SCe Qin         if (ishypre) {
14676bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)RT_Pi[i]);CHKERRQ(ierr);
14686bf688a0SCe Qin           jac->RT_Pi[i] = RT_Pi[i];
14696bf688a0SCe Qin         } else {
14706bf688a0SCe Qin           ierr = MatConvert(RT_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_Pi[i]);CHKERRQ(ierr);
14716bf688a0SCe Qin         }
14726bf688a0SCe Qin       }
14736bf688a0SCe Qin     }
14746bf688a0SCe Qin   }
14756bf688a0SCe Qin   if (ND_PiFull) {
14766bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)ND_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
14776bf688a0SCe Qin     if (ishypre) {
14786bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)ND_PiFull);CHKERRQ(ierr);
14796bf688a0SCe Qin       jac->ND_PiFull = ND_PiFull;
14806bf688a0SCe Qin     } else {
14816bf688a0SCe Qin       ierr = MatConvert(ND_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_PiFull);CHKERRQ(ierr);
14826bf688a0SCe Qin     }
14836bf688a0SCe Qin   }
14846bf688a0SCe Qin   if (ND_Pi) {
14856bf688a0SCe Qin     for (i=0;i<dim;++i) {
14866bf688a0SCe Qin       if (ND_Pi[i]) {
14876bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)ND_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
14886bf688a0SCe Qin         if (ishypre) {
14896bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)ND_Pi[i]);CHKERRQ(ierr);
14906bf688a0SCe Qin           jac->ND_Pi[i] = ND_Pi[i];
14916bf688a0SCe Qin         } else {
14926bf688a0SCe Qin           ierr = MatConvert(ND_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_Pi[i]);CHKERRQ(ierr);
14936bf688a0SCe Qin         }
14946bf688a0SCe Qin       }
14956bf688a0SCe Qin     }
14966bf688a0SCe Qin   }
14976bf688a0SCe Qin 
14986bf688a0SCe Qin   PetscFunctionReturn(0);
14996bf688a0SCe Qin }
15006bf688a0SCe Qin 
15016bf688a0SCe Qin /*@
15026bf688a0SCe Qin  PCHYPRESetInterpolations - Set interpolation matrices for AMS/ADS preconditioner
15036bf688a0SCe Qin 
15046bf688a0SCe Qin    Collective on PC
15056bf688a0SCe Qin 
15066bf688a0SCe Qin    Input Parameters:
15076bf688a0SCe Qin +  pc - the preconditioning context
15086bf688a0SCe Qin -  dim - the dimension of the problem, only used in AMS
15096bf688a0SCe Qin -  RT_PiFull - Raviart-Thomas interpolation matrix
15106bf688a0SCe Qin -  RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix
15116bf688a0SCe Qin -  ND_PiFull - Nedelec interpolation matrix
15126bf688a0SCe Qin -  ND_Pi - x/y/z component of Nedelec interpolation matrix
15136bf688a0SCe Qin 
151495452b02SPatrick Sanan    Notes:
151595452b02SPatrick Sanan     For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL.
15166bf688a0SCe Qin           For ADS, both type of interpolation matrices are needed.
15176bf688a0SCe Qin    Level: intermediate
15186bf688a0SCe Qin 
15196bf688a0SCe Qin .seealso:
15206bf688a0SCe Qin @*/
15216bf688a0SCe Qin PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
15226bf688a0SCe Qin {
15236bf688a0SCe Qin   PetscErrorCode ierr;
15246bf688a0SCe Qin   PetscInt       i;
15256bf688a0SCe Qin 
15266bf688a0SCe Qin   PetscFunctionBegin;
15276bf688a0SCe Qin   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15286bf688a0SCe Qin   if (RT_PiFull) {
15296bf688a0SCe Qin     PetscValidHeaderSpecific(RT_PiFull,MAT_CLASSID,3);
15306bf688a0SCe Qin     PetscCheckSameComm(pc,1,RT_PiFull,3);
15316bf688a0SCe Qin   }
15326bf688a0SCe Qin   if (RT_Pi) {
15336bf688a0SCe Qin     PetscValidPointer(RT_Pi,4);
15346bf688a0SCe Qin     for (i=0;i<dim;++i) {
15356bf688a0SCe Qin       if (RT_Pi[i]) {
15366bf688a0SCe Qin         PetscValidHeaderSpecific(RT_Pi[i],MAT_CLASSID,4);
15376bf688a0SCe Qin         PetscCheckSameComm(pc,1,RT_Pi[i],4);
15386bf688a0SCe Qin       }
15396bf688a0SCe Qin     }
15406bf688a0SCe Qin   }
15416bf688a0SCe Qin   if (ND_PiFull) {
15426bf688a0SCe Qin     PetscValidHeaderSpecific(ND_PiFull,MAT_CLASSID,5);
15436bf688a0SCe Qin     PetscCheckSameComm(pc,1,ND_PiFull,5);
15446bf688a0SCe Qin   }
15456bf688a0SCe Qin   if (ND_Pi) {
15466bf688a0SCe Qin     PetscValidPointer(ND_Pi,6);
15476bf688a0SCe Qin     for (i=0;i<dim;++i) {
15486bf688a0SCe Qin       if (ND_Pi[i]) {
15496bf688a0SCe Qin         PetscValidHeaderSpecific(ND_Pi[i],MAT_CLASSID,6);
15506bf688a0SCe Qin         PetscCheckSameComm(pc,1,ND_Pi[i],6);
15516bf688a0SCe Qin       }
15526bf688a0SCe Qin     }
15536bf688a0SCe Qin   }
15546bf688a0SCe Qin   ierr = PetscTryMethod(pc,"PCHYPRESetInterpolations_C",(PC,PetscInt,Mat,Mat[],Mat,Mat[]),(pc,dim,RT_PiFull,RT_Pi,ND_PiFull,ND_Pi));CHKERRQ(ierr);
15556bf688a0SCe Qin   PetscFunctionReturn(0);
15566bf688a0SCe Qin }
15576bf688a0SCe Qin 
15585ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha)
15594cb006feSStefano Zampini {
15604cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
15615ac14e1cSStefano Zampini   PetscBool      ishypre;
15624cb006feSStefano Zampini   PetscErrorCode ierr;
15634cb006feSStefano Zampini 
15644cb006feSStefano Zampini   PetscFunctionBegin;
15655ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr);
15665ac14e1cSStefano Zampini   if (ishypre) {
15675ac14e1cSStefano Zampini     if (isalpha) {
15685ac14e1cSStefano Zampini       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
15695ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
15705ac14e1cSStefano Zampini       jac->alpha_Poisson = A;
15715ac14e1cSStefano Zampini     } else {
15725ac14e1cSStefano Zampini       if (A) {
15735ac14e1cSStefano Zampini         ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
15745ac14e1cSStefano Zampini       } else {
15755ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
15765ac14e1cSStefano Zampini       }
15775ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
15785ac14e1cSStefano Zampini       jac->beta_Poisson = A;
15795ac14e1cSStefano Zampini     }
15805ac14e1cSStefano Zampini   } else {
15815ac14e1cSStefano Zampini     if (isalpha) {
15826bf688a0SCe Qin       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
15836bf688a0SCe Qin       ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->alpha_Poisson);CHKERRQ(ierr);
15845ac14e1cSStefano Zampini     } else {
15855ac14e1cSStefano Zampini       if (A) {
15866bf688a0SCe Qin         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
15876bf688a0SCe Qin         ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->beta_Poisson);CHKERRQ(ierr);
15885ac14e1cSStefano Zampini       } else {
15895ac14e1cSStefano Zampini         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
15905ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
15915ac14e1cSStefano Zampini       }
15925ac14e1cSStefano Zampini     }
15935ac14e1cSStefano Zampini   }
15944cb006feSStefano Zampini   PetscFunctionReturn(0);
15954cb006feSStefano Zampini }
15964cb006feSStefano Zampini 
15974cb006feSStefano Zampini /*@
15984cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
15994cb006feSStefano Zampini 
16004cb006feSStefano Zampini    Collective on PC
16014cb006feSStefano Zampini 
16024cb006feSStefano Zampini    Input Parameters:
16034cb006feSStefano Zampini +  pc - the preconditioning context
16044cb006feSStefano Zampini -  A - the matrix
16054cb006feSStefano Zampini 
16064cb006feSStefano Zampini    Level: intermediate
16074cb006feSStefano Zampini 
160895452b02SPatrick Sanan    Notes:
160995452b02SPatrick Sanan     A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
16104cb006feSStefano Zampini 
16114cb006feSStefano Zampini .seealso:
16124cb006feSStefano Zampini @*/
16134cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
16144cb006feSStefano Zampini {
16154cb006feSStefano Zampini   PetscErrorCode ierr;
16164cb006feSStefano Zampini 
16174cb006feSStefano Zampini   PetscFunctionBegin;
16184cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
16194cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
16204cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
16215ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_TRUE));CHKERRQ(ierr);
16224cb006feSStefano Zampini   PetscFunctionReturn(0);
16234cb006feSStefano Zampini }
16244cb006feSStefano Zampini 
16254cb006feSStefano Zampini /*@
16264cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
16274cb006feSStefano Zampini 
16284cb006feSStefano Zampini    Collective on PC
16294cb006feSStefano Zampini 
16304cb006feSStefano Zampini    Input Parameters:
16314cb006feSStefano Zampini +  pc - the preconditioning context
16324cb006feSStefano Zampini -  A - the matrix
16334cb006feSStefano Zampini 
16344cb006feSStefano Zampini    Level: intermediate
16354cb006feSStefano Zampini 
163695452b02SPatrick Sanan    Notes:
163795452b02SPatrick Sanan     A should be obtained by discretizing the Poisson problem with linear finite elements.
16384cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
16394cb006feSStefano Zampini 
16404cb006feSStefano Zampini .seealso:
16414cb006feSStefano Zampini @*/
16424cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
16434cb006feSStefano Zampini {
16444cb006feSStefano Zampini   PetscErrorCode ierr;
16454cb006feSStefano Zampini 
16464cb006feSStefano Zampini   PetscFunctionBegin;
16474cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
16484cb006feSStefano Zampini   if (A) {
16494cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
16504cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
16514cb006feSStefano Zampini   }
16525ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_FALSE));CHKERRQ(ierr);
16534cb006feSStefano Zampini   PetscFunctionReturn(0);
16544cb006feSStefano Zampini }
16554cb006feSStefano Zampini 
16565ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz, Vec zoz, Vec zzo)
16574cb006feSStefano Zampini {
16584cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
16594cb006feSStefano Zampini   PetscErrorCode     ierr;
16604cb006feSStefano Zampini 
16614cb006feSStefano Zampini   PetscFunctionBegin;
16624cb006feSStefano Zampini   /* throw away any vector if already set */
1663*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->constants[0]);CHKERRQ(ierr);
1664*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->constants[1]);CHKERRQ(ierr);
1665*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->constants[2]);CHKERRQ(ierr);
1666*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz->map,&jac->constants[0]);CHKERRQ(ierr);
16674cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
1668*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz->map,&jac->constants[1]);CHKERRQ(ierr);
16694cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
16705ac14e1cSStefano Zampini   jac->dim = 2;
16714cb006feSStefano Zampini   if (zzo) {
1672*6ea7df73SStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo->map,&jac->constants[2]);CHKERRQ(ierr);
16734cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
16745ac14e1cSStefano Zampini     jac->dim++;
16754cb006feSStefano Zampini   }
16764cb006feSStefano Zampini   PetscFunctionReturn(0);
16774cb006feSStefano Zampini }
16784cb006feSStefano Zampini 
16794cb006feSStefano Zampini /*@
16804cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
16814cb006feSStefano Zampini 
16824cb006feSStefano Zampini    Collective on PC
16834cb006feSStefano Zampini 
16844cb006feSStefano Zampini    Input Parameters:
16854cb006feSStefano Zampini +  pc - the preconditioning context
16864cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
16874cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
16884cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
16894cb006feSStefano Zampini 
16904cb006feSStefano Zampini    Level: intermediate
16914cb006feSStefano Zampini 
16924cb006feSStefano Zampini    Notes:
16934cb006feSStefano Zampini 
16944cb006feSStefano Zampini .seealso:
16954cb006feSStefano Zampini @*/
16964cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
16974cb006feSStefano Zampini {
16984cb006feSStefano Zampini   PetscErrorCode ierr;
16994cb006feSStefano Zampini 
17004cb006feSStefano Zampini   PetscFunctionBegin;
17014cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
17024cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
17034cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
17044cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
17054cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
17064cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
17074cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
17084cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
17094cb006feSStefano Zampini   PetscFunctionReturn(0);
17104cb006feSStefano Zampini }
17114cb006feSStefano Zampini 
1712863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
17134cb006feSStefano Zampini {
17144cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
17154cb006feSStefano Zampini   Vec             tv;
17164cb006feSStefano Zampini   PetscInt        i;
17174cb006feSStefano Zampini   PetscErrorCode  ierr;
17184cb006feSStefano Zampini 
17194cb006feSStefano Zampini   PetscFunctionBegin;
17204cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
1721*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->coords[0]);CHKERRQ(ierr);
1722*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->coords[1]);CHKERRQ(ierr);
1723*6ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->coords[2]);CHKERRQ(ierr);
17245ac14e1cSStefano Zampini   jac->dim = dim;
17255ac14e1cSStefano Zampini 
17264cb006feSStefano Zampini   /* compute IJ vector for coordinates */
17274cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
17284cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
17294cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
17304cb006feSStefano Zampini   for (i=0;i<dim;i++) {
17314cb006feSStefano Zampini     PetscScalar *array;
17324cb006feSStefano Zampini     PetscInt    j;
17334cb006feSStefano Zampini 
1734*6ea7df73SStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv->map,&jac->coords[i]);CHKERRQ(ierr);
1735589dcaf0SStefano Zampini     ierr = VecGetArrayWrite(tv,&array);CHKERRQ(ierr);
1736*6ea7df73SStefano Zampini     for (j=0;j<nloc;j++) array[j] = coords[j*dim+i];
1737589dcaf0SStefano Zampini     ierr = VecRestoreArrayWrite(tv,&array);CHKERRQ(ierr);
1738*6ea7df73SStefano Zampini     ierr = VecHYPRE_IJVectorCopy(tv,jac->coords[i]);CHKERRQ(ierr);
17394cb006feSStefano Zampini   }
17404cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
17414cb006feSStefano Zampini   PetscFunctionReturn(0);
17424cb006feSStefano Zampini }
17434cb006feSStefano Zampini 
174416d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
174516d9e3a6SLisandro Dalcin 
1746f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
174716d9e3a6SLisandro Dalcin {
174816d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
174916d9e3a6SLisandro Dalcin 
175016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
175116d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
175216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
175316d9e3a6SLisandro Dalcin }
175416d9e3a6SLisandro Dalcin 
1755f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
175616d9e3a6SLisandro Dalcin {
175716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
175816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1759ace3abfcSBarry Smith   PetscBool      flag;
176016d9e3a6SLisandro Dalcin 
176116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
176216d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
176316d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1764ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
176516d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
176616d9e3a6SLisandro Dalcin   } else {
176716d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
176816d9e3a6SLisandro Dalcin   }
176916d9e3a6SLisandro Dalcin 
177016d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
177116d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
177216d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
177316d9e3a6SLisandro Dalcin 
177416d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
177516d9e3a6SLisandro Dalcin   if (flag) {
1776ffc4695bSBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRMPI(ierr);
1777fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
177816d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
177916d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
178016d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
178116d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
178216d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
178316d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
178416d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
178516d9e3a6SLisandro Dalcin   }
1786db966c6cSHong Zhang   ierr = PetscStrcmp("euclid",jac->hypre_type,&flag);CHKERRQ(ierr);
1787db966c6cSHong Zhang   if (flag) {
17888bf83915SBarry Smith #if defined(PETSC_HAVE_64BIT_INDICES)
17898bf83915SBarry Smith     SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Hypre Euclid not support with 64 bit indices");
17908bf83915SBarry Smith #endif
1791ffc4695bSBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRMPI(ierr);
1792db966c6cSHong Zhang     PetscStackCallStandard(HYPRE_EuclidCreate,(jac->comm_hypre,&jac->hsolver));
1793db966c6cSHong Zhang     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
1794db966c6cSHong Zhang     pc->ops->view           = PCView_HYPRE_Euclid;
1795db966c6cSHong Zhang     jac->destroy            = HYPRE_EuclidDestroy;
1796db966c6cSHong Zhang     jac->setup              = HYPRE_EuclidSetup;
1797db966c6cSHong Zhang     jac->solve              = HYPRE_EuclidSolve;
1798db966c6cSHong Zhang     jac->factorrowsize      = PETSC_DEFAULT;
1799db966c6cSHong Zhang     jac->eu_level           = PETSC_DEFAULT; /* default */
1800db966c6cSHong Zhang     PetscFunctionReturn(0);
1801db966c6cSHong Zhang   }
180216d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
180316d9e3a6SLisandro Dalcin   if (flag) {
1804ffc4695bSBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRMPI(ierr);
1805fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
180616d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
180716d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
180816d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
180916d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
181016d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
181116d9e3a6SLisandro Dalcin     /* initialize */
181216d9e3a6SLisandro Dalcin     jac->nlevels   = 1;
18138966356dSPierre Jolivet     jac->threshold = .1;
181416d9e3a6SLisandro Dalcin     jac->filter    = .1;
181516d9e3a6SLisandro Dalcin     jac->loadbal   = 0;
18162fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
18172fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
18182fa5cd67SKarl Rupp 
181916d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
182016d9e3a6SLisandro Dalcin     jac->symt = 0;
18218966356dSPierre Jolivet     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshold,jac->nlevels));
1822fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1823fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1824fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1825fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1826fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
182716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
182816d9e3a6SLisandro Dalcin   }
182916d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
183016d9e3a6SLisandro Dalcin   if (flag) {
183116d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
183216d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
183316d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
183416d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
183516d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
1836fd2dd295SFande Kong     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",PCGetInterpolations_BoomerAMG);CHKERRQ(ierr);
1837fd2dd295SFande Kong     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",PCGetCoarseOperators_BoomerAMG);CHKERRQ(ierr);
183816d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
183916d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
184016d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
184116d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
184216d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
184316d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
184416d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
184516d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
18468f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
184716d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
184816d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
184916d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
185016d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
185116d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
18520f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
18536a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1854b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
18551810e44eSEike Mueller     jac->eu_level         = 0;
18561810e44eSEike Mueller     jac->eu_droptolerance = 0;
18571810e44eSEike Mueller     jac->eu_bj            = 0;
1858589dcaf0SStefano Zampini     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a PC - most likely with CG */
18590f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
186016d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
186116d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
186216d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
18630f1074feSSatish Balay     jac->interptype       = 0;
1864589dcaf0SStefano Zampini     jac->Rtype            = 0;
1865589dcaf0SStefano Zampini     jac->Rstrongthreshold = 0.25;
1866589dcaf0SStefano Zampini     jac->Rfilterthreshold = 0.0;
1867589dcaf0SStefano Zampini     jac->Adroptype        = -1;
1868589dcaf0SStefano Zampini     jac->Adroptol         = 0.0;
18690f1074feSSatish Balay     jac->agg_nl           = 0;
1870*6ea7df73SStefano Zampini     jac->agg_interptype   = 4;
18710f1074feSSatish Balay     jac->pmax             = 0;
18720f1074feSSatish Balay     jac->truncfactor      = 0.0;
18730f1074feSSatish Balay     jac->agg_num_paths    = 1;
1874589dcaf0SStefano Zampini     jac->maxc             = 9;
1875589dcaf0SStefano Zampini     jac->minc             = 1;
18768f87f92bSBarry Smith 
187722e51d31SStefano Zampini     jac->nodal_coarsening      = 0;
187822e51d31SStefano Zampini     jac->nodal_coarsening_diag = 0;
187922e51d31SStefano Zampini     jac->vec_interp_variant    = 0;
188022e51d31SStefano Zampini     jac->vec_interp_qmax       = 0;
188122e51d31SStefano Zampini     jac->vec_interp_smooth     = PETSC_FALSE;
188222e51d31SStefano Zampini     jac->interp_refine         = 0;
18838f87f92bSBarry Smith     jac->nodal_relax           = PETSC_FALSE;
18848f87f92bSBarry Smith     jac->nodal_relax_levels    = 1;
1885*6ea7df73SStefano Zampini     jac->rap2                  = 0;
1886*6ea7df73SStefano Zampini 
1887*6ea7df73SStefano Zampini     /* GPU defaults
1888*6ea7df73SStefano Zampini          from https://hypre.readthedocs.io/en/latest/solvers-boomeramg.html#gpu-supported-options
1889*6ea7df73SStefano Zampini          and /src/parcsr_ls/par_amg.c */
1890*6ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE)
1891*6ea7df73SStefano Zampini     jac->keeptranspose         = PETSC_TRUE;
1892*6ea7df73SStefano Zampini     jac->mod_rap2              = 1;
1893*6ea7df73SStefano Zampini     jac->coarsentype           = 8;
1894*6ea7df73SStefano Zampini     jac->relaxorder            = 0;
1895*6ea7df73SStefano Zampini     jac->interptype            = 6;
1896*6ea7df73SStefano Zampini     jac->relaxtype[0]          = 18;
1897*6ea7df73SStefano Zampini     jac->relaxtype[1]          = 18;
1898*6ea7df73SStefano Zampini     jac->agg_interptype        = 7;
1899*6ea7df73SStefano Zampini #else
1900*6ea7df73SStefano Zampini     jac->keeptranspose         = PETSC_FALSE;
1901*6ea7df73SStefano Zampini     jac->mod_rap2              = 0;
1902*6ea7df73SStefano Zampini #endif
1903fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1904fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1905fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1906fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1907fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1908fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1909fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1910fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1911fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1912fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1913fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1914fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1915*6ea7df73SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetAggInterpType,(jac->hsolver,jac->agg_interptype));
1916fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1917fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1918fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /* defaults coarse to 9 */
1919fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /* defaults coarse to 1 */
1920589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxCoarseSize,(jac->hsolver, jac->maxc));
1921589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetMinCoarseSize,(jac->hsolver, jac->minc));
1922589dcaf0SStefano Zampini 
1923*6ea7df73SStefano Zampini     /* GPU */
1924*6ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0)
1925*6ea7df73SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetKeepTranspose,(jac->hsolver,jac->keeptranspose ? 1 : 0));
1926*6ea7df73SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetRAP2,(jac->hsolver, jac->rap2));
1927*6ea7df73SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetModuleRAP2,(jac->hsolver, jac->mod_rap2));
1928*6ea7df73SStefano Zampini #endif
1929*6ea7df73SStefano Zampini 
1930589dcaf0SStefano Zampini     /* AIR */
1931*6ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0)
1932589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetRestriction,(jac->hsolver,jac->Rtype));
1933589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThresholdR,(jac->hsolver,jac->Rstrongthreshold));
1934589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetFilterThresholdR,(jac->hsolver,jac->Rfilterthreshold));
1935589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetADropTol,(jac->hsolver,jac->Adroptol));
1936589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetADropType,(jac->hsolver,jac->Adroptype));
1937*6ea7df73SStefano Zampini #endif
193816d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
193916d9e3a6SLisandro Dalcin   }
19404cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
19414cb006feSStefano Zampini   if (flag) {
19424cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
19434cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
19444cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
19454cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
19464cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
19474cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
19484cb006feSStefano Zampini     jac->coords[0]           = NULL;
19494cb006feSStefano Zampini     jac->coords[1]           = NULL;
19504cb006feSStefano Zampini     jac->coords[2]           = NULL;
19514cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1952863406b8SStefano Zampini     jac->as_print           = 0;
1953863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1954863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
19554cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
19564cb006feSStefano Zampini     /* Smoothing options */
1957863406b8SStefano Zampini     jac->as_relax_type      = 2;
1958863406b8SStefano Zampini     jac->as_relax_times     = 1;
1959863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1960863406b8SStefano Zampini     jac->as_omega           = 1.0;
19614cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1962863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1963863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
19640bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1965863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1966863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1967863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
19684cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1969863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1970863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
19710bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1972863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1973863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1974863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1975863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1976863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
19774cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1978863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1979863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1980863406b8SStefano Zampini                                                                       jac->as_relax_times,
1981863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1982863406b8SStefano Zampini                                                                       jac->as_omega));
1983863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1984863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1985863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1986863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1987863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1988863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1989863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1990863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1991863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1992863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1993863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1994863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
199523df4f25SStefano Zampini     /* Zero conductivity */
199623df4f25SStefano Zampini     jac->ams_beta_is_zero      = PETSC_FALSE;
199723df4f25SStefano Zampini     jac->ams_beta_is_zero_part = PETSC_FALSE;
19984cb006feSStefano Zampini     PetscFunctionReturn(0);
19994cb006feSStefano Zampini   }
2000863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
2001863406b8SStefano Zampini   if (flag) {
2002863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
2003863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
2004863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
2005863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
2006863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
2007863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
2008863406b8SStefano Zampini     jac->coords[0]           = NULL;
2009863406b8SStefano Zampini     jac->coords[1]           = NULL;
2010863406b8SStefano Zampini     jac->coords[2]           = NULL;
2011863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
2012863406b8SStefano Zampini     jac->as_print           = 0;
2013863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
2014863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
2015863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
2016863406b8SStefano Zampini     /* Smoothing options */
2017863406b8SStefano Zampini     jac->as_relax_type      = 2;
2018863406b8SStefano Zampini     jac->as_relax_times     = 1;
2019863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
2020863406b8SStefano Zampini     jac->as_omega           = 1.0;
2021863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
2022863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
2023863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
2024863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
2025863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
2026863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
2027863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
2028863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
2029863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
2030863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
2031863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
2032863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
2033863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
2034863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
2035863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
2036863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
2037863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
2038863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
2039863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
2040863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
2041863406b8SStefano Zampini                                                                       jac->as_relax_times,
2042863406b8SStefano Zampini                                                                       jac->as_relax_weight,
2043863406b8SStefano Zampini                                                                       jac->as_omega));
2044863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
2045863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
2046863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
2047863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
2048863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
2049863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
2050863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
2051863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
2052863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
2053863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
2054863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
2055863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
2056863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
2057863406b8SStefano Zampini     PetscFunctionReturn(0);
2058863406b8SStefano Zampini   }
2059503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
20602fa5cd67SKarl Rupp 
20610298fd71SBarry Smith   jac->hypre_type = NULL;
2062db966c6cSHong Zhang   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams",name);
206316d9e3a6SLisandro Dalcin }
206416d9e3a6SLisandro Dalcin 
206516d9e3a6SLisandro Dalcin /*
206616d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
206716d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
206816d9e3a6SLisandro Dalcin */
2069360ee056SFande Kong PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc)
207016d9e3a6SLisandro Dalcin {
207116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
20724ddd07fcSJed Brown   PetscInt       indx;
2073db966c6cSHong Zhang   const char     *type[] = {"euclid","pilut","parasails","boomeramg","ams","ads"};
2074ace3abfcSBarry Smith   PetscBool      flg;
207516d9e3a6SLisandro Dalcin 
207616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
20779fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
2078cab5ea25SPierre Jolivet   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,ALEN(type),"boomeramg",&indx,&flg);CHKERRQ(ierr);
207916d9e3a6SLisandro Dalcin   if (flg) {
208016d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
208102a17cd4SBarry Smith   } else {
208202a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
208316d9e3a6SLisandro Dalcin   }
208416d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
20853931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
208616d9e3a6SLisandro Dalcin   }
208716d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
208816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
208916d9e3a6SLisandro Dalcin }
209016d9e3a6SLisandro Dalcin 
209116d9e3a6SLisandro Dalcin /*@C
209216d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
209316d9e3a6SLisandro Dalcin 
209416d9e3a6SLisandro Dalcin    Input Parameters:
209516d9e3a6SLisandro Dalcin +     pc - the preconditioner context
2096db966c6cSHong Zhang -     name - either  euclid, pilut, parasails, boomeramg, ams, ads
209716d9e3a6SLisandro Dalcin 
209816d9e3a6SLisandro Dalcin    Options Database Keys:
2099db966c6cSHong Zhang    -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
210016d9e3a6SLisandro Dalcin 
210116d9e3a6SLisandro Dalcin    Level: intermediate
210216d9e3a6SLisandro Dalcin 
210316d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
210416d9e3a6SLisandro Dalcin            PCHYPRE
210516d9e3a6SLisandro Dalcin 
210616d9e3a6SLisandro Dalcin @*/
21077087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
210816d9e3a6SLisandro Dalcin {
21094ac538c5SBarry Smith   PetscErrorCode ierr;
211016d9e3a6SLisandro Dalcin 
211116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
21120700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
211316d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
21144ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
211516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
211616d9e3a6SLisandro Dalcin }
211716d9e3a6SLisandro Dalcin 
211816d9e3a6SLisandro Dalcin /*@C
211916d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
212016d9e3a6SLisandro Dalcin 
212116d9e3a6SLisandro Dalcin    Input Parameter:
212216d9e3a6SLisandro Dalcin .     pc - the preconditioner context
212316d9e3a6SLisandro Dalcin 
212416d9e3a6SLisandro Dalcin    Output Parameter:
2125db966c6cSHong Zhang .     name - either  euclid, pilut, parasails, boomeramg, ams, ads
212616d9e3a6SLisandro Dalcin 
212716d9e3a6SLisandro Dalcin    Level: intermediate
212816d9e3a6SLisandro Dalcin 
212916d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
213016d9e3a6SLisandro Dalcin            PCHYPRE
213116d9e3a6SLisandro Dalcin 
213216d9e3a6SLisandro Dalcin @*/
21337087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
213416d9e3a6SLisandro Dalcin {
21354ac538c5SBarry Smith   PetscErrorCode ierr;
213616d9e3a6SLisandro Dalcin 
213716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
21380700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
213916d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
21404ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
214116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
214216d9e3a6SLisandro Dalcin }
214316d9e3a6SLisandro Dalcin 
214416d9e3a6SLisandro Dalcin /*MC
214516d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
214616d9e3a6SLisandro Dalcin 
214716d9e3a6SLisandro Dalcin    Options Database Keys:
2148db966c6cSHong Zhang +   -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
214916d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
215016d9e3a6SLisandro Dalcin           preconditioner
215116d9e3a6SLisandro Dalcin 
215216d9e3a6SLisandro Dalcin    Level: intermediate
215316d9e3a6SLisandro Dalcin 
215495452b02SPatrick Sanan    Notes:
215595452b02SPatrick Sanan     Apart from pc_hypre_type (for which there is PCHYPRESetType()),
215616d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
215716d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
215816d9e3a6SLisandro Dalcin 
2159c231f9e3SBarryFSmith           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_tol refer to the number of iterations
21600f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
21610f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
2162c231f9e3SBarryFSmith           (-pc_hypre_boomeramg_tol should be set to 0.0 - the default - to strictly use a fixed number of
21638f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
21640f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
21650f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
216616d9e3a6SLisandro Dalcin 
21670f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
21680f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
21690f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
217016d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
217116d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
217216d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
217316d9e3a6SLisandro Dalcin 
217416d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
217516d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
217616d9e3a6SLisandro Dalcin 
21775272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
2178fdd15c9aSJunchao Zhang           the following two options:
21790b1a5bd9SEric Chamberland 
2180fdd15c9aSJunchao Zhang    Options Database Keys:
21815272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
2182fdd15c9aSJunchao Zhang -   -pc_hypre_boomeramg_vec_interp_variant <v> - where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
21835272c319SBarry Smith 
21845272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
21855272c319SBarry Smith 
21869e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
21879e5bc791SBarry Smith 
218816d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
21899e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
219016d9e3a6SLisandro Dalcin 
219116d9e3a6SLisandro Dalcin M*/
219216d9e3a6SLisandro Dalcin 
21938cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
219416d9e3a6SLisandro Dalcin {
219516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
219616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
219716d9e3a6SLisandro Dalcin 
219816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
2199b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
22002fa5cd67SKarl Rupp 
220116d9e3a6SLisandro Dalcin   pc->data                = jac;
22028695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
220316d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
220416d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
220516d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
220616d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
220716d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
2208bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
2209bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
22105ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
22115ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
22125ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
22136bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",PCHYPRESetInterpolations_HYPRE);CHKERRQ(ierr);
22145ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE);CHKERRQ(ierr);
22155ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",PCHYPRESetPoissonMatrix_HYPRE);CHKERRQ(ierr);
2216*6ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE)
2217*6ea7df73SStefano Zampini #if defined(HYPRE_USING_HIP)
2218*6ea7df73SStefano Zampini   ierr = PetscHIPInitializeCheck();CHKERRQ(ierr);
2219*6ea7df73SStefano Zampini #endif
2220*6ea7df73SStefano Zampini #if defined(HYPRE_USING_CUDA)
2221*6ea7df73SStefano Zampini   ierr = PetscCUDAInitializeCheck();CHKERRQ(ierr);
2222*6ea7df73SStefano Zampini #endif
2223*6ea7df73SStefano Zampini #endif
222416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
222516d9e3a6SLisandro Dalcin }
2226ebc551c0SBarry Smith 
2227f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
2228f91d8e95SBarry Smith 
2229ebc551c0SBarry Smith typedef struct {
223068326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
2231f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
22329e5bc791SBarry Smith 
22339e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
22344ddd07fcSJed Brown   PetscInt its;
22359e5bc791SBarry Smith   double   tol;
22364ddd07fcSJed Brown   PetscInt relax_type;
22374ddd07fcSJed Brown   PetscInt rap_type;
22384ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
22394ddd07fcSJed Brown   PetscInt max_levels;
2240ebc551c0SBarry Smith } PC_PFMG;
2241ebc551c0SBarry Smith 
2242ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
2243ebc551c0SBarry Smith {
2244ebc551c0SBarry Smith   PetscErrorCode ierr;
2245f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2246ebc551c0SBarry Smith 
2247ebc551c0SBarry Smith   PetscFunctionBegin;
22482fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2249ffc4695bSBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRMPI(ierr);
2250c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2251ebc551c0SBarry Smith   PetscFunctionReturn(0);
2252ebc551c0SBarry Smith }
2253ebc551c0SBarry Smith 
22549e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
22559e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
22569e5bc791SBarry Smith 
2257ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
2258ebc551c0SBarry Smith {
2259ebc551c0SBarry Smith   PetscErrorCode ierr;
2260ace3abfcSBarry Smith   PetscBool      iascii;
2261f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2262ebc551c0SBarry Smith 
2263ebc551c0SBarry Smith   PetscFunctionBegin;
2264251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
22659e5bc791SBarry Smith   if (iascii) {
22669e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
2267efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max iterations %d\n",ex->its);CHKERRQ(ierr);
2268efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    tolerance %g\n",ex->tol);CHKERRQ(ierr);
2269efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2270efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
2271efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2272efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max levels %d\n",ex->max_levels);CHKERRQ(ierr);
22739e5bc791SBarry Smith   }
2274ebc551c0SBarry Smith   PetscFunctionReturn(0);
2275ebc551c0SBarry Smith }
2276ebc551c0SBarry Smith 
22774416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2278ebc551c0SBarry Smith {
2279ebc551c0SBarry Smith   PetscErrorCode ierr;
2280f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2281ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2282ebc551c0SBarry Smith 
2283ebc551c0SBarry Smith   PetscFunctionBegin;
2284e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
22850298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
228668326731SBarry Smith   if (flg) {
22875bd1e576SStefano Zampini     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,3));
228868326731SBarry Smith   }
22890298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2290fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
22910298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_num_pre_relax","Number of smoothing steps before coarse grid","HYPRE_StructPFMGSetNumPreRelax",ex->num_pre_relax,&ex->num_pre_relax,NULL);CHKERRQ(ierr);
2292fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
22930298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_num_post_relax","Number of smoothing steps after coarse grid","HYPRE_StructPFMGSetNumPostRelax",ex->num_post_relax,&ex->num_post_relax,NULL);CHKERRQ(ierr);
2294fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
22959e5bc791SBarry Smith 
22960298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
2297fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
22983b46a515SGlenn Hammond 
22990298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2300fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
23010298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_relax_type","Relax type for the up and down cycles","HYPRE_StructPFMGSetRelaxType",PFMGRelaxType,ALEN(PFMGRelaxType),PFMGRelaxType[ex->relax_type],&ex->relax_type,NULL);CHKERRQ(ierr);
2302fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
23030298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
2304fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
2305ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
2306ebc551c0SBarry Smith   PetscFunctionReturn(0);
2307ebc551c0SBarry Smith }
2308ebc551c0SBarry Smith 
2309f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
2310f91d8e95SBarry Smith {
2311f91d8e95SBarry Smith   PetscErrorCode    ierr;
2312f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
2313d9ca1df4SBarry Smith   PetscScalar       *yy;
2314d9ca1df4SBarry Smith   const PetscScalar *xx;
23154ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
23162cf14000SStefano Zampini   HYPRE_Int         hlower[3],hupper[3];
231768326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2318f91d8e95SBarry Smith 
2319f91d8e95SBarry Smith   PetscFunctionBegin;
2320dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2321aa219208SBarry Smith   ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
23222cf14000SStefano Zampini   /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
2323f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
2324f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
2325f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
23262cf14000SStefano Zampini   hlower[0]  = (HYPRE_Int)ilower[0];
23272cf14000SStefano Zampini   hlower[1]  = (HYPRE_Int)ilower[1];
23282cf14000SStefano Zampini   hlower[2]  = (HYPRE_Int)ilower[2];
23292cf14000SStefano Zampini   hupper[0]  = (HYPRE_Int)iupper[0];
23302cf14000SStefano Zampini   hupper[1]  = (HYPRE_Int)iupper[1];
23312cf14000SStefano Zampini   hupper[2]  = (HYPRE_Int)iupper[2];
2332f91d8e95SBarry Smith 
2333f91d8e95SBarry Smith   /* copy x values over to hypre */
2334fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
2335d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
233639accc25SStefano Zampini   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,hlower,hupper,(HYPRE_Complex*)xx));
2337d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2338fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
2339fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2340f91d8e95SBarry Smith 
2341f91d8e95SBarry Smith   /* copy solution values back to PETSc */
2342f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
234339accc25SStefano Zampini   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,hlower,hupper,(HYPRE_Complex*)yy));
2344f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2345f91d8e95SBarry Smith   PetscFunctionReturn(0);
2346f91d8e95SBarry Smith }
2347f91d8e95SBarry Smith 
2348ace3abfcSBarry 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)
23499e5bc791SBarry Smith {
23509e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
23519e5bc791SBarry Smith   PetscErrorCode ierr;
23522cf14000SStefano Zampini   HYPRE_Int      oits;
23539e5bc791SBarry Smith 
23549e5bc791SBarry Smith   PetscFunctionBegin;
2355dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2356fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
2357fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
23589e5bc791SBarry Smith 
23599e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
23602cf14000SStefano Zampini   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,&oits));
23619e5bc791SBarry Smith   *outits = oits;
23629e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
23639e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2364fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
2365fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
23669e5bc791SBarry Smith   PetscFunctionReturn(0);
23679e5bc791SBarry Smith }
23689e5bc791SBarry Smith 
23693a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
23703a32d3dbSGlenn Hammond {
23713a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
23723a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
23733a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2374ace3abfcSBarry Smith   PetscBool       flg;
23753a32d3dbSGlenn Hammond 
23763a32d3dbSGlenn Hammond   PetscFunctionBegin;
2377251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
2378ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
23793a32d3dbSGlenn Hammond 
23803a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
23812fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2382fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2383fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2384fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
23853a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
23863a32d3dbSGlenn Hammond }
23873a32d3dbSGlenn Hammond 
2388ebc551c0SBarry Smith /*MC
2389ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
2390ebc551c0SBarry Smith 
2391ebc551c0SBarry Smith    Level: advanced
2392ebc551c0SBarry Smith 
23939e5bc791SBarry Smith    Options Database:
23949e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
23959e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
23969e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
23979e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
23989e5bc791SBarry 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
23999e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
2400f91d8e95SBarry Smith 
240195452b02SPatrick Sanan    Notes:
240295452b02SPatrick Sanan     This is for CELL-centered descretizations
24039e5bc791SBarry Smith 
24048e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
2405aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
24069e5bc791SBarry Smith 
24079e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
2408ebc551c0SBarry Smith M*/
2409ebc551c0SBarry Smith 
24108cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
2411ebc551c0SBarry Smith {
2412ebc551c0SBarry Smith   PetscErrorCode ierr;
2413ebc551c0SBarry Smith   PC_PFMG        *ex;
2414ebc551c0SBarry Smith 
2415ebc551c0SBarry Smith   PetscFunctionBegin;
2416b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
241768326731SBarry Smith   pc->data = ex;
2418ebc551c0SBarry Smith 
24199e5bc791SBarry Smith   ex->its            = 1;
24209e5bc791SBarry Smith   ex->tol            = 1.e-8;
24219e5bc791SBarry Smith   ex->relax_type     = 1;
24229e5bc791SBarry Smith   ex->rap_type       = 0;
24239e5bc791SBarry Smith   ex->num_pre_relax  = 1;
24249e5bc791SBarry Smith   ex->num_post_relax = 1;
24253b46a515SGlenn Hammond   ex->max_levels     = 0;
24269e5bc791SBarry Smith 
2427ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2428ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2429ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2430f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
24319e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
243268326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
24332fa5cd67SKarl Rupp 
2434ffc4695bSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRMPI(ierr);
2435fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2436ebc551c0SBarry Smith   PetscFunctionReturn(0);
2437ebc551c0SBarry Smith }
2438d851a50bSGlenn Hammond 
2439325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2440325fc9f4SBarry Smith 
2441d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2442d851a50bSGlenn Hammond typedef struct {
2443d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2444d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2445d851a50bSGlenn Hammond 
2446d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
24474ddd07fcSJed Brown   PetscInt its;
2448d851a50bSGlenn Hammond   double   tol;
24494ddd07fcSJed Brown   PetscInt relax_type;
24504ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2451d851a50bSGlenn Hammond } PC_SysPFMG;
2452d851a50bSGlenn Hammond 
2453d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2454d851a50bSGlenn Hammond {
2455d851a50bSGlenn Hammond   PetscErrorCode ierr;
2456d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2457d851a50bSGlenn Hammond 
2458d851a50bSGlenn Hammond   PetscFunctionBegin;
24592fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2460ffc4695bSBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRMPI(ierr);
2461c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2462d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2463d851a50bSGlenn Hammond }
2464d851a50bSGlenn Hammond 
2465d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2466d851a50bSGlenn Hammond 
2467d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2468d851a50bSGlenn Hammond {
2469d851a50bSGlenn Hammond   PetscErrorCode ierr;
2470ace3abfcSBarry Smith   PetscBool      iascii;
2471d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2472d851a50bSGlenn Hammond 
2473d851a50bSGlenn Hammond   PetscFunctionBegin;
2474251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2475d851a50bSGlenn Hammond   if (iascii) {
2476d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2477efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  max iterations %d\n",ex->its);CHKERRQ(ierr);
2478efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerance %g\n",ex->tol);CHKERRQ(ierr);
2479efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2480efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2481d851a50bSGlenn Hammond   }
2482d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2483d851a50bSGlenn Hammond }
2484d851a50bSGlenn Hammond 
24854416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2486d851a50bSGlenn Hammond {
2487d851a50bSGlenn Hammond   PetscErrorCode ierr;
2488d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2489ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2490d851a50bSGlenn Hammond 
2491d851a50bSGlenn Hammond   PetscFunctionBegin;
2492e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
24930298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2494d851a50bSGlenn Hammond   if (flg) {
24955bd1e576SStefano Zampini     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,3));
2496d851a50bSGlenn Hammond   }
24970298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2498fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
24990298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_num_pre_relax","Number of smoothing steps before coarse grid","HYPRE_SStructSysPFMGSetNumPreRelax",ex->num_pre_relax,&ex->num_pre_relax,NULL);CHKERRQ(ierr);
2500fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
25010298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_num_post_relax","Number of smoothing steps after coarse grid","HYPRE_SStructSysPFMGSetNumPostRelax",ex->num_post_relax,&ex->num_post_relax,NULL);CHKERRQ(ierr);
2502fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2503d851a50bSGlenn Hammond 
25040298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2505fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
250661710fbeSStefano Zampini   ierr = PetscOptionsEList("-pc_syspfmg_relax_type","Relax type for the up and down cycles","HYPRE_SStructSysPFMGSetRelaxType",SysPFMGRelaxType,ALEN(SysPFMGRelaxType),SysPFMGRelaxType[ex->relax_type],&ex->relax_type,NULL);CHKERRQ(ierr);
2507fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2508d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2509d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2510d851a50bSGlenn Hammond }
2511d851a50bSGlenn Hammond 
2512d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2513d851a50bSGlenn Hammond {
2514d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2515d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2516d9ca1df4SBarry Smith   PetscScalar       *yy;
2517d9ca1df4SBarry Smith   const PetscScalar *xx;
25184ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
25192cf14000SStefano Zampini   HYPRE_Int         hlower[3],hupper[3];
2520d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
25214ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
25224ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
25234ddd07fcSJed Brown   PetscInt          part    = 0;
25244ddd07fcSJed Brown   PetscInt          size;
25254ddd07fcSJed Brown   PetscInt          i;
2526d851a50bSGlenn Hammond 
2527d851a50bSGlenn Hammond   PetscFunctionBegin;
2528dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2529aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
25302cf14000SStefano Zampini   /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
2531d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2532d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2533d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
25342cf14000SStefano Zampini   hlower[0]  = (HYPRE_Int)ilower[0];
25352cf14000SStefano Zampini   hlower[1]  = (HYPRE_Int)ilower[1];
25362cf14000SStefano Zampini   hlower[2]  = (HYPRE_Int)ilower[2];
25372cf14000SStefano Zampini   hupper[0]  = (HYPRE_Int)iupper[0];
25382cf14000SStefano Zampini   hupper[1]  = (HYPRE_Int)iupper[1];
25392cf14000SStefano Zampini   hupper[2]  = (HYPRE_Int)iupper[2];
2540d851a50bSGlenn Hammond 
2541d851a50bSGlenn Hammond   size = 1;
25422fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
25432fa5cd67SKarl Rupp 
2544d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2545d851a50bSGlenn Hammond   if (ordering) {
2546fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2547d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
254839accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(xx+(size*i))));
2549d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2550fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2551fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2552fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2553d851a50bSGlenn Hammond 
2554d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2555d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
255639accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(yy+(size*i))));
2557d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2558a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2559d851a50bSGlenn Hammond     PetscScalar *z;
25604ddd07fcSJed Brown     PetscInt    j, k;
2561d851a50bSGlenn Hammond 
2562785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2563fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2564d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2565d851a50bSGlenn Hammond 
2566d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2567d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2568d851a50bSGlenn Hammond       k= i*nvars;
25692fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2570d851a50bSGlenn Hammond     }
257139accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i))));
2572d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2573fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2574fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2575d851a50bSGlenn Hammond 
2576d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2577d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
257839accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i))));
2579d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2580d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2581d851a50bSGlenn Hammond       k= i*nvars;
25822fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2583d851a50bSGlenn Hammond     }
2584d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2585d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2586d851a50bSGlenn Hammond   }
2587d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2588d851a50bSGlenn Hammond }
2589d851a50bSGlenn Hammond 
2590ace3abfcSBarry 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)
2591d851a50bSGlenn Hammond {
2592d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2593d851a50bSGlenn Hammond   PetscErrorCode ierr;
25942cf14000SStefano Zampini   HYPRE_Int      oits;
2595d851a50bSGlenn Hammond 
2596d851a50bSGlenn Hammond   PetscFunctionBegin;
2597dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2598fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2599fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2600d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
26012cf14000SStefano Zampini   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,&oits));
2602d851a50bSGlenn Hammond   *outits = oits;
2603d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2604d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2605fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2606fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2607d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2608d851a50bSGlenn Hammond }
2609d851a50bSGlenn Hammond 
2610d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2611d851a50bSGlenn Hammond {
2612d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2613d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2614d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2615ace3abfcSBarry Smith   PetscBool        flg;
2616d851a50bSGlenn Hammond 
2617d851a50bSGlenn Hammond   PetscFunctionBegin;
2618251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2619ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2620d851a50bSGlenn Hammond 
2621d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
26222fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2623fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2624fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2625fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2626d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2627d851a50bSGlenn Hammond }
2628d851a50bSGlenn Hammond 
2629d851a50bSGlenn Hammond /*MC
2630d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2631d851a50bSGlenn Hammond 
2632d851a50bSGlenn Hammond    Level: advanced
2633d851a50bSGlenn Hammond 
2634d851a50bSGlenn Hammond    Options Database:
2635d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2636d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2637d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2638d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2639a2b725a8SWilliam Gropp - -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2640d851a50bSGlenn Hammond 
264195452b02SPatrick Sanan    Notes:
264295452b02SPatrick Sanan     This is for CELL-centered descretizations
2643d851a50bSGlenn Hammond 
2644f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2645aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2646d851a50bSGlenn Hammond            Also, only cell-centered variables.
2647d851a50bSGlenn Hammond 
2648d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2649d851a50bSGlenn Hammond M*/
2650d851a50bSGlenn Hammond 
26518cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2652d851a50bSGlenn Hammond {
2653d851a50bSGlenn Hammond   PetscErrorCode ierr;
2654d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2655d851a50bSGlenn Hammond 
2656d851a50bSGlenn Hammond   PetscFunctionBegin;
2657b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2658d851a50bSGlenn Hammond   pc->data = ex;
2659d851a50bSGlenn Hammond 
2660d851a50bSGlenn Hammond   ex->its            = 1;
2661d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2662d851a50bSGlenn Hammond   ex->relax_type     = 1;
2663d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2664d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2665d851a50bSGlenn Hammond 
2666d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2667d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2668d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2669d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2670d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2671d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
26722fa5cd67SKarl Rupp 
2673ffc4695bSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRMPI(ierr);
2674fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2675d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2676d851a50bSGlenn Hammond }
2677