xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision a4af0ceea8a251db97ee0dc5c0d52d4adf50264a)
116d9e3a6SLisandro Dalcin /*
216d9e3a6SLisandro Dalcin    Provides an interface to the LLNL package hypre
316d9e3a6SLisandro Dalcin */
40f1074feSSatish Balay 
5589dcaf0SStefano Zampini #include <petscpkg_version.h>
6af0996ceSBarry Smith #include <petsc/private/pcimpl.h>          /*I "petscpc.h" I*/
749a781f5SStefano Zampini /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
849a781f5SStefano Zampini #include <petsc/private/matimpl.h>
96ea7df73SStefano Zampini #include <petsc/private/vecimpl.h>
1058968eb6SStefano Zampini #include <../src/vec/vec/impls/hypre/vhyp.h>
1149a781f5SStefano Zampini #include <../src/mat/impls/hypre/mhypre.h>
12c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h>
134cb006feSStefano Zampini #include <_hypre_parcsr_ls.h>
148a2c336bSFande Kong #include <petscmathypre.h>
1516d9e3a6SLisandro Dalcin 
16*a4af0ceeSJacob Faibussowitsch #if defined(PETSC_HAVE_HYPRE_DEVICE)
17*a4af0ceeSJacob Faibussowitsch #include <petsc/private/deviceimpl.h>
18*a4af0ceeSJacob Faibussowitsch #endif
19*a4af0ceeSJacob Faibussowitsch 
20dff31646SBarry Smith static PetscBool cite = PETSC_FALSE;
21a8d69d7bSBarry Smith static const char hypreCitation[] = "@manual{hypre-web-page,\n  title  = {{\\sl hypre}: High Performance Preconditioners},\n  organization = {Lawrence Livermore National Laboratory},\n  note  = {\\url{https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods}}\n}\n";
221f817a21SBarry Smith 
2316d9e3a6SLisandro Dalcin /*
2416d9e3a6SLisandro Dalcin    Private context (data structure) for the  preconditioner.
2516d9e3a6SLisandro Dalcin */
2616d9e3a6SLisandro Dalcin typedef struct {
2716d9e3a6SLisandro Dalcin   HYPRE_Solver   hsolver;
2849a781f5SStefano Zampini   Mat            hpmat; /* MatHYPRE */
2916d9e3a6SLisandro Dalcin 
304ddd07fcSJed Brown   HYPRE_Int (*destroy)(HYPRE_Solver);
314ddd07fcSJed Brown   HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
324ddd07fcSJed Brown   HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
3316d9e3a6SLisandro Dalcin 
3416d9e3a6SLisandro Dalcin   MPI_Comm comm_hypre;
3516d9e3a6SLisandro Dalcin   char     *hypre_type;
3616d9e3a6SLisandro Dalcin 
3716d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
384ddd07fcSJed Brown   PetscInt  maxiter;
3939accc25SStefano Zampini   PetscReal tol;
4016d9e3a6SLisandro Dalcin 
4116d9e3a6SLisandro Dalcin   /* options for Pilut */
424ddd07fcSJed Brown   PetscInt factorrowsize;
4316d9e3a6SLisandro Dalcin 
4416d9e3a6SLisandro Dalcin   /* options for ParaSails */
454ddd07fcSJed Brown   PetscInt  nlevels;
468966356dSPierre Jolivet   PetscReal threshold;
4739accc25SStefano Zampini   PetscReal filter;
4839accc25SStefano Zampini   PetscReal loadbal;
494ddd07fcSJed Brown   PetscInt  logging;
504ddd07fcSJed Brown   PetscInt  ruse;
514ddd07fcSJed Brown   PetscInt  symt;
5216d9e3a6SLisandro Dalcin 
5322b6d1caSBarry Smith   /* options for BoomerAMG */
54ace3abfcSBarry Smith   PetscBool printstatistics;
5516d9e3a6SLisandro Dalcin 
5616d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
574ddd07fcSJed Brown   PetscInt  cycletype;
584ddd07fcSJed Brown   PetscInt  maxlevels;
5939accc25SStefano Zampini   PetscReal strongthreshold;
6039accc25SStefano Zampini   PetscReal maxrowsum;
614ddd07fcSJed Brown   PetscInt  gridsweeps[3];
624ddd07fcSJed Brown   PetscInt  coarsentype;
634ddd07fcSJed Brown   PetscInt  measuretype;
646a251517SEike Mueller   PetscInt  smoothtype;
658131ecf7SEike Mueller   PetscInt  smoothnumlevels;
66ec64516dSEike Mueller   PetscInt  eu_level;   /* Number of levels for ILU(k) in Euclid */
6739accc25SStefano Zampini   PetscReal eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */
68ec64516dSEike Mueller   PetscInt  eu_bj;      /* Defines use of Block Jacobi ILU in Euclid */
694ddd07fcSJed Brown   PetscInt  relaxtype[3];
7039accc25SStefano Zampini   PetscReal relaxweight;
7139accc25SStefano Zampini   PetscReal outerrelaxweight;
724ddd07fcSJed Brown   PetscInt  relaxorder;
7339accc25SStefano Zampini   PetscReal truncfactor;
74ace3abfcSBarry Smith   PetscBool applyrichardson;
754ddd07fcSJed Brown   PetscInt  pmax;
764ddd07fcSJed Brown   PetscInt  interptype;
77589dcaf0SStefano Zampini   PetscInt  maxc;
78589dcaf0SStefano Zampini   PetscInt  minc;
79589dcaf0SStefano Zampini 
806ea7df73SStefano Zampini   /* GPU */
816ea7df73SStefano Zampini   PetscBool keeptranspose;
826ea7df73SStefano Zampini   PetscInt  rap2;
836ea7df73SStefano Zampini   PetscInt  mod_rap2;
846ea7df73SStefano Zampini 
85589dcaf0SStefano Zampini   /* AIR */
86589dcaf0SStefano Zampini   PetscInt  Rtype;
87589dcaf0SStefano Zampini   PetscReal Rstrongthreshold;
88589dcaf0SStefano Zampini   PetscReal Rfilterthreshold;
89589dcaf0SStefano Zampini   PetscInt  Adroptype;
90589dcaf0SStefano Zampini   PetscReal Adroptol;
91589dcaf0SStefano Zampini 
924ddd07fcSJed Brown   PetscInt  agg_nl;
936ea7df73SStefano Zampini   PetscInt  agg_interptype;
944ddd07fcSJed Brown   PetscInt  agg_num_paths;
95ace3abfcSBarry Smith   PetscBool nodal_relax;
964ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
974cb006feSStefano Zampini 
985272c319SBarry Smith   PetscInt  nodal_coarsening;
9922e51d31SStefano Zampini   PetscInt  nodal_coarsening_diag;
1005272c319SBarry Smith   PetscInt  vec_interp_variant;
10122e51d31SStefano Zampini   PetscInt  vec_interp_qmax;
10222e51d31SStefano Zampini   PetscBool vec_interp_smooth;
10322e51d31SStefano Zampini   PetscInt  interp_refine;
10422e51d31SStefano Zampini 
1056ea7df73SStefano Zampini   /* NearNullSpace support */
1066ea7df73SStefano Zampini   VecHYPRE_IJVector *hmnull;
1076ea7df73SStefano Zampini   HYPRE_ParVector   *phmnull;
1085272c319SBarry Smith   PetscInt          n_hmnull;
1095272c319SBarry Smith   Vec               hmnull_constant;
1105272c319SBarry Smith 
111863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
112863406b8SStefano Zampini   PetscInt  as_print;
113863406b8SStefano Zampini   PetscInt  as_max_iter;
114863406b8SStefano Zampini   PetscReal as_tol;
115863406b8SStefano Zampini   PetscInt  as_relax_type;
116863406b8SStefano Zampini   PetscInt  as_relax_times;
117863406b8SStefano Zampini   PetscReal as_relax_weight;
118863406b8SStefano Zampini   PetscReal as_omega;
119863406b8SStefano 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) */
120863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
121863406b8SStefano 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) */
122863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
1234cb006feSStefano Zampini   PetscInt  ams_cycle_type;
124863406b8SStefano Zampini   PetscInt  ads_cycle_type;
1254cb006feSStefano Zampini 
1264cb006feSStefano Zampini   /* additional data */
1275ac14e1cSStefano Zampini   Mat G;             /* MatHYPRE */
1285ac14e1cSStefano Zampini   Mat C;             /* MatHYPRE */
1295ac14e1cSStefano Zampini   Mat alpha_Poisson; /* MatHYPRE */
1305ac14e1cSStefano Zampini   Mat beta_Poisson;  /* MatHYPRE */
1315ac14e1cSStefano Zampini 
1325ac14e1cSStefano Zampini   /* extra information for AMS */
1335ac14e1cSStefano Zampini   PetscInt          dim; /* geometrical dimension */
1346ea7df73SStefano Zampini   VecHYPRE_IJVector coords[3];
1356ea7df73SStefano Zampini   VecHYPRE_IJVector constants[3];
1366bf688a0SCe Qin   Mat               RT_PiFull, RT_Pi[3];
1376bf688a0SCe Qin   Mat               ND_PiFull, ND_Pi[3];
1384cb006feSStefano Zampini   PetscBool         ams_beta_is_zero;
13923df4f25SStefano Zampini   PetscBool         ams_beta_is_zero_part;
14023df4f25SStefano Zampini   PetscInt          ams_proj_freq;
14116d9e3a6SLisandro Dalcin } PC_HYPRE;
14216d9e3a6SLisandro Dalcin 
143d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
144d2128fa2SBarry Smith {
145d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
146d2128fa2SBarry Smith 
147d2128fa2SBarry Smith   PetscFunctionBegin;
148d2128fa2SBarry Smith   *hsolver = jac->hsolver;
149d2128fa2SBarry Smith   PetscFunctionReturn(0);
150d2128fa2SBarry Smith }
15116d9e3a6SLisandro Dalcin 
152fd2dd295SFande Kong /*
1538a2c336bSFande Kong   Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix
1548a2c336bSFande Kong   is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine.
1558a2c336bSFande Kong   It is used in PCHMG. Other users should avoid using this function.
156fd2dd295SFande Kong */
157fd2dd295SFande Kong static PetscErrorCode PCGetCoarseOperators_BoomerAMG(PC pc,PetscInt *nlevels,Mat *operators[])
1588a2c336bSFande Kong {
1598a2c336bSFande Kong   PC_HYPRE             *jac  = (PC_HYPRE*)pc->data;
1608a2c336bSFande Kong   PetscBool            same = PETSC_FALSE;
1618a2c336bSFande Kong   PetscErrorCode       ierr;
1628a2c336bSFande Kong   PetscInt             num_levels,l;
1638a2c336bSFande Kong   Mat                  *mattmp;
1648a2c336bSFande Kong   hypre_ParCSRMatrix   **A_array;
1658a2c336bSFande Kong 
1668a2c336bSFande Kong   PetscFunctionBegin;
1678a2c336bSFande Kong   ierr = PetscStrcmp(jac->hypre_type,"boomeramg",&same);CHKERRQ(ierr);
1688a2c336bSFande Kong   if (!same) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_NOTSAMETYPE,"Hypre type is not BoomerAMG \n");
1698a2c336bSFande Kong   num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData*) (jac->hsolver));
1708a2c336bSFande Kong   ierr = PetscMalloc1(num_levels,&mattmp);CHKERRQ(ierr);
1718a2c336bSFande Kong   A_array    = hypre_ParAMGDataAArray((hypre_ParAMGData*) (jac->hsolver));
1728a2c336bSFande Kong   for (l=1; l<num_levels; l++) {
1738a2c336bSFande Kong     ierr = MatCreateFromParCSR(A_array[l],MATAIJ,PETSC_OWN_POINTER, &(mattmp[num_levels-1-l]));CHKERRQ(ierr);
1748a2c336bSFande Kong     /* We want to own the data, and HYPRE can not touch this matrix any more */
1758a2c336bSFande Kong     A_array[l] = NULL;
1768a2c336bSFande Kong   }
1778a2c336bSFande Kong   *nlevels = num_levels;
1788a2c336bSFande Kong   *operators = mattmp;
1798a2c336bSFande Kong   PetscFunctionReturn(0);
1808a2c336bSFande Kong }
1818a2c336bSFande Kong 
182fd2dd295SFande Kong /*
1838a2c336bSFande Kong   Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix
1848a2c336bSFande Kong   is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine.
1858a2c336bSFande Kong   It is used in PCHMG. Other users should avoid using this function.
186fd2dd295SFande Kong */
187fd2dd295SFande Kong static PetscErrorCode PCGetInterpolations_BoomerAMG(PC pc,PetscInt *nlevels,Mat *interpolations[])
1888a2c336bSFande Kong {
1898a2c336bSFande Kong   PC_HYPRE             *jac  = (PC_HYPRE*)pc->data;
1908a2c336bSFande Kong   PetscBool            same = PETSC_FALSE;
1918a2c336bSFande Kong   PetscErrorCode       ierr;
1928a2c336bSFande Kong   PetscInt             num_levels,l;
1938a2c336bSFande Kong   Mat                  *mattmp;
1948a2c336bSFande Kong   hypre_ParCSRMatrix   **P_array;
1958a2c336bSFande Kong 
1968a2c336bSFande Kong   PetscFunctionBegin;
1978a2c336bSFande Kong   ierr = PetscStrcmp(jac->hypre_type,"boomeramg",&same);CHKERRQ(ierr);
1988a2c336bSFande Kong   if (!same) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_NOTSAMETYPE,"Hypre type is not BoomerAMG \n");
1998a2c336bSFande Kong   num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData*) (jac->hsolver));
2008a2c336bSFande Kong   ierr = PetscMalloc1(num_levels,&mattmp);CHKERRQ(ierr);
2018a2c336bSFande Kong   P_array  = hypre_ParAMGDataPArray((hypre_ParAMGData*) (jac->hsolver));
2028a2c336bSFande Kong   for (l=1; l<num_levels; l++) {
2038a2c336bSFande Kong     ierr = MatCreateFromParCSR(P_array[num_levels-1-l],MATAIJ,PETSC_OWN_POINTER, &(mattmp[l-1]));CHKERRQ(ierr);
2048a2c336bSFande Kong     /* We want to own the data, and HYPRE can not touch this matrix any more */
2058a2c336bSFande Kong     P_array[num_levels-1-l] = NULL;
2068a2c336bSFande Kong   }
2078a2c336bSFande Kong   *nlevels = num_levels;
2088a2c336bSFande Kong   *interpolations = mattmp;
2098a2c336bSFande Kong   PetscFunctionReturn(0);
2108a2c336bSFande Kong }
2118a2c336bSFande Kong 
212ce6a8a0dSJed Brown /* Resets (frees) Hypre's representation of the near null space */
213ce6a8a0dSJed Brown static PetscErrorCode PCHYPREResetNearNullSpace_Private(PC pc)
214ce6a8a0dSJed Brown {
215ce6a8a0dSJed Brown   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
216ce6a8a0dSJed Brown   PetscInt       i;
2179d678128SJed Brown   PetscErrorCode ierr;
218ce6a8a0dSJed Brown 
2199d678128SJed Brown   PetscFunctionBegin;
220ce6a8a0dSJed Brown   for (i=0; i<jac->n_hmnull; i++) {
2216ea7df73SStefano Zampini     ierr = VecHYPRE_IJVectorDestroy(&jac->hmnull[i]);CHKERRQ(ierr);
222ce6a8a0dSJed Brown   }
223ce6a8a0dSJed Brown   ierr = PetscFree(jac->hmnull);CHKERRQ(ierr);
224ce6a8a0dSJed Brown   ierr = PetscFree(jac->phmnull);CHKERRQ(ierr);
225ce6a8a0dSJed Brown   ierr = VecDestroy(&jac->hmnull_constant);CHKERRQ(ierr);
2269d678128SJed Brown   jac->n_hmnull = 0;
227ce6a8a0dSJed Brown   PetscFunctionReturn(0);
228ce6a8a0dSJed Brown }
229ce6a8a0dSJed Brown 
23016d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
23116d9e3a6SLisandro Dalcin {
23216d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
23349a781f5SStefano Zampini   Mat_HYPRE          *hjac;
23416d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
23516d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
23649a781f5SStefano Zampini   PetscBool          ishypre;
23749a781f5SStefano Zampini   PetscErrorCode     ierr;
23816d9e3a6SLisandro Dalcin 
23916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
24016d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
24102a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
24216d9e3a6SLisandro Dalcin   }
2435f5c5b43SBarry Smith 
24449a781f5SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRE,&ishypre);CHKERRQ(ierr);
24549a781f5SStefano Zampini   if (!ishypre) {
2466bf688a0SCe Qin     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
2476bf688a0SCe Qin     ierr = MatConvert(pc->pmat,MATHYPRE,MAT_INITIAL_MATRIX,&jac->hpmat);CHKERRQ(ierr);
248589dcaf0SStefano Zampini     ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)jac->hpmat);CHKERRQ(ierr);
24949a781f5SStefano Zampini   } else {
25049a781f5SStefano Zampini     ierr = PetscObjectReference((PetscObject)pc->pmat);CHKERRQ(ierr);
25149a781f5SStefano Zampini     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
25249a781f5SStefano Zampini     jac->hpmat = pc->pmat;
25316d9e3a6SLisandro Dalcin   }
2546ea7df73SStefano Zampini   /* allow debug */
2556ea7df73SStefano Zampini   ierr = MatViewFromOptions(jac->hpmat,NULL,"-pc_hypre_mat_view");CHKERRQ(ierr);
25649a781f5SStefano Zampini   hjac = (Mat_HYPRE*)(jac->hpmat->data);
2575f5c5b43SBarry Smith 
25816d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
25916d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
2605272c319SBarry Smith     MatNullSpace mnull;
2615272c319SBarry Smith     PetscBool    has_const;
26249a781f5SStefano Zampini     PetscInt     bs,nvec,i;
2635272c319SBarry Smith     const Vec    *vecs;
2645272c319SBarry Smith 
26516d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
2662fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
2675272c319SBarry Smith     ierr = MatGetNearNullSpace(pc->mat, &mnull);CHKERRQ(ierr);
2685272c319SBarry Smith     if (mnull) {
269ce6a8a0dSJed Brown       ierr = PCHYPREResetNearNullSpace_Private(pc);CHKERRQ(ierr);
2705272c319SBarry Smith       ierr = MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs);CHKERRQ(ierr);
2715272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull);CHKERRQ(ierr);
2725272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->phmnull);CHKERRQ(ierr);
2735272c319SBarry Smith       for (i=0; i<nvec; i++) {
2746ea7df73SStefano Zampini         ierr = VecHYPRE_IJVectorCreate(vecs[i]->map,&jac->hmnull[i]);CHKERRQ(ierr);
2756ea7df73SStefano Zampini         ierr = VecHYPRE_IJVectorCopy(vecs[i],jac->hmnull[i]);CHKERRQ(ierr);
2766ea7df73SStefano Zampini         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[i]->ij,(void**)&jac->phmnull[i]));
2775272c319SBarry Smith       }
2785272c319SBarry Smith       if (has_const) {
2795272c319SBarry Smith         ierr = MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL);CHKERRQ(ierr);
280589dcaf0SStefano Zampini         ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)jac->hmnull_constant);CHKERRQ(ierr);
2815272c319SBarry Smith         ierr = VecSet(jac->hmnull_constant,1);CHKERRQ(ierr);
2821e1ea65dSPierre Jolivet         ierr = VecNormalize(jac->hmnull_constant,NULL);CHKERRQ(ierr);
2836ea7df73SStefano Zampini         ierr = VecHYPRE_IJVectorCreate(jac->hmnull_constant->map,&jac->hmnull[nvec]);CHKERRQ(ierr);
2846ea7df73SStefano Zampini         ierr = VecHYPRE_IJVectorCopy(jac->hmnull_constant,jac->hmnull[nvec]);CHKERRQ(ierr);
2856ea7df73SStefano Zampini         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[nvec]->ij,(void**)&jac->phmnull[nvec]));
2865272c319SBarry Smith         nvec++;
2875272c319SBarry Smith       }
2885272c319SBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVectors,(jac->hsolver,nvec,jac->phmnull));
2895272c319SBarry Smith       jac->n_hmnull = nvec;
2905272c319SBarry Smith     }
2914cb006feSStefano Zampini   }
292863406b8SStefano Zampini 
2934cb006feSStefano Zampini   /* special case for AMS */
2944cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
2955ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2965ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
2976bf688a0SCe Qin     if (!jac->coords[0] && !jac->constants[0] && !(jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
2986bf688a0SCe 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");
2996bf688a0SCe Qin     }
3005ac14e1cSStefano Zampini     if (jac->dim) {
3015ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,jac->dim));
3025ac14e1cSStefano Zampini     }
3035ac14e1cSStefano Zampini     if (jac->constants[0]) {
3045ac14e1cSStefano Zampini       HYPRE_ParVector ozz,zoz,zzo = NULL;
3056ea7df73SStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0]->ij,(void**)(&ozz)));
3066ea7df73SStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1]->ij,(void**)(&zoz)));
3075ac14e1cSStefano Zampini       if (jac->constants[2]) {
3086ea7df73SStefano Zampini         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2]->ij,(void**)(&zzo)));
3095ac14e1cSStefano Zampini       }
3105ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,ozz,zoz,zzo));
3115ac14e1cSStefano Zampini     }
3125ac14e1cSStefano Zampini     if (jac->coords[0]) {
3135ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
3145ac14e1cSStefano Zampini       coords[0] = NULL;
3155ac14e1cSStefano Zampini       coords[1] = NULL;
3165ac14e1cSStefano Zampini       coords[2] = NULL;
3176ea7df73SStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0]->ij,(void**)(&coords[0])));
3186ea7df73SStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1]->ij,(void**)(&coords[1])));
3196ea7df73SStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2]->ij,(void**)(&coords[2])));
3205ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
3215ac14e1cSStefano Zampini     }
32249a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
3235ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
3245ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3255ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr));
3265ac14e1cSStefano Zampini     if (jac->alpha_Poisson) {
3275ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->alpha_Poisson->data);
3285ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3295ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr));
3305ac14e1cSStefano Zampini     }
3315ac14e1cSStefano Zampini     if (jac->ams_beta_is_zero) {
3325ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
3335ac14e1cSStefano Zampini     } else if (jac->beta_Poisson) {
3345ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->beta_Poisson->data);
3355ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3365ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr));
3375ac14e1cSStefano Zampini     }
3386bf688a0SCe Qin     if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) {
3396bf688a0SCe Qin       PetscInt           i;
3406bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
3416bf688a0SCe Qin       if (jac->ND_PiFull) {
3426bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
3436bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
3446bf688a0SCe Qin       } else {
3456bf688a0SCe Qin         nd_parcsrfull = NULL;
3466bf688a0SCe Qin       }
3476bf688a0SCe Qin       for (i=0;i<3;++i) {
3486bf688a0SCe Qin         if (jac->ND_Pi[i]) {
3496bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
3506bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
3516bf688a0SCe Qin         } else {
3526bf688a0SCe Qin           nd_parcsr[i] = NULL;
3536bf688a0SCe Qin         }
3546bf688a0SCe Qin       }
3556bf688a0SCe Qin       PetscStackCallStandard(HYPRE_AMSSetInterpolations,(jac->hsolver,nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]));
3566bf688a0SCe Qin     }
3574cb006feSStefano Zampini   }
358863406b8SStefano Zampini   /* special case for ADS */
359863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
3605ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
3615ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
3626bf688a0SCe 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])))) {
3636bf688a0SCe Qin       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations");
3646bf688a0SCe Qin     }
36537096e45SBarry 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");
36649a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
36749a781f5SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient");
3685ac14e1cSStefano Zampini     if (jac->coords[0]) {
3695ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
3705ac14e1cSStefano Zampini       coords[0] = NULL;
3715ac14e1cSStefano Zampini       coords[1] = NULL;
3725ac14e1cSStefano Zampini       coords[2] = NULL;
3736ea7df73SStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0]->ij,(void**)(&coords[0])));
3746ea7df73SStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1]->ij,(void**)(&coords[1])));
3756ea7df73SStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2]->ij,(void**)(&coords[2])));
3765ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_ADSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
3775ac14e1cSStefano Zampini     }
3785ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
3795ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3805ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteGradient,(jac->hsolver,parcsr));
3815ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->C->data);
3825ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3835ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteCurl,(jac->hsolver,parcsr));
3846bf688a0SCe Qin     if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
3856bf688a0SCe Qin       PetscInt           i;
3866bf688a0SCe Qin       HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3];
3876bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
3886bf688a0SCe Qin       if (jac->RT_PiFull) {
3896bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->RT_PiFull->data);
3906bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsrfull)));
3916bf688a0SCe Qin       } else {
3926bf688a0SCe Qin         rt_parcsrfull = NULL;
3936bf688a0SCe Qin       }
3946bf688a0SCe Qin       for (i=0;i<3;++i) {
3956bf688a0SCe Qin         if (jac->RT_Pi[i]) {
3966bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->RT_Pi[i]->data);
3976bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsr[i])));
3986bf688a0SCe Qin         } else {
3996bf688a0SCe Qin           rt_parcsr[i] = NULL;
4006bf688a0SCe Qin         }
4016bf688a0SCe Qin       }
4026bf688a0SCe Qin       if (jac->ND_PiFull) {
4036bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
4046bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
4056bf688a0SCe Qin       } else {
4066bf688a0SCe Qin         nd_parcsrfull = NULL;
4076bf688a0SCe Qin       }
4086bf688a0SCe Qin       for (i=0;i<3;++i) {
4096bf688a0SCe Qin         if (jac->ND_Pi[i]) {
4106bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
4116bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
4126bf688a0SCe Qin         } else {
4136bf688a0SCe Qin           nd_parcsr[i] = NULL;
4146bf688a0SCe Qin         }
4156bf688a0SCe Qin       }
4166bf688a0SCe 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]));
4176bf688a0SCe Qin     }
418863406b8SStefano Zampini   }
41949a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
4206ea7df73SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b->ij,(void**)&bv));
4216ea7df73SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x->ij,(void**)&xv));
42222e51d31SStefano Zampini   PetscStackCallStandard(jac->setup,(jac->hsolver,hmat,bv,xv));
42316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
42416d9e3a6SLisandro Dalcin }
42516d9e3a6SLisandro Dalcin 
42616d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
42716d9e3a6SLisandro Dalcin {
42816d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
42949a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
43016d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
43116d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
43216d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
4334ddd07fcSJed Brown   PetscInt           hierr;
43416d9e3a6SLisandro Dalcin 
43516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
436dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
43716d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
4386ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPushVecRead(hjac->b,b);CHKERRQ(ierr);
4396ea7df73SStefano Zampini   if (jac->applyrichardson) { ierr = VecHYPRE_IJVectorPushVec(hjac->x,x);CHKERRQ(ierr); }
4406ea7df73SStefano Zampini   else { ierr = VecHYPRE_IJVectorPushVecWrite(hjac->x,x);CHKERRQ(ierr); }
44149a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
4426ea7df73SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b->ij,(void**)&jbv));
4436ea7df73SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x->ij,(void**)&jxv));
444fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
44565e19b50SBarry Smith   if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
446fd3f9acdSBarry Smith   if (hierr) hypre__global_error = 0;);
44716d9e3a6SLisandro Dalcin 
44823df4f25SStefano Zampini   if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) {
4495ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSProjectOutGradients,(jac->hsolver,jxv));
45021df291bSStefano Zampini   }
4516ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPopVec(hjac->x);CHKERRQ(ierr);
4526ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPopVec(hjac->b);CHKERRQ(ierr);
45316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
45416d9e3a6SLisandro Dalcin }
45516d9e3a6SLisandro Dalcin 
4568695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc)
4578695de01SBarry Smith {
4588695de01SBarry Smith   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
4598695de01SBarry Smith   PetscErrorCode ierr;
4608695de01SBarry Smith 
4618695de01SBarry Smith   PetscFunctionBegin;
46249a781f5SStefano Zampini   ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
4635ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
4645ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
4655ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
4665ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
4676bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
4686bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[0]);CHKERRQ(ierr);
4696bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[1]);CHKERRQ(ierr);
4706bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[2]);CHKERRQ(ierr);
4716bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
4726bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[0]);CHKERRQ(ierr);
4736bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[1]);CHKERRQ(ierr);
4746bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[2]);CHKERRQ(ierr);
4756ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->coords[0]);CHKERRQ(ierr);
4766ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->coords[1]);CHKERRQ(ierr);
4776ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->coords[2]);CHKERRQ(ierr);
4786ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->constants[0]);CHKERRQ(ierr);
4796ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->constants[1]);CHKERRQ(ierr);
4806ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->constants[2]);CHKERRQ(ierr);
481ce6a8a0dSJed Brown   ierr = PCHYPREResetNearNullSpace_Private(pc);CHKERRQ(ierr);
4825ac14e1cSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
4835ac14e1cSStefano Zampini   jac->dim = 0;
4848695de01SBarry Smith   PetscFunctionReturn(0);
4858695de01SBarry Smith }
4868695de01SBarry Smith 
48716d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
48816d9e3a6SLisandro Dalcin {
48916d9e3a6SLisandro Dalcin   PC_HYPRE                 *jac = (PC_HYPRE*)pc->data;
49016d9e3a6SLisandro Dalcin   PetscErrorCode           ierr;
49116d9e3a6SLisandro Dalcin 
49216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
4938695de01SBarry Smith   ierr = PCReset_HYPRE(pc);CHKERRQ(ierr);
49422e51d31SStefano Zampini   if (jac->destroy) PetscStackCallStandard(jac->destroy,(jac->hsolver));
495503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
496ffc4695bSBarry Smith   if (jac->comm_hypre != MPI_COMM_NULL) {ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRMPI(ierr);}
497c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
49816d9e3a6SLisandro Dalcin 
49916d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
500bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
501bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
5024cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
5034cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
504863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
5056bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",NULL);CHKERRQ(ierr);
5064cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
5075ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",NULL);CHKERRQ(ierr);
508fd2dd295SFande Kong   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",NULL);CHKERRQ(ierr);
509fd2dd295SFande Kong   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",NULL);CHKERRQ(ierr);
51016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
51116d9e3a6SLisandro Dalcin }
51216d9e3a6SLisandro Dalcin 
51316d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
5144416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptionItems *PetscOptionsObject,PC pc)
51516d9e3a6SLisandro Dalcin {
51616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
51716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
518ace3abfcSBarry Smith   PetscBool      flag;
51916d9e3a6SLisandro Dalcin 
52016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
521e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
52216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
523fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
52416d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
525fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
52616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
527fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
52816d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
52916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
53016d9e3a6SLisandro Dalcin }
53116d9e3a6SLisandro Dalcin 
53216d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
53316d9e3a6SLisandro Dalcin {
53416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
53516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
536ace3abfcSBarry Smith   PetscBool      iascii;
53716d9e3a6SLisandro Dalcin 
53816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
539251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
54016d9e3a6SLisandro Dalcin   if (iascii) {
54116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
54216d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
543efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
54416d9e3a6SLisandro Dalcin     } else {
545efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default maximum number of iterations \n");CHKERRQ(ierr);
54616d9e3a6SLisandro Dalcin     }
54716d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
548efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
54916d9e3a6SLisandro Dalcin     } else {
550efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default drop tolerance \n");CHKERRQ(ierr);
55116d9e3a6SLisandro Dalcin     }
55216d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
553efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
55416d9e3a6SLisandro Dalcin     } else {
555efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default factor row size \n");CHKERRQ(ierr);
55616d9e3a6SLisandro Dalcin     }
55716d9e3a6SLisandro Dalcin   }
55816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
55916d9e3a6SLisandro Dalcin }
56016d9e3a6SLisandro Dalcin 
56116d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
562db966c6cSHong Zhang static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PetscOptionItems *PetscOptionsObject,PC pc)
563db966c6cSHong Zhang {
564db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
565db966c6cSHong Zhang   PetscErrorCode ierr;
5668bf83915SBarry Smith   PetscBool      flag,eu_bj = jac->eu_bj ? PETSC_TRUE : PETSC_FALSE;
567db966c6cSHong Zhang 
568db966c6cSHong Zhang   PetscFunctionBegin;
569db966c6cSHong Zhang   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Euclid Options");CHKERRQ(ierr);
570db966c6cSHong Zhang   ierr = PetscOptionsInt("-pc_hypre_euclid_level","Factorization levels","None",jac->eu_level,&jac->eu_level,&flag);CHKERRQ(ierr);
571db966c6cSHong Zhang   if (flag) PetscStackCallStandard(HYPRE_EuclidSetLevel,(jac->hsolver,jac->eu_level));
5728bf83915SBarry Smith 
5738bf83915SBarry Smith   ierr = PetscOptionsReal("-pc_hypre_euclid_droptolerance","Drop tolerance for ILU(k) in Euclid","None",jac->eu_droptolerance,&jac->eu_droptolerance,&flag);CHKERRQ(ierr);
5748bf83915SBarry Smith   if (flag) {
5758bf83915SBarry Smith     PetscMPIInt size;
5768bf83915SBarry Smith 
57755b25c41SPierre Jolivet     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRMPI(ierr);
5788bf83915SBarry Smith     if (size > 1) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"hypre's Euclid does not support a parallel drop tolerance");
5798bf83915SBarry Smith     PetscStackCallStandard(HYPRE_EuclidSetILUT,(jac->hsolver,jac->eu_droptolerance));
5808bf83915SBarry Smith   }
5818bf83915SBarry Smith 
5828bf83915SBarry Smith   ierr = PetscOptionsBool("-pc_hypre_euclid_bj", "Use Block Jacobi for ILU in Euclid", "None", eu_bj,&eu_bj,&flag);CHKERRQ(ierr);
5838bf83915SBarry Smith   if (flag) {
5848bf83915SBarry Smith     jac->eu_bj = eu_bj ? 1 : 0;
5858bf83915SBarry Smith     PetscStackCallStandard(HYPRE_EuclidSetBJ,(jac->hsolver,jac->eu_bj));
5868bf83915SBarry Smith   }
587db966c6cSHong Zhang   ierr = PetscOptionsTail();CHKERRQ(ierr);
588db966c6cSHong Zhang   PetscFunctionReturn(0);
589db966c6cSHong Zhang }
590db966c6cSHong Zhang 
591db966c6cSHong Zhang static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer)
592db966c6cSHong Zhang {
593db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
594db966c6cSHong Zhang   PetscErrorCode ierr;
595db966c6cSHong Zhang   PetscBool      iascii;
596db966c6cSHong Zhang 
597db966c6cSHong Zhang   PetscFunctionBegin;
598db966c6cSHong Zhang   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
599db966c6cSHong Zhang   if (iascii) {
600db966c6cSHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid preconditioning\n");CHKERRQ(ierr);
601db966c6cSHong Zhang     if (jac->eu_level != PETSC_DEFAULT) {
602db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    factorization levels %d\n",jac->eu_level);CHKERRQ(ierr);
603db966c6cSHong Zhang     } else {
604db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    default factorization levels \n");CHKERRQ(ierr);
605db966c6cSHong Zhang     }
6068bf83915SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->eu_droptolerance);CHKERRQ(ierr);
6078bf83915SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    use Block-Jacobi? %D\n",jac->eu_bj);CHKERRQ(ierr);
608db966c6cSHong Zhang   }
609db966c6cSHong Zhang   PetscFunctionReturn(0);
610db966c6cSHong Zhang }
611db966c6cSHong Zhang 
612db966c6cSHong Zhang /* --------------------------------------------------------------------------------------------*/
61316d9e3a6SLisandro Dalcin 
61416d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
61516d9e3a6SLisandro Dalcin {
61616d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
61749a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
61816d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
61916d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
62016d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
6214ddd07fcSJed Brown   PetscInt           hierr;
62216d9e3a6SLisandro Dalcin 
62316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
624dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
62516d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
6266ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPushVecRead(hjac->x,b);CHKERRQ(ierr);
6276ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPushVecWrite(hjac->b,x);CHKERRQ(ierr);
62816d9e3a6SLisandro Dalcin 
62949a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
6306ea7df73SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b->ij,(void**)&jbv));
6316ea7df73SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x->ij,(void**)&jxv));
63216d9e3a6SLisandro Dalcin 
6336ea7df73SStefano Zampini   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jxv,jbv);
63416d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
635e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
63616d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
63716d9e3a6SLisandro Dalcin 
6386ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPopVec(hjac->x);CHKERRQ(ierr);
6396ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorPopVec(hjac->b);CHKERRQ(ierr);
64016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
64116d9e3a6SLisandro Dalcin }
64216d9e3a6SLisandro Dalcin 
643a669f990SJed Brown /* static array length */
644a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
645a669f990SJed Brown 
64616d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
6470f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
64816d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
64965de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
6506a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]  = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
65165de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
65265de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
65365de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
6547b7fa87dSPierre Jolivet                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "l1-Gauss-Seidel" /* nonsymmetric */, "backward-l1-Gauss-Seidel" /* nonsymmetric */,
65565de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
6560f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
657589dcaf0SStefano Zampini                                                   "ext+i-cc", "standard", "standard-wts", "block", "block-wtd", "FF", "FF1",
658589dcaf0SStefano Zampini                                                   "ext", "ad-wts", "ext-mm", "ext+i-mm", "ext+e-mm"};
6594416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc)
66016d9e3a6SLisandro Dalcin {
66116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
66216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
66322e51d31SStefano Zampini   PetscInt       bs,n,indx,level;
664ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
66516d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
666589dcaf0SStefano Zampini   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
66716d9e3a6SLisandro Dalcin 
66816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
669e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
6704336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
67116d9e3a6SLisandro Dalcin   if (flg) {
6724336a9eeSBarry Smith     jac->cycletype = indx+1;
673fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
67416d9e3a6SLisandro Dalcin   }
67516d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
67616d9e3a6SLisandro Dalcin   if (flg) {
677ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
678fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
67916d9e3a6SLisandro Dalcin   }
68016d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
68116d9e3a6SLisandro Dalcin   if (flg) {
682ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
683fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
68416d9e3a6SLisandro Dalcin   }
68539accc25SStefano 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);
68616d9e3a6SLisandro Dalcin   if (flg) {
68757622a8eSBarry 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);
688fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
68916d9e3a6SLisandro Dalcin   }
69022e51d31SStefano Zampini   bs = 1;
69122e51d31SStefano Zampini   if (pc->pmat) {
69222e51d31SStefano Zampini     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
69322e51d31SStefano Zampini   }
69422e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_numfunctions","Number of functions","HYPRE_BoomerAMGSetNumFunctions",bs,&bs,&flg);CHKERRQ(ierr);
69522e51d31SStefano Zampini   if (flg) {
69622e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
69722e51d31SStefano Zampini   }
69816d9e3a6SLisandro Dalcin 
69939accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
70016d9e3a6SLisandro Dalcin   if (flg) {
70157622a8eSBarry 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);
702fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
70316d9e3a6SLisandro Dalcin   }
70416d9e3a6SLisandro Dalcin 
7050f1074feSSatish 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);
7060f1074feSSatish Balay   if (flg) {
707f8add624SPierre Jolivet     if (jac->pmax < 0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"P_max %D must be greater than or equal to zero",jac->pmax);
708fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
7090f1074feSSatish Balay   }
7100f1074feSSatish Balay 
711f8add624SPierre Jolivet   ierr = PetscOptionsRangeInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg,0,jac->maxlevels);CHKERRQ(ierr);
712f8add624SPierre Jolivet   if (flg) PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
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) {
716f8add624SPierre Jolivet     if (jac->agg_num_paths < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of paths %D must be greater than or equal to 1",jac->agg_num_paths);
717fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
7180f1074feSSatish Balay   }
7190f1074feSSatish Balay 
72039accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
72116d9e3a6SLisandro Dalcin   if (flg) {
72257622a8eSBarry 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);
723fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
72416d9e3a6SLisandro Dalcin   }
72539accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
72616d9e3a6SLisandro Dalcin   if (flg) {
72757622a8eSBarry 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);
72857622a8eSBarry 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);
729fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
73016d9e3a6SLisandro Dalcin   }
73116d9e3a6SLisandro Dalcin 
73216d9e3a6SLisandro Dalcin   /* Grid sweeps */
7330f1074feSSatish 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);
73416d9e3a6SLisandro Dalcin   if (flg) {
735fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
73616d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
73716d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
7380f1074feSSatish Balay     jac->gridsweeps[1] = indx;
7390f1074feSSatish Balay     /*defaults coarse to 1 */
7400f1074feSSatish Balay     jac->gridsweeps[2] = 1;
74116d9e3a6SLisandro Dalcin   }
7425272c319SBarry 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);
7435272c319SBarry Smith   if (flg) {
7445272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,jac->nodal_coarsening));
7455272c319SBarry Smith   }
74622e51d31SStefano 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);
74722e51d31SStefano Zampini   if (flg) {
74822e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNodalDiag,(jac->hsolver,jac->nodal_coarsening_diag));
74922e51d31SStefano Zampini   }
750cbc39033SBarry 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);
7515272c319SBarry Smith   if (flg) {
7525272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,(jac->hsolver,jac->vec_interp_variant));
7535272c319SBarry Smith   }
75422e51d31SStefano 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);
75522e51d31SStefano Zampini   if (flg) {
75622e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecQMax,(jac->hsolver,jac->vec_interp_qmax));
75722e51d31SStefano Zampini   }
75822e51d31SStefano 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);
75922e51d31SStefano Zampini   if (flg) {
76022e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothInterpVectors,(jac->hsolver,jac->vec_interp_smooth));
76122e51d31SStefano Zampini   }
76222e51d31SStefano 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);
76322e51d31SStefano Zampini   if (flg) {
76422e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpRefine,(jac->hsolver,jac->interp_refine));
76522e51d31SStefano Zampini   }
7660f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
76716d9e3a6SLisandro Dalcin   if (flg) {
768fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
7690f1074feSSatish Balay     jac->gridsweeps[0] = indx;
77016d9e3a6SLisandro Dalcin   }
77116d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
77216d9e3a6SLisandro Dalcin   if (flg) {
773fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
7740f1074feSSatish Balay     jac->gridsweeps[1] = indx;
77516d9e3a6SLisandro Dalcin   }
7760f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
77716d9e3a6SLisandro Dalcin   if (flg) {
778fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
7790f1074feSSatish Balay     jac->gridsweeps[2] = indx;
78016d9e3a6SLisandro Dalcin   }
78116d9e3a6SLisandro Dalcin 
7826a251517SEike Mueller   /* Smooth type */
7831e1ea65dSPierre Jolivet   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);CHKERRQ(ierr);
7846a251517SEike Mueller   if (flg) {
7856a251517SEike Mueller     jac->smoothtype = indx;
7866a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
7878131ecf7SEike Mueller     jac->smoothnumlevels = 25;
7888131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
7898131ecf7SEike Mueller   }
7908131ecf7SEike Mueller 
7918131ecf7SEike Mueller   /* Number of smoothing levels */
7928131ecf7SEike 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);
7938131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
7948131ecf7SEike Mueller     jac->smoothnumlevels = indx;
7958131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
7966a251517SEike Mueller   }
7976a251517SEike Mueller 
7981810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
7991810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
8001810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8011810e44eSEike Mueller     jac->eu_level = indx;
8021810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
8031810e44eSEike Mueller   }
8041810e44eSEike Mueller 
8051810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
8061810e44eSEike Mueller   double droptolerance;
80739accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
8081810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8091810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
8101810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
8111810e44eSEike Mueller   }
8121810e44eSEike Mueller 
8131810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
8141810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
8151810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8161810e44eSEike Mueller     jac->eu_bj = tmp_truth;
817493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
8181810e44eSEike Mueller   }
8191810e44eSEike Mueller 
82016d9e3a6SLisandro Dalcin   /* Relax type */
821a669f990SJed 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);
82216d9e3a6SLisandro Dalcin   if (flg) {
8230f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
824fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
8250f1074feSSatish Balay     /* by default, coarse type set to 9 */
8260f1074feSSatish Balay     jac->relaxtype[2] = 9;
827ddbeb582SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, 9, 3));
82816d9e3a6SLisandro Dalcin   }
829a669f990SJed 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);
83016d9e3a6SLisandro Dalcin   if (flg) {
83116d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
832fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
83316d9e3a6SLisandro Dalcin   }
834a669f990SJed 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);
83516d9e3a6SLisandro Dalcin   if (flg) {
8360f1074feSSatish Balay     jac->relaxtype[1] = indx;
837fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
83816d9e3a6SLisandro Dalcin   }
839a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
84016d9e3a6SLisandro Dalcin   if (flg) {
8410f1074feSSatish Balay     jac->relaxtype[2] = indx;
842fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
84316d9e3a6SLisandro Dalcin   }
84416d9e3a6SLisandro Dalcin 
84516d9e3a6SLisandro Dalcin   /* Relaxation Weight */
84616d9e3a6SLisandro 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);
84716d9e3a6SLisandro Dalcin   if (flg) {
848fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
84916d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
85016d9e3a6SLisandro Dalcin   }
85116d9e3a6SLisandro Dalcin 
85216d9e3a6SLisandro Dalcin   n         = 2;
85316d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
85416d9e3a6SLisandro 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);
85516d9e3a6SLisandro Dalcin   if (flg) {
85616d9e3a6SLisandro Dalcin     if (n == 2) {
85716d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
858fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
859ce94432eSBarry 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);
86016d9e3a6SLisandro Dalcin   }
86116d9e3a6SLisandro Dalcin 
86216d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
86316d9e3a6SLisandro 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);
86416d9e3a6SLisandro Dalcin   if (flg) {
865fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
86616d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
86716d9e3a6SLisandro Dalcin   }
86816d9e3a6SLisandro Dalcin 
86916d9e3a6SLisandro Dalcin   n         = 2;
87016d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
87116d9e3a6SLisandro 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);
87216d9e3a6SLisandro Dalcin   if (flg) {
87316d9e3a6SLisandro Dalcin     if (n == 2) {
87416d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
875fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
876ce94432eSBarry 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);
87716d9e3a6SLisandro Dalcin   }
87816d9e3a6SLisandro Dalcin 
87916d9e3a6SLisandro Dalcin   /* the Relax Order */
880acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
88116d9e3a6SLisandro Dalcin 
8828afaa268SBarry Smith   if (flg && tmp_truth) {
88316d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
884fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
88516d9e3a6SLisandro Dalcin   }
886a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
88716d9e3a6SLisandro Dalcin   if (flg) {
88816d9e3a6SLisandro Dalcin     jac->measuretype = indx;
889fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
89016d9e3a6SLisandro Dalcin   }
8910f1074feSSatish Balay   /* update list length 3/07 */
892a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
89316d9e3a6SLisandro Dalcin   if (flg) {
89416d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
895fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
89616d9e3a6SLisandro Dalcin   }
8970f1074feSSatish Balay 
898589dcaf0SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_coarse_size", "Maximum size of coarsest grid", "None", jac->maxc, &jac->maxc, &flg);CHKERRQ(ierr);
899589dcaf0SStefano Zampini   if (flg) {
900589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxCoarseSize,(jac->hsolver, jac->maxc));
901589dcaf0SStefano Zampini   }
902589dcaf0SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_min_coarse_size", "Minimum size of coarsest grid", "None", jac->minc, &jac->minc, &flg);CHKERRQ(ierr);
903589dcaf0SStefano Zampini   if (flg) {
904589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetMinCoarseSize,(jac->hsolver, jac->minc));
905589dcaf0SStefano Zampini   }
906589dcaf0SStefano Zampini 
907589dcaf0SStefano Zampini   /* AIR */
908589dcaf0SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0)
909589dcaf0SStefano 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);
910589dcaf0SStefano Zampini   PetscStackCallStandard(HYPRE_BoomerAMGSetRestriction,(jac->hsolver,jac->Rtype));
911589dcaf0SStefano Zampini   if (jac->Rtype) {
912589dcaf0SStefano 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 */
913589dcaf0SStefano Zampini 
914589dcaf0SStefano Zampini     ierr = PetscOptionsReal("-pc_hypre_boomeramg_strongthresholdR","Threshold for R","None",jac->Rstrongthreshold,&jac->Rstrongthreshold,NULL);CHKERRQ(ierr);
915589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThresholdR,(jac->hsolver,jac->Rstrongthreshold));
916589dcaf0SStefano Zampini 
917589dcaf0SStefano Zampini     ierr = PetscOptionsReal("-pc_hypre_boomeramg_filterthresholdR","Filter threshold for R","None",jac->Rfilterthreshold,&jac->Rfilterthreshold,NULL);CHKERRQ(ierr);
918589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetFilterThresholdR,(jac->hsolver,jac->Rfilterthreshold));
919589dcaf0SStefano Zampini 
920589dcaf0SStefano 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);
921589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetADropTol,(jac->hsolver,jac->Adroptol));
922589dcaf0SStefano Zampini 
923589dcaf0SStefano 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);
924589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetADropType,(jac->hsolver,jac->Adroptype));
925589dcaf0SStefano Zampini   }
926589dcaf0SStefano Zampini #endif
927589dcaf0SStefano Zampini 
928ecae95adSPierre Jolivet #if PETSC_PKG_HYPRE_VERSION_LE(9,9,9)
929ecae95adSPierre Jolivet   if (jac->Rtype && jac->agg_nl) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"-pc_hypre_boomeramg_restriction_type (%D) and -pc_hypre_boomeramg_agg_nl (%D)",jac->Rtype,jac->agg_nl);
930ecae95adSPierre Jolivet #endif
931ecae95adSPierre Jolivet 
9320f1074feSSatish Balay   /* new 3/07 */
933a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
934589dcaf0SStefano Zampini   if (flg || jac->Rtype) {
935589dcaf0SStefano Zampini     if (flg) jac->interptype = indx;
936fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
9370f1074feSSatish Balay   }
9380f1074feSSatish Balay 
939b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
94016d9e3a6SLisandro Dalcin   if (flg) {
941b96a4a96SBarry Smith     level = 3;
9420298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
9432fa5cd67SKarl Rupp 
944b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
945fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
9462ae77aedSBarry Smith   }
9472ae77aedSBarry Smith 
948b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
9492ae77aedSBarry Smith   if (flg) {
950b96a4a96SBarry Smith     level = 3;
9510298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
9522fa5cd67SKarl Rupp 
953b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
954fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
95516d9e3a6SLisandro Dalcin   }
9568f87f92bSBarry Smith 
957acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
9588f87f92bSBarry Smith   if (flg && tmp_truth) {
9598f87f92bSBarry Smith     PetscInt tmp_int;
9608f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
9618f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
962fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
963fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
964fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
965fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
9668f87f92bSBarry Smith   }
9678f87f92bSBarry Smith 
968589dcaf0SStefano Zampini   ierr = PetscOptionsBool("-pc_hypre_boomeramg_keeptranspose", "Avoid transpose matvecs in preconditioner application", "None", jac->keeptranspose, &jac->keeptranspose, NULL);CHKERRQ(ierr);
969589dcaf0SStefano Zampini   PetscStackCallStandard(HYPRE_BoomerAMGSetKeepTranspose,(jac->hsolver,jac->keeptranspose ? 1 : 0));
970589dcaf0SStefano Zampini 
971589dcaf0SStefano Zampini   /* options for ParaSails solvers */
972589dcaf0SStefano Zampini   ierr = PetscOptionsEList("-pc_hypre_boomeramg_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flg);CHKERRQ(ierr);
973589dcaf0SStefano Zampini   if (flg) {
974589dcaf0SStefano Zampini     jac->symt = indx;
975589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetSym,(jac->hsolver,jac->symt));
976589dcaf0SStefano Zampini   }
977589dcaf0SStefano Zampini 
97816d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
97916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
98016d9e3a6SLisandro Dalcin }
98116d9e3a6SLisandro Dalcin 
982ace3abfcSBarry 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)
98316d9e3a6SLisandro Dalcin {
98416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
98516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
9862cf14000SStefano Zampini   HYPRE_Int      oits;
98716d9e3a6SLisandro Dalcin 
98816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
989dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
990fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
991fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
99216d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
99316d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
99416d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
9952cf14000SStefano Zampini   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,&oits));
9964d0a8057SBarry Smith   *outits = oits;
9974d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
9984d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
999fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1000fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
100116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
100216d9e3a6SLisandro Dalcin }
100316d9e3a6SLisandro Dalcin 
100416d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
100516d9e3a6SLisandro Dalcin {
100616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
100716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1008ace3abfcSBarry Smith   PetscBool      iascii;
100916d9e3a6SLisandro Dalcin 
101016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1011251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
101216d9e3a6SLisandro Dalcin   if (iascii) {
101316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
1014efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
101522e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of levels %D\n",jac->maxlevels);CHKERRQ(ierr);
101622e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of iterations PER hypre call %D\n",jac->maxiter);CHKERRQ(ierr);
1017efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
1018efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
1019efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
102022e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: max elements per row %D\n",jac->pmax);CHKERRQ(ierr);
102122e51d31SStefano Zampini     if (jac->interp_refine) {
102222e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: number of steps of weighted refinement %D\n",jac->interp_refine);CHKERRQ(ierr);
102322e51d31SStefano Zampini     }
102422e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of levels of aggressive coarsening %D\n",jac->agg_nl);CHKERRQ(ierr);
102522e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of paths for aggressive coarsening %D\n",jac->agg_num_paths);CHKERRQ(ierr);
10260f1074feSSatish Balay 
1027efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
102816d9e3a6SLisandro Dalcin 
102922e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps down         %D\n",jac->gridsweeps[0]);CHKERRQ(ierr);
103022e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps up           %D\n",jac->gridsweeps[1]);CHKERRQ(ierr);
103122e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps on coarse    %D\n",jac->gridsweeps[2]);CHKERRQ(ierr);
103216d9e3a6SLisandro Dalcin 
1033efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
1034efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
1035efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
103616d9e3a6SLisandro Dalcin 
1037efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
1038efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
103916d9e3a6SLisandro Dalcin 
104016d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
1041efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using CF-relaxation\n");CHKERRQ(ierr);
104216d9e3a6SLisandro Dalcin     } else {
1043efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using CF-relaxation\n");CHKERRQ(ierr);
104416d9e3a6SLisandro Dalcin     }
10456a251517SEike Mueller     if (jac->smoothtype!=-1) {
1046efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
104722e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth num levels    %D\n",jac->smoothnumlevels);CHKERRQ(ierr);
10487e352d70SEike Mueller     } else {
1049efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using more complex smoothers.\n");CHKERRQ(ierr);
10501810e44eSEike Mueller     }
10511810e44eSEike Mueller     if (jac->smoothtype==3) {
105222e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) levels %D\n",jac->eu_level);CHKERRQ(ierr);
105322e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) drop tolerance %g\n",(double)jac->eu_droptolerance);CHKERRQ(ierr);
105422e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU use Block-Jacobi? %D\n",jac->eu_bj);CHKERRQ(ierr);
10556a251517SEike Mueller     }
1056efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
1057efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
1058589dcaf0SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation type  %s\n",jac->interptype != 100 ? HYPREBoomerAMGInterpType[jac->interptype] : "1pt");CHKERRQ(ierr);
10595272c319SBarry Smith     if (jac->nodal_coarsening) {
106084c7a2fdSPierre Jolivet       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal coarsening with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
10615272c319SBarry Smith     }
10625272c319SBarry Smith     if (jac->vec_interp_variant) {
1063efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
106422e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecQMax() %D\n",jac->vec_interp_qmax);CHKERRQ(ierr);
106522e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n",jac->vec_interp_smooth);CHKERRQ(ierr);
10668f87f92bSBarry Smith     }
10678f87f92bSBarry Smith     if (jac->nodal_relax) {
106822e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal relaxation via Schwarz smoothing on levels %D\n",jac->nodal_relax_levels);CHKERRQ(ierr);
10698f87f92bSBarry Smith     }
1070589dcaf0SStefano Zampini 
1071589dcaf0SStefano Zampini     /* AIR */
1072589dcaf0SStefano Zampini     if (jac->Rtype) {
1073589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Using approximate ideal restriction type %D\n",jac->Rtype);CHKERRQ(ierr);
1074589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"      Threshold for R %g\n",(double)jac->Rstrongthreshold);CHKERRQ(ierr);
1075589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"      Filter for R %g\n",(double)jac->Rfilterthreshold);CHKERRQ(ierr);
1076589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"      A drop tolerance %g\n",(double)jac->Adroptol);CHKERRQ(ierr);
1077589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"      A drop type %D\n",jac->Adroptype);CHKERRQ(ierr);
1078589dcaf0SStefano Zampini     }
107916d9e3a6SLisandro Dalcin   }
108016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
108116d9e3a6SLisandro Dalcin }
108216d9e3a6SLisandro Dalcin 
108316d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
10844416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc)
108516d9e3a6SLisandro Dalcin {
108616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
108716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
10884ddd07fcSJed Brown   PetscInt       indx;
1089ace3abfcSBarry Smith   PetscBool      flag;
109016d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
109116d9e3a6SLisandro Dalcin 
109216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1093e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
109416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
10958966356dSPierre Jolivet   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshold,&jac->threshold,&flag);CHKERRQ(ierr);
10968966356dSPierre Jolivet   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshold,jac->nlevels));
109716d9e3a6SLisandro Dalcin 
109816d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
10992fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
110016d9e3a6SLisandro Dalcin 
110116d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
11022fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
110316d9e3a6SLisandro Dalcin 
1104acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
11052fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
110616d9e3a6SLisandro Dalcin 
1107acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
11082fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
110916d9e3a6SLisandro Dalcin 
1110a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
111116d9e3a6SLisandro Dalcin   if (flag) {
111216d9e3a6SLisandro Dalcin     jac->symt = indx;
1113fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
111416d9e3a6SLisandro Dalcin   }
111516d9e3a6SLisandro Dalcin 
111616d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
111716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
111816d9e3a6SLisandro Dalcin }
111916d9e3a6SLisandro Dalcin 
112016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
112116d9e3a6SLisandro Dalcin {
112216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
112316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1124ace3abfcSBarry Smith   PetscBool      iascii;
1125feb237baSPierre Jolivet   const char     *symt = 0;
112616d9e3a6SLisandro Dalcin 
112716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1128251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
112916d9e3a6SLisandro Dalcin   if (iascii) {
113016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
1131efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
11328966356dSPierre Jolivet     ierr = PetscViewerASCIIPrintf(viewer,"    threshold %g\n",(double)jac->threshold);CHKERRQ(ierr);
1133efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    filter %g\n",(double)jac->filter);CHKERRQ(ierr);
1134efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
1135efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
1136efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
11372fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
11382fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
11392fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
1140ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
1141efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    %s\n",symt);CHKERRQ(ierr);
114216d9e3a6SLisandro Dalcin   }
114316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
114416d9e3a6SLisandro Dalcin }
11454cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
11464416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc)
11474cb006feSStefano Zampini {
11484cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
11494cb006feSStefano Zampini   PetscErrorCode ierr;
11504cb006feSStefano Zampini   PetscInt       n;
11514cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
11524cb006feSStefano Zampini 
11534cb006feSStefano Zampini   PetscFunctionBegin;
11549fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
1155863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1156863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1157863406b8SStefano 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);
1158863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
11594cb006feSStefano 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);
11604cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1161863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1162863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1163863406b8SStefano 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);
1164863406b8SStefano 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);
1165863406b8SStefano 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);
1166863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
11674cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1168863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1169863406b8SStefano Zampini                                                                       jac->as_relax_times,
1170863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1171863406b8SStefano Zampini                                                                       jac->as_omega));
11724cb006feSStefano Zampini   }
1173863406b8SStefano 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);
11744cb006feSStefano Zampini   n = 5;
1175863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
11764cb006feSStefano Zampini   if (flag || flag2) {
1177863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1178863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1179863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1180863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1181863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1182863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
11834cb006feSStefano Zampini   }
1184863406b8SStefano 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);
11854cb006feSStefano Zampini   n = 5;
1186863406b8SStefano 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);
11874cb006feSStefano Zampini   if (flag || flag2) {
1188863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1189863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1190863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1191863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1192863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1193863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
11944cb006feSStefano Zampini   }
119523df4f25SStefano 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);
119623df4f25SStefano Zampini   if (flag) { /* override HYPRE's default only if the options is used */
119723df4f25SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetProjectionFrequency,(jac->hsolver,jac->ams_proj_freq));
119823df4f25SStefano Zampini   }
11994cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
12004cb006feSStefano Zampini   PetscFunctionReturn(0);
12014cb006feSStefano Zampini }
12024cb006feSStefano Zampini 
12034cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
12044cb006feSStefano Zampini {
12054cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12064cb006feSStefano Zampini   PetscErrorCode ierr;
12074cb006feSStefano Zampini   PetscBool      iascii;
12084cb006feSStefano Zampini 
12094cb006feSStefano Zampini   PetscFunctionBegin;
12104cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
12114cb006feSStefano Zampini   if (iascii) {
12124cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
1213efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1214efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1215efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1216efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1217efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1218efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1219efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
12204cb006feSStefano Zampini     if (jac->alpha_Poisson) {
1221efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
12224cb006feSStefano Zampini     } else {
1223efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (computed) \n");CHKERRQ(ierr);
12244cb006feSStefano Zampini     }
1225efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1226efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1227efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1228efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1229efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1230efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
12314cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
12324cb006feSStefano Zampini       if (jac->beta_Poisson) {
1233efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
12344cb006feSStefano Zampini       } else {
1235efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (computed) \n");CHKERRQ(ierr);
12364cb006feSStefano Zampini       }
1237efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1238efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1239efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1240efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1241efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1242efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
124323df4f25SStefano Zampini       if (jac->ams_beta_is_zero_part) {
1244efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"        compatible subspace projection frequency %d (-1 HYPRE uses default)\n",jac->ams_proj_freq);CHKERRQ(ierr);
124523df4f25SStefano Zampini       }
124623df4f25SStefano Zampini     } else {
1247efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver not used (zero-conductivity everywhere) \n");CHKERRQ(ierr);
12484cb006feSStefano Zampini     }
12494cb006feSStefano Zampini   }
12504cb006feSStefano Zampini   PetscFunctionReturn(0);
12514cb006feSStefano Zampini }
12524cb006feSStefano Zampini 
12534416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc)
1254863406b8SStefano Zampini {
1255863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1256863406b8SStefano Zampini   PetscErrorCode ierr;
1257863406b8SStefano Zampini   PetscInt       n;
1258863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
1259863406b8SStefano Zampini 
1260863406b8SStefano Zampini   PetscFunctionBegin;
1261863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
1262863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1263863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1264863406b8SStefano 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);
1265863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1266863406b8SStefano 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);
1267863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
1268863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1269863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1270863406b8SStefano 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);
1271863406b8SStefano 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);
1272863406b8SStefano 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);
1273863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
1274863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1275863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1276863406b8SStefano Zampini                                                                       jac->as_relax_times,
1277863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1278863406b8SStefano Zampini                                                                       jac->as_omega));
1279863406b8SStefano Zampini   }
1280863406b8SStefano 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);
1281863406b8SStefano Zampini   n = 5;
1282863406b8SStefano 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);
1283863406b8SStefano 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);
1284863406b8SStefano Zampini   if (flag || flag2 || flag3) {
1285863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
1286863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1287863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1288863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1289863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1290863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1291863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1292863406b8SStefano Zampini   }
1293863406b8SStefano 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);
1294863406b8SStefano Zampini   n = 5;
1295863406b8SStefano 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);
1296863406b8SStefano Zampini   if (flag || flag2) {
1297863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1298863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1299863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1300863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1301863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1302863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1303863406b8SStefano Zampini   }
1304863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
1305863406b8SStefano Zampini   PetscFunctionReturn(0);
1306863406b8SStefano Zampini }
1307863406b8SStefano Zampini 
1308863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1309863406b8SStefano Zampini {
1310863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1311863406b8SStefano Zampini   PetscErrorCode ierr;
1312863406b8SStefano Zampini   PetscBool      iascii;
1313863406b8SStefano Zampini 
1314863406b8SStefano Zampini   PetscFunctionBegin;
1315863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1316863406b8SStefano Zampini   if (iascii) {
1317863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
1318efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1319efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
1320efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1321efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1322efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1323efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1324efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
1325efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    AMS solver using boomerAMG\n");CHKERRQ(ierr);
1326efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1327efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1328efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1329efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1330efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1331efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1332efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
1333efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver using boomerAMG\n");CHKERRQ(ierr);
1334efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1335efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1336efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1337efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1338efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1339efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
1340863406b8SStefano Zampini   }
1341863406b8SStefano Zampini   PetscFunctionReturn(0);
1342863406b8SStefano Zampini }
1343863406b8SStefano Zampini 
1344863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
13454cb006feSStefano Zampini {
13464cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
13475ac14e1cSStefano Zampini   PetscBool      ishypre;
13484cb006feSStefano Zampini   PetscErrorCode ierr;
13494cb006feSStefano Zampini 
13504cb006feSStefano Zampini   PetscFunctionBegin;
13515ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)G,MATHYPRE,&ishypre);CHKERRQ(ierr);
13525ac14e1cSStefano Zampini   if (ishypre) {
13535ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr);
13545ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
13555ac14e1cSStefano Zampini     jac->G = G;
13565ac14e1cSStefano Zampini   } else {
13576bf688a0SCe Qin     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
13586bf688a0SCe Qin     ierr = MatConvert(G,MATHYPRE,MAT_INITIAL_MATRIX,&jac->G);CHKERRQ(ierr);
13595ac14e1cSStefano Zampini   }
13604cb006feSStefano Zampini   PetscFunctionReturn(0);
13614cb006feSStefano Zampini }
13624cb006feSStefano Zampini 
13634cb006feSStefano Zampini /*@
13644cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
13654cb006feSStefano Zampini 
13664cb006feSStefano Zampini    Collective on PC
13674cb006feSStefano Zampini 
13684cb006feSStefano Zampini    Input Parameters:
13694cb006feSStefano Zampini +  pc - the preconditioning context
13704cb006feSStefano Zampini -  G - the discrete gradient
13714cb006feSStefano Zampini 
13724cb006feSStefano Zampini    Level: intermediate
13734cb006feSStefano Zampini 
137495452b02SPatrick Sanan    Notes:
137595452b02SPatrick Sanan     G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh
1376863406b8SStefano 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
13774cb006feSStefano Zampini 
13784cb006feSStefano Zampini .seealso:
13794cb006feSStefano Zampini @*/
13804cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
13814cb006feSStefano Zampini {
13824cb006feSStefano Zampini   PetscErrorCode ierr;
13834cb006feSStefano Zampini 
13844cb006feSStefano Zampini   PetscFunctionBegin;
13854cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
13864cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
13874cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
13884cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
13894cb006feSStefano Zampini   PetscFunctionReturn(0);
13904cb006feSStefano Zampini }
13914cb006feSStefano Zampini 
1392863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1393863406b8SStefano Zampini {
1394863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
13955ac14e1cSStefano Zampini   PetscBool      ishypre;
1396863406b8SStefano Zampini   PetscErrorCode ierr;
1397863406b8SStefano Zampini 
1398863406b8SStefano Zampini   PetscFunctionBegin;
13995ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)C,MATHYPRE,&ishypre);CHKERRQ(ierr);
14005ac14e1cSStefano Zampini   if (ishypre) {
14015ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr);
14025ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
14035ac14e1cSStefano Zampini     jac->C = C;
14045ac14e1cSStefano Zampini   } else {
14056bf688a0SCe Qin     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
14066bf688a0SCe Qin     ierr = MatConvert(C,MATHYPRE,MAT_INITIAL_MATRIX,&jac->C);CHKERRQ(ierr);
14075ac14e1cSStefano Zampini   }
1408863406b8SStefano Zampini   PetscFunctionReturn(0);
1409863406b8SStefano Zampini }
1410863406b8SStefano Zampini 
1411863406b8SStefano Zampini /*@
1412863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1413863406b8SStefano Zampini 
1414863406b8SStefano Zampini    Collective on PC
1415863406b8SStefano Zampini 
1416863406b8SStefano Zampini    Input Parameters:
1417863406b8SStefano Zampini +  pc - the preconditioning context
1418863406b8SStefano Zampini -  C - the discrete curl
1419863406b8SStefano Zampini 
1420863406b8SStefano Zampini    Level: intermediate
1421863406b8SStefano Zampini 
142295452b02SPatrick Sanan    Notes:
142395452b02SPatrick Sanan     C should have as many rows as the number of faces and as many columns as the number of edges in the mesh
1424863406b8SStefano 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
1425863406b8SStefano Zampini 
1426863406b8SStefano Zampini .seealso:
1427863406b8SStefano Zampini @*/
1428863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1429863406b8SStefano Zampini {
1430863406b8SStefano Zampini   PetscErrorCode ierr;
1431863406b8SStefano Zampini 
1432863406b8SStefano Zampini   PetscFunctionBegin;
1433863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1434863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1435863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1436863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1437863406b8SStefano Zampini   PetscFunctionReturn(0);
1438863406b8SStefano Zampini }
1439863406b8SStefano Zampini 
14406bf688a0SCe Qin static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
14416bf688a0SCe Qin {
14426bf688a0SCe Qin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
14436bf688a0SCe Qin   PetscBool      ishypre;
14446bf688a0SCe Qin   PetscErrorCode ierr;
14456bf688a0SCe Qin   PetscInt       i;
14466bf688a0SCe Qin   PetscFunctionBegin;
14476bf688a0SCe Qin 
14486bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
14496bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
14506bf688a0SCe Qin   for (i=0;i<3;++i) {
14516bf688a0SCe Qin     ierr = MatDestroy(&jac->RT_Pi[i]);CHKERRQ(ierr);
14526bf688a0SCe Qin     ierr = MatDestroy(&jac->ND_Pi[i]);CHKERRQ(ierr);
14536bf688a0SCe Qin   }
14546bf688a0SCe Qin 
14556bf688a0SCe Qin   jac->dim = dim;
14566bf688a0SCe Qin   if (RT_PiFull) {
14576bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)RT_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
14586bf688a0SCe Qin     if (ishypre) {
14596bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)RT_PiFull);CHKERRQ(ierr);
14606bf688a0SCe Qin       jac->RT_PiFull = RT_PiFull;
14616bf688a0SCe Qin     } else {
14626bf688a0SCe Qin       ierr = MatConvert(RT_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_PiFull);CHKERRQ(ierr);
14636bf688a0SCe Qin     }
14646bf688a0SCe Qin   }
14656bf688a0SCe Qin   if (RT_Pi) {
14666bf688a0SCe Qin     for (i=0;i<dim;++i) {
14676bf688a0SCe Qin       if (RT_Pi[i]) {
14686bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)RT_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
14696bf688a0SCe Qin         if (ishypre) {
14706bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)RT_Pi[i]);CHKERRQ(ierr);
14716bf688a0SCe Qin           jac->RT_Pi[i] = RT_Pi[i];
14726bf688a0SCe Qin         } else {
14736bf688a0SCe Qin           ierr = MatConvert(RT_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_Pi[i]);CHKERRQ(ierr);
14746bf688a0SCe Qin         }
14756bf688a0SCe Qin       }
14766bf688a0SCe Qin     }
14776bf688a0SCe Qin   }
14786bf688a0SCe Qin   if (ND_PiFull) {
14796bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)ND_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
14806bf688a0SCe Qin     if (ishypre) {
14816bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)ND_PiFull);CHKERRQ(ierr);
14826bf688a0SCe Qin       jac->ND_PiFull = ND_PiFull;
14836bf688a0SCe Qin     } else {
14846bf688a0SCe Qin       ierr = MatConvert(ND_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_PiFull);CHKERRQ(ierr);
14856bf688a0SCe Qin     }
14866bf688a0SCe Qin   }
14876bf688a0SCe Qin   if (ND_Pi) {
14886bf688a0SCe Qin     for (i=0;i<dim;++i) {
14896bf688a0SCe Qin       if (ND_Pi[i]) {
14906bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)ND_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
14916bf688a0SCe Qin         if (ishypre) {
14926bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)ND_Pi[i]);CHKERRQ(ierr);
14936bf688a0SCe Qin           jac->ND_Pi[i] = ND_Pi[i];
14946bf688a0SCe Qin         } else {
14956bf688a0SCe Qin           ierr = MatConvert(ND_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_Pi[i]);CHKERRQ(ierr);
14966bf688a0SCe Qin         }
14976bf688a0SCe Qin       }
14986bf688a0SCe Qin     }
14996bf688a0SCe Qin   }
15006bf688a0SCe Qin 
15016bf688a0SCe Qin   PetscFunctionReturn(0);
15026bf688a0SCe Qin }
15036bf688a0SCe Qin 
15046bf688a0SCe Qin /*@
15056bf688a0SCe Qin  PCHYPRESetInterpolations - Set interpolation matrices for AMS/ADS preconditioner
15066bf688a0SCe Qin 
15076bf688a0SCe Qin    Collective on PC
15086bf688a0SCe Qin 
15096bf688a0SCe Qin    Input Parameters:
15106bf688a0SCe Qin +  pc - the preconditioning context
15116bf688a0SCe Qin -  dim - the dimension of the problem, only used in AMS
15126bf688a0SCe Qin -  RT_PiFull - Raviart-Thomas interpolation matrix
15136bf688a0SCe Qin -  RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix
15146bf688a0SCe Qin -  ND_PiFull - Nedelec interpolation matrix
15156bf688a0SCe Qin -  ND_Pi - x/y/z component of Nedelec interpolation matrix
15166bf688a0SCe Qin 
151795452b02SPatrick Sanan    Notes:
151895452b02SPatrick Sanan     For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL.
15196bf688a0SCe Qin           For ADS, both type of interpolation matrices are needed.
15206bf688a0SCe Qin    Level: intermediate
15216bf688a0SCe Qin 
15226bf688a0SCe Qin .seealso:
15236bf688a0SCe Qin @*/
15246bf688a0SCe Qin PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
15256bf688a0SCe Qin {
15266bf688a0SCe Qin   PetscErrorCode ierr;
15276bf688a0SCe Qin   PetscInt       i;
15286bf688a0SCe Qin 
15296bf688a0SCe Qin   PetscFunctionBegin;
15306bf688a0SCe Qin   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15316bf688a0SCe Qin   if (RT_PiFull) {
15326bf688a0SCe Qin     PetscValidHeaderSpecific(RT_PiFull,MAT_CLASSID,3);
15336bf688a0SCe Qin     PetscCheckSameComm(pc,1,RT_PiFull,3);
15346bf688a0SCe Qin   }
15356bf688a0SCe Qin   if (RT_Pi) {
15366bf688a0SCe Qin     PetscValidPointer(RT_Pi,4);
15376bf688a0SCe Qin     for (i=0;i<dim;++i) {
15386bf688a0SCe Qin       if (RT_Pi[i]) {
15396bf688a0SCe Qin         PetscValidHeaderSpecific(RT_Pi[i],MAT_CLASSID,4);
15406bf688a0SCe Qin         PetscCheckSameComm(pc,1,RT_Pi[i],4);
15416bf688a0SCe Qin       }
15426bf688a0SCe Qin     }
15436bf688a0SCe Qin   }
15446bf688a0SCe Qin   if (ND_PiFull) {
15456bf688a0SCe Qin     PetscValidHeaderSpecific(ND_PiFull,MAT_CLASSID,5);
15466bf688a0SCe Qin     PetscCheckSameComm(pc,1,ND_PiFull,5);
15476bf688a0SCe Qin   }
15486bf688a0SCe Qin   if (ND_Pi) {
15496bf688a0SCe Qin     PetscValidPointer(ND_Pi,6);
15506bf688a0SCe Qin     for (i=0;i<dim;++i) {
15516bf688a0SCe Qin       if (ND_Pi[i]) {
15526bf688a0SCe Qin         PetscValidHeaderSpecific(ND_Pi[i],MAT_CLASSID,6);
15536bf688a0SCe Qin         PetscCheckSameComm(pc,1,ND_Pi[i],6);
15546bf688a0SCe Qin       }
15556bf688a0SCe Qin     }
15566bf688a0SCe Qin   }
15576bf688a0SCe Qin   ierr = PetscTryMethod(pc,"PCHYPRESetInterpolations_C",(PC,PetscInt,Mat,Mat[],Mat,Mat[]),(pc,dim,RT_PiFull,RT_Pi,ND_PiFull,ND_Pi));CHKERRQ(ierr);
15586bf688a0SCe Qin   PetscFunctionReturn(0);
15596bf688a0SCe Qin }
15606bf688a0SCe Qin 
15615ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha)
15624cb006feSStefano Zampini {
15634cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
15645ac14e1cSStefano Zampini   PetscBool      ishypre;
15654cb006feSStefano Zampini   PetscErrorCode ierr;
15664cb006feSStefano Zampini 
15674cb006feSStefano Zampini   PetscFunctionBegin;
15685ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr);
15695ac14e1cSStefano Zampini   if (ishypre) {
15705ac14e1cSStefano Zampini     if (isalpha) {
15715ac14e1cSStefano Zampini       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
15725ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
15735ac14e1cSStefano Zampini       jac->alpha_Poisson = A;
15745ac14e1cSStefano Zampini     } else {
15755ac14e1cSStefano Zampini       if (A) {
15765ac14e1cSStefano Zampini         ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
15775ac14e1cSStefano Zampini       } else {
15785ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
15795ac14e1cSStefano Zampini       }
15805ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
15815ac14e1cSStefano Zampini       jac->beta_Poisson = A;
15825ac14e1cSStefano Zampini     }
15835ac14e1cSStefano Zampini   } else {
15845ac14e1cSStefano Zampini     if (isalpha) {
15856bf688a0SCe Qin       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
15866bf688a0SCe Qin       ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->alpha_Poisson);CHKERRQ(ierr);
15875ac14e1cSStefano Zampini     } else {
15885ac14e1cSStefano Zampini       if (A) {
15896bf688a0SCe Qin         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
15906bf688a0SCe Qin         ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->beta_Poisson);CHKERRQ(ierr);
15915ac14e1cSStefano Zampini       } else {
15925ac14e1cSStefano Zampini         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
15935ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
15945ac14e1cSStefano Zampini       }
15955ac14e1cSStefano Zampini     }
15965ac14e1cSStefano Zampini   }
15974cb006feSStefano Zampini   PetscFunctionReturn(0);
15984cb006feSStefano Zampini }
15994cb006feSStefano Zampini 
16004cb006feSStefano Zampini /*@
16014cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
16024cb006feSStefano Zampini 
16034cb006feSStefano Zampini    Collective on PC
16044cb006feSStefano Zampini 
16054cb006feSStefano Zampini    Input Parameters:
16064cb006feSStefano Zampini +  pc - the preconditioning context
16074cb006feSStefano Zampini -  A - the matrix
16084cb006feSStefano Zampini 
16094cb006feSStefano Zampini    Level: intermediate
16104cb006feSStefano Zampini 
161195452b02SPatrick Sanan    Notes:
161295452b02SPatrick Sanan     A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
16134cb006feSStefano Zampini 
16144cb006feSStefano Zampini .seealso:
16154cb006feSStefano Zampini @*/
16164cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
16174cb006feSStefano Zampini {
16184cb006feSStefano Zampini   PetscErrorCode ierr;
16194cb006feSStefano Zampini 
16204cb006feSStefano Zampini   PetscFunctionBegin;
16214cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
16224cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
16234cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
16245ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_TRUE));CHKERRQ(ierr);
16254cb006feSStefano Zampini   PetscFunctionReturn(0);
16264cb006feSStefano Zampini }
16274cb006feSStefano Zampini 
16284cb006feSStefano Zampini /*@
16294cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
16304cb006feSStefano Zampini 
16314cb006feSStefano Zampini    Collective on PC
16324cb006feSStefano Zampini 
16334cb006feSStefano Zampini    Input Parameters:
16344cb006feSStefano Zampini +  pc - the preconditioning context
16354cb006feSStefano Zampini -  A - the matrix
16364cb006feSStefano Zampini 
16374cb006feSStefano Zampini    Level: intermediate
16384cb006feSStefano Zampini 
163995452b02SPatrick Sanan    Notes:
164095452b02SPatrick Sanan     A should be obtained by discretizing the Poisson problem with linear finite elements.
16414cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
16424cb006feSStefano Zampini 
16434cb006feSStefano Zampini .seealso:
16444cb006feSStefano Zampini @*/
16454cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
16464cb006feSStefano Zampini {
16474cb006feSStefano Zampini   PetscErrorCode ierr;
16484cb006feSStefano Zampini 
16494cb006feSStefano Zampini   PetscFunctionBegin;
16504cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
16514cb006feSStefano Zampini   if (A) {
16524cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
16534cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
16544cb006feSStefano Zampini   }
16555ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_FALSE));CHKERRQ(ierr);
16564cb006feSStefano Zampini   PetscFunctionReturn(0);
16574cb006feSStefano Zampini }
16584cb006feSStefano Zampini 
16595ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz, Vec zoz, Vec zzo)
16604cb006feSStefano Zampini {
16614cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
16624cb006feSStefano Zampini   PetscErrorCode     ierr;
16634cb006feSStefano Zampini 
16644cb006feSStefano Zampini   PetscFunctionBegin;
16654cb006feSStefano Zampini   /* throw away any vector if already set */
16666ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->constants[0]);CHKERRQ(ierr);
16676ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->constants[1]);CHKERRQ(ierr);
16686ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->constants[2]);CHKERRQ(ierr);
16696ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz->map,&jac->constants[0]);CHKERRQ(ierr);
16704cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
16716ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz->map,&jac->constants[1]);CHKERRQ(ierr);
16724cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
16735ac14e1cSStefano Zampini   jac->dim = 2;
16744cb006feSStefano Zampini   if (zzo) {
16756ea7df73SStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo->map,&jac->constants[2]);CHKERRQ(ierr);
16764cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
16775ac14e1cSStefano Zampini     jac->dim++;
16784cb006feSStefano Zampini   }
16794cb006feSStefano Zampini   PetscFunctionReturn(0);
16804cb006feSStefano Zampini }
16814cb006feSStefano Zampini 
16824cb006feSStefano Zampini /*@
16834cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
16844cb006feSStefano Zampini 
16854cb006feSStefano Zampini    Collective on PC
16864cb006feSStefano Zampini 
16874cb006feSStefano Zampini    Input Parameters:
16884cb006feSStefano Zampini +  pc - the preconditioning context
16894cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
16904cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
16914cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
16924cb006feSStefano Zampini 
16934cb006feSStefano Zampini    Level: intermediate
16944cb006feSStefano Zampini 
16954cb006feSStefano Zampini    Notes:
16964cb006feSStefano Zampini 
16974cb006feSStefano Zampini .seealso:
16984cb006feSStefano Zampini @*/
16994cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
17004cb006feSStefano Zampini {
17014cb006feSStefano Zampini   PetscErrorCode ierr;
17024cb006feSStefano Zampini 
17034cb006feSStefano Zampini   PetscFunctionBegin;
17044cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
17054cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
17064cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
17074cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
17084cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
17094cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
17104cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
17114cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
17124cb006feSStefano Zampini   PetscFunctionReturn(0);
17134cb006feSStefano Zampini }
17144cb006feSStefano Zampini 
1715863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
17164cb006feSStefano Zampini {
17174cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
17184cb006feSStefano Zampini   Vec             tv;
17194cb006feSStefano Zampini   PetscInt        i;
17204cb006feSStefano Zampini   PetscErrorCode  ierr;
17214cb006feSStefano Zampini 
17224cb006feSStefano Zampini   PetscFunctionBegin;
17234cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
17246ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->coords[0]);CHKERRQ(ierr);
17256ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->coords[1]);CHKERRQ(ierr);
17266ea7df73SStefano Zampini   ierr = VecHYPRE_IJVectorDestroy(&jac->coords[2]);CHKERRQ(ierr);
17275ac14e1cSStefano Zampini   jac->dim = dim;
17285ac14e1cSStefano Zampini 
17294cb006feSStefano Zampini   /* compute IJ vector for coordinates */
17304cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
17314cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
17324cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
17334cb006feSStefano Zampini   for (i=0;i<dim;i++) {
17344cb006feSStefano Zampini     PetscScalar *array;
17354cb006feSStefano Zampini     PetscInt    j;
17364cb006feSStefano Zampini 
17376ea7df73SStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv->map,&jac->coords[i]);CHKERRQ(ierr);
1738589dcaf0SStefano Zampini     ierr = VecGetArrayWrite(tv,&array);CHKERRQ(ierr);
17396ea7df73SStefano Zampini     for (j=0;j<nloc;j++) array[j] = coords[j*dim+i];
1740589dcaf0SStefano Zampini     ierr = VecRestoreArrayWrite(tv,&array);CHKERRQ(ierr);
17416ea7df73SStefano Zampini     ierr = VecHYPRE_IJVectorCopy(tv,jac->coords[i]);CHKERRQ(ierr);
17424cb006feSStefano Zampini   }
17434cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
17444cb006feSStefano Zampini   PetscFunctionReturn(0);
17454cb006feSStefano Zampini }
17464cb006feSStefano Zampini 
174716d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
174816d9e3a6SLisandro Dalcin 
1749f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
175016d9e3a6SLisandro Dalcin {
175116d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
175216d9e3a6SLisandro Dalcin 
175316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
175416d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
175516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
175616d9e3a6SLisandro Dalcin }
175716d9e3a6SLisandro Dalcin 
1758f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
175916d9e3a6SLisandro Dalcin {
176016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
176116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1762ace3abfcSBarry Smith   PetscBool      flag;
176316d9e3a6SLisandro Dalcin 
176416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
176516d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
176616d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1767ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
176816d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
176916d9e3a6SLisandro Dalcin   } else {
177016d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
177116d9e3a6SLisandro Dalcin   }
177216d9e3a6SLisandro Dalcin 
177316d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
177416d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
177516d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
177616d9e3a6SLisandro Dalcin 
177716d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
177816d9e3a6SLisandro Dalcin   if (flag) {
1779ffc4695bSBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRMPI(ierr);
1780fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
178116d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
178216d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
178316d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
178416d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
178516d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
178616d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
178716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
178816d9e3a6SLisandro Dalcin   }
1789db966c6cSHong Zhang   ierr = PetscStrcmp("euclid",jac->hypre_type,&flag);CHKERRQ(ierr);
1790db966c6cSHong Zhang   if (flag) {
17918bf83915SBarry Smith #if defined(PETSC_HAVE_64BIT_INDICES)
17928bf83915SBarry Smith     SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Hypre Euclid not support with 64 bit indices");
17938bf83915SBarry Smith #endif
1794ffc4695bSBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRMPI(ierr);
1795db966c6cSHong Zhang     PetscStackCallStandard(HYPRE_EuclidCreate,(jac->comm_hypre,&jac->hsolver));
1796db966c6cSHong Zhang     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
1797db966c6cSHong Zhang     pc->ops->view           = PCView_HYPRE_Euclid;
1798db966c6cSHong Zhang     jac->destroy            = HYPRE_EuclidDestroy;
1799db966c6cSHong Zhang     jac->setup              = HYPRE_EuclidSetup;
1800db966c6cSHong Zhang     jac->solve              = HYPRE_EuclidSolve;
1801db966c6cSHong Zhang     jac->factorrowsize      = PETSC_DEFAULT;
1802db966c6cSHong Zhang     jac->eu_level           = PETSC_DEFAULT; /* default */
1803db966c6cSHong Zhang     PetscFunctionReturn(0);
1804db966c6cSHong Zhang   }
180516d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
180616d9e3a6SLisandro Dalcin   if (flag) {
1807ffc4695bSBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRMPI(ierr);
1808fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
180916d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
181016d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
181116d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
181216d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
181316d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
181416d9e3a6SLisandro Dalcin     /* initialize */
181516d9e3a6SLisandro Dalcin     jac->nlevels   = 1;
18168966356dSPierre Jolivet     jac->threshold = .1;
181716d9e3a6SLisandro Dalcin     jac->filter    = .1;
181816d9e3a6SLisandro Dalcin     jac->loadbal   = 0;
18192fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
18202fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
18212fa5cd67SKarl Rupp 
182216d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
182316d9e3a6SLisandro Dalcin     jac->symt = 0;
18248966356dSPierre Jolivet     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshold,jac->nlevels));
1825fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1826fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1827fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1828fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1829fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
183016d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
183116d9e3a6SLisandro Dalcin   }
183216d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
183316d9e3a6SLisandro Dalcin   if (flag) {
183416d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
183516d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
183616d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
183716d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
183816d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
1839fd2dd295SFande Kong     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",PCGetInterpolations_BoomerAMG);CHKERRQ(ierr);
1840fd2dd295SFande Kong     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",PCGetCoarseOperators_BoomerAMG);CHKERRQ(ierr);
184116d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
184216d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
184316d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
184416d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
184516d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
184616d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
184716d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
184816d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
18498f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
185016d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
185116d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
185216d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
185316d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
185416d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
18550f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
18566a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1857b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
18581810e44eSEike Mueller     jac->eu_level         = 0;
18591810e44eSEike Mueller     jac->eu_droptolerance = 0;
18601810e44eSEike Mueller     jac->eu_bj            = 0;
1861589dcaf0SStefano Zampini     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a PC - most likely with CG */
18620f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
186316d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
186416d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
186516d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
18660f1074feSSatish Balay     jac->interptype       = 0;
1867589dcaf0SStefano Zampini     jac->Rtype            = 0;
1868589dcaf0SStefano Zampini     jac->Rstrongthreshold = 0.25;
1869589dcaf0SStefano Zampini     jac->Rfilterthreshold = 0.0;
1870589dcaf0SStefano Zampini     jac->Adroptype        = -1;
1871589dcaf0SStefano Zampini     jac->Adroptol         = 0.0;
18720f1074feSSatish Balay     jac->agg_nl           = 0;
18736ea7df73SStefano Zampini     jac->agg_interptype   = 4;
18740f1074feSSatish Balay     jac->pmax             = 0;
18750f1074feSSatish Balay     jac->truncfactor      = 0.0;
18760f1074feSSatish Balay     jac->agg_num_paths    = 1;
1877589dcaf0SStefano Zampini     jac->maxc             = 9;
1878589dcaf0SStefano Zampini     jac->minc             = 1;
18798f87f92bSBarry Smith 
188022e51d31SStefano Zampini     jac->nodal_coarsening      = 0;
188122e51d31SStefano Zampini     jac->nodal_coarsening_diag = 0;
188222e51d31SStefano Zampini     jac->vec_interp_variant    = 0;
188322e51d31SStefano Zampini     jac->vec_interp_qmax       = 0;
188422e51d31SStefano Zampini     jac->vec_interp_smooth     = PETSC_FALSE;
188522e51d31SStefano Zampini     jac->interp_refine         = 0;
18868f87f92bSBarry Smith     jac->nodal_relax           = PETSC_FALSE;
18878f87f92bSBarry Smith     jac->nodal_relax_levels    = 1;
18886ea7df73SStefano Zampini     jac->rap2                  = 0;
18896ea7df73SStefano Zampini 
18906ea7df73SStefano Zampini     /* GPU defaults
18916ea7df73SStefano Zampini          from https://hypre.readthedocs.io/en/latest/solvers-boomeramg.html#gpu-supported-options
18926ea7df73SStefano Zampini          and /src/parcsr_ls/par_amg.c */
18936ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE)
18946ea7df73SStefano Zampini     jac->keeptranspose         = PETSC_TRUE;
18956ea7df73SStefano Zampini     jac->mod_rap2              = 1;
18966ea7df73SStefano Zampini     jac->coarsentype           = 8;
18976ea7df73SStefano Zampini     jac->relaxorder            = 0;
18986ea7df73SStefano Zampini     jac->interptype            = 6;
18996ea7df73SStefano Zampini     jac->relaxtype[0]          = 18;
19006ea7df73SStefano Zampini     jac->relaxtype[1]          = 18;
19016ea7df73SStefano Zampini     jac->agg_interptype        = 7;
19026ea7df73SStefano Zampini #else
19036ea7df73SStefano Zampini     jac->keeptranspose         = PETSC_FALSE;
19046ea7df73SStefano Zampini     jac->mod_rap2              = 0;
19056ea7df73SStefano Zampini #endif
1906fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1907fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1908fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1909fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1910fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1911fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1912fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1913fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1914fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1915fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1916fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1917fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
19186ea7df73SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetAggInterpType,(jac->hsolver,jac->agg_interptype));
1919fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1920fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1921fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /* defaults coarse to 9 */
1922fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /* defaults coarse to 1 */
1923589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxCoarseSize,(jac->hsolver, jac->maxc));
1924589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetMinCoarseSize,(jac->hsolver, jac->minc));
1925589dcaf0SStefano Zampini 
19266ea7df73SStefano Zampini     /* GPU */
19276ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0)
19286ea7df73SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetKeepTranspose,(jac->hsolver,jac->keeptranspose ? 1 : 0));
19296ea7df73SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetRAP2,(jac->hsolver, jac->rap2));
19306ea7df73SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetModuleRAP2,(jac->hsolver, jac->mod_rap2));
19316ea7df73SStefano Zampini #endif
19326ea7df73SStefano Zampini 
1933589dcaf0SStefano Zampini     /* AIR */
19346ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0)
1935589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetRestriction,(jac->hsolver,jac->Rtype));
1936589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThresholdR,(jac->hsolver,jac->Rstrongthreshold));
1937589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetFilterThresholdR,(jac->hsolver,jac->Rfilterthreshold));
1938589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetADropTol,(jac->hsolver,jac->Adroptol));
1939589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetADropType,(jac->hsolver,jac->Adroptype));
19406ea7df73SStefano Zampini #endif
194116d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
194216d9e3a6SLisandro Dalcin   }
19434cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
19444cb006feSStefano Zampini   if (flag) {
19454cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
19464cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
19474cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
19484cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
19494cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
19504cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
19514cb006feSStefano Zampini     jac->coords[0]           = NULL;
19524cb006feSStefano Zampini     jac->coords[1]           = NULL;
19534cb006feSStefano Zampini     jac->coords[2]           = NULL;
19544cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1955863406b8SStefano Zampini     jac->as_print           = 0;
1956863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1957863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
19584cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
19594cb006feSStefano Zampini     /* Smoothing options */
1960863406b8SStefano Zampini     jac->as_relax_type      = 2;
1961863406b8SStefano Zampini     jac->as_relax_times     = 1;
1962863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1963863406b8SStefano Zampini     jac->as_omega           = 1.0;
19644cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1965863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1966863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
19670bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1968863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1969863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1970863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
19714cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1972863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1973863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
19740bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1975863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1976863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1977863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1978863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1979863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
19804cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1981863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1982863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1983863406b8SStefano Zampini                                                                       jac->as_relax_times,
1984863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1985863406b8SStefano Zampini                                                                       jac->as_omega));
1986863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1987863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1988863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1989863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1990863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1991863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1992863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1993863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1994863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1995863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1996863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1997863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
199823df4f25SStefano Zampini     /* Zero conductivity */
199923df4f25SStefano Zampini     jac->ams_beta_is_zero      = PETSC_FALSE;
200023df4f25SStefano Zampini     jac->ams_beta_is_zero_part = PETSC_FALSE;
20014cb006feSStefano Zampini     PetscFunctionReturn(0);
20024cb006feSStefano Zampini   }
2003863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
2004863406b8SStefano Zampini   if (flag) {
2005863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
2006863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
2007863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
2008863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
2009863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
2010863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
2011863406b8SStefano Zampini     jac->coords[0]           = NULL;
2012863406b8SStefano Zampini     jac->coords[1]           = NULL;
2013863406b8SStefano Zampini     jac->coords[2]           = NULL;
2014863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
2015863406b8SStefano Zampini     jac->as_print           = 0;
2016863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
2017863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
2018863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
2019863406b8SStefano Zampini     /* Smoothing options */
2020863406b8SStefano Zampini     jac->as_relax_type      = 2;
2021863406b8SStefano Zampini     jac->as_relax_times     = 1;
2022863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
2023863406b8SStefano Zampini     jac->as_omega           = 1.0;
2024863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
2025863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
2026863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
2027863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
2028863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
2029863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
2030863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
2031863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
2032863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
2033863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
2034863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
2035863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
2036863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
2037863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
2038863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
2039863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
2040863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
2041863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
2042863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
2043863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
2044863406b8SStefano Zampini                                                                       jac->as_relax_times,
2045863406b8SStefano Zampini                                                                       jac->as_relax_weight,
2046863406b8SStefano Zampini                                                                       jac->as_omega));
2047863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
2048863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
2049863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
2050863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
2051863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
2052863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
2053863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
2054863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
2055863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
2056863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
2057863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
2058863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
2059863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
2060863406b8SStefano Zampini     PetscFunctionReturn(0);
2061863406b8SStefano Zampini   }
2062503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
20632fa5cd67SKarl Rupp 
20640298fd71SBarry Smith   jac->hypre_type = NULL;
2065db966c6cSHong Zhang   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams",name);
206616d9e3a6SLisandro Dalcin }
206716d9e3a6SLisandro Dalcin 
206816d9e3a6SLisandro Dalcin /*
206916d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
207016d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
207116d9e3a6SLisandro Dalcin */
2072360ee056SFande Kong PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc)
207316d9e3a6SLisandro Dalcin {
207416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
20754ddd07fcSJed Brown   PetscInt       indx;
2076db966c6cSHong Zhang   const char     *type[] = {"euclid","pilut","parasails","boomeramg","ams","ads"};
2077ace3abfcSBarry Smith   PetscBool      flg;
207816d9e3a6SLisandro Dalcin 
207916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
20809fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
2081cab5ea25SPierre Jolivet   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,ALEN(type),"boomeramg",&indx,&flg);CHKERRQ(ierr);
208216d9e3a6SLisandro Dalcin   if (flg) {
208316d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
208402a17cd4SBarry Smith   } else {
208502a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
208616d9e3a6SLisandro Dalcin   }
208716d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
20883931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
208916d9e3a6SLisandro Dalcin   }
209016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
209116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
209216d9e3a6SLisandro Dalcin }
209316d9e3a6SLisandro Dalcin 
209416d9e3a6SLisandro Dalcin /*@C
209516d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
209616d9e3a6SLisandro Dalcin 
209716d9e3a6SLisandro Dalcin    Input Parameters:
209816d9e3a6SLisandro Dalcin +     pc - the preconditioner context
2099db966c6cSHong Zhang -     name - either  euclid, pilut, parasails, boomeramg, ams, ads
210016d9e3a6SLisandro Dalcin 
210116d9e3a6SLisandro Dalcin    Options Database Keys:
2102db966c6cSHong Zhang    -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
210316d9e3a6SLisandro Dalcin 
210416d9e3a6SLisandro Dalcin    Level: intermediate
210516d9e3a6SLisandro Dalcin 
210616d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
210716d9e3a6SLisandro Dalcin            PCHYPRE
210816d9e3a6SLisandro Dalcin 
210916d9e3a6SLisandro Dalcin @*/
21107087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
211116d9e3a6SLisandro Dalcin {
21124ac538c5SBarry Smith   PetscErrorCode ierr;
211316d9e3a6SLisandro Dalcin 
211416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
21150700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
211616d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
21174ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
211816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
211916d9e3a6SLisandro Dalcin }
212016d9e3a6SLisandro Dalcin 
212116d9e3a6SLisandro Dalcin /*@C
212216d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
212316d9e3a6SLisandro Dalcin 
212416d9e3a6SLisandro Dalcin    Input Parameter:
212516d9e3a6SLisandro Dalcin .     pc - the preconditioner context
212616d9e3a6SLisandro Dalcin 
212716d9e3a6SLisandro Dalcin    Output Parameter:
2128db966c6cSHong Zhang .     name - either  euclid, pilut, parasails, boomeramg, ams, ads
212916d9e3a6SLisandro Dalcin 
213016d9e3a6SLisandro Dalcin    Level: intermediate
213116d9e3a6SLisandro Dalcin 
213216d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
213316d9e3a6SLisandro Dalcin            PCHYPRE
213416d9e3a6SLisandro Dalcin 
213516d9e3a6SLisandro Dalcin @*/
21367087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
213716d9e3a6SLisandro Dalcin {
21384ac538c5SBarry Smith   PetscErrorCode ierr;
213916d9e3a6SLisandro Dalcin 
214016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
21410700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
214216d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
21434ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
214416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
214516d9e3a6SLisandro Dalcin }
214616d9e3a6SLisandro Dalcin 
214716d9e3a6SLisandro Dalcin /*MC
214816d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
214916d9e3a6SLisandro Dalcin 
215016d9e3a6SLisandro Dalcin    Options Database Keys:
2151db966c6cSHong Zhang +   -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
215216d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
215316d9e3a6SLisandro Dalcin           preconditioner
215416d9e3a6SLisandro Dalcin 
215516d9e3a6SLisandro Dalcin    Level: intermediate
215616d9e3a6SLisandro Dalcin 
215795452b02SPatrick Sanan    Notes:
215895452b02SPatrick Sanan     Apart from pc_hypre_type (for which there is PCHYPRESetType()),
215916d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
216016d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
216116d9e3a6SLisandro Dalcin 
2162c231f9e3SBarryFSmith           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_tol refer to the number of iterations
21630f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
21640f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
2165c231f9e3SBarryFSmith           (-pc_hypre_boomeramg_tol should be set to 0.0 - the default - to strictly use a fixed number of
21668f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
21670f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
21680f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
216916d9e3a6SLisandro Dalcin 
21700f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
21710f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
21720f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
217316d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
217416d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
217516d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
217616d9e3a6SLisandro Dalcin 
217716d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
217816d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
217916d9e3a6SLisandro Dalcin 
21805272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
2181fdd15c9aSJunchao Zhang           the following two options:
21820b1a5bd9SEric Chamberland 
2183fdd15c9aSJunchao Zhang    Options Database Keys:
21845272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
2185fdd15c9aSJunchao Zhang -   -pc_hypre_boomeramg_vec_interp_variant <v> - where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
21865272c319SBarry Smith 
21875272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
21885272c319SBarry Smith 
21899e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
21909e5bc791SBarry Smith 
219116d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
21929e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
219316d9e3a6SLisandro Dalcin 
219416d9e3a6SLisandro Dalcin M*/
219516d9e3a6SLisandro Dalcin 
21968cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
219716d9e3a6SLisandro Dalcin {
219816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
219916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
220016d9e3a6SLisandro Dalcin 
220116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
2202b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
22032fa5cd67SKarl Rupp 
220416d9e3a6SLisandro Dalcin   pc->data                = jac;
22058695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
220616d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
220716d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
220816d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
220916d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
221016d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
2211bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
2212bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
22135ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
22145ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
22155ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
22166bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",PCHYPRESetInterpolations_HYPRE);CHKERRQ(ierr);
22175ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE);CHKERRQ(ierr);
22185ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",PCHYPRESetPoissonMatrix_HYPRE);CHKERRQ(ierr);
22196ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE)
22206ea7df73SStefano Zampini #if defined(HYPRE_USING_HIP)
2221*a4af0ceeSJacob Faibussowitsch   ierr = PetscDeviceInitialize(PETSC_DEVICE_HIP);CHKERRQ(ierr);
22226ea7df73SStefano Zampini #endif
22236ea7df73SStefano Zampini #if defined(HYPRE_USING_CUDA)
2224*a4af0ceeSJacob Faibussowitsch   ierr = PetscDeviceInitialize(PETSC_DEVICE_CUDA);CHKERRQ(ierr);
22256ea7df73SStefano Zampini #endif
22266ea7df73SStefano Zampini #endif
222716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
222816d9e3a6SLisandro Dalcin }
2229ebc551c0SBarry Smith 
2230f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
2231f91d8e95SBarry Smith 
2232ebc551c0SBarry Smith typedef struct {
223368326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
2234f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
22359e5bc791SBarry Smith 
22369e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
22374ddd07fcSJed Brown   PetscInt its;
22389e5bc791SBarry Smith   double   tol;
22394ddd07fcSJed Brown   PetscInt relax_type;
22404ddd07fcSJed Brown   PetscInt rap_type;
22414ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
22424ddd07fcSJed Brown   PetscInt max_levels;
2243ebc551c0SBarry Smith } PC_PFMG;
2244ebc551c0SBarry Smith 
2245ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
2246ebc551c0SBarry Smith {
2247ebc551c0SBarry Smith   PetscErrorCode ierr;
2248f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2249ebc551c0SBarry Smith 
2250ebc551c0SBarry Smith   PetscFunctionBegin;
22512fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2252ffc4695bSBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRMPI(ierr);
2253c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2254ebc551c0SBarry Smith   PetscFunctionReturn(0);
2255ebc551c0SBarry Smith }
2256ebc551c0SBarry Smith 
22579e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
22589e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
22599e5bc791SBarry Smith 
2260ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
2261ebc551c0SBarry Smith {
2262ebc551c0SBarry Smith   PetscErrorCode ierr;
2263ace3abfcSBarry Smith   PetscBool      iascii;
2264f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2265ebc551c0SBarry Smith 
2266ebc551c0SBarry Smith   PetscFunctionBegin;
2267251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
22689e5bc791SBarry Smith   if (iascii) {
22699e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
2270efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max iterations %d\n",ex->its);CHKERRQ(ierr);
2271efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    tolerance %g\n",ex->tol);CHKERRQ(ierr);
2272efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2273efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
2274efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2275efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max levels %d\n",ex->max_levels);CHKERRQ(ierr);
22769e5bc791SBarry Smith   }
2277ebc551c0SBarry Smith   PetscFunctionReturn(0);
2278ebc551c0SBarry Smith }
2279ebc551c0SBarry Smith 
22804416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2281ebc551c0SBarry Smith {
2282ebc551c0SBarry Smith   PetscErrorCode ierr;
2283f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2284ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2285ebc551c0SBarry Smith 
2286ebc551c0SBarry Smith   PetscFunctionBegin;
2287e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
22880298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
228968326731SBarry Smith   if (flg) {
22905bd1e576SStefano Zampini     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,3));
229168326731SBarry Smith   }
22920298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2293fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
22940298fd71SBarry 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);
2295fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
22960298fd71SBarry 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);
2297fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
22989e5bc791SBarry Smith 
22990298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
2300fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
23013b46a515SGlenn Hammond 
23020298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2303fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
23040298fd71SBarry 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);
2305fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
23060298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
2307fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
2308ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
2309ebc551c0SBarry Smith   PetscFunctionReturn(0);
2310ebc551c0SBarry Smith }
2311ebc551c0SBarry Smith 
2312f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
2313f91d8e95SBarry Smith {
2314f91d8e95SBarry Smith   PetscErrorCode    ierr;
2315f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
2316d9ca1df4SBarry Smith   PetscScalar       *yy;
2317d9ca1df4SBarry Smith   const PetscScalar *xx;
23184ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
23192cf14000SStefano Zampini   HYPRE_Int         hlower[3],hupper[3];
232068326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2321f91d8e95SBarry Smith 
2322f91d8e95SBarry Smith   PetscFunctionBegin;
2323dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2324aa219208SBarry Smith   ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
23252cf14000SStefano Zampini   /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
2326f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
2327f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
2328f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
23292cf14000SStefano Zampini   hlower[0]  = (HYPRE_Int)ilower[0];
23302cf14000SStefano Zampini   hlower[1]  = (HYPRE_Int)ilower[1];
23312cf14000SStefano Zampini   hlower[2]  = (HYPRE_Int)ilower[2];
23322cf14000SStefano Zampini   hupper[0]  = (HYPRE_Int)iupper[0];
23332cf14000SStefano Zampini   hupper[1]  = (HYPRE_Int)iupper[1];
23342cf14000SStefano Zampini   hupper[2]  = (HYPRE_Int)iupper[2];
2335f91d8e95SBarry Smith 
2336f91d8e95SBarry Smith   /* copy x values over to hypre */
2337fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
2338d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
233939accc25SStefano Zampini   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,hlower,hupper,(HYPRE_Complex*)xx));
2340d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2341fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
2342fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2343f91d8e95SBarry Smith 
2344f91d8e95SBarry Smith   /* copy solution values back to PETSc */
2345f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
234639accc25SStefano Zampini   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,hlower,hupper,(HYPRE_Complex*)yy));
2347f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2348f91d8e95SBarry Smith   PetscFunctionReturn(0);
2349f91d8e95SBarry Smith }
2350f91d8e95SBarry Smith 
2351ace3abfcSBarry 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)
23529e5bc791SBarry Smith {
23539e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
23549e5bc791SBarry Smith   PetscErrorCode ierr;
23552cf14000SStefano Zampini   HYPRE_Int      oits;
23569e5bc791SBarry Smith 
23579e5bc791SBarry Smith   PetscFunctionBegin;
2358dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2359fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
2360fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
23619e5bc791SBarry Smith 
23629e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
23632cf14000SStefano Zampini   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,&oits));
23649e5bc791SBarry Smith   *outits = oits;
23659e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
23669e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2367fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
2368fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
23699e5bc791SBarry Smith   PetscFunctionReturn(0);
23709e5bc791SBarry Smith }
23719e5bc791SBarry Smith 
23723a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
23733a32d3dbSGlenn Hammond {
23743a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
23753a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
23763a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2377ace3abfcSBarry Smith   PetscBool       flg;
23783a32d3dbSGlenn Hammond 
23793a32d3dbSGlenn Hammond   PetscFunctionBegin;
2380251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
2381ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
23823a32d3dbSGlenn Hammond 
23833a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
23842fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2385fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2386fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2387fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
23883a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
23893a32d3dbSGlenn Hammond }
23903a32d3dbSGlenn Hammond 
2391ebc551c0SBarry Smith /*MC
2392ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
2393ebc551c0SBarry Smith 
2394ebc551c0SBarry Smith    Level: advanced
2395ebc551c0SBarry Smith 
23969e5bc791SBarry Smith    Options Database:
23979e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
23989e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
23999e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
24009e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
24019e5bc791SBarry 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
24029e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
2403f91d8e95SBarry Smith 
240495452b02SPatrick Sanan    Notes:
240595452b02SPatrick Sanan     This is for CELL-centered descretizations
24069e5bc791SBarry Smith 
24078e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
2408aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
24099e5bc791SBarry Smith 
24109e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
2411ebc551c0SBarry Smith M*/
2412ebc551c0SBarry Smith 
24138cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
2414ebc551c0SBarry Smith {
2415ebc551c0SBarry Smith   PetscErrorCode ierr;
2416ebc551c0SBarry Smith   PC_PFMG        *ex;
2417ebc551c0SBarry Smith 
2418ebc551c0SBarry Smith   PetscFunctionBegin;
2419b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
242068326731SBarry Smith   pc->data = ex;
2421ebc551c0SBarry Smith 
24229e5bc791SBarry Smith   ex->its            = 1;
24239e5bc791SBarry Smith   ex->tol            = 1.e-8;
24249e5bc791SBarry Smith   ex->relax_type     = 1;
24259e5bc791SBarry Smith   ex->rap_type       = 0;
24269e5bc791SBarry Smith   ex->num_pre_relax  = 1;
24279e5bc791SBarry Smith   ex->num_post_relax = 1;
24283b46a515SGlenn Hammond   ex->max_levels     = 0;
24299e5bc791SBarry Smith 
2430ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2431ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2432ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2433f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
24349e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
243568326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
24362fa5cd67SKarl Rupp 
2437ffc4695bSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRMPI(ierr);
2438fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2439ebc551c0SBarry Smith   PetscFunctionReturn(0);
2440ebc551c0SBarry Smith }
2441d851a50bSGlenn Hammond 
2442325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2443325fc9f4SBarry Smith 
2444d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2445d851a50bSGlenn Hammond typedef struct {
2446d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2447d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2448d851a50bSGlenn Hammond 
2449d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
24504ddd07fcSJed Brown   PetscInt its;
2451d851a50bSGlenn Hammond   double   tol;
24524ddd07fcSJed Brown   PetscInt relax_type;
24534ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2454d851a50bSGlenn Hammond } PC_SysPFMG;
2455d851a50bSGlenn Hammond 
2456d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2457d851a50bSGlenn Hammond {
2458d851a50bSGlenn Hammond   PetscErrorCode ierr;
2459d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2460d851a50bSGlenn Hammond 
2461d851a50bSGlenn Hammond   PetscFunctionBegin;
24622fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2463ffc4695bSBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRMPI(ierr);
2464c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2465d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2466d851a50bSGlenn Hammond }
2467d851a50bSGlenn Hammond 
2468d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2469d851a50bSGlenn Hammond 
2470d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2471d851a50bSGlenn Hammond {
2472d851a50bSGlenn Hammond   PetscErrorCode ierr;
2473ace3abfcSBarry Smith   PetscBool      iascii;
2474d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2475d851a50bSGlenn Hammond 
2476d851a50bSGlenn Hammond   PetscFunctionBegin;
2477251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2478d851a50bSGlenn Hammond   if (iascii) {
2479d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2480efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  max iterations %d\n",ex->its);CHKERRQ(ierr);
2481efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerance %g\n",ex->tol);CHKERRQ(ierr);
2482efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2483efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2484d851a50bSGlenn Hammond   }
2485d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2486d851a50bSGlenn Hammond }
2487d851a50bSGlenn Hammond 
24884416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2489d851a50bSGlenn Hammond {
2490d851a50bSGlenn Hammond   PetscErrorCode ierr;
2491d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2492ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2493d851a50bSGlenn Hammond 
2494d851a50bSGlenn Hammond   PetscFunctionBegin;
2495e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
24960298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2497d851a50bSGlenn Hammond   if (flg) {
24985bd1e576SStefano Zampini     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,3));
2499d851a50bSGlenn Hammond   }
25000298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2501fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
25020298fd71SBarry 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);
2503fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
25040298fd71SBarry 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);
2505fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2506d851a50bSGlenn Hammond 
25070298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2508fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
250961710fbeSStefano 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);
2510fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2511d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2512d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2513d851a50bSGlenn Hammond }
2514d851a50bSGlenn Hammond 
2515d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2516d851a50bSGlenn Hammond {
2517d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2518d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2519d9ca1df4SBarry Smith   PetscScalar       *yy;
2520d9ca1df4SBarry Smith   const PetscScalar *xx;
25214ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
25222cf14000SStefano Zampini   HYPRE_Int         hlower[3],hupper[3];
2523d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
25244ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
25254ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
25264ddd07fcSJed Brown   PetscInt          part    = 0;
25274ddd07fcSJed Brown   PetscInt          size;
25284ddd07fcSJed Brown   PetscInt          i;
2529d851a50bSGlenn Hammond 
2530d851a50bSGlenn Hammond   PetscFunctionBegin;
2531dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2532aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
25332cf14000SStefano Zampini   /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
2534d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2535d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2536d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
25372cf14000SStefano Zampini   hlower[0]  = (HYPRE_Int)ilower[0];
25382cf14000SStefano Zampini   hlower[1]  = (HYPRE_Int)ilower[1];
25392cf14000SStefano Zampini   hlower[2]  = (HYPRE_Int)ilower[2];
25402cf14000SStefano Zampini   hupper[0]  = (HYPRE_Int)iupper[0];
25412cf14000SStefano Zampini   hupper[1]  = (HYPRE_Int)iupper[1];
25422cf14000SStefano Zampini   hupper[2]  = (HYPRE_Int)iupper[2];
2543d851a50bSGlenn Hammond 
2544d851a50bSGlenn Hammond   size = 1;
25452fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
25462fa5cd67SKarl Rupp 
2547d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2548d851a50bSGlenn Hammond   if (ordering) {
2549fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2550d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
255139accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(xx+(size*i))));
2552d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2553fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2554fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2555fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2556d851a50bSGlenn Hammond 
2557d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2558d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
255939accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(yy+(size*i))));
2560d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2561a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2562d851a50bSGlenn Hammond     PetscScalar *z;
25634ddd07fcSJed Brown     PetscInt    j, k;
2564d851a50bSGlenn Hammond 
2565785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2566fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2567d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2568d851a50bSGlenn Hammond 
2569d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2570d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2571d851a50bSGlenn Hammond       k= i*nvars;
25722fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2573d851a50bSGlenn Hammond     }
257439accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i))));
2575d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2576fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2577fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2578d851a50bSGlenn Hammond 
2579d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2580d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
258139accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i))));
2582d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2583d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2584d851a50bSGlenn Hammond       k= i*nvars;
25852fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2586d851a50bSGlenn Hammond     }
2587d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2588d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2589d851a50bSGlenn Hammond   }
2590d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2591d851a50bSGlenn Hammond }
2592d851a50bSGlenn Hammond 
2593ace3abfcSBarry 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)
2594d851a50bSGlenn Hammond {
2595d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2596d851a50bSGlenn Hammond   PetscErrorCode ierr;
25972cf14000SStefano Zampini   HYPRE_Int      oits;
2598d851a50bSGlenn Hammond 
2599d851a50bSGlenn Hammond   PetscFunctionBegin;
2600dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2601fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2602fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2603d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
26042cf14000SStefano Zampini   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,&oits));
2605d851a50bSGlenn Hammond   *outits = oits;
2606d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2607d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2608fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2609fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2610d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2611d851a50bSGlenn Hammond }
2612d851a50bSGlenn Hammond 
2613d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2614d851a50bSGlenn Hammond {
2615d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2616d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2617d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2618ace3abfcSBarry Smith   PetscBool        flg;
2619d851a50bSGlenn Hammond 
2620d851a50bSGlenn Hammond   PetscFunctionBegin;
2621251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2622ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2623d851a50bSGlenn Hammond 
2624d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
26252fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2626fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2627fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2628fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2629d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2630d851a50bSGlenn Hammond }
2631d851a50bSGlenn Hammond 
2632d851a50bSGlenn Hammond /*MC
2633d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2634d851a50bSGlenn Hammond 
2635d851a50bSGlenn Hammond    Level: advanced
2636d851a50bSGlenn Hammond 
2637d851a50bSGlenn Hammond    Options Database:
2638d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2639d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2640d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2641d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2642a2b725a8SWilliam Gropp - -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2643d851a50bSGlenn Hammond 
264495452b02SPatrick Sanan    Notes:
264595452b02SPatrick Sanan     This is for CELL-centered descretizations
2646d851a50bSGlenn Hammond 
2647f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2648aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2649d851a50bSGlenn Hammond            Also, only cell-centered variables.
2650d851a50bSGlenn Hammond 
2651d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2652d851a50bSGlenn Hammond M*/
2653d851a50bSGlenn Hammond 
26548cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2655d851a50bSGlenn Hammond {
2656d851a50bSGlenn Hammond   PetscErrorCode ierr;
2657d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2658d851a50bSGlenn Hammond 
2659d851a50bSGlenn Hammond   PetscFunctionBegin;
2660b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2661d851a50bSGlenn Hammond   pc->data = ex;
2662d851a50bSGlenn Hammond 
2663d851a50bSGlenn Hammond   ex->its            = 1;
2664d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2665d851a50bSGlenn Hammond   ex->relax_type     = 1;
2666d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2667d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2668d851a50bSGlenn Hammond 
2669d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2670d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2671d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2672d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2673d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2674d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
26752fa5cd67SKarl Rupp 
2676ffc4695bSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRMPI(ierr);
2677fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2678d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2679d851a50bSGlenn Hammond }
2680