xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 589dcaf07fd26677a8cdbdcb936941dbb1fc089f)
116d9e3a6SLisandro Dalcin /*
216d9e3a6SLisandro Dalcin    Provides an interface to the LLNL package hypre
316d9e3a6SLisandro Dalcin */
40f1074feSSatish Balay 
5*589dcaf0SStefano 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>
958968eb6SStefano Zampini #include <../src/vec/vec/impls/hypre/vhyp.h>
1049a781f5SStefano Zampini #include <../src/mat/impls/hypre/mhypre.h>
11c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h>
124cb006feSStefano Zampini #include <_hypre_parcsr_ls.h>
138a2c336bSFande Kong #include <petscmathypre.h>
1416d9e3a6SLisandro Dalcin 
15dff31646SBarry Smith static PetscBool cite = PETSC_FALSE;
16a8d69d7bSBarry 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";
171f817a21SBarry Smith 
1816d9e3a6SLisandro Dalcin /*
1916d9e3a6SLisandro Dalcin    Private context (data structure) for the  preconditioner.
2016d9e3a6SLisandro Dalcin */
2116d9e3a6SLisandro Dalcin typedef struct {
2216d9e3a6SLisandro Dalcin   HYPRE_Solver   hsolver;
2349a781f5SStefano Zampini   Mat            hpmat; /* MatHYPRE */
2416d9e3a6SLisandro Dalcin 
254ddd07fcSJed Brown   HYPRE_Int (*destroy)(HYPRE_Solver);
264ddd07fcSJed Brown   HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
274ddd07fcSJed Brown   HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
2816d9e3a6SLisandro Dalcin 
2916d9e3a6SLisandro Dalcin   MPI_Comm comm_hypre;
3016d9e3a6SLisandro Dalcin   char     *hypre_type;
3116d9e3a6SLisandro Dalcin 
3216d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
334ddd07fcSJed Brown   PetscInt  maxiter;
3439accc25SStefano Zampini   PetscReal tol;
3516d9e3a6SLisandro Dalcin 
3616d9e3a6SLisandro Dalcin   /* options for Pilut */
374ddd07fcSJed Brown   PetscInt factorrowsize;
3816d9e3a6SLisandro Dalcin 
3916d9e3a6SLisandro Dalcin   /* options for ParaSails */
404ddd07fcSJed Brown   PetscInt  nlevels;
418966356dSPierre Jolivet   PetscReal threshold;
4239accc25SStefano Zampini   PetscReal filter;
4339accc25SStefano Zampini   PetscReal loadbal;
444ddd07fcSJed Brown   PetscInt  logging;
454ddd07fcSJed Brown   PetscInt  ruse;
464ddd07fcSJed Brown   PetscInt  symt;
4716d9e3a6SLisandro Dalcin 
4822b6d1caSBarry Smith   /* options for BoomerAMG */
49ace3abfcSBarry Smith   PetscBool printstatistics;
5016d9e3a6SLisandro Dalcin 
5116d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
524ddd07fcSJed Brown   PetscInt  cycletype;
534ddd07fcSJed Brown   PetscInt  maxlevels;
5439accc25SStefano Zampini   PetscReal strongthreshold;
5539accc25SStefano Zampini   PetscReal maxrowsum;
564ddd07fcSJed Brown   PetscInt  gridsweeps[3];
574ddd07fcSJed Brown   PetscInt  coarsentype;
584ddd07fcSJed Brown   PetscInt  measuretype;
596a251517SEike Mueller   PetscInt  smoothtype;
608131ecf7SEike Mueller   PetscInt  smoothnumlevels;
61ec64516dSEike Mueller   PetscInt  eu_level;   /* Number of levels for ILU(k) in Euclid */
6239accc25SStefano Zampini   PetscReal eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */
63ec64516dSEike Mueller   PetscInt  eu_bj;      /* Defines use of Block Jacobi ILU in Euclid */
644ddd07fcSJed Brown   PetscInt  relaxtype[3];
6539accc25SStefano Zampini   PetscReal relaxweight;
6639accc25SStefano Zampini   PetscReal outerrelaxweight;
674ddd07fcSJed Brown   PetscInt  relaxorder;
6839accc25SStefano Zampini   PetscReal truncfactor;
69ace3abfcSBarry Smith   PetscBool applyrichardson;
704ddd07fcSJed Brown   PetscInt  pmax;
714ddd07fcSJed Brown   PetscInt  interptype;
72*589dcaf0SStefano Zampini   PetscInt  maxc;
73*589dcaf0SStefano Zampini   PetscInt  minc;
74*589dcaf0SStefano Zampini 
75*589dcaf0SStefano Zampini   /* AIR */
76*589dcaf0SStefano Zampini   PetscInt  Rtype;
77*589dcaf0SStefano Zampini   PetscReal Rstrongthreshold;
78*589dcaf0SStefano Zampini   PetscReal Rfilterthreshold;
79*589dcaf0SStefano Zampini   PetscInt  Adroptype;
80*589dcaf0SStefano Zampini   PetscReal Adroptol;
81*589dcaf0SStefano Zampini 
824ddd07fcSJed Brown   PetscInt  agg_nl;
834ddd07fcSJed Brown   PetscInt  agg_num_paths;
84ace3abfcSBarry Smith   PetscBool nodal_relax;
854ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
86*589dcaf0SStefano Zampini   PetscBool keeptranspose;
874cb006feSStefano Zampini 
885272c319SBarry Smith   PetscInt  nodal_coarsening;
8922e51d31SStefano Zampini   PetscInt  nodal_coarsening_diag;
905272c319SBarry Smith   PetscInt  vec_interp_variant;
9122e51d31SStefano Zampini   PetscInt  vec_interp_qmax;
9222e51d31SStefano Zampini   PetscBool vec_interp_smooth;
9322e51d31SStefano Zampini   PetscInt  interp_refine;
9422e51d31SStefano Zampini 
955272c319SBarry Smith   HYPRE_IJVector  *hmnull;
965272c319SBarry Smith   HYPRE_ParVector *phmnull;  /* near null space passed to hypre */
975272c319SBarry Smith   PetscInt        n_hmnull;
985272c319SBarry Smith   Vec             hmnull_constant;
9939accc25SStefano Zampini   HYPRE_Complex   **hmnull_hypre_data_array;   /* this is the space in hmnull that was allocated by hypre, it is restored to hypre just before freeing the phmnull vectors */
1005272c319SBarry Smith 
101863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
102863406b8SStefano Zampini   PetscInt  as_print;
103863406b8SStefano Zampini   PetscInt  as_max_iter;
104863406b8SStefano Zampini   PetscReal as_tol;
105863406b8SStefano Zampini   PetscInt  as_relax_type;
106863406b8SStefano Zampini   PetscInt  as_relax_times;
107863406b8SStefano Zampini   PetscReal as_relax_weight;
108863406b8SStefano Zampini   PetscReal as_omega;
109863406b8SStefano 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) */
110863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
111863406b8SStefano 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) */
112863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
1134cb006feSStefano Zampini   PetscInt  ams_cycle_type;
114863406b8SStefano Zampini   PetscInt  ads_cycle_type;
1154cb006feSStefano Zampini 
1164cb006feSStefano Zampini   /* additional data */
1175ac14e1cSStefano Zampini   Mat G;             /* MatHYPRE */
1185ac14e1cSStefano Zampini   Mat C;             /* MatHYPRE */
1195ac14e1cSStefano Zampini   Mat alpha_Poisson; /* MatHYPRE */
1205ac14e1cSStefano Zampini   Mat beta_Poisson;  /* MatHYPRE */
1215ac14e1cSStefano Zampini 
1225ac14e1cSStefano Zampini   /* extra information for AMS */
1235ac14e1cSStefano Zampini   PetscInt       dim; /* geometrical dimension */
1244cb006feSStefano Zampini   HYPRE_IJVector coords[3];
1254cb006feSStefano Zampini   HYPRE_IJVector constants[3];
1266bf688a0SCe Qin   Mat            RT_PiFull, RT_Pi[3];
1276bf688a0SCe Qin   Mat            ND_PiFull, ND_Pi[3];
1284cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
12923df4f25SStefano Zampini   PetscBool      ams_beta_is_zero_part;
13023df4f25SStefano Zampini   PetscInt       ams_proj_freq;
13116d9e3a6SLisandro Dalcin } PC_HYPRE;
13216d9e3a6SLisandro Dalcin 
133d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
134d2128fa2SBarry Smith {
135d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
136d2128fa2SBarry Smith 
137d2128fa2SBarry Smith   PetscFunctionBegin;
138d2128fa2SBarry Smith   *hsolver = jac->hsolver;
139d2128fa2SBarry Smith   PetscFunctionReturn(0);
140d2128fa2SBarry Smith }
14116d9e3a6SLisandro Dalcin 
142fd2dd295SFande Kong /*
1438a2c336bSFande Kong   Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix
1448a2c336bSFande Kong   is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine.
1458a2c336bSFande Kong   It is used in PCHMG. Other users should avoid using this function.
146fd2dd295SFande Kong */
147fd2dd295SFande Kong static PetscErrorCode PCGetCoarseOperators_BoomerAMG(PC pc,PetscInt *nlevels,Mat *operators[])
1488a2c336bSFande Kong {
1498a2c336bSFande Kong   PC_HYPRE             *jac  = (PC_HYPRE*)pc->data;
1508a2c336bSFande Kong   PetscBool            same = PETSC_FALSE;
1518a2c336bSFande Kong   PetscErrorCode       ierr;
1528a2c336bSFande Kong   PetscInt             num_levels,l;
1538a2c336bSFande Kong   Mat                  *mattmp;
1548a2c336bSFande Kong   hypre_ParCSRMatrix   **A_array;
1558a2c336bSFande Kong 
1568a2c336bSFande Kong   PetscFunctionBegin;
1578a2c336bSFande Kong   ierr = PetscStrcmp(jac->hypre_type,"boomeramg",&same);CHKERRQ(ierr);
1588a2c336bSFande Kong   if (!same) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_NOTSAMETYPE,"Hypre type is not BoomerAMG \n");
1598a2c336bSFande Kong   num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData*) (jac->hsolver));
1608a2c336bSFande Kong   ierr = PetscMalloc1(num_levels,&mattmp);CHKERRQ(ierr);
1618a2c336bSFande Kong   A_array    = hypre_ParAMGDataAArray((hypre_ParAMGData*) (jac->hsolver));
1628a2c336bSFande Kong   for (l=1; l<num_levels; l++) {
1638a2c336bSFande Kong     ierr = MatCreateFromParCSR(A_array[l],MATAIJ,PETSC_OWN_POINTER, &(mattmp[num_levels-1-l]));CHKERRQ(ierr);
1648a2c336bSFande Kong     /* We want to own the data, and HYPRE can not touch this matrix any more */
1658a2c336bSFande Kong     A_array[l] = NULL;
1668a2c336bSFande Kong   }
1678a2c336bSFande Kong   *nlevels = num_levels;
1688a2c336bSFande Kong   *operators = mattmp;
1698a2c336bSFande Kong   PetscFunctionReturn(0);
1708a2c336bSFande Kong }
1718a2c336bSFande Kong 
172fd2dd295SFande Kong /*
1738a2c336bSFande Kong   Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix
1748a2c336bSFande Kong   is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine.
1758a2c336bSFande Kong   It is used in PCHMG. Other users should avoid using this function.
176fd2dd295SFande Kong */
177fd2dd295SFande Kong static PetscErrorCode PCGetInterpolations_BoomerAMG(PC pc,PetscInt *nlevels,Mat *interpolations[])
1788a2c336bSFande Kong {
1798a2c336bSFande Kong   PC_HYPRE             *jac  = (PC_HYPRE*)pc->data;
1808a2c336bSFande Kong   PetscBool            same = PETSC_FALSE;
1818a2c336bSFande Kong   PetscErrorCode       ierr;
1828a2c336bSFande Kong   PetscInt             num_levels,l;
1838a2c336bSFande Kong   Mat                  *mattmp;
1848a2c336bSFande Kong   hypre_ParCSRMatrix   **P_array;
1858a2c336bSFande Kong 
1868a2c336bSFande Kong   PetscFunctionBegin;
1878a2c336bSFande Kong   ierr = PetscStrcmp(jac->hypre_type,"boomeramg",&same);CHKERRQ(ierr);
1888a2c336bSFande Kong   if (!same) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_NOTSAMETYPE,"Hypre type is not BoomerAMG \n");
1898a2c336bSFande Kong   num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData*) (jac->hsolver));
1908a2c336bSFande Kong   ierr = PetscMalloc1(num_levels,&mattmp);CHKERRQ(ierr);
1918a2c336bSFande Kong   P_array  = hypre_ParAMGDataPArray((hypre_ParAMGData*) (jac->hsolver));
1928a2c336bSFande Kong   for (l=1; l<num_levels; l++) {
1938a2c336bSFande Kong     ierr = MatCreateFromParCSR(P_array[num_levels-1-l],MATAIJ,PETSC_OWN_POINTER, &(mattmp[l-1]));CHKERRQ(ierr);
1948a2c336bSFande Kong     /* We want to own the data, and HYPRE can not touch this matrix any more */
1958a2c336bSFande Kong     P_array[num_levels-1-l] = NULL;
1968a2c336bSFande Kong   }
1978a2c336bSFande Kong   *nlevels = num_levels;
1988a2c336bSFande Kong   *interpolations = mattmp;
1998a2c336bSFande Kong   PetscFunctionReturn(0);
2008a2c336bSFande Kong }
2018a2c336bSFande Kong 
202ce6a8a0dSJed Brown /* Resets (frees) Hypre's representation of the near null space */
203ce6a8a0dSJed Brown static PetscErrorCode PCHYPREResetNearNullSpace_Private(PC pc)
204ce6a8a0dSJed Brown {
205ce6a8a0dSJed Brown   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
206ce6a8a0dSJed Brown   PetscInt       i;
2079d678128SJed Brown   PetscErrorCode ierr;
208ce6a8a0dSJed Brown 
2099d678128SJed Brown   PetscFunctionBegin;
210ce6a8a0dSJed Brown   for (i=0; i<jac->n_hmnull; i++) {
21139accc25SStefano Zampini     PETSC_UNUSED HYPRE_Complex *harray;
21239accc25SStefano Zampini     VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],jac->hmnull_hypre_data_array[i],harray);
213ce6a8a0dSJed Brown     PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->hmnull[i]));
214ce6a8a0dSJed Brown   }
215ce6a8a0dSJed Brown   ierr = PetscFree(jac->hmnull);CHKERRQ(ierr);
216ce6a8a0dSJed Brown   ierr = PetscFree(jac->hmnull_hypre_data_array);CHKERRQ(ierr);
217ce6a8a0dSJed Brown   ierr = PetscFree(jac->phmnull);CHKERRQ(ierr);
218ce6a8a0dSJed Brown   ierr = VecDestroy(&jac->hmnull_constant);CHKERRQ(ierr);
2199d678128SJed Brown   jac->n_hmnull = 0;
220ce6a8a0dSJed Brown   PetscFunctionReturn(0);
221ce6a8a0dSJed Brown }
222ce6a8a0dSJed Brown 
22316d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
22416d9e3a6SLisandro Dalcin {
22516d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
22649a781f5SStefano Zampini   Mat_HYPRE          *hjac;
22716d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
22816d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
22949a781f5SStefano Zampini   PetscBool          ishypre;
23049a781f5SStefano Zampini   PetscErrorCode     ierr;
23116d9e3a6SLisandro Dalcin 
23216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
23316d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
23402a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
23516d9e3a6SLisandro Dalcin   }
2365f5c5b43SBarry Smith 
23749a781f5SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRE,&ishypre);CHKERRQ(ierr);
23849a781f5SStefano Zampini   if (!ishypre) {
2396bf688a0SCe Qin     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
2406bf688a0SCe Qin     ierr = MatConvert(pc->pmat,MATHYPRE,MAT_INITIAL_MATRIX,&jac->hpmat);CHKERRQ(ierr);
241*589dcaf0SStefano Zampini     ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)jac->hpmat);CHKERRQ(ierr);
24249a781f5SStefano Zampini   } else {
24349a781f5SStefano Zampini     ierr = PetscObjectReference((PetscObject)pc->pmat);CHKERRQ(ierr);
24449a781f5SStefano Zampini     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
24549a781f5SStefano Zampini     jac->hpmat = pc->pmat;
24616d9e3a6SLisandro Dalcin   }
24749a781f5SStefano Zampini   hjac = (Mat_HYPRE*)(jac->hpmat->data);
2485f5c5b43SBarry Smith 
24916d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
25016d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
2515272c319SBarry Smith     MatNullSpace    mnull;
2525272c319SBarry Smith     PetscBool       has_const;
25349a781f5SStefano Zampini     PetscInt        bs,nvec,i;
2545272c319SBarry Smith     const Vec       *vecs;
25539accc25SStefano Zampini     HYPRE_Complex   *petscvecarray;
2565272c319SBarry Smith 
25716d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
2582fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
2595272c319SBarry Smith     ierr = MatGetNearNullSpace(pc->mat, &mnull);CHKERRQ(ierr);
2605272c319SBarry Smith     if (mnull) {
261ce6a8a0dSJed Brown       ierr = PCHYPREResetNearNullSpace_Private(pc);CHKERRQ(ierr);
2625272c319SBarry Smith       ierr = MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs);CHKERRQ(ierr);
2635272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull);CHKERRQ(ierr);
26472827435SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull_hypre_data_array);CHKERRQ(ierr);
2655272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->phmnull);CHKERRQ(ierr);
2665272c319SBarry Smith       for (i=0; i<nvec; i++) {
2675272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(vecs[i],&jac->hmnull[i]);CHKERRQ(ierr);
26872827435SBarry Smith         ierr = VecGetArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
26958968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],petscvecarray,jac->hmnull_hypre_data_array[i]);
27072827435SBarry Smith         ierr = VecRestoreArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
2715272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[i],(void**)&jac->phmnull[i]));
2725272c319SBarry Smith       }
2735272c319SBarry Smith       if (has_const) {
2745272c319SBarry Smith         ierr = MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL);CHKERRQ(ierr);
275*589dcaf0SStefano Zampini         ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)jac->hmnull_constant);CHKERRQ(ierr);
2765272c319SBarry Smith         ierr = VecSet(jac->hmnull_constant,1);CHKERRQ(ierr);
2775272c319SBarry Smith         ierr = VecNormalize(jac->hmnull_constant,NULL);
2785272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(jac->hmnull_constant,&jac->hmnull[nvec]);CHKERRQ(ierr);
27972827435SBarry Smith         ierr = VecGetArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
28058968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[nvec],petscvecarray,jac->hmnull_hypre_data_array[nvec]);
28172827435SBarry Smith         ierr = VecRestoreArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
2825272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[nvec],(void**)&jac->phmnull[nvec]));
2835272c319SBarry Smith         nvec++;
2845272c319SBarry Smith       }
2855272c319SBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVectors,(jac->hsolver,nvec,jac->phmnull));
2865272c319SBarry Smith       jac->n_hmnull = nvec;
2875272c319SBarry Smith     }
2884cb006feSStefano Zampini   }
289863406b8SStefano Zampini 
2904cb006feSStefano Zampini   /* special case for AMS */
2914cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
2925ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2935ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
2946bf688a0SCe Qin     if (!jac->coords[0] && !jac->constants[0] && !(jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
2956bf688a0SCe 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");
2966bf688a0SCe Qin     }
2975ac14e1cSStefano Zampini     if (jac->dim) {
2985ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,jac->dim));
2995ac14e1cSStefano Zampini     }
3005ac14e1cSStefano Zampini     if (jac->constants[0]) {
3015ac14e1cSStefano Zampini       HYPRE_ParVector ozz,zoz,zzo = NULL;
3025ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&ozz)));
3035ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&zoz)));
3045ac14e1cSStefano Zampini       if (jac->constants[2]) {
3055ac14e1cSStefano Zampini         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&zzo)));
3065ac14e1cSStefano Zampini       }
3075ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,ozz,zoz,zzo));
3085ac14e1cSStefano Zampini     }
3095ac14e1cSStefano Zampini     if (jac->coords[0]) {
3105ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
3115ac14e1cSStefano Zampini       coords[0] = NULL;
3125ac14e1cSStefano Zampini       coords[1] = NULL;
3135ac14e1cSStefano Zampini       coords[2] = NULL;
3145ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
3155ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
3165ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
3175ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
3185ac14e1cSStefano Zampini     }
31949a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
3205ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
3215ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3225ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr));
3235ac14e1cSStefano Zampini     if (jac->alpha_Poisson) {
3245ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->alpha_Poisson->data);
3255ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3265ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr));
3275ac14e1cSStefano Zampini     }
3285ac14e1cSStefano Zampini     if (jac->ams_beta_is_zero) {
3295ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
3305ac14e1cSStefano Zampini     } else if (jac->beta_Poisson) {
3315ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->beta_Poisson->data);
3325ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3335ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr));
3345ac14e1cSStefano Zampini     }
3356bf688a0SCe Qin     if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) {
3366bf688a0SCe Qin       PetscInt           i;
3376bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
3386bf688a0SCe Qin       if (jac->ND_PiFull) {
3396bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
3406bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
3416bf688a0SCe Qin       } else {
3426bf688a0SCe Qin         nd_parcsrfull = NULL;
3436bf688a0SCe Qin       }
3446bf688a0SCe Qin       for (i=0;i<3;++i) {
3456bf688a0SCe Qin         if (jac->ND_Pi[i]) {
3466bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
3476bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
3486bf688a0SCe Qin         } else {
3496bf688a0SCe Qin           nd_parcsr[i] = NULL;
3506bf688a0SCe Qin         }
3516bf688a0SCe Qin       }
3526bf688a0SCe Qin       PetscStackCallStandard(HYPRE_AMSSetInterpolations,(jac->hsolver,nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]));
3536bf688a0SCe Qin     }
3544cb006feSStefano Zampini   }
355863406b8SStefano Zampini   /* special case for ADS */
356863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
3575ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
3585ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
3596bf688a0SCe 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])))) {
3606bf688a0SCe Qin       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations");
3616bf688a0SCe Qin     }
36237096e45SBarry 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");
36349a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
36449a781f5SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient");
3655ac14e1cSStefano Zampini     if (jac->coords[0]) {
3665ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
3675ac14e1cSStefano Zampini       coords[0] = NULL;
3685ac14e1cSStefano Zampini       coords[1] = NULL;
3695ac14e1cSStefano Zampini       coords[2] = NULL;
3705ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
3715ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
3725ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
3735ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_ADSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
3745ac14e1cSStefano Zampini     }
3755ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
3765ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3775ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteGradient,(jac->hsolver,parcsr));
3785ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->C->data);
3795ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3805ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteCurl,(jac->hsolver,parcsr));
3816bf688a0SCe Qin     if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
3826bf688a0SCe Qin       PetscInt           i;
3836bf688a0SCe Qin       HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3];
3846bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
3856bf688a0SCe Qin       if (jac->RT_PiFull) {
3866bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->RT_PiFull->data);
3876bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsrfull)));
3886bf688a0SCe Qin       } else {
3896bf688a0SCe Qin         rt_parcsrfull = NULL;
3906bf688a0SCe Qin       }
3916bf688a0SCe Qin       for (i=0;i<3;++i) {
3926bf688a0SCe Qin         if (jac->RT_Pi[i]) {
3936bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->RT_Pi[i]->data);
3946bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsr[i])));
3956bf688a0SCe Qin         } else {
3966bf688a0SCe Qin           rt_parcsr[i] = NULL;
3976bf688a0SCe Qin         }
3986bf688a0SCe Qin       }
3996bf688a0SCe Qin       if (jac->ND_PiFull) {
4006bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
4016bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
4026bf688a0SCe Qin       } else {
4036bf688a0SCe Qin         nd_parcsrfull = NULL;
4046bf688a0SCe Qin       }
4056bf688a0SCe Qin       for (i=0;i<3;++i) {
4066bf688a0SCe Qin         if (jac->ND_Pi[i]) {
4076bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
4086bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
4096bf688a0SCe Qin         } else {
4106bf688a0SCe Qin           nd_parcsr[i] = NULL;
4116bf688a0SCe Qin         }
4126bf688a0SCe Qin       }
4136bf688a0SCe 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]));
4146bf688a0SCe Qin     }
415863406b8SStefano Zampini   }
41649a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
41749a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&bv));
41849a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&xv));
41922e51d31SStefano Zampini   PetscStackCallStandard(jac->setup,(jac->hsolver,hmat,bv,xv));
42016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
42116d9e3a6SLisandro Dalcin }
42216d9e3a6SLisandro Dalcin 
42316d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
42416d9e3a6SLisandro Dalcin {
42516d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
42649a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
42716d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
42816d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
42939accc25SStefano Zampini   HYPRE_Complex      *xv,*sxv;
43039accc25SStefano Zampini   HYPRE_Complex      *bv,*sbv;
43116d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
4324ddd07fcSJed Brown   PetscInt           hierr;
43316d9e3a6SLisandro Dalcin 
43416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
435dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
43616d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
43739accc25SStefano Zampini   ierr = VecGetArrayRead(b,(const PetscScalar **)&bv);CHKERRQ(ierr);
438*589dcaf0SStefano Zampini   ierr = VecGetArrayWrite(x,(PetscScalar **)&xv);CHKERRQ(ierr);
43939accc25SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,bv,sbv);
44058968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
44116d9e3a6SLisandro Dalcin 
44249a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
44349a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
44449a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
445fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
44665e19b50SBarry Smith   if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
447fd3f9acdSBarry Smith   if (hierr) hypre__global_error = 0;);
44816d9e3a6SLisandro Dalcin 
44923df4f25SStefano Zampini   if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) {
4505ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSProjectOutGradients,(jac->hsolver,jxv));
45121df291bSStefano Zampini   }
45239accc25SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,sbv,bv);
45358968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
454*589dcaf0SStefano Zampini   ierr = VecRestoreArrayWrite(x,(PetscScalar **)&xv);CHKERRQ(ierr);
45539accc25SStefano Zampini   ierr = VecRestoreArrayRead(b,(const PetscScalar **)&bv);CHKERRQ(ierr);
45616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
45716d9e3a6SLisandro Dalcin }
45816d9e3a6SLisandro Dalcin 
4598695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc)
4608695de01SBarry Smith {
4618695de01SBarry Smith   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
4628695de01SBarry Smith   PetscErrorCode ierr;
4638695de01SBarry Smith 
4648695de01SBarry Smith   PetscFunctionBegin;
46549a781f5SStefano Zampini   ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
4665ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
4675ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
4685ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
4695ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
4706bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
4716bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[0]);CHKERRQ(ierr);
4726bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[1]);CHKERRQ(ierr);
4736bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[2]);CHKERRQ(ierr);
4746bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
4756bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[0]);CHKERRQ(ierr);
4766bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[1]);CHKERRQ(ierr);
4776bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[2]);CHKERRQ(ierr);
4788695de01SBarry Smith   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); jac->coords[0] = NULL;
4798695de01SBarry Smith   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); jac->coords[1] = NULL;
4808695de01SBarry Smith   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); jac->coords[2] = NULL;
4818695de01SBarry Smith   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); jac->constants[0] = NULL;
4828695de01SBarry Smith   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); jac->constants[1] = NULL;
4838695de01SBarry Smith   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); jac->constants[2] = NULL;
484ce6a8a0dSJed Brown   ierr = PCHYPREResetNearNullSpace_Private(pc);CHKERRQ(ierr);
4855ac14e1cSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
4865ac14e1cSStefano Zampini   jac->dim = 0;
4878695de01SBarry Smith   PetscFunctionReturn(0);
4888695de01SBarry Smith }
4898695de01SBarry Smith 
49016d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
49116d9e3a6SLisandro Dalcin {
49216d9e3a6SLisandro Dalcin   PC_HYPRE                 *jac = (PC_HYPRE*)pc->data;
49316d9e3a6SLisandro Dalcin   PetscErrorCode           ierr;
49416d9e3a6SLisandro Dalcin 
49516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
4968695de01SBarry Smith   ierr = PCReset_HYPRE(pc);CHKERRQ(ierr);
49722e51d31SStefano Zampini   if (jac->destroy) PetscStackCallStandard(jac->destroy,(jac->hsolver));
498503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
499ffc4695bSBarry Smith   if (jac->comm_hypre != MPI_COMM_NULL) {ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRMPI(ierr);}
500c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
50116d9e3a6SLisandro Dalcin 
50216d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
503bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
504bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
5054cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
5064cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
507863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
5086bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",NULL);CHKERRQ(ierr);
5094cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
5105ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",NULL);CHKERRQ(ierr);
511fd2dd295SFande Kong   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",NULL);CHKERRQ(ierr);
512fd2dd295SFande Kong   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",NULL);CHKERRQ(ierr);
51316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
51416d9e3a6SLisandro Dalcin }
51516d9e3a6SLisandro Dalcin 
51616d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
5174416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptionItems *PetscOptionsObject,PC pc)
51816d9e3a6SLisandro Dalcin {
51916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
52016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
521ace3abfcSBarry Smith   PetscBool      flag;
52216d9e3a6SLisandro Dalcin 
52316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
524e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
52516d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
526fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
52716d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
528fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
52916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
530fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
53116d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
53216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
53316d9e3a6SLisandro Dalcin }
53416d9e3a6SLisandro Dalcin 
53516d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
53616d9e3a6SLisandro Dalcin {
53716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
53816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
539ace3abfcSBarry Smith   PetscBool      iascii;
54016d9e3a6SLisandro Dalcin 
54116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
542251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
54316d9e3a6SLisandro Dalcin   if (iascii) {
54416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
54516d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
546efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
54716d9e3a6SLisandro Dalcin     } else {
548efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default maximum number of iterations \n");CHKERRQ(ierr);
54916d9e3a6SLisandro Dalcin     }
55016d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
551efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
55216d9e3a6SLisandro Dalcin     } else {
553efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default drop tolerance \n");CHKERRQ(ierr);
55416d9e3a6SLisandro Dalcin     }
55516d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
556efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
55716d9e3a6SLisandro Dalcin     } else {
558efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default factor row size \n");CHKERRQ(ierr);
55916d9e3a6SLisandro Dalcin     }
56016d9e3a6SLisandro Dalcin   }
56116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
56216d9e3a6SLisandro Dalcin }
56316d9e3a6SLisandro Dalcin 
56416d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
565db966c6cSHong Zhang static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PetscOptionItems *PetscOptionsObject,PC pc)
566db966c6cSHong Zhang {
567db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
568db966c6cSHong Zhang   PetscErrorCode ierr;
5698bf83915SBarry Smith   PetscBool      flag,eu_bj = jac->eu_bj ? PETSC_TRUE : PETSC_FALSE;
570db966c6cSHong Zhang 
571db966c6cSHong Zhang   PetscFunctionBegin;
572db966c6cSHong Zhang   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Euclid Options");CHKERRQ(ierr);
573db966c6cSHong Zhang   ierr = PetscOptionsInt("-pc_hypre_euclid_level","Factorization levels","None",jac->eu_level,&jac->eu_level,&flag);CHKERRQ(ierr);
574db966c6cSHong Zhang   if (flag) PetscStackCallStandard(HYPRE_EuclidSetLevel,(jac->hsolver,jac->eu_level));
5758bf83915SBarry Smith 
5768bf83915SBarry Smith   ierr = PetscOptionsReal("-pc_hypre_euclid_droptolerance","Drop tolerance for ILU(k) in Euclid","None",jac->eu_droptolerance,&jac->eu_droptolerance,&flag);CHKERRQ(ierr);
5778bf83915SBarry Smith   if (flag){
5788bf83915SBarry Smith     PetscMPIInt size;
5798bf83915SBarry Smith 
58055b25c41SPierre Jolivet     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRMPI(ierr);
5818bf83915SBarry Smith     if (size > 1) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"hypre's Euclid does not support a parallel drop tolerance");
5828bf83915SBarry Smith     PetscStackCallStandard(HYPRE_EuclidSetILUT,(jac->hsolver,jac->eu_droptolerance));
5838bf83915SBarry Smith   }
5848bf83915SBarry Smith 
5858bf83915SBarry Smith   ierr = PetscOptionsBool("-pc_hypre_euclid_bj", "Use Block Jacobi for ILU in Euclid", "None", eu_bj,&eu_bj,&flag);CHKERRQ(ierr);
5868bf83915SBarry Smith   if (flag) {
5878bf83915SBarry Smith     jac->eu_bj = eu_bj ? 1 : 0;
5888bf83915SBarry Smith     PetscStackCallStandard(HYPRE_EuclidSetBJ,(jac->hsolver,jac->eu_bj));
5898bf83915SBarry Smith   }
590db966c6cSHong Zhang   ierr = PetscOptionsTail();CHKERRQ(ierr);
591db966c6cSHong Zhang   PetscFunctionReturn(0);
592db966c6cSHong Zhang }
593db966c6cSHong Zhang 
594db966c6cSHong Zhang static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer)
595db966c6cSHong Zhang {
596db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
597db966c6cSHong Zhang   PetscErrorCode ierr;
598db966c6cSHong Zhang   PetscBool      iascii;
599db966c6cSHong Zhang 
600db966c6cSHong Zhang   PetscFunctionBegin;
601db966c6cSHong Zhang   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
602db966c6cSHong Zhang   if (iascii) {
603db966c6cSHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid preconditioning\n");CHKERRQ(ierr);
604db966c6cSHong Zhang     if (jac->eu_level != PETSC_DEFAULT) {
605db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    factorization levels %d\n",jac->eu_level);CHKERRQ(ierr);
606db966c6cSHong Zhang     } else {
607db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    default factorization levels \n");CHKERRQ(ierr);
608db966c6cSHong Zhang     }
6098bf83915SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->eu_droptolerance);CHKERRQ(ierr);
6108bf83915SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    use Block-Jacobi? %D\n",jac->eu_bj);CHKERRQ(ierr);
611db966c6cSHong Zhang   }
612db966c6cSHong Zhang   PetscFunctionReturn(0);
613db966c6cSHong Zhang }
614db966c6cSHong Zhang 
615db966c6cSHong Zhang /* --------------------------------------------------------------------------------------------*/
61616d9e3a6SLisandro Dalcin 
61716d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
61816d9e3a6SLisandro Dalcin {
61916d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
62049a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
62116d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
62216d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
62339accc25SStefano Zampini   HYPRE_Complex      *xv,*bv;
62439accc25SStefano Zampini   HYPRE_Complex      *sbv,*sxv;
62516d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
6264ddd07fcSJed Brown   PetscInt           hierr;
62716d9e3a6SLisandro Dalcin 
62816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
629dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
63016d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
63139accc25SStefano Zampini   ierr = VecGetArrayRead(b,(const PetscScalar**)&bv);CHKERRQ(ierr);
63239accc25SStefano Zampini   ierr = VecGetArray(x,(PetscScalar**)&xv);CHKERRQ(ierr);
63339accc25SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,bv,sbv);
63458968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
63516d9e3a6SLisandro Dalcin 
63649a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
63749a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
63849a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
63916d9e3a6SLisandro Dalcin 
64016d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
64116d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
642e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
64316d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
64416d9e3a6SLisandro Dalcin 
64558968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,sbv,bv);
64658968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
64739accc25SStefano Zampini   ierr = VecRestoreArray(x,(PetscScalar**)&xv);CHKERRQ(ierr);
64839accc25SStefano Zampini   ierr = VecRestoreArrayRead(b,(const PetscScalar**)&bv);CHKERRQ(ierr);
64916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
65016d9e3a6SLisandro Dalcin }
65116d9e3a6SLisandro Dalcin 
652a669f990SJed Brown /* static array length */
653a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
654a669f990SJed Brown 
65516d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
6560f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
65716d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
65865de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
6596a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]  = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
66065de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
66165de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
66265de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
6637b7fa87dSPierre Jolivet                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "l1-Gauss-Seidel" /* nonsymmetric */, "backward-l1-Gauss-Seidel" /* nonsymmetric */,
66465de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
6650f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
666*589dcaf0SStefano Zampini                                                   "ext+i-cc", "standard", "standard-wts", "block", "block-wtd", "FF", "FF1",
667*589dcaf0SStefano Zampini                                                   "ext", "ad-wts", "ext-mm", "ext+i-mm", "ext+e-mm"};
6684416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc)
66916d9e3a6SLisandro Dalcin {
67016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
67116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
67222e51d31SStefano Zampini   PetscInt       bs,n,indx,level;
673ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
67416d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
675*589dcaf0SStefano Zampini   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
67616d9e3a6SLisandro Dalcin 
67716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
678e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
6794336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
68016d9e3a6SLisandro Dalcin   if (flg) {
6814336a9eeSBarry Smith     jac->cycletype = indx+1;
682fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
68316d9e3a6SLisandro Dalcin   }
68416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
68516d9e3a6SLisandro Dalcin   if (flg) {
686ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
687fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
68816d9e3a6SLisandro Dalcin   }
68916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
69016d9e3a6SLisandro Dalcin   if (flg) {
691ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
692fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
69316d9e3a6SLisandro Dalcin   }
69439accc25SStefano 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);
69516d9e3a6SLisandro Dalcin   if (flg) {
69657622a8eSBarry 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);
697fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
69816d9e3a6SLisandro Dalcin   }
69922e51d31SStefano Zampini   bs = 1;
70022e51d31SStefano Zampini   if (pc->pmat) {
70122e51d31SStefano Zampini     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
70222e51d31SStefano Zampini   }
70322e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_numfunctions","Number of functions","HYPRE_BoomerAMGSetNumFunctions",bs,&bs,&flg);CHKERRQ(ierr);
70422e51d31SStefano Zampini   if (flg) {
70522e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
70622e51d31SStefano Zampini   }
70716d9e3a6SLisandro Dalcin 
70839accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
70916d9e3a6SLisandro Dalcin   if (flg) {
71057622a8eSBarry 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);
711fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
71216d9e3a6SLisandro Dalcin   }
71316d9e3a6SLisandro Dalcin 
7140f1074feSSatish 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);
7150f1074feSSatish Balay   if (flg) {
71657622a8eSBarry Smith     if (jac->pmax < 0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"P_max %g must be greater than or equal to zero",(double)jac->pmax);
717fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
7180f1074feSSatish Balay   }
7190f1074feSSatish Balay 
7200f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
7210f1074feSSatish Balay   if (flg) {
72257622a8eSBarry Smith     if (jac->agg_nl < 0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %g must be greater than or equal to zero",(double)jac->agg_nl);
7230f1074feSSatish Balay 
724fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
7250f1074feSSatish Balay   }
7260f1074feSSatish Balay 
7270f1074feSSatish 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);
7280f1074feSSatish Balay   if (flg) {
72957622a8eSBarry Smith     if (jac->agg_num_paths < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of paths %g must be greater than or equal to 1",(double)jac->agg_num_paths);
7300f1074feSSatish Balay 
731fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
7320f1074feSSatish Balay   }
7330f1074feSSatish Balay 
7340f1074feSSatish Balay 
73539accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
73616d9e3a6SLisandro Dalcin   if (flg) {
73757622a8eSBarry 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);
738fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
73916d9e3a6SLisandro Dalcin   }
74039accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
74116d9e3a6SLisandro Dalcin   if (flg) {
74257622a8eSBarry 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);
74357622a8eSBarry 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);
744fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
74516d9e3a6SLisandro Dalcin   }
74616d9e3a6SLisandro Dalcin 
74716d9e3a6SLisandro Dalcin   /* Grid sweeps */
7480f1074feSSatish 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);
74916d9e3a6SLisandro Dalcin   if (flg) {
750fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
75116d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
75216d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
7530f1074feSSatish Balay     jac->gridsweeps[1] = indx;
7540f1074feSSatish Balay     /*defaults coarse to 1 */
7550f1074feSSatish Balay     jac->gridsweeps[2] = 1;
75616d9e3a6SLisandro Dalcin   }
7575272c319SBarry 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);
7585272c319SBarry Smith   if (flg) {
7595272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,jac->nodal_coarsening));
7605272c319SBarry Smith   }
76122e51d31SStefano 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);
76222e51d31SStefano Zampini   if (flg) {
76322e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNodalDiag,(jac->hsolver,jac->nodal_coarsening_diag));
76422e51d31SStefano Zampini   }
765cbc39033SBarry 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);
7665272c319SBarry Smith   if (flg) {
7675272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,(jac->hsolver,jac->vec_interp_variant));
7685272c319SBarry Smith   }
76922e51d31SStefano 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);
77022e51d31SStefano Zampini   if (flg) {
77122e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecQMax,(jac->hsolver,jac->vec_interp_qmax));
77222e51d31SStefano Zampini   }
77322e51d31SStefano 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);
77422e51d31SStefano Zampini   if (flg) {
77522e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothInterpVectors,(jac->hsolver,jac->vec_interp_smooth));
77622e51d31SStefano Zampini   }
77722e51d31SStefano 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);
77822e51d31SStefano Zampini   if (flg) {
77922e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpRefine,(jac->hsolver,jac->interp_refine));
78022e51d31SStefano Zampini   }
7810f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
78216d9e3a6SLisandro Dalcin   if (flg) {
783fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
7840f1074feSSatish Balay     jac->gridsweeps[0] = indx;
78516d9e3a6SLisandro Dalcin   }
78616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
78716d9e3a6SLisandro Dalcin   if (flg) {
788fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
7890f1074feSSatish Balay     jac->gridsweeps[1] = indx;
79016d9e3a6SLisandro Dalcin   }
7910f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
79216d9e3a6SLisandro Dalcin   if (flg) {
793fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
7940f1074feSSatish Balay     jac->gridsweeps[2] = indx;
79516d9e3a6SLisandro Dalcin   }
79616d9e3a6SLisandro Dalcin 
7976a251517SEike Mueller   /* Smooth type */
7986a251517SEike Mueller   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);
7996a251517SEike Mueller   if (flg) {
8006a251517SEike Mueller     jac->smoothtype = indx;
8016a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
8028131ecf7SEike Mueller     jac->smoothnumlevels = 25;
8038131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
8048131ecf7SEike Mueller   }
8058131ecf7SEike Mueller 
8068131ecf7SEike Mueller   /* Number of smoothing levels */
8078131ecf7SEike 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);
8088131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
8098131ecf7SEike Mueller     jac->smoothnumlevels = indx;
8108131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
8116a251517SEike Mueller   }
8126a251517SEike Mueller 
8131810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
8141810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
8151810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8161810e44eSEike Mueller     jac->eu_level = indx;
8171810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
8181810e44eSEike Mueller   }
8191810e44eSEike Mueller 
8201810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
8211810e44eSEike Mueller   double droptolerance;
82239accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
8231810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8241810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
8251810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
8261810e44eSEike Mueller   }
8271810e44eSEike Mueller 
8281810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
8291810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
8301810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8311810e44eSEike Mueller     jac->eu_bj = tmp_truth;
832493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
8331810e44eSEike Mueller   }
8341810e44eSEike Mueller 
83516d9e3a6SLisandro Dalcin   /* Relax type */
836a669f990SJed 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);
83716d9e3a6SLisandro Dalcin   if (flg) {
8380f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
839fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
8400f1074feSSatish Balay     /* by default, coarse type set to 9 */
8410f1074feSSatish Balay     jac->relaxtype[2] = 9;
842ddbeb582SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, 9, 3));
84316d9e3a6SLisandro Dalcin   }
844a669f990SJed 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);
84516d9e3a6SLisandro Dalcin   if (flg) {
84616d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
847fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
84816d9e3a6SLisandro Dalcin   }
849a669f990SJed 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);
85016d9e3a6SLisandro Dalcin   if (flg) {
8510f1074feSSatish Balay     jac->relaxtype[1] = indx;
852fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
85316d9e3a6SLisandro Dalcin   }
854a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
85516d9e3a6SLisandro Dalcin   if (flg) {
8560f1074feSSatish Balay     jac->relaxtype[2] = indx;
857fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
85816d9e3a6SLisandro Dalcin   }
85916d9e3a6SLisandro Dalcin 
86016d9e3a6SLisandro Dalcin   /* Relaxation Weight */
86116d9e3a6SLisandro 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);
86216d9e3a6SLisandro Dalcin   if (flg) {
863fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
86416d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
86516d9e3a6SLisandro Dalcin   }
86616d9e3a6SLisandro Dalcin 
86716d9e3a6SLisandro Dalcin   n         = 2;
86816d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
86916d9e3a6SLisandro 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);
87016d9e3a6SLisandro Dalcin   if (flg) {
87116d9e3a6SLisandro Dalcin     if (n == 2) {
87216d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
873fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
874ce94432eSBarry 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);
87516d9e3a6SLisandro Dalcin   }
87616d9e3a6SLisandro Dalcin 
87716d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
87816d9e3a6SLisandro 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);
87916d9e3a6SLisandro Dalcin   if (flg) {
880fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
88116d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
88216d9e3a6SLisandro Dalcin   }
88316d9e3a6SLisandro Dalcin 
88416d9e3a6SLisandro Dalcin   n         = 2;
88516d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
88616d9e3a6SLisandro 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);
88716d9e3a6SLisandro Dalcin   if (flg) {
88816d9e3a6SLisandro Dalcin     if (n == 2) {
88916d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
890fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
891ce94432eSBarry 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);
89216d9e3a6SLisandro Dalcin   }
89316d9e3a6SLisandro Dalcin 
89416d9e3a6SLisandro Dalcin   /* the Relax Order */
895acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
89616d9e3a6SLisandro Dalcin 
8978afaa268SBarry Smith   if (flg && tmp_truth) {
89816d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
899fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
90016d9e3a6SLisandro Dalcin   }
901a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
90216d9e3a6SLisandro Dalcin   if (flg) {
90316d9e3a6SLisandro Dalcin     jac->measuretype = indx;
904fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
90516d9e3a6SLisandro Dalcin   }
9060f1074feSSatish Balay   /* update list length 3/07 */
907a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
90816d9e3a6SLisandro Dalcin   if (flg) {
90916d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
910fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
91116d9e3a6SLisandro Dalcin   }
9120f1074feSSatish Balay 
913*589dcaf0SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_coarse_size", "Maximum size of coarsest grid", "None", jac->maxc, &jac->maxc, &flg);CHKERRQ(ierr);
914*589dcaf0SStefano Zampini   if (flg) {
915*589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxCoarseSize,(jac->hsolver, jac->maxc));
916*589dcaf0SStefano Zampini   }
917*589dcaf0SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_min_coarse_size", "Minimum size of coarsest grid", "None", jac->minc, &jac->minc, &flg);CHKERRQ(ierr);
918*589dcaf0SStefano Zampini   if (flg) {
919*589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetMinCoarseSize,(jac->hsolver, jac->minc));
920*589dcaf0SStefano Zampini   }
921*589dcaf0SStefano Zampini 
922*589dcaf0SStefano Zampini   /* AIR */
923*589dcaf0SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,18,0)
924*589dcaf0SStefano 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);
925*589dcaf0SStefano Zampini   PetscStackCallStandard(HYPRE_BoomerAMGSetRestriction,(jac->hsolver,jac->Rtype));
926*589dcaf0SStefano Zampini   if (jac->Rtype) {
927*589dcaf0SStefano 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 */
928*589dcaf0SStefano Zampini 
929*589dcaf0SStefano Zampini     ierr = PetscOptionsReal("-pc_hypre_boomeramg_strongthresholdR","Threshold for R","None",jac->Rstrongthreshold,&jac->Rstrongthreshold,NULL);CHKERRQ(ierr);
930*589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThresholdR,(jac->hsolver,jac->Rstrongthreshold));
931*589dcaf0SStefano Zampini 
932*589dcaf0SStefano Zampini     ierr = PetscOptionsReal("-pc_hypre_boomeramg_filterthresholdR","Filter threshold for R","None",jac->Rfilterthreshold,&jac->Rfilterthreshold,NULL);CHKERRQ(ierr);
933*589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetFilterThresholdR,(jac->hsolver,jac->Rfilterthreshold));
934*589dcaf0SStefano Zampini 
935*589dcaf0SStefano 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);
936*589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetADropTol,(jac->hsolver,jac->Adroptol));
937*589dcaf0SStefano Zampini 
938*589dcaf0SStefano 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);
939*589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetADropType,(jac->hsolver,jac->Adroptype));
940*589dcaf0SStefano Zampini   }
941*589dcaf0SStefano Zampini #endif
942*589dcaf0SStefano Zampini 
9430f1074feSSatish Balay   /* new 3/07 */
944a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
945*589dcaf0SStefano Zampini   if (flg || jac->Rtype) {
946*589dcaf0SStefano Zampini     if (flg) jac->interptype = indx;
947fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
9480f1074feSSatish Balay   }
9490f1074feSSatish Balay 
950b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
95116d9e3a6SLisandro Dalcin   if (flg) {
952b96a4a96SBarry Smith     level = 3;
9530298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
9542fa5cd67SKarl Rupp 
955b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
956fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
9572ae77aedSBarry Smith   }
9582ae77aedSBarry Smith 
959b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
9602ae77aedSBarry Smith   if (flg) {
961b96a4a96SBarry Smith     level = 3;
9620298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
9632fa5cd67SKarl Rupp 
964b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
965fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
96616d9e3a6SLisandro Dalcin   }
9678f87f92bSBarry Smith 
968acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
9698f87f92bSBarry Smith   if (flg && tmp_truth) {
9708f87f92bSBarry Smith     PetscInt tmp_int;
9718f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
9728f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
973fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
974fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
975fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
976fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
9778f87f92bSBarry Smith   }
9788f87f92bSBarry Smith 
979*589dcaf0SStefano Zampini   ierr = PetscOptionsBool("-pc_hypre_boomeramg_keeptranspose", "Avoid transpose matvecs in preconditioner application", "None", jac->keeptranspose, &jac->keeptranspose, NULL);CHKERRQ(ierr);
980*589dcaf0SStefano Zampini   PetscStackCallStandard(HYPRE_BoomerAMGSetKeepTranspose,(jac->hsolver,jac->keeptranspose ? 1 : 0));
981*589dcaf0SStefano Zampini 
982*589dcaf0SStefano Zampini   /* options for ParaSails solvers */
983*589dcaf0SStefano Zampini   ierr = PetscOptionsEList("-pc_hypre_boomeramg_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flg);CHKERRQ(ierr);
984*589dcaf0SStefano Zampini   if (flg) {
985*589dcaf0SStefano Zampini     jac->symt = indx;
986*589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetSym,(jac->hsolver,jac->symt));
987*589dcaf0SStefano Zampini   }
988*589dcaf0SStefano Zampini 
98916d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
99016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
99116d9e3a6SLisandro Dalcin }
99216d9e3a6SLisandro Dalcin 
993ace3abfcSBarry 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)
99416d9e3a6SLisandro Dalcin {
99516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
99616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
9972cf14000SStefano Zampini   HYPRE_Int      oits;
99816d9e3a6SLisandro Dalcin 
99916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1000dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1001fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
1002fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
100316d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
100416d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
100516d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
10062cf14000SStefano Zampini   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,&oits));
10074d0a8057SBarry Smith   *outits = oits;
10084d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
10094d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1010fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1011fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
101216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
101316d9e3a6SLisandro Dalcin }
101416d9e3a6SLisandro Dalcin 
101516d9e3a6SLisandro Dalcin 
101616d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
101716d9e3a6SLisandro Dalcin {
101816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
101916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1020ace3abfcSBarry Smith   PetscBool      iascii;
102116d9e3a6SLisandro Dalcin 
102216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1023251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
102416d9e3a6SLisandro Dalcin   if (iascii) {
102516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
1026efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
102722e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of levels %D\n",jac->maxlevels);CHKERRQ(ierr);
102822e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of iterations PER hypre call %D\n",jac->maxiter);CHKERRQ(ierr);
1029efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
1030efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
1031efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
103222e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: max elements per row %D\n",jac->pmax);CHKERRQ(ierr);
103322e51d31SStefano Zampini     if (jac->interp_refine) {
103422e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: number of steps of weighted refinement %D\n",jac->interp_refine);CHKERRQ(ierr);
103522e51d31SStefano Zampini     }
103622e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of levels of aggressive coarsening %D\n",jac->agg_nl);CHKERRQ(ierr);
103722e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of paths for aggressive coarsening %D\n",jac->agg_num_paths);CHKERRQ(ierr);
10380f1074feSSatish Balay 
1039efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
104016d9e3a6SLisandro Dalcin 
104122e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps down         %D\n",jac->gridsweeps[0]);CHKERRQ(ierr);
104222e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps up           %D\n",jac->gridsweeps[1]);CHKERRQ(ierr);
104322e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps on coarse    %D\n",jac->gridsweeps[2]);CHKERRQ(ierr);
104416d9e3a6SLisandro Dalcin 
1045efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
1046efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
1047efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
104816d9e3a6SLisandro Dalcin 
1049efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
1050efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
105116d9e3a6SLisandro Dalcin 
105216d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
1053efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using CF-relaxation\n");CHKERRQ(ierr);
105416d9e3a6SLisandro Dalcin     } else {
1055efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using CF-relaxation\n");CHKERRQ(ierr);
105616d9e3a6SLisandro Dalcin     }
10576a251517SEike Mueller     if (jac->smoothtype!=-1) {
1058efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
105922e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth num levels    %D\n",jac->smoothnumlevels);CHKERRQ(ierr);
10607e352d70SEike Mueller     } else {
1061efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using more complex smoothers.\n");CHKERRQ(ierr);
10621810e44eSEike Mueller     }
10631810e44eSEike Mueller     if (jac->smoothtype==3) {
106422e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) levels %D\n",jac->eu_level);CHKERRQ(ierr);
106522e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) drop tolerance %g\n",(double)jac->eu_droptolerance);CHKERRQ(ierr);
106622e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU use Block-Jacobi? %D\n",jac->eu_bj);CHKERRQ(ierr);
10676a251517SEike Mueller     }
1068efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
1069efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
1070*589dcaf0SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation type  %s\n",jac->interptype != 100 ? HYPREBoomerAMGInterpType[jac->interptype] : "1pt");CHKERRQ(ierr);
10715272c319SBarry Smith     if (jac->nodal_coarsening) {
1072efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
10735272c319SBarry Smith     }
10745272c319SBarry Smith     if (jac->vec_interp_variant) {
1075efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
107622e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecQMax() %D\n",jac->vec_interp_qmax);CHKERRQ(ierr);
107722e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n",jac->vec_interp_smooth);CHKERRQ(ierr);
10788f87f92bSBarry Smith     }
10798f87f92bSBarry Smith     if (jac->nodal_relax) {
108022e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal relaxation via Schwarz smoothing on levels %D\n",jac->nodal_relax_levels);CHKERRQ(ierr);
10818f87f92bSBarry Smith     }
1082*589dcaf0SStefano Zampini 
1083*589dcaf0SStefano Zampini     /* AIR */
1084*589dcaf0SStefano Zampini     if (jac->Rtype) {
1085*589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Using approximate ideal restriction type %D\n",jac->Rtype);CHKERRQ(ierr);
1086*589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"      Threshold for R %g\n",(double)jac->Rstrongthreshold);CHKERRQ(ierr);
1087*589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"      Filter for R %g\n",(double)jac->Rfilterthreshold);CHKERRQ(ierr);
1088*589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"      A drop tolerance %g\n",(double)jac->Adroptol);CHKERRQ(ierr);
1089*589dcaf0SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"      A drop type %D\n",jac->Adroptype);CHKERRQ(ierr);
1090*589dcaf0SStefano Zampini     }
109116d9e3a6SLisandro Dalcin   }
109216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
109316d9e3a6SLisandro Dalcin }
109416d9e3a6SLisandro Dalcin 
109516d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
10964416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc)
109716d9e3a6SLisandro Dalcin {
109816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
109916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
11004ddd07fcSJed Brown   PetscInt       indx;
1101ace3abfcSBarry Smith   PetscBool      flag;
110216d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
110316d9e3a6SLisandro Dalcin 
110416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1105e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
110616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
11078966356dSPierre Jolivet   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshold,&jac->threshold,&flag);CHKERRQ(ierr);
11088966356dSPierre Jolivet   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshold,jac->nlevels));
110916d9e3a6SLisandro Dalcin 
111016d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
11112fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
111216d9e3a6SLisandro Dalcin 
111316d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
11142fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
111516d9e3a6SLisandro Dalcin 
1116acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
11172fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
111816d9e3a6SLisandro Dalcin 
1119acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
11202fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
112116d9e3a6SLisandro Dalcin 
1122a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
112316d9e3a6SLisandro Dalcin   if (flag) {
112416d9e3a6SLisandro Dalcin     jac->symt = indx;
1125fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
112616d9e3a6SLisandro Dalcin   }
112716d9e3a6SLisandro Dalcin 
112816d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
112916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
113016d9e3a6SLisandro Dalcin }
113116d9e3a6SLisandro Dalcin 
113216d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
113316d9e3a6SLisandro Dalcin {
113416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
113516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1136ace3abfcSBarry Smith   PetscBool      iascii;
1137feb237baSPierre Jolivet   const char     *symt = 0;
113816d9e3a6SLisandro Dalcin 
113916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1140251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
114116d9e3a6SLisandro Dalcin   if (iascii) {
114216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
1143efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
11448966356dSPierre Jolivet     ierr = PetscViewerASCIIPrintf(viewer,"    threshold %g\n",(double)jac->threshold);CHKERRQ(ierr);
1145efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    filter %g\n",(double)jac->filter);CHKERRQ(ierr);
1146efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
1147efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
1148efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
11492fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
11502fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
11512fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
1152ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
1153efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    %s\n",symt);CHKERRQ(ierr);
115416d9e3a6SLisandro Dalcin   }
115516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
115616d9e3a6SLisandro Dalcin }
11574cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
11584416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc)
11594cb006feSStefano Zampini {
11604cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
11614cb006feSStefano Zampini   PetscErrorCode ierr;
11624cb006feSStefano Zampini   PetscInt       n;
11634cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
11644cb006feSStefano Zampini 
11654cb006feSStefano Zampini   PetscFunctionBegin;
11669fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
1167863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1168863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1169863406b8SStefano 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);
1170863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
11714cb006feSStefano 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);
11724cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1173863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1174863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1175863406b8SStefano 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);
1176863406b8SStefano 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);
1177863406b8SStefano 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);
1178863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
11794cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1180863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1181863406b8SStefano Zampini                                                                       jac->as_relax_times,
1182863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1183863406b8SStefano Zampini                                                                       jac->as_omega));
11844cb006feSStefano Zampini   }
1185863406b8SStefano 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);
11864cb006feSStefano Zampini   n = 5;
1187863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
11884cb006feSStefano Zampini   if (flag || flag2) {
1189863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1190863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1191863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1192863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1193863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1194863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
11954cb006feSStefano Zampini   }
1196863406b8SStefano 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);
11974cb006feSStefano Zampini   n = 5;
1198863406b8SStefano 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);
11994cb006feSStefano Zampini   if (flag || flag2) {
1200863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1201863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1202863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1203863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1204863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1205863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
12064cb006feSStefano Zampini   }
120723df4f25SStefano 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);
120823df4f25SStefano Zampini   if (flag) { /* override HYPRE's default only if the options is used */
120923df4f25SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetProjectionFrequency,(jac->hsolver,jac->ams_proj_freq));
121023df4f25SStefano Zampini   }
12114cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
12124cb006feSStefano Zampini   PetscFunctionReturn(0);
12134cb006feSStefano Zampini }
12144cb006feSStefano Zampini 
12154cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
12164cb006feSStefano Zampini {
12174cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12184cb006feSStefano Zampini   PetscErrorCode ierr;
12194cb006feSStefano Zampini   PetscBool      iascii;
12204cb006feSStefano Zampini 
12214cb006feSStefano Zampini   PetscFunctionBegin;
12224cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
12234cb006feSStefano Zampini   if (iascii) {
12244cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
1225efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1226efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1227efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1228efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1229efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1230efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1231efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
12324cb006feSStefano Zampini     if (jac->alpha_Poisson) {
1233efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
12344cb006feSStefano Zampini     } else {
1235efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (computed) \n");CHKERRQ(ierr);
12364cb006feSStefano Zampini     }
1237efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1238efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1239efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1240efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1241efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1242efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
12434cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
12444cb006feSStefano Zampini       if (jac->beta_Poisson) {
1245efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
12464cb006feSStefano Zampini       } else {
1247efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (computed) \n");CHKERRQ(ierr);
12484cb006feSStefano Zampini       }
1249efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1250efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1251efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1252efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1253efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1254efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
125523df4f25SStefano Zampini       if (jac->ams_beta_is_zero_part) {
1256efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"        compatible subspace projection frequency %d (-1 HYPRE uses default)\n",jac->ams_proj_freq);CHKERRQ(ierr);
125723df4f25SStefano Zampini       }
125823df4f25SStefano Zampini     } else {
1259efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver not used (zero-conductivity everywhere) \n");CHKERRQ(ierr);
12604cb006feSStefano Zampini     }
12614cb006feSStefano Zampini   }
12624cb006feSStefano Zampini   PetscFunctionReturn(0);
12634cb006feSStefano Zampini }
12644cb006feSStefano Zampini 
12654416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc)
1266863406b8SStefano Zampini {
1267863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1268863406b8SStefano Zampini   PetscErrorCode ierr;
1269863406b8SStefano Zampini   PetscInt       n;
1270863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
1271863406b8SStefano Zampini 
1272863406b8SStefano Zampini   PetscFunctionBegin;
1273863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
1274863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1275863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1276863406b8SStefano 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);
1277863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1278863406b8SStefano 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);
1279863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
1280863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1281863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1282863406b8SStefano 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);
1283863406b8SStefano 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);
1284863406b8SStefano 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);
1285863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
1286863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1287863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1288863406b8SStefano Zampini                                                                       jac->as_relax_times,
1289863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1290863406b8SStefano Zampini                                                                       jac->as_omega));
1291863406b8SStefano Zampini   }
1292863406b8SStefano 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);
1293863406b8SStefano Zampini   n = 5;
1294863406b8SStefano 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);
1295863406b8SStefano 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);
1296863406b8SStefano Zampini   if (flag || flag2 || flag3) {
1297863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
1298863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1299863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1300863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1301863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1302863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1303863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1304863406b8SStefano Zampini   }
1305863406b8SStefano 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);
1306863406b8SStefano Zampini   n = 5;
1307863406b8SStefano 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);
1308863406b8SStefano Zampini   if (flag || flag2) {
1309863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1310863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1311863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1312863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1313863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1314863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1315863406b8SStefano Zampini   }
1316863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
1317863406b8SStefano Zampini   PetscFunctionReturn(0);
1318863406b8SStefano Zampini }
1319863406b8SStefano Zampini 
1320863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1321863406b8SStefano Zampini {
1322863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1323863406b8SStefano Zampini   PetscErrorCode ierr;
1324863406b8SStefano Zampini   PetscBool      iascii;
1325863406b8SStefano Zampini 
1326863406b8SStefano Zampini   PetscFunctionBegin;
1327863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1328863406b8SStefano Zampini   if (iascii) {
1329863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
1330efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1331efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
1332efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1333efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1334efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1335efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1336efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
1337efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    AMS solver using boomerAMG\n");CHKERRQ(ierr);
1338efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1339efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1340efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1341efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1342efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1343efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1344efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
1345efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver using boomerAMG\n");CHKERRQ(ierr);
1346efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1347efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1348efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1349efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1350efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1351efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
1352863406b8SStefano Zampini   }
1353863406b8SStefano Zampini   PetscFunctionReturn(0);
1354863406b8SStefano Zampini }
1355863406b8SStefano Zampini 
1356863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
13574cb006feSStefano Zampini {
13584cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
13595ac14e1cSStefano Zampini   PetscBool      ishypre;
13604cb006feSStefano Zampini   PetscErrorCode ierr;
13614cb006feSStefano Zampini 
13624cb006feSStefano Zampini   PetscFunctionBegin;
13635ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)G,MATHYPRE,&ishypre);CHKERRQ(ierr);
13645ac14e1cSStefano Zampini   if (ishypre) {
13655ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr);
13665ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
13675ac14e1cSStefano Zampini     jac->G = G;
13685ac14e1cSStefano Zampini   } else {
13696bf688a0SCe Qin     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
13706bf688a0SCe Qin     ierr = MatConvert(G,MATHYPRE,MAT_INITIAL_MATRIX,&jac->G);CHKERRQ(ierr);
13715ac14e1cSStefano Zampini   }
13724cb006feSStefano Zampini   PetscFunctionReturn(0);
13734cb006feSStefano Zampini }
13744cb006feSStefano Zampini 
13754cb006feSStefano Zampini /*@
13764cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
13774cb006feSStefano Zampini 
13784cb006feSStefano Zampini    Collective on PC
13794cb006feSStefano Zampini 
13804cb006feSStefano Zampini    Input Parameters:
13814cb006feSStefano Zampini +  pc - the preconditioning context
13824cb006feSStefano Zampini -  G - the discrete gradient
13834cb006feSStefano Zampini 
13844cb006feSStefano Zampini    Level: intermediate
13854cb006feSStefano Zampini 
138695452b02SPatrick Sanan    Notes:
138795452b02SPatrick Sanan     G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh
1388863406b8SStefano 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
13894cb006feSStefano Zampini 
13904cb006feSStefano Zampini .seealso:
13914cb006feSStefano Zampini @*/
13924cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
13934cb006feSStefano Zampini {
13944cb006feSStefano Zampini   PetscErrorCode ierr;
13954cb006feSStefano Zampini 
13964cb006feSStefano Zampini   PetscFunctionBegin;
13974cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
13984cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
13994cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
14004cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
14014cb006feSStefano Zampini   PetscFunctionReturn(0);
14024cb006feSStefano Zampini }
14034cb006feSStefano Zampini 
1404863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1405863406b8SStefano Zampini {
1406863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
14075ac14e1cSStefano Zampini   PetscBool      ishypre;
1408863406b8SStefano Zampini   PetscErrorCode ierr;
1409863406b8SStefano Zampini 
1410863406b8SStefano Zampini   PetscFunctionBegin;
14115ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)C,MATHYPRE,&ishypre);CHKERRQ(ierr);
14125ac14e1cSStefano Zampini   if (ishypre) {
14135ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr);
14145ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
14155ac14e1cSStefano Zampini     jac->C = C;
14165ac14e1cSStefano Zampini   } else {
14176bf688a0SCe Qin     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
14186bf688a0SCe Qin     ierr = MatConvert(C,MATHYPRE,MAT_INITIAL_MATRIX,&jac->C);CHKERRQ(ierr);
14195ac14e1cSStefano Zampini   }
1420863406b8SStefano Zampini   PetscFunctionReturn(0);
1421863406b8SStefano Zampini }
1422863406b8SStefano Zampini 
1423863406b8SStefano Zampini /*@
1424863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1425863406b8SStefano Zampini 
1426863406b8SStefano Zampini    Collective on PC
1427863406b8SStefano Zampini 
1428863406b8SStefano Zampini    Input Parameters:
1429863406b8SStefano Zampini +  pc - the preconditioning context
1430863406b8SStefano Zampini -  C - the discrete curl
1431863406b8SStefano Zampini 
1432863406b8SStefano Zampini    Level: intermediate
1433863406b8SStefano Zampini 
143495452b02SPatrick Sanan    Notes:
143595452b02SPatrick Sanan     C should have as many rows as the number of faces and as many columns as the number of edges in the mesh
1436863406b8SStefano 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
1437863406b8SStefano Zampini 
1438863406b8SStefano Zampini .seealso:
1439863406b8SStefano Zampini @*/
1440863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1441863406b8SStefano Zampini {
1442863406b8SStefano Zampini   PetscErrorCode ierr;
1443863406b8SStefano Zampini 
1444863406b8SStefano Zampini   PetscFunctionBegin;
1445863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1446863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1447863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1448863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1449863406b8SStefano Zampini   PetscFunctionReturn(0);
1450863406b8SStefano Zampini }
1451863406b8SStefano Zampini 
14526bf688a0SCe Qin static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
14536bf688a0SCe Qin {
14546bf688a0SCe Qin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
14556bf688a0SCe Qin   PetscBool      ishypre;
14566bf688a0SCe Qin   PetscErrorCode ierr;
14576bf688a0SCe Qin   PetscInt       i;
14586bf688a0SCe Qin   PetscFunctionBegin;
14596bf688a0SCe Qin 
14606bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
14616bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
14626bf688a0SCe Qin   for (i=0;i<3;++i) {
14636bf688a0SCe Qin     ierr = MatDestroy(&jac->RT_Pi[i]);CHKERRQ(ierr);
14646bf688a0SCe Qin     ierr = MatDestroy(&jac->ND_Pi[i]);CHKERRQ(ierr);
14656bf688a0SCe Qin   }
14666bf688a0SCe Qin 
14676bf688a0SCe Qin   jac->dim = dim;
14686bf688a0SCe Qin   if (RT_PiFull) {
14696bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)RT_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
14706bf688a0SCe Qin     if (ishypre) {
14716bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)RT_PiFull);CHKERRQ(ierr);
14726bf688a0SCe Qin       jac->RT_PiFull = RT_PiFull;
14736bf688a0SCe Qin     } else {
14746bf688a0SCe Qin       ierr = MatConvert(RT_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_PiFull);CHKERRQ(ierr);
14756bf688a0SCe Qin     }
14766bf688a0SCe Qin   }
14776bf688a0SCe Qin   if (RT_Pi) {
14786bf688a0SCe Qin     for (i=0;i<dim;++i) {
14796bf688a0SCe Qin       if (RT_Pi[i]) {
14806bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)RT_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
14816bf688a0SCe Qin         if (ishypre) {
14826bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)RT_Pi[i]);CHKERRQ(ierr);
14836bf688a0SCe Qin           jac->RT_Pi[i] = RT_Pi[i];
14846bf688a0SCe Qin         } else {
14856bf688a0SCe Qin           ierr = MatConvert(RT_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_Pi[i]);CHKERRQ(ierr);
14866bf688a0SCe Qin         }
14876bf688a0SCe Qin       }
14886bf688a0SCe Qin     }
14896bf688a0SCe Qin   }
14906bf688a0SCe Qin   if (ND_PiFull) {
14916bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)ND_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
14926bf688a0SCe Qin     if (ishypre) {
14936bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)ND_PiFull);CHKERRQ(ierr);
14946bf688a0SCe Qin       jac->ND_PiFull = ND_PiFull;
14956bf688a0SCe Qin     } else {
14966bf688a0SCe Qin       ierr = MatConvert(ND_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_PiFull);CHKERRQ(ierr);
14976bf688a0SCe Qin     }
14986bf688a0SCe Qin   }
14996bf688a0SCe Qin   if (ND_Pi) {
15006bf688a0SCe Qin     for (i=0;i<dim;++i) {
15016bf688a0SCe Qin       if (ND_Pi[i]) {
15026bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)ND_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
15036bf688a0SCe Qin         if (ishypre) {
15046bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)ND_Pi[i]);CHKERRQ(ierr);
15056bf688a0SCe Qin           jac->ND_Pi[i] = ND_Pi[i];
15066bf688a0SCe Qin         } else {
15076bf688a0SCe Qin           ierr = MatConvert(ND_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_Pi[i]);CHKERRQ(ierr);
15086bf688a0SCe Qin         }
15096bf688a0SCe Qin       }
15106bf688a0SCe Qin     }
15116bf688a0SCe Qin   }
15126bf688a0SCe Qin 
15136bf688a0SCe Qin   PetscFunctionReturn(0);
15146bf688a0SCe Qin }
15156bf688a0SCe Qin 
15166bf688a0SCe Qin /*@
15176bf688a0SCe Qin  PCHYPRESetInterpolations - Set interpolation matrices for AMS/ADS preconditioner
15186bf688a0SCe Qin 
15196bf688a0SCe Qin    Collective on PC
15206bf688a0SCe Qin 
15216bf688a0SCe Qin    Input Parameters:
15226bf688a0SCe Qin +  pc - the preconditioning context
15236bf688a0SCe Qin -  dim - the dimension of the problem, only used in AMS
15246bf688a0SCe Qin -  RT_PiFull - Raviart-Thomas interpolation matrix
15256bf688a0SCe Qin -  RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix
15266bf688a0SCe Qin -  ND_PiFull - Nedelec interpolation matrix
15276bf688a0SCe Qin -  ND_Pi - x/y/z component of Nedelec interpolation matrix
15286bf688a0SCe Qin 
152995452b02SPatrick Sanan    Notes:
153095452b02SPatrick Sanan     For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL.
15316bf688a0SCe Qin           For ADS, both type of interpolation matrices are needed.
15326bf688a0SCe Qin    Level: intermediate
15336bf688a0SCe Qin 
15346bf688a0SCe Qin .seealso:
15356bf688a0SCe Qin @*/
15366bf688a0SCe Qin PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
15376bf688a0SCe Qin {
15386bf688a0SCe Qin   PetscErrorCode ierr;
15396bf688a0SCe Qin   PetscInt       i;
15406bf688a0SCe Qin 
15416bf688a0SCe Qin   PetscFunctionBegin;
15426bf688a0SCe Qin   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15436bf688a0SCe Qin   if (RT_PiFull) {
15446bf688a0SCe Qin     PetscValidHeaderSpecific(RT_PiFull,MAT_CLASSID,3);
15456bf688a0SCe Qin     PetscCheckSameComm(pc,1,RT_PiFull,3);
15466bf688a0SCe Qin   }
15476bf688a0SCe Qin   if (RT_Pi) {
15486bf688a0SCe Qin     PetscValidPointer(RT_Pi,4);
15496bf688a0SCe Qin     for (i=0;i<dim;++i) {
15506bf688a0SCe Qin       if (RT_Pi[i]) {
15516bf688a0SCe Qin         PetscValidHeaderSpecific(RT_Pi[i],MAT_CLASSID,4);
15526bf688a0SCe Qin         PetscCheckSameComm(pc,1,RT_Pi[i],4);
15536bf688a0SCe Qin       }
15546bf688a0SCe Qin     }
15556bf688a0SCe Qin   }
15566bf688a0SCe Qin   if (ND_PiFull) {
15576bf688a0SCe Qin     PetscValidHeaderSpecific(ND_PiFull,MAT_CLASSID,5);
15586bf688a0SCe Qin     PetscCheckSameComm(pc,1,ND_PiFull,5);
15596bf688a0SCe Qin   }
15606bf688a0SCe Qin   if (ND_Pi) {
15616bf688a0SCe Qin     PetscValidPointer(ND_Pi,6);
15626bf688a0SCe Qin     for (i=0;i<dim;++i) {
15636bf688a0SCe Qin       if (ND_Pi[i]) {
15646bf688a0SCe Qin         PetscValidHeaderSpecific(ND_Pi[i],MAT_CLASSID,6);
15656bf688a0SCe Qin         PetscCheckSameComm(pc,1,ND_Pi[i],6);
15666bf688a0SCe Qin       }
15676bf688a0SCe Qin     }
15686bf688a0SCe Qin   }
15696bf688a0SCe Qin   ierr = PetscTryMethod(pc,"PCHYPRESetInterpolations_C",(PC,PetscInt,Mat,Mat[],Mat,Mat[]),(pc,dim,RT_PiFull,RT_Pi,ND_PiFull,ND_Pi));CHKERRQ(ierr);
15706bf688a0SCe Qin   PetscFunctionReturn(0);
15716bf688a0SCe Qin }
15726bf688a0SCe Qin 
15735ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha)
15744cb006feSStefano Zampini {
15754cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
15765ac14e1cSStefano Zampini   PetscBool      ishypre;
15774cb006feSStefano Zampini   PetscErrorCode ierr;
15784cb006feSStefano Zampini 
15794cb006feSStefano Zampini   PetscFunctionBegin;
15805ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr);
15815ac14e1cSStefano Zampini   if (ishypre) {
15825ac14e1cSStefano Zampini     if (isalpha) {
15835ac14e1cSStefano Zampini       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
15845ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
15855ac14e1cSStefano Zampini       jac->alpha_Poisson = A;
15865ac14e1cSStefano Zampini     } else {
15875ac14e1cSStefano Zampini       if (A) {
15885ac14e1cSStefano Zampini         ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
15895ac14e1cSStefano Zampini       } else {
15905ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
15915ac14e1cSStefano Zampini       }
15925ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
15935ac14e1cSStefano Zampini       jac->beta_Poisson = A;
15945ac14e1cSStefano Zampini     }
15955ac14e1cSStefano Zampini   } else {
15965ac14e1cSStefano Zampini     if (isalpha) {
15976bf688a0SCe Qin       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
15986bf688a0SCe Qin       ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->alpha_Poisson);CHKERRQ(ierr);
15995ac14e1cSStefano Zampini     } else {
16005ac14e1cSStefano Zampini       if (A) {
16016bf688a0SCe Qin         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
16026bf688a0SCe Qin         ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->beta_Poisson);CHKERRQ(ierr);
16035ac14e1cSStefano Zampini       } else {
16045ac14e1cSStefano Zampini         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
16055ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
16065ac14e1cSStefano Zampini       }
16075ac14e1cSStefano Zampini     }
16085ac14e1cSStefano Zampini   }
16094cb006feSStefano Zampini   PetscFunctionReturn(0);
16104cb006feSStefano Zampini }
16114cb006feSStefano Zampini 
16124cb006feSStefano Zampini /*@
16134cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
16144cb006feSStefano Zampini 
16154cb006feSStefano Zampini    Collective on PC
16164cb006feSStefano Zampini 
16174cb006feSStefano Zampini    Input Parameters:
16184cb006feSStefano Zampini +  pc - the preconditioning context
16194cb006feSStefano Zampini -  A - the matrix
16204cb006feSStefano Zampini 
16214cb006feSStefano Zampini    Level: intermediate
16224cb006feSStefano Zampini 
162395452b02SPatrick Sanan    Notes:
162495452b02SPatrick Sanan     A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
16254cb006feSStefano Zampini 
16264cb006feSStefano Zampini .seealso:
16274cb006feSStefano Zampini @*/
16284cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
16294cb006feSStefano Zampini {
16304cb006feSStefano Zampini   PetscErrorCode ierr;
16314cb006feSStefano Zampini 
16324cb006feSStefano Zampini   PetscFunctionBegin;
16334cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
16344cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
16354cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
16365ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_TRUE));CHKERRQ(ierr);
16374cb006feSStefano Zampini   PetscFunctionReturn(0);
16384cb006feSStefano Zampini }
16394cb006feSStefano Zampini 
16404cb006feSStefano Zampini /*@
16414cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
16424cb006feSStefano Zampini 
16434cb006feSStefano Zampini    Collective on PC
16444cb006feSStefano Zampini 
16454cb006feSStefano Zampini    Input Parameters:
16464cb006feSStefano Zampini +  pc - the preconditioning context
16474cb006feSStefano Zampini -  A - the matrix
16484cb006feSStefano Zampini 
16494cb006feSStefano Zampini    Level: intermediate
16504cb006feSStefano Zampini 
165195452b02SPatrick Sanan    Notes:
165295452b02SPatrick Sanan     A should be obtained by discretizing the Poisson problem with linear finite elements.
16534cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
16544cb006feSStefano Zampini 
16554cb006feSStefano Zampini .seealso:
16564cb006feSStefano Zampini @*/
16574cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
16584cb006feSStefano Zampini {
16594cb006feSStefano Zampini   PetscErrorCode ierr;
16604cb006feSStefano Zampini 
16614cb006feSStefano Zampini   PetscFunctionBegin;
16624cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
16634cb006feSStefano Zampini   if (A) {
16644cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
16654cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
16664cb006feSStefano Zampini   }
16675ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_FALSE));CHKERRQ(ierr);
16684cb006feSStefano Zampini   PetscFunctionReturn(0);
16694cb006feSStefano Zampini }
16704cb006feSStefano Zampini 
16715ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz, Vec zoz, Vec zzo)
16724cb006feSStefano Zampini {
16734cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
16744cb006feSStefano Zampini   PetscErrorCode     ierr;
16754cb006feSStefano Zampini 
16764cb006feSStefano Zampini   PetscFunctionBegin;
16774cb006feSStefano Zampini   /* throw away any vector if already set */
16784cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
16794cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
16804cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
16814cb006feSStefano Zampini   jac->constants[0] = NULL;
16824cb006feSStefano Zampini   jac->constants[1] = NULL;
16834cb006feSStefano Zampini   jac->constants[2] = NULL;
16844cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
16854cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
16864cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
16874cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
16885ac14e1cSStefano Zampini   jac->dim = 2;
16894cb006feSStefano Zampini   if (zzo) {
16904cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
16914cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
16925ac14e1cSStefano Zampini     jac->dim++;
16934cb006feSStefano Zampini   }
16944cb006feSStefano Zampini   PetscFunctionReturn(0);
16954cb006feSStefano Zampini }
16964cb006feSStefano Zampini 
16974cb006feSStefano Zampini /*@
16984cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
16994cb006feSStefano Zampini 
17004cb006feSStefano Zampini    Collective on PC
17014cb006feSStefano Zampini 
17024cb006feSStefano Zampini    Input Parameters:
17034cb006feSStefano Zampini +  pc - the preconditioning context
17044cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
17054cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
17064cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
17074cb006feSStefano Zampini 
17084cb006feSStefano Zampini    Level: intermediate
17094cb006feSStefano Zampini 
17104cb006feSStefano Zampini    Notes:
17114cb006feSStefano Zampini 
17124cb006feSStefano Zampini .seealso:
17134cb006feSStefano Zampini @*/
17144cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
17154cb006feSStefano Zampini {
17164cb006feSStefano Zampini   PetscErrorCode ierr;
17174cb006feSStefano Zampini 
17184cb006feSStefano Zampini   PetscFunctionBegin;
17194cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
17204cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
17214cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
17224cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
17234cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
17244cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
17254cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
17264cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
17274cb006feSStefano Zampini   PetscFunctionReturn(0);
17284cb006feSStefano Zampini }
17294cb006feSStefano Zampini 
1730863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
17314cb006feSStefano Zampini {
17324cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
17334cb006feSStefano Zampini   Vec             tv;
17344cb006feSStefano Zampini   PetscInt        i;
17354cb006feSStefano Zampini   PetscErrorCode  ierr;
17364cb006feSStefano Zampini 
17374cb006feSStefano Zampini   PetscFunctionBegin;
17384cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
17394cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
17404cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
17414cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
17425ac14e1cSStefano Zampini   jac->dim = dim;
17435ac14e1cSStefano Zampini 
17444cb006feSStefano Zampini   /* compute IJ vector for coordinates */
17454cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
17464cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
17474cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
17484cb006feSStefano Zampini   for (i=0;i<dim;i++) {
17494cb006feSStefano Zampini     PetscScalar *array;
17504cb006feSStefano Zampini     PetscInt    j;
17514cb006feSStefano Zampini 
17524cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
1753*589dcaf0SStefano Zampini     ierr = VecGetArrayWrite(tv,&array);CHKERRQ(ierr);
17544cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
17554cb006feSStefano Zampini       array[j] = coords[j*dim+i];
17564cb006feSStefano Zampini     }
175739accc25SStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,(HYPRE_Complex*)array));
17584cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
1759*589dcaf0SStefano Zampini     ierr = VecRestoreArrayWrite(tv,&array);CHKERRQ(ierr);
17604cb006feSStefano Zampini   }
17614cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
17624cb006feSStefano Zampini   PetscFunctionReturn(0);
17634cb006feSStefano Zampini }
17644cb006feSStefano Zampini 
176516d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
176616d9e3a6SLisandro Dalcin 
1767f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
176816d9e3a6SLisandro Dalcin {
176916d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
177016d9e3a6SLisandro Dalcin 
177116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
177216d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
177316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
177416d9e3a6SLisandro Dalcin }
177516d9e3a6SLisandro Dalcin 
1776f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
177716d9e3a6SLisandro Dalcin {
177816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
177916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1780ace3abfcSBarry Smith   PetscBool      flag;
178116d9e3a6SLisandro Dalcin 
178216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
178316d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
178416d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1785ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
178616d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
178716d9e3a6SLisandro Dalcin   } else {
178816d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
178916d9e3a6SLisandro Dalcin   }
179016d9e3a6SLisandro Dalcin 
179116d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
179216d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
179316d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
179416d9e3a6SLisandro Dalcin 
179516d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
179616d9e3a6SLisandro Dalcin   if (flag) {
1797ffc4695bSBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRMPI(ierr);
1798fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
179916d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
180016d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
180116d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
180216d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
180316d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
180416d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
180516d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
180616d9e3a6SLisandro Dalcin   }
1807db966c6cSHong Zhang   ierr = PetscStrcmp("euclid",jac->hypre_type,&flag);CHKERRQ(ierr);
1808db966c6cSHong Zhang   if (flag) {
18098bf83915SBarry Smith #if defined(PETSC_HAVE_64BIT_INDICES)
18108bf83915SBarry Smith     SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Hypre Euclid not support with 64 bit indices");
18118bf83915SBarry Smith #endif
1812ffc4695bSBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRMPI(ierr);
1813db966c6cSHong Zhang     PetscStackCallStandard(HYPRE_EuclidCreate,(jac->comm_hypre,&jac->hsolver));
1814db966c6cSHong Zhang     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
1815db966c6cSHong Zhang     pc->ops->view           = PCView_HYPRE_Euclid;
1816db966c6cSHong Zhang     jac->destroy            = HYPRE_EuclidDestroy;
1817db966c6cSHong Zhang     jac->setup              = HYPRE_EuclidSetup;
1818db966c6cSHong Zhang     jac->solve              = HYPRE_EuclidSolve;
1819db966c6cSHong Zhang     jac->factorrowsize      = PETSC_DEFAULT;
1820db966c6cSHong Zhang     jac->eu_level           = PETSC_DEFAULT; /* default */
1821db966c6cSHong Zhang     PetscFunctionReturn(0);
1822db966c6cSHong Zhang   }
182316d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
182416d9e3a6SLisandro Dalcin   if (flag) {
1825ffc4695bSBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRMPI(ierr);
1826fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
182716d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
182816d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
182916d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
183016d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
183116d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
183216d9e3a6SLisandro Dalcin     /* initialize */
183316d9e3a6SLisandro Dalcin     jac->nlevels   = 1;
18348966356dSPierre Jolivet     jac->threshold = .1;
183516d9e3a6SLisandro Dalcin     jac->filter    = .1;
183616d9e3a6SLisandro Dalcin     jac->loadbal   = 0;
18372fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
18382fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
18392fa5cd67SKarl Rupp 
184016d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
184116d9e3a6SLisandro Dalcin     jac->symt = 0;
18428966356dSPierre Jolivet     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshold,jac->nlevels));
1843fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1844fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1845fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1846fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1847fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
184816d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
184916d9e3a6SLisandro Dalcin   }
185016d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
185116d9e3a6SLisandro Dalcin   if (flag) {
185216d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
185316d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
185416d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
185516d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
185616d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
1857fd2dd295SFande Kong     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",PCGetInterpolations_BoomerAMG);CHKERRQ(ierr);
1858fd2dd295SFande Kong     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",PCGetCoarseOperators_BoomerAMG);CHKERRQ(ierr);
185916d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
186016d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
186116d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
186216d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
186316d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
186416d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
186516d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
186616d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
18678f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
186816d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
186916d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
187016d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
187116d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
187216d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
18730f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
18746a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1875b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
18761810e44eSEike Mueller     jac->eu_level         = 0;
18771810e44eSEike Mueller     jac->eu_droptolerance = 0;
18781810e44eSEike Mueller     jac->eu_bj            = 0;
1879*589dcaf0SStefano Zampini     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a PC - most likely with CG */
18800f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
188116d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
188216d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
188316d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
18840f1074feSSatish Balay     jac->interptype       = 0;
1885*589dcaf0SStefano Zampini     jac->Rtype            = 0;
1886*589dcaf0SStefano Zampini     jac->Rstrongthreshold = 0.25;
1887*589dcaf0SStefano Zampini     jac->Rfilterthreshold = 0.0;
1888*589dcaf0SStefano Zampini     jac->Adroptype        = -1;
1889*589dcaf0SStefano Zampini     jac->Adroptol         = 0.0;
18900f1074feSSatish Balay     jac->agg_nl           = 0;
18910f1074feSSatish Balay     jac->pmax             = 0;
18920f1074feSSatish Balay     jac->truncfactor      = 0.0;
18930f1074feSSatish Balay     jac->agg_num_paths    = 1;
1894*589dcaf0SStefano Zampini     jac->maxc             = 9;
1895*589dcaf0SStefano Zampini     jac->minc             = 1;
18968f87f92bSBarry Smith 
189722e51d31SStefano Zampini     jac->nodal_coarsening      = 0;
189822e51d31SStefano Zampini     jac->nodal_coarsening_diag = 0;
189922e51d31SStefano Zampini     jac->vec_interp_variant    = 0;
190022e51d31SStefano Zampini     jac->vec_interp_qmax       = 0;
190122e51d31SStefano Zampini     jac->vec_interp_smooth     = PETSC_FALSE;
190222e51d31SStefano Zampini     jac->interp_refine         = 0;
19038f87f92bSBarry Smith     jac->nodal_relax           = PETSC_FALSE;
19048f87f92bSBarry Smith     jac->nodal_relax_levels    = 1;
1905fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1906fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1907fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1908fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1909fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1910fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1911fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1912fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1913fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1914fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1915fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1916fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1917fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1918fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1919fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1920fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
1921*589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxCoarseSize,(jac->hsolver, jac->maxc));
1922*589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetMinCoarseSize,(jac->hsolver, jac->minc));
1923*589dcaf0SStefano Zampini 
1924*589dcaf0SStefano Zampini     /* AIR */
1925*589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetRestriction,(jac->hsolver,jac->Rtype));
1926*589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThresholdR,(jac->hsolver,jac->Rstrongthreshold));
1927*589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetFilterThresholdR,(jac->hsolver,jac->Rfilterthreshold));
1928*589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetADropTol,(jac->hsolver,jac->Adroptol));
1929*589dcaf0SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetADropType,(jac->hsolver,jac->Adroptype));
193016d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
193116d9e3a6SLisandro Dalcin   }
19324cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
19334cb006feSStefano Zampini   if (flag) {
19344cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
19354cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
19364cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
19374cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
19384cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
19394cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
19404cb006feSStefano Zampini     jac->coords[0]           = NULL;
19414cb006feSStefano Zampini     jac->coords[1]           = NULL;
19424cb006feSStefano Zampini     jac->coords[2]           = NULL;
19434cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1944863406b8SStefano Zampini     jac->as_print           = 0;
1945863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1946863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
19474cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
19484cb006feSStefano Zampini     /* Smoothing options */
1949863406b8SStefano Zampini     jac->as_relax_type      = 2;
1950863406b8SStefano Zampini     jac->as_relax_times     = 1;
1951863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1952863406b8SStefano Zampini     jac->as_omega           = 1.0;
19534cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1954863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1955863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
19560bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1957863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1958863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1959863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
19604cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1961863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1962863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
19630bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1964863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1965863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1966863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1967863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1968863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
19694cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1970863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1971863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1972863406b8SStefano Zampini                                                                       jac->as_relax_times,
1973863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1974863406b8SStefano Zampini                                                                       jac->as_omega));
1975863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1976863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1977863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1978863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1979863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1980863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1981863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1982863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1983863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1984863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1985863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1986863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
198723df4f25SStefano Zampini     /* Zero conductivity */
198823df4f25SStefano Zampini     jac->ams_beta_is_zero      = PETSC_FALSE;
198923df4f25SStefano Zampini     jac->ams_beta_is_zero_part = PETSC_FALSE;
19904cb006feSStefano Zampini     PetscFunctionReturn(0);
19914cb006feSStefano Zampini   }
1992863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1993863406b8SStefano Zampini   if (flag) {
1994863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1995863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1996863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1997863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1998863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1999863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
2000863406b8SStefano Zampini     jac->coords[0]           = NULL;
2001863406b8SStefano Zampini     jac->coords[1]           = NULL;
2002863406b8SStefano Zampini     jac->coords[2]           = NULL;
2003863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
2004863406b8SStefano Zampini     jac->as_print           = 0;
2005863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
2006863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
2007863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
2008863406b8SStefano Zampini     /* Smoothing options */
2009863406b8SStefano Zampini     jac->as_relax_type      = 2;
2010863406b8SStefano Zampini     jac->as_relax_times     = 1;
2011863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
2012863406b8SStefano Zampini     jac->as_omega           = 1.0;
2013863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
2014863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
2015863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
2016863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
2017863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
2018863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
2019863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
2020863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
2021863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
2022863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
2023863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
2024863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
2025863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
2026863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
2027863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
2028863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
2029863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
2030863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
2031863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
2032863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
2033863406b8SStefano Zampini                                                                       jac->as_relax_times,
2034863406b8SStefano Zampini                                                                       jac->as_relax_weight,
2035863406b8SStefano Zampini                                                                       jac->as_omega));
2036863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
2037863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
2038863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
2039863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
2040863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
2041863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
2042863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
2043863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
2044863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
2045863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
2046863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
2047863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
2048863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
2049863406b8SStefano Zampini     PetscFunctionReturn(0);
2050863406b8SStefano Zampini   }
2051503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
20522fa5cd67SKarl Rupp 
20530298fd71SBarry Smith   jac->hypre_type = NULL;
2054db966c6cSHong Zhang   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams",name);
205516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
205616d9e3a6SLisandro Dalcin }
205716d9e3a6SLisandro Dalcin 
205816d9e3a6SLisandro Dalcin /*
205916d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
206016d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
206116d9e3a6SLisandro Dalcin */
2062360ee056SFande Kong PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc)
206316d9e3a6SLisandro Dalcin {
206416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
20654ddd07fcSJed Brown   PetscInt       indx;
2066db966c6cSHong Zhang   const char     *type[] = {"euclid","pilut","parasails","boomeramg","ams","ads"};
2067ace3abfcSBarry Smith   PetscBool      flg;
206816d9e3a6SLisandro Dalcin 
206916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
20709fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
2071cab5ea25SPierre Jolivet   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,ALEN(type),"boomeramg",&indx,&flg);CHKERRQ(ierr);
207216d9e3a6SLisandro Dalcin   if (flg) {
207316d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
207402a17cd4SBarry Smith   } else {
207502a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
207616d9e3a6SLisandro Dalcin   }
207716d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
20783931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
207916d9e3a6SLisandro Dalcin   }
208016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
208116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
208216d9e3a6SLisandro Dalcin }
208316d9e3a6SLisandro Dalcin 
208416d9e3a6SLisandro Dalcin /*@C
208516d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
208616d9e3a6SLisandro Dalcin 
208716d9e3a6SLisandro Dalcin    Input Parameters:
208816d9e3a6SLisandro Dalcin +     pc - the preconditioner context
2089db966c6cSHong Zhang -     name - either  euclid, pilut, parasails, boomeramg, ams, ads
209016d9e3a6SLisandro Dalcin 
209116d9e3a6SLisandro Dalcin    Options Database Keys:
2092db966c6cSHong Zhang    -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
209316d9e3a6SLisandro Dalcin 
209416d9e3a6SLisandro Dalcin    Level: intermediate
209516d9e3a6SLisandro Dalcin 
209616d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
209716d9e3a6SLisandro Dalcin            PCHYPRE
209816d9e3a6SLisandro Dalcin 
209916d9e3a6SLisandro Dalcin @*/
21007087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
210116d9e3a6SLisandro Dalcin {
21024ac538c5SBarry Smith   PetscErrorCode ierr;
210316d9e3a6SLisandro Dalcin 
210416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
21050700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
210616d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
21074ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
210816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
210916d9e3a6SLisandro Dalcin }
211016d9e3a6SLisandro Dalcin 
211116d9e3a6SLisandro Dalcin /*@C
211216d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
211316d9e3a6SLisandro Dalcin 
211416d9e3a6SLisandro Dalcin    Input Parameter:
211516d9e3a6SLisandro Dalcin .     pc - the preconditioner context
211616d9e3a6SLisandro Dalcin 
211716d9e3a6SLisandro Dalcin    Output Parameter:
2118db966c6cSHong Zhang .     name - either  euclid, pilut, parasails, boomeramg, ams, ads
211916d9e3a6SLisandro Dalcin 
212016d9e3a6SLisandro Dalcin    Level: intermediate
212116d9e3a6SLisandro Dalcin 
212216d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
212316d9e3a6SLisandro Dalcin            PCHYPRE
212416d9e3a6SLisandro Dalcin 
212516d9e3a6SLisandro Dalcin @*/
21267087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
212716d9e3a6SLisandro Dalcin {
21284ac538c5SBarry Smith   PetscErrorCode ierr;
212916d9e3a6SLisandro Dalcin 
213016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
21310700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
213216d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
21334ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
213416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
213516d9e3a6SLisandro Dalcin }
213616d9e3a6SLisandro Dalcin 
213716d9e3a6SLisandro Dalcin /*MC
213816d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
213916d9e3a6SLisandro Dalcin 
214016d9e3a6SLisandro Dalcin    Options Database Keys:
2141db966c6cSHong Zhang +   -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
214216d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
214316d9e3a6SLisandro Dalcin           preconditioner
214416d9e3a6SLisandro Dalcin 
214516d9e3a6SLisandro Dalcin    Level: intermediate
214616d9e3a6SLisandro Dalcin 
214795452b02SPatrick Sanan    Notes:
214895452b02SPatrick Sanan     Apart from pc_hypre_type (for which there is PCHYPRESetType()),
214916d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
215016d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
215116d9e3a6SLisandro Dalcin 
2152c231f9e3SBarryFSmith           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_tol refer to the number of iterations
21530f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
21540f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
2155c231f9e3SBarryFSmith           (-pc_hypre_boomeramg_tol should be set to 0.0 - the default - to strictly use a fixed number of
21568f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
21570f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
21580f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
215916d9e3a6SLisandro Dalcin 
21600f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
21610f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
21620f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
216316d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
216416d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
216516d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
216616d9e3a6SLisandro Dalcin 
216716d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
216816d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
216916d9e3a6SLisandro Dalcin 
21705272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
2171fdd15c9aSJunchao Zhang           the following two options:
21720b1a5bd9SEric Chamberland 
2173fdd15c9aSJunchao Zhang    Options Database Keys:
21745272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
2175fdd15c9aSJunchao Zhang -   -pc_hypre_boomeramg_vec_interp_variant <v> - where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
21765272c319SBarry Smith 
21775272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
21785272c319SBarry Smith 
21799e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
21809e5bc791SBarry Smith 
218116d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
21829e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
218316d9e3a6SLisandro Dalcin 
218416d9e3a6SLisandro Dalcin M*/
218516d9e3a6SLisandro Dalcin 
21868cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
218716d9e3a6SLisandro Dalcin {
218816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
218916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
219016d9e3a6SLisandro Dalcin 
219116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
2192b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
21932fa5cd67SKarl Rupp 
219416d9e3a6SLisandro Dalcin   pc->data                = jac;
21958695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
219616d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
219716d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
219816d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
219916d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
220016d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
2201bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
2202bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
22035ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
22045ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
22055ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
22066bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",PCHYPRESetInterpolations_HYPRE);CHKERRQ(ierr);
22075ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE);CHKERRQ(ierr);
22085ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",PCHYPRESetPoissonMatrix_HYPRE);CHKERRQ(ierr);
220916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
221016d9e3a6SLisandro Dalcin }
2211ebc551c0SBarry Smith 
2212f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
2213f91d8e95SBarry Smith 
2214ebc551c0SBarry Smith typedef struct {
221568326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
2216f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
22179e5bc791SBarry Smith 
22189e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
22194ddd07fcSJed Brown   PetscInt its;
22209e5bc791SBarry Smith   double   tol;
22214ddd07fcSJed Brown   PetscInt relax_type;
22224ddd07fcSJed Brown   PetscInt rap_type;
22234ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
22244ddd07fcSJed Brown   PetscInt max_levels;
2225ebc551c0SBarry Smith } PC_PFMG;
2226ebc551c0SBarry Smith 
2227ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
2228ebc551c0SBarry Smith {
2229ebc551c0SBarry Smith   PetscErrorCode ierr;
2230f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2231ebc551c0SBarry Smith 
2232ebc551c0SBarry Smith   PetscFunctionBegin;
22332fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2234ffc4695bSBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRMPI(ierr);
2235c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2236ebc551c0SBarry Smith   PetscFunctionReturn(0);
2237ebc551c0SBarry Smith }
2238ebc551c0SBarry Smith 
22399e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
22409e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
22419e5bc791SBarry Smith 
2242ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
2243ebc551c0SBarry Smith {
2244ebc551c0SBarry Smith   PetscErrorCode ierr;
2245ace3abfcSBarry Smith   PetscBool      iascii;
2246f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2247ebc551c0SBarry Smith 
2248ebc551c0SBarry Smith   PetscFunctionBegin;
2249251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
22509e5bc791SBarry Smith   if (iascii) {
22519e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
2252efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max iterations %d\n",ex->its);CHKERRQ(ierr);
2253efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    tolerance %g\n",ex->tol);CHKERRQ(ierr);
2254efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2255efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
2256efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2257efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max levels %d\n",ex->max_levels);CHKERRQ(ierr);
22589e5bc791SBarry Smith   }
2259ebc551c0SBarry Smith   PetscFunctionReturn(0);
2260ebc551c0SBarry Smith }
2261ebc551c0SBarry Smith 
22624416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2263ebc551c0SBarry Smith {
2264ebc551c0SBarry Smith   PetscErrorCode ierr;
2265f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2266ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2267ebc551c0SBarry Smith 
2268ebc551c0SBarry Smith   PetscFunctionBegin;
2269e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
22700298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
227168326731SBarry Smith   if (flg) {
22725bd1e576SStefano Zampini     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,3));
227368326731SBarry Smith   }
22740298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2275fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
22760298fd71SBarry 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);
2277fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
22780298fd71SBarry 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);
2279fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
22809e5bc791SBarry Smith 
22810298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
2282fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
22833b46a515SGlenn Hammond 
22840298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2285fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
22860298fd71SBarry 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);
2287fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
22880298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
2289fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
2290ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
2291ebc551c0SBarry Smith   PetscFunctionReturn(0);
2292ebc551c0SBarry Smith }
2293ebc551c0SBarry Smith 
2294f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
2295f91d8e95SBarry Smith {
2296f91d8e95SBarry Smith   PetscErrorCode    ierr;
2297f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
2298d9ca1df4SBarry Smith   PetscScalar       *yy;
2299d9ca1df4SBarry Smith   const PetscScalar *xx;
23004ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
23012cf14000SStefano Zampini   HYPRE_Int         hlower[3],hupper[3];
230268326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2303f91d8e95SBarry Smith 
2304f91d8e95SBarry Smith   PetscFunctionBegin;
2305dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2306aa219208SBarry Smith   ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
23072cf14000SStefano Zampini   /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
2308f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
2309f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
2310f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
23112cf14000SStefano Zampini   hlower[0]  = (HYPRE_Int)ilower[0];
23122cf14000SStefano Zampini   hlower[1]  = (HYPRE_Int)ilower[1];
23132cf14000SStefano Zampini   hlower[2]  = (HYPRE_Int)ilower[2];
23142cf14000SStefano Zampini   hupper[0]  = (HYPRE_Int)iupper[0];
23152cf14000SStefano Zampini   hupper[1]  = (HYPRE_Int)iupper[1];
23162cf14000SStefano Zampini   hupper[2]  = (HYPRE_Int)iupper[2];
2317f91d8e95SBarry Smith 
2318f91d8e95SBarry Smith   /* copy x values over to hypre */
2319fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
2320d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
232139accc25SStefano Zampini   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,hlower,hupper,(HYPRE_Complex*)xx));
2322d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2323fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
2324fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2325f91d8e95SBarry Smith 
2326f91d8e95SBarry Smith   /* copy solution values back to PETSc */
2327f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
232839accc25SStefano Zampini   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,hlower,hupper,(HYPRE_Complex*)yy));
2329f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2330f91d8e95SBarry Smith   PetscFunctionReturn(0);
2331f91d8e95SBarry Smith }
2332f91d8e95SBarry Smith 
2333ace3abfcSBarry 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)
23349e5bc791SBarry Smith {
23359e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
23369e5bc791SBarry Smith   PetscErrorCode ierr;
23372cf14000SStefano Zampini   HYPRE_Int      oits;
23389e5bc791SBarry Smith 
23399e5bc791SBarry Smith   PetscFunctionBegin;
2340dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2341fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
2342fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
23439e5bc791SBarry Smith 
23449e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
23452cf14000SStefano Zampini   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,&oits));
23469e5bc791SBarry Smith   *outits = oits;
23479e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
23489e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2349fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
2350fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
23519e5bc791SBarry Smith   PetscFunctionReturn(0);
23529e5bc791SBarry Smith }
23539e5bc791SBarry Smith 
23549e5bc791SBarry Smith 
23553a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
23563a32d3dbSGlenn Hammond {
23573a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
23583a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
23593a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2360ace3abfcSBarry Smith   PetscBool       flg;
23613a32d3dbSGlenn Hammond 
23623a32d3dbSGlenn Hammond   PetscFunctionBegin;
2363251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
2364ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
23653a32d3dbSGlenn Hammond 
23663a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
23672fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2368fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2369fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2370fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
23713a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
23723a32d3dbSGlenn Hammond }
23733a32d3dbSGlenn Hammond 
2374ebc551c0SBarry Smith /*MC
2375ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
2376ebc551c0SBarry Smith 
2377ebc551c0SBarry Smith    Level: advanced
2378ebc551c0SBarry Smith 
23799e5bc791SBarry Smith    Options Database:
23809e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
23819e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
23829e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
23839e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
23849e5bc791SBarry 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
23859e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
2386f91d8e95SBarry Smith 
238795452b02SPatrick Sanan    Notes:
238895452b02SPatrick Sanan     This is for CELL-centered descretizations
23899e5bc791SBarry Smith 
23908e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
2391aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
23929e5bc791SBarry Smith 
23939e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
2394ebc551c0SBarry Smith M*/
2395ebc551c0SBarry Smith 
23968cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
2397ebc551c0SBarry Smith {
2398ebc551c0SBarry Smith   PetscErrorCode ierr;
2399ebc551c0SBarry Smith   PC_PFMG        *ex;
2400ebc551c0SBarry Smith 
2401ebc551c0SBarry Smith   PetscFunctionBegin;
2402b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
240368326731SBarry Smith   pc->data = ex;
2404ebc551c0SBarry Smith 
24059e5bc791SBarry Smith   ex->its            = 1;
24069e5bc791SBarry Smith   ex->tol            = 1.e-8;
24079e5bc791SBarry Smith   ex->relax_type     = 1;
24089e5bc791SBarry Smith   ex->rap_type       = 0;
24099e5bc791SBarry Smith   ex->num_pre_relax  = 1;
24109e5bc791SBarry Smith   ex->num_post_relax = 1;
24113b46a515SGlenn Hammond   ex->max_levels     = 0;
24129e5bc791SBarry Smith 
2413ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2414ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2415ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2416f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
24179e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
241868326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
24192fa5cd67SKarl Rupp 
2420ffc4695bSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRMPI(ierr);
2421fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2422ebc551c0SBarry Smith   PetscFunctionReturn(0);
2423ebc551c0SBarry Smith }
2424d851a50bSGlenn Hammond 
2425325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2426325fc9f4SBarry Smith 
2427d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2428d851a50bSGlenn Hammond typedef struct {
2429d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2430d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2431d851a50bSGlenn Hammond 
2432d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
24334ddd07fcSJed Brown   PetscInt its;
2434d851a50bSGlenn Hammond   double   tol;
24354ddd07fcSJed Brown   PetscInt relax_type;
24364ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2437d851a50bSGlenn Hammond } PC_SysPFMG;
2438d851a50bSGlenn Hammond 
2439d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2440d851a50bSGlenn Hammond {
2441d851a50bSGlenn Hammond   PetscErrorCode ierr;
2442d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2443d851a50bSGlenn Hammond 
2444d851a50bSGlenn Hammond   PetscFunctionBegin;
24452fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2446ffc4695bSBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRMPI(ierr);
2447c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2448d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2449d851a50bSGlenn Hammond }
2450d851a50bSGlenn Hammond 
2451d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2452d851a50bSGlenn Hammond 
2453d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2454d851a50bSGlenn Hammond {
2455d851a50bSGlenn Hammond   PetscErrorCode ierr;
2456ace3abfcSBarry Smith   PetscBool      iascii;
2457d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2458d851a50bSGlenn Hammond 
2459d851a50bSGlenn Hammond   PetscFunctionBegin;
2460251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2461d851a50bSGlenn Hammond   if (iascii) {
2462d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2463efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  max iterations %d\n",ex->its);CHKERRQ(ierr);
2464efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerance %g\n",ex->tol);CHKERRQ(ierr);
2465efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2466efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2467d851a50bSGlenn Hammond   }
2468d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2469d851a50bSGlenn Hammond }
2470d851a50bSGlenn Hammond 
24714416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2472d851a50bSGlenn Hammond {
2473d851a50bSGlenn Hammond   PetscErrorCode ierr;
2474d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2475ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2476d851a50bSGlenn Hammond 
2477d851a50bSGlenn Hammond   PetscFunctionBegin;
2478e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
24790298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2480d851a50bSGlenn Hammond   if (flg) {
24815bd1e576SStefano Zampini     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,3));
2482d851a50bSGlenn Hammond   }
24830298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2484fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
24850298fd71SBarry 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);
2486fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
24870298fd71SBarry 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);
2488fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2489d851a50bSGlenn Hammond 
24900298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2491fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
249261710fbeSStefano 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);
2493fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2494d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2495d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2496d851a50bSGlenn Hammond }
2497d851a50bSGlenn Hammond 
2498d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2499d851a50bSGlenn Hammond {
2500d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2501d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2502d9ca1df4SBarry Smith   PetscScalar       *yy;
2503d9ca1df4SBarry Smith   const PetscScalar *xx;
25044ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
25052cf14000SStefano Zampini   HYPRE_Int         hlower[3],hupper[3];
2506d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
25074ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
25084ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
25094ddd07fcSJed Brown   PetscInt          part    = 0;
25104ddd07fcSJed Brown   PetscInt          size;
25114ddd07fcSJed Brown   PetscInt          i;
2512d851a50bSGlenn Hammond 
2513d851a50bSGlenn Hammond   PetscFunctionBegin;
2514dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2515aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
25162cf14000SStefano Zampini   /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
2517d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2518d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2519d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
25202cf14000SStefano Zampini   hlower[0]  = (HYPRE_Int)ilower[0];
25212cf14000SStefano Zampini   hlower[1]  = (HYPRE_Int)ilower[1];
25222cf14000SStefano Zampini   hlower[2]  = (HYPRE_Int)ilower[2];
25232cf14000SStefano Zampini   hupper[0]  = (HYPRE_Int)iupper[0];
25242cf14000SStefano Zampini   hupper[1]  = (HYPRE_Int)iupper[1];
25252cf14000SStefano Zampini   hupper[2]  = (HYPRE_Int)iupper[2];
2526d851a50bSGlenn Hammond 
2527d851a50bSGlenn Hammond   size = 1;
25282fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
25292fa5cd67SKarl Rupp 
2530d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2531d851a50bSGlenn Hammond   if (ordering) {
2532fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2533d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
253439accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(xx+(size*i))));
2535d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2536fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2537fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2538fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2539d851a50bSGlenn Hammond 
2540d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2541d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
254239accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(yy+(size*i))));
2543d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2544a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2545d851a50bSGlenn Hammond     PetscScalar *z;
25464ddd07fcSJed Brown     PetscInt    j, k;
2547d851a50bSGlenn Hammond 
2548785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2549fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2550d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2551d851a50bSGlenn Hammond 
2552d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2553d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2554d851a50bSGlenn Hammond       k= i*nvars;
25552fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2556d851a50bSGlenn Hammond     }
255739accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i))));
2558d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2559fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2560fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2561d851a50bSGlenn Hammond 
2562d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2563d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
256439accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i))));
2565d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2566d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2567d851a50bSGlenn Hammond       k= i*nvars;
25682fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2569d851a50bSGlenn Hammond     }
2570d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2571d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2572d851a50bSGlenn Hammond   }
2573d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2574d851a50bSGlenn Hammond }
2575d851a50bSGlenn Hammond 
2576ace3abfcSBarry 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)
2577d851a50bSGlenn Hammond {
2578d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2579d851a50bSGlenn Hammond   PetscErrorCode ierr;
25802cf14000SStefano Zampini   HYPRE_Int      oits;
2581d851a50bSGlenn Hammond 
2582d851a50bSGlenn Hammond   PetscFunctionBegin;
2583dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2584fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2585fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2586d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
25872cf14000SStefano Zampini   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,&oits));
2588d851a50bSGlenn Hammond   *outits = oits;
2589d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2590d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2591fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2592fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2593d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2594d851a50bSGlenn Hammond }
2595d851a50bSGlenn Hammond 
2596d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2597d851a50bSGlenn Hammond {
2598d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2599d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2600d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2601ace3abfcSBarry Smith   PetscBool        flg;
2602d851a50bSGlenn Hammond 
2603d851a50bSGlenn Hammond   PetscFunctionBegin;
2604251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2605ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2606d851a50bSGlenn Hammond 
2607d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
26082fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2609fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2610fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2611fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2612d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2613d851a50bSGlenn Hammond }
2614d851a50bSGlenn Hammond 
2615d851a50bSGlenn Hammond /*MC
2616d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2617d851a50bSGlenn Hammond 
2618d851a50bSGlenn Hammond    Level: advanced
2619d851a50bSGlenn Hammond 
2620d851a50bSGlenn Hammond    Options Database:
2621d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2622d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2623d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2624d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2625a2b725a8SWilliam Gropp - -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2626d851a50bSGlenn Hammond 
262795452b02SPatrick Sanan    Notes:
262895452b02SPatrick Sanan     This is for CELL-centered descretizations
2629d851a50bSGlenn Hammond 
2630f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2631aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2632d851a50bSGlenn Hammond            Also, only cell-centered variables.
2633d851a50bSGlenn Hammond 
2634d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2635d851a50bSGlenn Hammond M*/
2636d851a50bSGlenn Hammond 
26378cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2638d851a50bSGlenn Hammond {
2639d851a50bSGlenn Hammond   PetscErrorCode ierr;
2640d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2641d851a50bSGlenn Hammond 
2642d851a50bSGlenn Hammond   PetscFunctionBegin;
2643b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2644d851a50bSGlenn Hammond   pc->data = ex;
2645d851a50bSGlenn Hammond 
2646d851a50bSGlenn Hammond   ex->its            = 1;
2647d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2648d851a50bSGlenn Hammond   ex->relax_type     = 1;
2649d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2650d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2651d851a50bSGlenn Hammond 
2652d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2653d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2654d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2655d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2656d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2657d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
26582fa5cd67SKarl Rupp 
2659ffc4695bSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRMPI(ierr);
2660fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2661d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2662d851a50bSGlenn Hammond }
2663