xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision fd2dd29587ccae96583179f094812ea051599fc0)
116d9e3a6SLisandro Dalcin 
216d9e3a6SLisandro Dalcin /*
316d9e3a6SLisandro Dalcin    Provides an interface to the LLNL package hypre
416d9e3a6SLisandro Dalcin */
50f1074feSSatish Balay 
60f1074feSSatish Balay /* Must use hypre 2.0.0 or more recent. */
70f1074feSSatish Balay 
8af0996ceSBarry Smith #include <petsc/private/pcimpl.h>          /*I "petscpc.h" I*/
949a781f5SStefano Zampini /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1049a781f5SStefano Zampini #include <petsc/private/matimpl.h>
1158968eb6SStefano Zampini #include <../src/vec/vec/impls/hypre/vhyp.h>
1249a781f5SStefano Zampini #include <../src/mat/impls/hypre/mhypre.h>
13c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h>
144cb006feSStefano Zampini #include <_hypre_parcsr_ls.h>
158a2c336bSFande Kong #include <petscmathypre.h>
1616d9e3a6SLisandro Dalcin 
17dff31646SBarry Smith static PetscBool cite = PETSC_FALSE;
18a8d69d7bSBarry 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";
191f817a21SBarry Smith 
2016d9e3a6SLisandro Dalcin /*
2116d9e3a6SLisandro Dalcin    Private context (data structure) for the  preconditioner.
2216d9e3a6SLisandro Dalcin */
2316d9e3a6SLisandro Dalcin typedef struct {
2416d9e3a6SLisandro Dalcin   HYPRE_Solver   hsolver;
2549a781f5SStefano Zampini   Mat            hpmat; /* MatHYPRE */
2616d9e3a6SLisandro Dalcin 
274ddd07fcSJed Brown   HYPRE_Int (*destroy)(HYPRE_Solver);
284ddd07fcSJed Brown   HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
294ddd07fcSJed Brown   HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
3016d9e3a6SLisandro Dalcin 
3116d9e3a6SLisandro Dalcin   MPI_Comm comm_hypre;
3216d9e3a6SLisandro Dalcin   char     *hypre_type;
3316d9e3a6SLisandro Dalcin 
3416d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
354ddd07fcSJed Brown   PetscInt maxiter;
3616d9e3a6SLisandro Dalcin   double   tol;
3716d9e3a6SLisandro Dalcin 
3816d9e3a6SLisandro Dalcin   /* options for Pilut */
394ddd07fcSJed Brown   PetscInt factorrowsize;
4016d9e3a6SLisandro Dalcin 
4116d9e3a6SLisandro Dalcin   /* options for ParaSails */
424ddd07fcSJed Brown   PetscInt nlevels;
4316d9e3a6SLisandro Dalcin   double   threshhold;
4416d9e3a6SLisandro Dalcin   double   filter;
454ddd07fcSJed Brown   PetscInt sym;
4616d9e3a6SLisandro Dalcin   double   loadbal;
474ddd07fcSJed Brown   PetscInt logging;
484ddd07fcSJed Brown   PetscInt ruse;
494ddd07fcSJed Brown   PetscInt symt;
5016d9e3a6SLisandro Dalcin 
5122b6d1caSBarry Smith   /* options for BoomerAMG */
52ace3abfcSBarry Smith   PetscBool printstatistics;
5316d9e3a6SLisandro Dalcin 
5416d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
554ddd07fcSJed Brown   PetscInt  cycletype;
564ddd07fcSJed Brown   PetscInt  maxlevels;
5716d9e3a6SLisandro Dalcin   double    strongthreshold;
5816d9e3a6SLisandro Dalcin   double    maxrowsum;
594ddd07fcSJed Brown   PetscInt  gridsweeps[3];
604ddd07fcSJed Brown   PetscInt  coarsentype;
614ddd07fcSJed Brown   PetscInt  measuretype;
626a251517SEike Mueller   PetscInt  smoothtype;
638131ecf7SEike Mueller   PetscInt  smoothnumlevels;
64ec64516dSEike Mueller   PetscInt  eu_level;   /* Number of levels for ILU(k) in Euclid */
65ec64516dSEike Mueller   double    eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */
66ec64516dSEike Mueller   PetscInt  eu_bj;      /* Defines use of Block Jacobi ILU in Euclid */
674ddd07fcSJed Brown   PetscInt  relaxtype[3];
6816d9e3a6SLisandro Dalcin   double    relaxweight;
6916d9e3a6SLisandro Dalcin   double    outerrelaxweight;
704ddd07fcSJed Brown   PetscInt  relaxorder;
7116d9e3a6SLisandro Dalcin   double    truncfactor;
72ace3abfcSBarry Smith   PetscBool applyrichardson;
734ddd07fcSJed Brown   PetscInt  pmax;
744ddd07fcSJed Brown   PetscInt  interptype;
754ddd07fcSJed Brown   PetscInt  agg_nl;
764ddd07fcSJed Brown   PetscInt  agg_num_paths;
77ace3abfcSBarry Smith   PetscBool nodal_relax;
784ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
794cb006feSStefano Zampini 
805272c319SBarry Smith   PetscInt  nodal_coarsening;
8122e51d31SStefano Zampini   PetscInt  nodal_coarsening_diag;
825272c319SBarry Smith   PetscInt  vec_interp_variant;
8322e51d31SStefano Zampini   PetscInt  vec_interp_qmax;
8422e51d31SStefano Zampini   PetscBool vec_interp_smooth;
8522e51d31SStefano Zampini   PetscInt  interp_refine;
8622e51d31SStefano Zampini 
875272c319SBarry Smith   HYPRE_IJVector  *hmnull;
885272c319SBarry Smith   HYPRE_ParVector *phmnull;  /* near null space passed to hypre */
895272c319SBarry Smith   PetscInt        n_hmnull;
905272c319SBarry Smith   Vec             hmnull_constant;
9172827435SBarry Smith   PetscScalar     **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 */
925272c319SBarry Smith 
93863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
94863406b8SStefano Zampini   PetscInt  as_print;
95863406b8SStefano Zampini   PetscInt  as_max_iter;
96863406b8SStefano Zampini   PetscReal as_tol;
97863406b8SStefano Zampini   PetscInt  as_relax_type;
98863406b8SStefano Zampini   PetscInt  as_relax_times;
99863406b8SStefano Zampini   PetscReal as_relax_weight;
100863406b8SStefano Zampini   PetscReal as_omega;
101863406b8SStefano 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) */
102863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
103863406b8SStefano 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) */
104863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
1054cb006feSStefano Zampini   PetscInt  ams_cycle_type;
106863406b8SStefano Zampini   PetscInt  ads_cycle_type;
1074cb006feSStefano Zampini 
1084cb006feSStefano Zampini   /* additional data */
1095ac14e1cSStefano Zampini   Mat G;             /* MatHYPRE */
1105ac14e1cSStefano Zampini   Mat C;             /* MatHYPRE */
1115ac14e1cSStefano Zampini   Mat alpha_Poisson; /* MatHYPRE */
1125ac14e1cSStefano Zampini   Mat beta_Poisson;  /* MatHYPRE */
1135ac14e1cSStefano Zampini 
1145ac14e1cSStefano Zampini   /* extra information for AMS */
1155ac14e1cSStefano Zampini   PetscInt       dim; /* geometrical dimension */
1164cb006feSStefano Zampini   HYPRE_IJVector coords[3];
1174cb006feSStefano Zampini   HYPRE_IJVector constants[3];
1186bf688a0SCe Qin   Mat            RT_PiFull, RT_Pi[3];
1196bf688a0SCe Qin   Mat            ND_PiFull, ND_Pi[3];
1204cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
12123df4f25SStefano Zampini   PetscBool      ams_beta_is_zero_part;
12223df4f25SStefano Zampini   PetscInt       ams_proj_freq;
12316d9e3a6SLisandro Dalcin } PC_HYPRE;
12416d9e3a6SLisandro Dalcin 
125d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
126d2128fa2SBarry Smith {
127d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
128d2128fa2SBarry Smith 
129d2128fa2SBarry Smith   PetscFunctionBegin;
130d2128fa2SBarry Smith   *hsolver = jac->hsolver;
131d2128fa2SBarry Smith   PetscFunctionReturn(0);
132d2128fa2SBarry Smith }
13316d9e3a6SLisandro Dalcin 
134*fd2dd295SFande Kong /*
1358a2c336bSFande Kong   Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix
1368a2c336bSFande Kong   is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine.
1378a2c336bSFande Kong   It is used in PCHMG. Other users should avoid using this function.
138*fd2dd295SFande Kong */
139*fd2dd295SFande Kong static PetscErrorCode PCGetCoarseOperators_BoomerAMG(PC pc,PetscInt *nlevels,Mat *operators[])
1408a2c336bSFande Kong {
1418a2c336bSFande Kong   PC_HYPRE             *jac  = (PC_HYPRE*)pc->data;
1428a2c336bSFande Kong   PetscBool            same = PETSC_FALSE;
1438a2c336bSFande Kong   PetscErrorCode       ierr;
1448a2c336bSFande Kong   PetscInt             num_levels,l;
1458a2c336bSFande Kong   Mat                  *mattmp;
1468a2c336bSFande Kong   hypre_ParCSRMatrix   **A_array;
1478a2c336bSFande Kong 
1488a2c336bSFande Kong   PetscFunctionBegin;
1498a2c336bSFande Kong   PetscValidIntPointer(nlevels,2);
1508a2c336bSFande Kong   PetscValidIntPointer(operators,3);
1518a2c336bSFande Kong   ierr = PetscStrcmp(jac->hypre_type,"boomeramg",&same);CHKERRQ(ierr);
1528a2c336bSFande Kong   if (!same) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_NOTSAMETYPE,"Hypre type is not BoomerAMG \n");
1538a2c336bSFande Kong   num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData*) (jac->hsolver));
1548a2c336bSFande Kong   ierr = PetscMalloc1(num_levels,&mattmp);CHKERRQ(ierr);
1558a2c336bSFande Kong   A_array    = hypre_ParAMGDataAArray((hypre_ParAMGData*) (jac->hsolver));
1568a2c336bSFande Kong   for (l=1; l<num_levels; l++) {
1578a2c336bSFande Kong     ierr = MatCreateFromParCSR(A_array[l],MATAIJ,PETSC_OWN_POINTER, &(mattmp[num_levels-1-l]));CHKERRQ(ierr);
1588a2c336bSFande Kong     /* We want to own the data, and HYPRE can not touch this matrix any more */
1598a2c336bSFande Kong     A_array[l] = NULL;
1608a2c336bSFande Kong   }
1618a2c336bSFande Kong   *nlevels = num_levels;
1628a2c336bSFande Kong   *operators = mattmp;
1638a2c336bSFande Kong   PetscFunctionReturn(0);
1648a2c336bSFande Kong }
1658a2c336bSFande Kong 
166*fd2dd295SFande Kong /*
1678a2c336bSFande Kong   Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix
1688a2c336bSFande Kong   is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine.
1698a2c336bSFande Kong   It is used in PCHMG. Other users should avoid using this function.
170*fd2dd295SFande Kong */
171*fd2dd295SFande Kong static PetscErrorCode PCGetInterpolations_BoomerAMG(PC pc,PetscInt *nlevels,Mat *interpolations[])
1728a2c336bSFande Kong {
1738a2c336bSFande Kong   PC_HYPRE             *jac  = (PC_HYPRE*)pc->data;
1748a2c336bSFande Kong   PetscBool            same = PETSC_FALSE;
1758a2c336bSFande Kong   PetscErrorCode       ierr;
1768a2c336bSFande Kong   PetscInt             num_levels,l;
1778a2c336bSFande Kong   Mat                  *mattmp;
1788a2c336bSFande Kong   hypre_ParCSRMatrix   **P_array;
1798a2c336bSFande Kong 
1808a2c336bSFande Kong   PetscFunctionBegin;
1818a2c336bSFande Kong   PetscValidIntPointer(nlevels,2);
1828a2c336bSFande Kong   PetscValidIntPointer(interpolations,3);
1838a2c336bSFande Kong   ierr = PetscStrcmp(jac->hypre_type,"boomeramg",&same);CHKERRQ(ierr);
1848a2c336bSFande Kong   if (!same) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_NOTSAMETYPE,"Hypre type is not BoomerAMG \n");
1858a2c336bSFande Kong   num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData*) (jac->hsolver));
1868a2c336bSFande Kong   ierr = PetscMalloc1(num_levels,&mattmp);CHKERRQ(ierr);
1878a2c336bSFande Kong   P_array  = hypre_ParAMGDataPArray((hypre_ParAMGData*) (jac->hsolver));
1888a2c336bSFande Kong   for (l=1; l<num_levels; l++) {
1898a2c336bSFande Kong     ierr = MatCreateFromParCSR(P_array[num_levels-1-l],MATAIJ,PETSC_OWN_POINTER, &(mattmp[l-1]));CHKERRQ(ierr);
1908a2c336bSFande Kong     /* We want to own the data, and HYPRE can not touch this matrix any more */
1918a2c336bSFande Kong     P_array[num_levels-1-l] = NULL;
1928a2c336bSFande Kong   }
1938a2c336bSFande Kong   *nlevels = num_levels;
1948a2c336bSFande Kong   *interpolations = mattmp;
1958a2c336bSFande Kong   PetscFunctionReturn(0);
1968a2c336bSFande Kong }
1978a2c336bSFande Kong 
198ce6a8a0dSJed Brown /* Resets (frees) Hypre's representation of the near null space */
199ce6a8a0dSJed Brown static PetscErrorCode PCHYPREResetNearNullSpace_Private(PC pc)
200ce6a8a0dSJed Brown {
201ce6a8a0dSJed Brown   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
202ce6a8a0dSJed Brown   PetscInt       i;
2039d678128SJed Brown   PetscErrorCode ierr;
204ce6a8a0dSJed Brown   PETSC_UNUSED PetscScalar *petscvecarray;
205ce6a8a0dSJed Brown 
2069d678128SJed Brown   PetscFunctionBegin;
207ce6a8a0dSJed Brown   for (i=0; i<jac->n_hmnull; i++) {
208ce6a8a0dSJed Brown     VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],jac->hmnull_hypre_data_array[i],petscvecarray);
209ce6a8a0dSJed Brown     PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->hmnull[i]));
210ce6a8a0dSJed Brown   }
211ce6a8a0dSJed Brown   ierr = PetscFree(jac->hmnull);CHKERRQ(ierr);
212ce6a8a0dSJed Brown   ierr = PetscFree(jac->hmnull_hypre_data_array);CHKERRQ(ierr);
213ce6a8a0dSJed Brown   ierr = PetscFree(jac->phmnull);CHKERRQ(ierr);
214ce6a8a0dSJed Brown   ierr = VecDestroy(&jac->hmnull_constant);CHKERRQ(ierr);
2159d678128SJed Brown   jac->n_hmnull = 0;
216ce6a8a0dSJed Brown   PetscFunctionReturn(0);
217ce6a8a0dSJed Brown }
218ce6a8a0dSJed Brown 
21916d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
22016d9e3a6SLisandro Dalcin {
22116d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
22249a781f5SStefano Zampini   Mat_HYPRE          *hjac;
22316d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
22416d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
22549a781f5SStefano Zampini   PetscBool          ishypre;
22649a781f5SStefano Zampini   PetscErrorCode     ierr;
22716d9e3a6SLisandro Dalcin 
22816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
22916d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
23002a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
23116d9e3a6SLisandro Dalcin   }
2325f5c5b43SBarry Smith 
23349a781f5SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRE,&ishypre);CHKERRQ(ierr);
23449a781f5SStefano Zampini   if (!ishypre) {
2356bf688a0SCe Qin     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
2366bf688a0SCe Qin     ierr = MatConvert(pc->pmat,MATHYPRE,MAT_INITIAL_MATRIX,&jac->hpmat);CHKERRQ(ierr);
23749a781f5SStefano Zampini   } else {
23849a781f5SStefano Zampini     ierr = PetscObjectReference((PetscObject)pc->pmat);CHKERRQ(ierr);
23949a781f5SStefano Zampini     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
24049a781f5SStefano Zampini     jac->hpmat = pc->pmat;
24116d9e3a6SLisandro Dalcin   }
24249a781f5SStefano Zampini   hjac = (Mat_HYPRE*)(jac->hpmat->data);
2435f5c5b43SBarry Smith 
24416d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
24516d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
2465272c319SBarry Smith     MatNullSpace    mnull;
2475272c319SBarry Smith     PetscBool       has_const;
24849a781f5SStefano Zampini     PetscInt        bs,nvec,i;
2495272c319SBarry Smith     const Vec       *vecs;
25072827435SBarry Smith     PetscScalar     *petscvecarray;
2515272c319SBarry Smith 
25216d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
2532fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
2545272c319SBarry Smith     ierr = MatGetNearNullSpace(pc->mat, &mnull);CHKERRQ(ierr);
2555272c319SBarry Smith     if (mnull) {
256ce6a8a0dSJed Brown       ierr = PCHYPREResetNearNullSpace_Private(pc);CHKERRQ(ierr);
2575272c319SBarry Smith       ierr = MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs);CHKERRQ(ierr);
2585272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull);CHKERRQ(ierr);
25972827435SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull_hypre_data_array);CHKERRQ(ierr);
2605272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->phmnull);CHKERRQ(ierr);
2615272c319SBarry Smith       for (i=0; i<nvec; i++) {
2625272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(vecs[i],&jac->hmnull[i]);CHKERRQ(ierr);
26372827435SBarry Smith         ierr = VecGetArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
26458968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],petscvecarray,jac->hmnull_hypre_data_array[i]);
26572827435SBarry Smith         ierr = VecRestoreArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
2665272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[i],(void**)&jac->phmnull[i]));
2675272c319SBarry Smith       }
2685272c319SBarry Smith       if (has_const) {
2695272c319SBarry Smith         ierr = MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL);CHKERRQ(ierr);
2705272c319SBarry Smith         ierr = VecSet(jac->hmnull_constant,1);CHKERRQ(ierr);
2715272c319SBarry Smith         ierr = VecNormalize(jac->hmnull_constant,NULL);
2725272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(jac->hmnull_constant,&jac->hmnull[nvec]);CHKERRQ(ierr);
27372827435SBarry Smith         ierr = VecGetArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
27458968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[nvec],petscvecarray,jac->hmnull_hypre_data_array[nvec]);
27572827435SBarry Smith         ierr = VecRestoreArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
2765272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[nvec],(void**)&jac->phmnull[nvec]));
2775272c319SBarry Smith         nvec++;
2785272c319SBarry Smith       }
2795272c319SBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVectors,(jac->hsolver,nvec,jac->phmnull));
2805272c319SBarry Smith       jac->n_hmnull = nvec;
2815272c319SBarry Smith     }
2824cb006feSStefano Zampini   }
283863406b8SStefano Zampini 
2844cb006feSStefano Zampini   /* special case for AMS */
2854cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
2865ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2875ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
2886bf688a0SCe Qin     if (!jac->coords[0] && !jac->constants[0] && !(jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
2896bf688a0SCe 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");
2906bf688a0SCe Qin     }
2915ac14e1cSStefano Zampini     if (jac->dim) {
2925ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,jac->dim));
2935ac14e1cSStefano Zampini     }
2945ac14e1cSStefano Zampini     if (jac->constants[0]) {
2955ac14e1cSStefano Zampini       HYPRE_ParVector ozz,zoz,zzo = NULL;
2965ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&ozz)));
2975ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&zoz)));
2985ac14e1cSStefano Zampini       if (jac->constants[2]) {
2995ac14e1cSStefano Zampini         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&zzo)));
3005ac14e1cSStefano Zampini       }
3015ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,ozz,zoz,zzo));
3025ac14e1cSStefano Zampini     }
3035ac14e1cSStefano Zampini     if (jac->coords[0]) {
3045ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
3055ac14e1cSStefano Zampini       coords[0] = NULL;
3065ac14e1cSStefano Zampini       coords[1] = NULL;
3075ac14e1cSStefano Zampini       coords[2] = NULL;
3085ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
3095ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
3105ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
3115ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
3125ac14e1cSStefano Zampini     }
31349a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
3145ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
3155ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3165ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr));
3175ac14e1cSStefano Zampini     if (jac->alpha_Poisson) {
3185ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->alpha_Poisson->data);
3195ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3205ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr));
3215ac14e1cSStefano Zampini     }
3225ac14e1cSStefano Zampini     if (jac->ams_beta_is_zero) {
3235ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
3245ac14e1cSStefano Zampini     } else if (jac->beta_Poisson) {
3255ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->beta_Poisson->data);
3265ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3275ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr));
3285ac14e1cSStefano Zampini     }
3296bf688a0SCe Qin     if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) {
3306bf688a0SCe Qin       PetscInt           i;
3316bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
3326bf688a0SCe Qin       if (jac->ND_PiFull) {
3336bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
3346bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
3356bf688a0SCe Qin       } else {
3366bf688a0SCe Qin         nd_parcsrfull = NULL;
3376bf688a0SCe Qin       }
3386bf688a0SCe Qin       for (i=0;i<3;++i) {
3396bf688a0SCe Qin         if (jac->ND_Pi[i]) {
3406bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
3416bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
3426bf688a0SCe Qin         } else {
3436bf688a0SCe Qin           nd_parcsr[i] = NULL;
3446bf688a0SCe Qin         }
3456bf688a0SCe Qin       }
3466bf688a0SCe Qin       PetscStackCallStandard(HYPRE_AMSSetInterpolations,(jac->hsolver,nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]));
3476bf688a0SCe Qin     }
3484cb006feSStefano Zampini   }
349863406b8SStefano Zampini   /* special case for ADS */
350863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
3515ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
3525ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
3536bf688a0SCe 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])))) {
3546bf688a0SCe Qin       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations");
3556bf688a0SCe Qin     }
35637096e45SBarry 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");
35749a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
35849a781f5SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient");
3595ac14e1cSStefano Zampini     if (jac->coords[0]) {
3605ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
3615ac14e1cSStefano Zampini       coords[0] = NULL;
3625ac14e1cSStefano Zampini       coords[1] = NULL;
3635ac14e1cSStefano Zampini       coords[2] = NULL;
3645ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
3655ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
3665ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
3675ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_ADSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
3685ac14e1cSStefano Zampini     }
3695ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
3705ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3715ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteGradient,(jac->hsolver,parcsr));
3725ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->C->data);
3735ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3745ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteCurl,(jac->hsolver,parcsr));
3756bf688a0SCe Qin     if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
3766bf688a0SCe Qin       PetscInt           i;
3776bf688a0SCe Qin       HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3];
3786bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
3796bf688a0SCe Qin       if (jac->RT_PiFull) {
3806bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->RT_PiFull->data);
3816bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsrfull)));
3826bf688a0SCe Qin       } else {
3836bf688a0SCe Qin         rt_parcsrfull = NULL;
3846bf688a0SCe Qin       }
3856bf688a0SCe Qin       for (i=0;i<3;++i) {
3866bf688a0SCe Qin         if (jac->RT_Pi[i]) {
3876bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->RT_Pi[i]->data);
3886bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsr[i])));
3896bf688a0SCe Qin         } else {
3906bf688a0SCe Qin           rt_parcsr[i] = NULL;
3916bf688a0SCe Qin         }
3926bf688a0SCe Qin       }
3936bf688a0SCe Qin       if (jac->ND_PiFull) {
3946bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
3956bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
3966bf688a0SCe Qin       } else {
3976bf688a0SCe Qin         nd_parcsrfull = NULL;
3986bf688a0SCe Qin       }
3996bf688a0SCe Qin       for (i=0;i<3;++i) {
4006bf688a0SCe Qin         if (jac->ND_Pi[i]) {
4016bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
4026bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
4036bf688a0SCe Qin         } else {
4046bf688a0SCe Qin           nd_parcsr[i] = NULL;
4056bf688a0SCe Qin         }
4066bf688a0SCe Qin       }
4076bf688a0SCe 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]));
4086bf688a0SCe Qin     }
409863406b8SStefano Zampini   }
41049a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
41149a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&bv));
41249a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&xv));
41322e51d31SStefano Zampini   PetscStackCallStandard(jac->setup,(jac->hsolver,hmat,bv,xv));
41416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
41516d9e3a6SLisandro Dalcin }
41616d9e3a6SLisandro Dalcin 
41716d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
41816d9e3a6SLisandro Dalcin {
41916d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
42049a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
42116d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
42216d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
423d9ca1df4SBarry Smith   PetscScalar        *xv;
424d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
42516d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
426d9ca1df4SBarry Smith   PetscScalar        *sxv;
4274ddd07fcSJed Brown   PetscInt           hierr;
42816d9e3a6SLisandro Dalcin 
42916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
430dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
43116d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
432d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
43316d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
43458968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)bv,sbv);
43558968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
43616d9e3a6SLisandro Dalcin 
43749a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
43849a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
43949a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
440fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
44165e19b50SBarry Smith   if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
442fd3f9acdSBarry Smith   if (hierr) hypre__global_error = 0;);
44316d9e3a6SLisandro Dalcin 
44423df4f25SStefano Zampini   if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) {
4455ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSProjectOutGradients,(jac->hsolver,jxv));
44621df291bSStefano Zampini   }
44758968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)sbv,bv);
44858968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
44916d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
450d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
45116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
45216d9e3a6SLisandro Dalcin }
45316d9e3a6SLisandro Dalcin 
4548695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc)
4558695de01SBarry Smith {
4568695de01SBarry Smith   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
4578695de01SBarry Smith   PetscErrorCode ierr;
4588695de01SBarry Smith 
4598695de01SBarry Smith   PetscFunctionBegin;
46049a781f5SStefano Zampini   ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
4615ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
4625ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
4635ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
4645ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
4656bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
4666bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[0]);CHKERRQ(ierr);
4676bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[1]);CHKERRQ(ierr);
4686bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[2]);CHKERRQ(ierr);
4696bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
4706bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[0]);CHKERRQ(ierr);
4716bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[1]);CHKERRQ(ierr);
4726bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[2]);CHKERRQ(ierr);
4738695de01SBarry Smith   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); jac->coords[0] = NULL;
4748695de01SBarry Smith   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); jac->coords[1] = NULL;
4758695de01SBarry Smith   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); jac->coords[2] = NULL;
4768695de01SBarry Smith   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); jac->constants[0] = NULL;
4778695de01SBarry Smith   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); jac->constants[1] = NULL;
4788695de01SBarry Smith   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); jac->constants[2] = NULL;
479ce6a8a0dSJed Brown   ierr = PCHYPREResetNearNullSpace_Private(pc);CHKERRQ(ierr);
4805ac14e1cSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
4815ac14e1cSStefano Zampini   jac->dim = 0;
4828695de01SBarry Smith   PetscFunctionReturn(0);
4838695de01SBarry Smith }
4848695de01SBarry Smith 
48516d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
48616d9e3a6SLisandro Dalcin {
48716d9e3a6SLisandro Dalcin   PC_HYPRE                 *jac = (PC_HYPRE*)pc->data;
48816d9e3a6SLisandro Dalcin   PetscErrorCode           ierr;
48916d9e3a6SLisandro Dalcin 
49016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
4918695de01SBarry Smith   ierr = PCReset_HYPRE(pc);CHKERRQ(ierr);
49222e51d31SStefano Zampini   if (jac->destroy) PetscStackCallStandard(jac->destroy,(jac->hsolver));
493503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
49416d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
495c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
49616d9e3a6SLisandro Dalcin 
49716d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
498bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
499bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
5004cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
5014cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
502863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
5036bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",NULL);CHKERRQ(ierr);
5044cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
5055ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",NULL);CHKERRQ(ierr);
506*fd2dd295SFande Kong   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",NULL);CHKERRQ(ierr);
507*fd2dd295SFande Kong   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",NULL);CHKERRQ(ierr);
50816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
50916d9e3a6SLisandro Dalcin }
51016d9e3a6SLisandro Dalcin 
51116d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
5124416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptionItems *PetscOptionsObject,PC pc)
51316d9e3a6SLisandro Dalcin {
51416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
51516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
516ace3abfcSBarry Smith   PetscBool      flag;
51716d9e3a6SLisandro Dalcin 
51816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
519e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
52016d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
521fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
52216d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
523fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
52416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
525fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
52616d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
52716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
52816d9e3a6SLisandro Dalcin }
52916d9e3a6SLisandro Dalcin 
53016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
53116d9e3a6SLisandro Dalcin {
53216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
53316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
534ace3abfcSBarry Smith   PetscBool      iascii;
53516d9e3a6SLisandro Dalcin 
53616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
537251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
53816d9e3a6SLisandro Dalcin   if (iascii) {
53916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
54016d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
541efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
54216d9e3a6SLisandro Dalcin     } else {
543efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default maximum number of iterations \n");CHKERRQ(ierr);
54416d9e3a6SLisandro Dalcin     }
54516d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
546efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
54716d9e3a6SLisandro Dalcin     } else {
548efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default drop tolerance \n");CHKERRQ(ierr);
54916d9e3a6SLisandro Dalcin     }
55016d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
551efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
55216d9e3a6SLisandro Dalcin     } else {
553efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default factor row size \n");CHKERRQ(ierr);
55416d9e3a6SLisandro Dalcin     }
55516d9e3a6SLisandro Dalcin   }
55616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
55716d9e3a6SLisandro Dalcin }
55816d9e3a6SLisandro Dalcin 
55916d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
560db966c6cSHong Zhang static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PetscOptionItems *PetscOptionsObject,PC pc)
561db966c6cSHong Zhang {
562db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
563db966c6cSHong Zhang   PetscErrorCode ierr;
564db966c6cSHong Zhang   PetscBool      flag;
565db966c6cSHong Zhang 
566db966c6cSHong Zhang   PetscFunctionBegin;
567db966c6cSHong Zhang   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Euclid Options");CHKERRQ(ierr);
568db966c6cSHong Zhang   ierr = PetscOptionsInt("-pc_hypre_euclid_level","Factorization levels","None",jac->eu_level,&jac->eu_level,&flag);CHKERRQ(ierr);
569db966c6cSHong Zhang   if (flag) PetscStackCallStandard(HYPRE_EuclidSetLevel,(jac->hsolver,jac->eu_level));
570db966c6cSHong Zhang   ierr = PetscOptionsTail();CHKERRQ(ierr);
571db966c6cSHong Zhang   PetscFunctionReturn(0);
572db966c6cSHong Zhang }
573db966c6cSHong Zhang 
574db966c6cSHong Zhang static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer)
575db966c6cSHong Zhang {
576db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
577db966c6cSHong Zhang   PetscErrorCode ierr;
578db966c6cSHong Zhang   PetscBool      iascii;
579db966c6cSHong Zhang 
580db966c6cSHong Zhang   PetscFunctionBegin;
581db966c6cSHong Zhang   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
582db966c6cSHong Zhang   if (iascii) {
583db966c6cSHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid preconditioning\n");CHKERRQ(ierr);
584db966c6cSHong Zhang     if (jac->eu_level != PETSC_DEFAULT) {
585db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    factorization levels %d\n",jac->eu_level);CHKERRQ(ierr);
586db966c6cSHong Zhang     } else {
587db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    default factorization levels \n");CHKERRQ(ierr);
588db966c6cSHong Zhang     }
589db966c6cSHong Zhang   }
590db966c6cSHong Zhang   PetscFunctionReturn(0);
591db966c6cSHong Zhang }
592db966c6cSHong Zhang 
593db966c6cSHong Zhang /* --------------------------------------------------------------------------------------------*/
59416d9e3a6SLisandro Dalcin 
59516d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
59616d9e3a6SLisandro Dalcin {
59716d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
59849a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
59916d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
60016d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
601d9ca1df4SBarry Smith   PetscScalar        *xv;
602d9ca1df4SBarry Smith   const PetscScalar  *bv;
60316d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
60416d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
6054ddd07fcSJed Brown   PetscInt           hierr;
60616d9e3a6SLisandro Dalcin 
60716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
608dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
60916d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
610d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
61116d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
61258968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)bv,sbv);
61358968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
61416d9e3a6SLisandro Dalcin 
61549a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
61649a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
61749a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
61816d9e3a6SLisandro Dalcin 
61916d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
62016d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
621e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
62216d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
62316d9e3a6SLisandro Dalcin 
62458968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,sbv,bv);
62558968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
62616d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
627d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
62816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
62916d9e3a6SLisandro Dalcin }
63016d9e3a6SLisandro Dalcin 
631a669f990SJed Brown /* static array length */
632a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
633a669f990SJed Brown 
63416d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
6350f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
63616d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
63765de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
6386a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]   = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
63965de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
64065de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
64165de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
6427b7fa87dSPierre Jolivet                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "l1-Gauss-Seidel" /* nonsymmetric */, "backward-l1-Gauss-Seidel" /* nonsymmetric */,
64365de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
6440f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
645e2287abbSStefano Zampini                                                   "ext+i-cc", "standard", "standard-wts", "block", "block-wtd", "FF", "FF1"};
6464416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc)
64716d9e3a6SLisandro Dalcin {
64816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
64916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
65022e51d31SStefano Zampini   PetscInt       bs,n,indx,level;
651ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
65216d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
65316d9e3a6SLisandro Dalcin 
65416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
655e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
6564336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
65716d9e3a6SLisandro Dalcin   if (flg) {
6584336a9eeSBarry Smith     jac->cycletype = indx+1;
659fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
66016d9e3a6SLisandro Dalcin   }
66116d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
66216d9e3a6SLisandro Dalcin   if (flg) {
663ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
664fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
66516d9e3a6SLisandro Dalcin   }
66616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
66716d9e3a6SLisandro Dalcin   if (flg) {
668ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
669fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
67016d9e3a6SLisandro Dalcin   }
6710f1074feSSatish Balay   ierr = PetscOptionsScalar("-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);
67216d9e3a6SLisandro Dalcin   if (flg) {
67357622a8eSBarry 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);
674fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
67516d9e3a6SLisandro Dalcin   }
67622e51d31SStefano Zampini   bs = 1;
67722e51d31SStefano Zampini   if (pc->pmat) {
67822e51d31SStefano Zampini     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
67922e51d31SStefano Zampini   }
68022e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_numfunctions","Number of functions","HYPRE_BoomerAMGSetNumFunctions",bs,&bs,&flg);CHKERRQ(ierr);
68122e51d31SStefano Zampini   if (flg) {
68222e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
68322e51d31SStefano Zampini   }
68416d9e3a6SLisandro Dalcin 
6850f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
68616d9e3a6SLisandro Dalcin   if (flg) {
68757622a8eSBarry 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);
688fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
68916d9e3a6SLisandro Dalcin   }
69016d9e3a6SLisandro Dalcin 
6910f1074feSSatish 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);
6920f1074feSSatish Balay   if (flg) {
69357622a8eSBarry 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);
694fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
6950f1074feSSatish Balay   }
6960f1074feSSatish Balay 
6970f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
6980f1074feSSatish Balay   if (flg) {
69957622a8eSBarry 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);
7000f1074feSSatish Balay 
701fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
7020f1074feSSatish Balay   }
7030f1074feSSatish Balay 
7040f1074feSSatish 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);
7050f1074feSSatish Balay   if (flg) {
70657622a8eSBarry 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);
7070f1074feSSatish Balay 
708fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
7090f1074feSSatish Balay   }
7100f1074feSSatish Balay 
7110f1074feSSatish Balay 
71216d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
71316d9e3a6SLisandro Dalcin   if (flg) {
71457622a8eSBarry 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);
715fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
71616d9e3a6SLisandro Dalcin   }
71716d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
71816d9e3a6SLisandro Dalcin   if (flg) {
71957622a8eSBarry 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);
72057622a8eSBarry 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);
721fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
72216d9e3a6SLisandro Dalcin   }
72316d9e3a6SLisandro Dalcin 
72416d9e3a6SLisandro Dalcin   /* Grid sweeps */
7250f1074feSSatish 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);
72616d9e3a6SLisandro Dalcin   if (flg) {
727fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
72816d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
72916d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
7300f1074feSSatish Balay     jac->gridsweeps[1] = indx;
7310f1074feSSatish Balay     /*defaults coarse to 1 */
7320f1074feSSatish Balay     jac->gridsweeps[2] = 1;
73316d9e3a6SLisandro Dalcin   }
7345272c319SBarry 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);
7355272c319SBarry Smith   if (flg) {
7365272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,jac->nodal_coarsening));
7375272c319SBarry Smith   }
73822e51d31SStefano 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);
73922e51d31SStefano Zampini   if (flg) {
74022e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNodalDiag,(jac->hsolver,jac->nodal_coarsening_diag));
74122e51d31SStefano Zampini   }
742cbc39033SBarry 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);
7435272c319SBarry Smith   if (flg) {
7445272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,(jac->hsolver,jac->vec_interp_variant));
7455272c319SBarry Smith   }
74622e51d31SStefano 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);
74722e51d31SStefano Zampini   if (flg) {
74822e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecQMax,(jac->hsolver,jac->vec_interp_qmax));
74922e51d31SStefano Zampini   }
75022e51d31SStefano 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);
75122e51d31SStefano Zampini   if (flg) {
75222e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothInterpVectors,(jac->hsolver,jac->vec_interp_smooth));
75322e51d31SStefano Zampini   }
75422e51d31SStefano 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);
75522e51d31SStefano Zampini   if (flg) {
75622e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpRefine,(jac->hsolver,jac->interp_refine));
75722e51d31SStefano Zampini   }
7580f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
75916d9e3a6SLisandro Dalcin   if (flg) {
760fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
7610f1074feSSatish Balay     jac->gridsweeps[0] = indx;
76216d9e3a6SLisandro Dalcin   }
76316d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
76416d9e3a6SLisandro Dalcin   if (flg) {
765fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
7660f1074feSSatish Balay     jac->gridsweeps[1] = indx;
76716d9e3a6SLisandro Dalcin   }
7680f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
76916d9e3a6SLisandro Dalcin   if (flg) {
770fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
7710f1074feSSatish Balay     jac->gridsweeps[2] = indx;
77216d9e3a6SLisandro Dalcin   }
77316d9e3a6SLisandro Dalcin 
7746a251517SEike Mueller   /* Smooth type */
7756a251517SEike Mueller   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);
7766a251517SEike Mueller   if (flg) {
7776a251517SEike Mueller     jac->smoothtype = indx;
7786a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
7798131ecf7SEike Mueller     jac->smoothnumlevels = 25;
7808131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
7818131ecf7SEike Mueller   }
7828131ecf7SEike Mueller 
7838131ecf7SEike Mueller   /* Number of smoothing levels */
7848131ecf7SEike 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);
7858131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
7868131ecf7SEike Mueller     jac->smoothnumlevels = indx;
7878131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
7886a251517SEike Mueller   }
7896a251517SEike Mueller 
7901810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
7911810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
7921810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
7931810e44eSEike Mueller     jac->eu_level = indx;
7941810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
7951810e44eSEike Mueller   }
7961810e44eSEike Mueller 
7971810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
7981810e44eSEike Mueller   double droptolerance;
7991810e44eSEike Mueller   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
8001810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8011810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
8021810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
8031810e44eSEike Mueller   }
8041810e44eSEike Mueller 
8051810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
8061810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
8071810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8081810e44eSEike Mueller     jac->eu_bj = tmp_truth;
809493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
8101810e44eSEike Mueller   }
8111810e44eSEike Mueller 
81216d9e3a6SLisandro Dalcin   /* Relax type */
813a669f990SJed 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);
81416d9e3a6SLisandro Dalcin   if (flg) {
8150f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
816fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
8170f1074feSSatish Balay     /* by default, coarse type set to 9 */
8180f1074feSSatish Balay     jac->relaxtype[2] = 9;
819ddbeb582SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, 9, 3));
82016d9e3a6SLisandro Dalcin   }
821a669f990SJed 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);
82216d9e3a6SLisandro Dalcin   if (flg) {
82316d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
824fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
82516d9e3a6SLisandro Dalcin   }
826a669f990SJed 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);
82716d9e3a6SLisandro Dalcin   if (flg) {
8280f1074feSSatish Balay     jac->relaxtype[1] = indx;
829fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
83016d9e3a6SLisandro Dalcin   }
831a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
83216d9e3a6SLisandro Dalcin   if (flg) {
8330f1074feSSatish Balay     jac->relaxtype[2] = indx;
834fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
83516d9e3a6SLisandro Dalcin   }
83616d9e3a6SLisandro Dalcin 
83716d9e3a6SLisandro Dalcin   /* Relaxation Weight */
83816d9e3a6SLisandro 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);
83916d9e3a6SLisandro Dalcin   if (flg) {
840fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
84116d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
84216d9e3a6SLisandro Dalcin   }
84316d9e3a6SLisandro Dalcin 
84416d9e3a6SLisandro Dalcin   n         = 2;
84516d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
84616d9e3a6SLisandro 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);
84716d9e3a6SLisandro Dalcin   if (flg) {
84816d9e3a6SLisandro Dalcin     if (n == 2) {
84916d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
850fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
851ce94432eSBarry 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);
85216d9e3a6SLisandro Dalcin   }
85316d9e3a6SLisandro Dalcin 
85416d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
85516d9e3a6SLisandro 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);
85616d9e3a6SLisandro Dalcin   if (flg) {
857fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
85816d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
85916d9e3a6SLisandro Dalcin   }
86016d9e3a6SLisandro Dalcin 
86116d9e3a6SLisandro Dalcin   n         = 2;
86216d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
86316d9e3a6SLisandro 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);
86416d9e3a6SLisandro Dalcin   if (flg) {
86516d9e3a6SLisandro Dalcin     if (n == 2) {
86616d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
867fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
868ce94432eSBarry 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);
86916d9e3a6SLisandro Dalcin   }
87016d9e3a6SLisandro Dalcin 
87116d9e3a6SLisandro Dalcin   /* the Relax Order */
872acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
87316d9e3a6SLisandro Dalcin 
8748afaa268SBarry Smith   if (flg && tmp_truth) {
87516d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
876fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
87716d9e3a6SLisandro Dalcin   }
878a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
87916d9e3a6SLisandro Dalcin   if (flg) {
88016d9e3a6SLisandro Dalcin     jac->measuretype = indx;
881fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
88216d9e3a6SLisandro Dalcin   }
8830f1074feSSatish Balay   /* update list length 3/07 */
884a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
88516d9e3a6SLisandro Dalcin   if (flg) {
88616d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
887fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
88816d9e3a6SLisandro Dalcin   }
8890f1074feSSatish Balay 
8900f1074feSSatish Balay   /* new 3/07 */
891a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
8920f1074feSSatish Balay   if (flg) {
8930f1074feSSatish Balay     jac->interptype = indx;
894fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
8950f1074feSSatish Balay   }
8960f1074feSSatish Balay 
897b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
89816d9e3a6SLisandro Dalcin   if (flg) {
899b96a4a96SBarry Smith     level = 3;
9000298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
9012fa5cd67SKarl Rupp 
902b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
903fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
9042ae77aedSBarry Smith   }
9052ae77aedSBarry Smith 
906b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
9072ae77aedSBarry Smith   if (flg) {
908b96a4a96SBarry Smith     level = 3;
9090298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
9102fa5cd67SKarl Rupp 
911b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
912fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
91316d9e3a6SLisandro Dalcin   }
9148f87f92bSBarry Smith 
915acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
9168f87f92bSBarry Smith   if (flg && tmp_truth) {
9178f87f92bSBarry Smith     PetscInt tmp_int;
9188f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
9198f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
920fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
921fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
922fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
923fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
9248f87f92bSBarry Smith   }
9258f87f92bSBarry Smith 
92616d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
92716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
92816d9e3a6SLisandro Dalcin }
92916d9e3a6SLisandro Dalcin 
930ace3abfcSBarry 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)
93116d9e3a6SLisandro Dalcin {
93216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
93316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
9344ddd07fcSJed Brown   PetscInt       oits;
93516d9e3a6SLisandro Dalcin 
93616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
937dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
938fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
939fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
94016d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
94116d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
94216d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
9438b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
9444d0a8057SBarry Smith   *outits = oits;
9454d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
9464d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
947fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
948fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
94916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
95016d9e3a6SLisandro Dalcin }
95116d9e3a6SLisandro Dalcin 
95216d9e3a6SLisandro Dalcin 
95316d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
95416d9e3a6SLisandro Dalcin {
95516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
95616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
957ace3abfcSBarry Smith   PetscBool      iascii;
95816d9e3a6SLisandro Dalcin 
95916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
960251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
96116d9e3a6SLisandro Dalcin   if (iascii) {
96216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
963efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
96422e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of levels %D\n",jac->maxlevels);CHKERRQ(ierr);
96522e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of iterations PER hypre call %D\n",jac->maxiter);CHKERRQ(ierr);
966efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
967efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
968efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
96922e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: max elements per row %D\n",jac->pmax);CHKERRQ(ierr);
97022e51d31SStefano Zampini     if (jac->interp_refine) {
97122e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: number of steps of weighted refinement %D\n",jac->interp_refine);CHKERRQ(ierr);
97222e51d31SStefano Zampini     }
97322e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of levels of aggressive coarsening %D\n",jac->agg_nl);CHKERRQ(ierr);
97422e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of paths for aggressive coarsening %D\n",jac->agg_num_paths);CHKERRQ(ierr);
9750f1074feSSatish Balay 
976efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
97716d9e3a6SLisandro Dalcin 
97822e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps down         %D\n",jac->gridsweeps[0]);CHKERRQ(ierr);
97922e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps up           %D\n",jac->gridsweeps[1]);CHKERRQ(ierr);
98022e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps on coarse    %D\n",jac->gridsweeps[2]);CHKERRQ(ierr);
98116d9e3a6SLisandro Dalcin 
982efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
983efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
984efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
98516d9e3a6SLisandro Dalcin 
986efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
987efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
98816d9e3a6SLisandro Dalcin 
98916d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
990efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using CF-relaxation\n");CHKERRQ(ierr);
99116d9e3a6SLisandro Dalcin     } else {
992efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using CF-relaxation\n");CHKERRQ(ierr);
99316d9e3a6SLisandro Dalcin     }
9946a251517SEike Mueller     if (jac->smoothtype!=-1) {
995efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
99622e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth num levels    %D\n",jac->smoothnumlevels);CHKERRQ(ierr);
9977e352d70SEike Mueller     } else {
998efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using more complex smoothers.\n");CHKERRQ(ierr);
9991810e44eSEike Mueller     }
10001810e44eSEike Mueller     if (jac->smoothtype==3) {
100122e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) levels %D\n",jac->eu_level);CHKERRQ(ierr);
100222e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) drop tolerance %g\n",(double)jac->eu_droptolerance);CHKERRQ(ierr);
100322e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU use Block-Jacobi? %D\n",jac->eu_bj);CHKERRQ(ierr);
10046a251517SEike Mueller     }
1005efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
1006efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
1007efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
10085272c319SBarry Smith     if (jac->nodal_coarsening) {
1009efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
10105272c319SBarry Smith     }
10115272c319SBarry Smith     if (jac->vec_interp_variant) {
1012efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
101322e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecQMax() %D\n",jac->vec_interp_qmax);CHKERRQ(ierr);
101422e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n",jac->vec_interp_smooth);CHKERRQ(ierr);
10158f87f92bSBarry Smith     }
10168f87f92bSBarry Smith     if (jac->nodal_relax) {
101722e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal relaxation via Schwarz smoothing on levels %D\n",jac->nodal_relax_levels);CHKERRQ(ierr);
10188f87f92bSBarry Smith     }
101916d9e3a6SLisandro Dalcin   }
102016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
102116d9e3a6SLisandro Dalcin }
102216d9e3a6SLisandro Dalcin 
102316d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
10244416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc)
102516d9e3a6SLisandro Dalcin {
102616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
102716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
10284ddd07fcSJed Brown   PetscInt       indx;
1029ace3abfcSBarry Smith   PetscBool      flag;
103016d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
103116d9e3a6SLisandro Dalcin 
103216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1033e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
103416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
103516d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
10362fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
103716d9e3a6SLisandro Dalcin 
103816d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
10392fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
104016d9e3a6SLisandro Dalcin 
104116d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
10422fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
104316d9e3a6SLisandro Dalcin 
1044acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
10452fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
104616d9e3a6SLisandro Dalcin 
1047acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
10482fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
104916d9e3a6SLisandro Dalcin 
1050a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
105116d9e3a6SLisandro Dalcin   if (flag) {
105216d9e3a6SLisandro Dalcin     jac->symt = indx;
1053fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
105416d9e3a6SLisandro Dalcin   }
105516d9e3a6SLisandro Dalcin 
105616d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
105716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
105816d9e3a6SLisandro Dalcin }
105916d9e3a6SLisandro Dalcin 
106016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
106116d9e3a6SLisandro Dalcin {
106216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
106316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1064ace3abfcSBarry Smith   PetscBool      iascii;
106516d9e3a6SLisandro Dalcin   const char     *symt = 0;;
106616d9e3a6SLisandro Dalcin 
106716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1068251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
106916d9e3a6SLisandro Dalcin   if (iascii) {
107016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
1071efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
1072efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
1073efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    filter %g\n",(double)jac->filter);CHKERRQ(ierr);
1074efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
1075efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
1076efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
10772fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
10782fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
10792fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
1080ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
1081efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    %s\n",symt);CHKERRQ(ierr);
108216d9e3a6SLisandro Dalcin   }
108316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
108416d9e3a6SLisandro Dalcin }
10854cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
10864416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc)
10874cb006feSStefano Zampini {
10884cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
10894cb006feSStefano Zampini   PetscErrorCode ierr;
10904cb006feSStefano Zampini   PetscInt       n;
10914cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
10924cb006feSStefano Zampini 
10934cb006feSStefano Zampini   PetscFunctionBegin;
10949fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
1095863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1096863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1097863406b8SStefano 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);
1098863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
10994cb006feSStefano 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);
11004cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1101863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1102863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1103863406b8SStefano 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);
1104863406b8SStefano 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);
1105863406b8SStefano 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);
1106863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
11074cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1108863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1109863406b8SStefano Zampini                                                                       jac->as_relax_times,
1110863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1111863406b8SStefano Zampini                                                                       jac->as_omega));
11124cb006feSStefano Zampini   }
1113863406b8SStefano 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);
11144cb006feSStefano Zampini   n = 5;
1115863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
11164cb006feSStefano Zampini   if (flag || flag2) {
1117863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1118863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1119863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1120863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1121863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1122863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
11234cb006feSStefano Zampini   }
1124863406b8SStefano 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);
11254cb006feSStefano Zampini   n = 5;
1126863406b8SStefano 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);
11274cb006feSStefano Zampini   if (flag || flag2) {
1128863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1129863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1130863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1131863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1132863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1133863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
11344cb006feSStefano Zampini   }
113523df4f25SStefano 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);
113623df4f25SStefano Zampini   if (flag) { /* override HYPRE's default only if the options is used */
113723df4f25SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetProjectionFrequency,(jac->hsolver,jac->ams_proj_freq));
113823df4f25SStefano Zampini   }
11394cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
11404cb006feSStefano Zampini   PetscFunctionReturn(0);
11414cb006feSStefano Zampini }
11424cb006feSStefano Zampini 
11434cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
11444cb006feSStefano Zampini {
11454cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
11464cb006feSStefano Zampini   PetscErrorCode ierr;
11474cb006feSStefano Zampini   PetscBool      iascii;
11484cb006feSStefano Zampini 
11494cb006feSStefano Zampini   PetscFunctionBegin;
11504cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
11514cb006feSStefano Zampini   if (iascii) {
11524cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
1153efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1154efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1155efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1156efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1157efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1158efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1159efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
11604cb006feSStefano Zampini     if (jac->alpha_Poisson) {
1161efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
11624cb006feSStefano Zampini     } else {
1163efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (computed) \n");CHKERRQ(ierr);
11644cb006feSStefano Zampini     }
1165efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1166efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1167efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1168efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1169efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1170efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
11714cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
11724cb006feSStefano Zampini       if (jac->beta_Poisson) {
1173efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
11744cb006feSStefano Zampini       } else {
1175efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (computed) \n");CHKERRQ(ierr);
11764cb006feSStefano Zampini       }
1177efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1178efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1179efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1180efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1181efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1182efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
118323df4f25SStefano Zampini       if (jac->ams_beta_is_zero_part) {
1184efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"        compatible subspace projection frequency %d (-1 HYPRE uses default)\n",jac->ams_proj_freq);CHKERRQ(ierr);
118523df4f25SStefano Zampini       }
118623df4f25SStefano Zampini     } else {
1187efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver not used (zero-conductivity everywhere) \n");CHKERRQ(ierr);
11884cb006feSStefano Zampini     }
11894cb006feSStefano Zampini   }
11904cb006feSStefano Zampini   PetscFunctionReturn(0);
11914cb006feSStefano Zampini }
11924cb006feSStefano Zampini 
11934416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc)
1194863406b8SStefano Zampini {
1195863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1196863406b8SStefano Zampini   PetscErrorCode ierr;
1197863406b8SStefano Zampini   PetscInt       n;
1198863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
1199863406b8SStefano Zampini 
1200863406b8SStefano Zampini   PetscFunctionBegin;
1201863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
1202863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1203863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1204863406b8SStefano 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);
1205863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1206863406b8SStefano 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);
1207863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
1208863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1209863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1210863406b8SStefano 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);
1211863406b8SStefano 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);
1212863406b8SStefano 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);
1213863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
1214863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1215863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1216863406b8SStefano Zampini                                                                       jac->as_relax_times,
1217863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1218863406b8SStefano Zampini                                                                       jac->as_omega));
1219863406b8SStefano Zampini   }
1220863406b8SStefano 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);
1221863406b8SStefano Zampini   n = 5;
1222863406b8SStefano 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);
1223863406b8SStefano 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);
1224863406b8SStefano Zampini   if (flag || flag2 || flag3) {
1225863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
1226863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1227863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1228863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1229863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1230863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1231863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1232863406b8SStefano Zampini   }
1233863406b8SStefano 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);
1234863406b8SStefano Zampini   n = 5;
1235863406b8SStefano 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);
1236863406b8SStefano Zampini   if (flag || flag2) {
1237863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1238863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1239863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1240863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1241863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1242863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1243863406b8SStefano Zampini   }
1244863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
1245863406b8SStefano Zampini   PetscFunctionReturn(0);
1246863406b8SStefano Zampini }
1247863406b8SStefano Zampini 
1248863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1249863406b8SStefano Zampini {
1250863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1251863406b8SStefano Zampini   PetscErrorCode ierr;
1252863406b8SStefano Zampini   PetscBool      iascii;
1253863406b8SStefano Zampini 
1254863406b8SStefano Zampini   PetscFunctionBegin;
1255863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1256863406b8SStefano Zampini   if (iascii) {
1257863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
1258efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1259efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
1260efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1261efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1262efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1263efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1264efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
1265efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    AMS solver using boomerAMG\n");CHKERRQ(ierr);
1266efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1267efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1268efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1269efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1270efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1271efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1272efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
1273efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver using boomerAMG\n");CHKERRQ(ierr);
1274efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1275efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1276efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1277efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1278efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1279efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
1280863406b8SStefano Zampini   }
1281863406b8SStefano Zampini   PetscFunctionReturn(0);
1282863406b8SStefano Zampini }
1283863406b8SStefano Zampini 
1284863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
12854cb006feSStefano Zampini {
12864cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12875ac14e1cSStefano Zampini   PetscBool      ishypre;
12884cb006feSStefano Zampini   PetscErrorCode ierr;
12894cb006feSStefano Zampini 
12904cb006feSStefano Zampini   PetscFunctionBegin;
12915ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)G,MATHYPRE,&ishypre);CHKERRQ(ierr);
12925ac14e1cSStefano Zampini   if (ishypre) {
12935ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr);
12945ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
12955ac14e1cSStefano Zampini     jac->G = G;
12965ac14e1cSStefano Zampini   } else {
12976bf688a0SCe Qin     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
12986bf688a0SCe Qin     ierr = MatConvert(G,MATHYPRE,MAT_INITIAL_MATRIX,&jac->G);CHKERRQ(ierr);
12995ac14e1cSStefano Zampini   }
13004cb006feSStefano Zampini   PetscFunctionReturn(0);
13014cb006feSStefano Zampini }
13024cb006feSStefano Zampini 
13034cb006feSStefano Zampini /*@
13044cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
13054cb006feSStefano Zampini 
13064cb006feSStefano Zampini    Collective on PC
13074cb006feSStefano Zampini 
13084cb006feSStefano Zampini    Input Parameters:
13094cb006feSStefano Zampini +  pc - the preconditioning context
13104cb006feSStefano Zampini -  G - the discrete gradient
13114cb006feSStefano Zampini 
13124cb006feSStefano Zampini    Level: intermediate
13134cb006feSStefano Zampini 
131495452b02SPatrick Sanan    Notes:
131595452b02SPatrick Sanan     G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh
1316863406b8SStefano 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
13174cb006feSStefano Zampini 
13184cb006feSStefano Zampini .seealso:
13194cb006feSStefano Zampini @*/
13204cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
13214cb006feSStefano Zampini {
13224cb006feSStefano Zampini   PetscErrorCode ierr;
13234cb006feSStefano Zampini 
13244cb006feSStefano Zampini   PetscFunctionBegin;
13254cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
13264cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
13274cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
13284cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
13294cb006feSStefano Zampini   PetscFunctionReturn(0);
13304cb006feSStefano Zampini }
13314cb006feSStefano Zampini 
1332863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1333863406b8SStefano Zampini {
1334863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
13355ac14e1cSStefano Zampini   PetscBool      ishypre;
1336863406b8SStefano Zampini   PetscErrorCode ierr;
1337863406b8SStefano Zampini 
1338863406b8SStefano Zampini   PetscFunctionBegin;
13395ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)C,MATHYPRE,&ishypre);CHKERRQ(ierr);
13405ac14e1cSStefano Zampini   if (ishypre) {
13415ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr);
13425ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
13435ac14e1cSStefano Zampini     jac->C = C;
13445ac14e1cSStefano Zampini   } else {
13456bf688a0SCe Qin     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
13466bf688a0SCe Qin     ierr = MatConvert(C,MATHYPRE,MAT_INITIAL_MATRIX,&jac->C);CHKERRQ(ierr);
13475ac14e1cSStefano Zampini   }
1348863406b8SStefano Zampini   PetscFunctionReturn(0);
1349863406b8SStefano Zampini }
1350863406b8SStefano Zampini 
1351863406b8SStefano Zampini /*@
1352863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1353863406b8SStefano Zampini 
1354863406b8SStefano Zampini    Collective on PC
1355863406b8SStefano Zampini 
1356863406b8SStefano Zampini    Input Parameters:
1357863406b8SStefano Zampini +  pc - the preconditioning context
1358863406b8SStefano Zampini -  C - the discrete curl
1359863406b8SStefano Zampini 
1360863406b8SStefano Zampini    Level: intermediate
1361863406b8SStefano Zampini 
136295452b02SPatrick Sanan    Notes:
136395452b02SPatrick Sanan     C should have as many rows as the number of faces and as many columns as the number of edges in the mesh
1364863406b8SStefano 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
1365863406b8SStefano Zampini 
1366863406b8SStefano Zampini .seealso:
1367863406b8SStefano Zampini @*/
1368863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1369863406b8SStefano Zampini {
1370863406b8SStefano Zampini   PetscErrorCode ierr;
1371863406b8SStefano Zampini 
1372863406b8SStefano Zampini   PetscFunctionBegin;
1373863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1374863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1375863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1376863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1377863406b8SStefano Zampini   PetscFunctionReturn(0);
1378863406b8SStefano Zampini }
1379863406b8SStefano Zampini 
13806bf688a0SCe Qin static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
13816bf688a0SCe Qin {
13826bf688a0SCe Qin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
13836bf688a0SCe Qin   PetscBool      ishypre;
13846bf688a0SCe Qin   PetscErrorCode ierr;
13856bf688a0SCe Qin   PetscInt       i;
13866bf688a0SCe Qin   PetscFunctionBegin;
13876bf688a0SCe Qin 
13886bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
13896bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
13906bf688a0SCe Qin   for (i=0;i<3;++i) {
13916bf688a0SCe Qin     ierr = MatDestroy(&jac->RT_Pi[i]);CHKERRQ(ierr);
13926bf688a0SCe Qin     ierr = MatDestroy(&jac->ND_Pi[i]);CHKERRQ(ierr);
13936bf688a0SCe Qin   }
13946bf688a0SCe Qin 
13956bf688a0SCe Qin   jac->dim = dim;
13966bf688a0SCe Qin   if (RT_PiFull) {
13976bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)RT_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
13986bf688a0SCe Qin     if (ishypre) {
13996bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)RT_PiFull);CHKERRQ(ierr);
14006bf688a0SCe Qin       jac->RT_PiFull = RT_PiFull;
14016bf688a0SCe Qin     } else {
14026bf688a0SCe Qin       ierr = MatConvert(RT_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_PiFull);CHKERRQ(ierr);
14036bf688a0SCe Qin     }
14046bf688a0SCe Qin   }
14056bf688a0SCe Qin   if (RT_Pi) {
14066bf688a0SCe Qin     for (i=0;i<dim;++i) {
14076bf688a0SCe Qin       if (RT_Pi[i]) {
14086bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)RT_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
14096bf688a0SCe Qin         if (ishypre) {
14106bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)RT_Pi[i]);CHKERRQ(ierr);
14116bf688a0SCe Qin           jac->RT_Pi[i] = RT_Pi[i];
14126bf688a0SCe Qin         } else {
14136bf688a0SCe Qin           ierr = MatConvert(RT_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_Pi[i]);CHKERRQ(ierr);
14146bf688a0SCe Qin         }
14156bf688a0SCe Qin       }
14166bf688a0SCe Qin     }
14176bf688a0SCe Qin   }
14186bf688a0SCe Qin   if (ND_PiFull) {
14196bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)ND_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
14206bf688a0SCe Qin     if (ishypre) {
14216bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)ND_PiFull);CHKERRQ(ierr);
14226bf688a0SCe Qin       jac->ND_PiFull = ND_PiFull;
14236bf688a0SCe Qin     } else {
14246bf688a0SCe Qin       ierr = MatConvert(ND_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_PiFull);CHKERRQ(ierr);
14256bf688a0SCe Qin     }
14266bf688a0SCe Qin   }
14276bf688a0SCe Qin   if (ND_Pi) {
14286bf688a0SCe Qin     for (i=0;i<dim;++i) {
14296bf688a0SCe Qin       if (ND_Pi[i]) {
14306bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)ND_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
14316bf688a0SCe Qin         if (ishypre) {
14326bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)ND_Pi[i]);CHKERRQ(ierr);
14336bf688a0SCe Qin           jac->ND_Pi[i] = ND_Pi[i];
14346bf688a0SCe Qin         } else {
14356bf688a0SCe Qin           ierr = MatConvert(ND_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_Pi[i]);CHKERRQ(ierr);
14366bf688a0SCe Qin         }
14376bf688a0SCe Qin       }
14386bf688a0SCe Qin     }
14396bf688a0SCe Qin   }
14406bf688a0SCe Qin 
14416bf688a0SCe Qin   PetscFunctionReturn(0);
14426bf688a0SCe Qin }
14436bf688a0SCe Qin 
14446bf688a0SCe Qin /*@
14456bf688a0SCe Qin  PCHYPRESetInterpolations - Set interpolation matrices for AMS/ADS preconditioner
14466bf688a0SCe Qin 
14476bf688a0SCe Qin    Collective on PC
14486bf688a0SCe Qin 
14496bf688a0SCe Qin    Input Parameters:
14506bf688a0SCe Qin +  pc - the preconditioning context
14516bf688a0SCe Qin -  dim - the dimension of the problem, only used in AMS
14526bf688a0SCe Qin -  RT_PiFull - Raviart-Thomas interpolation matrix
14536bf688a0SCe Qin -  RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix
14546bf688a0SCe Qin -  ND_PiFull - Nedelec interpolation matrix
14556bf688a0SCe Qin -  ND_Pi - x/y/z component of Nedelec interpolation matrix
14566bf688a0SCe Qin 
145795452b02SPatrick Sanan    Notes:
145895452b02SPatrick Sanan     For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL.
14596bf688a0SCe Qin           For ADS, both type of interpolation matrices are needed.
14606bf688a0SCe Qin    Level: intermediate
14616bf688a0SCe Qin 
14626bf688a0SCe Qin .seealso:
14636bf688a0SCe Qin @*/
14646bf688a0SCe Qin PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
14656bf688a0SCe Qin {
14666bf688a0SCe Qin   PetscErrorCode ierr;
14676bf688a0SCe Qin   PetscInt       i;
14686bf688a0SCe Qin 
14696bf688a0SCe Qin   PetscFunctionBegin;
14706bf688a0SCe Qin   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
14716bf688a0SCe Qin   if (RT_PiFull) {
14726bf688a0SCe Qin     PetscValidHeaderSpecific(RT_PiFull,MAT_CLASSID,3);
14736bf688a0SCe Qin     PetscCheckSameComm(pc,1,RT_PiFull,3);
14746bf688a0SCe Qin   }
14756bf688a0SCe Qin   if (RT_Pi) {
14766bf688a0SCe Qin     PetscValidPointer(RT_Pi,4);
14776bf688a0SCe Qin     for (i=0;i<dim;++i) {
14786bf688a0SCe Qin       if (RT_Pi[i]) {
14796bf688a0SCe Qin         PetscValidHeaderSpecific(RT_Pi[i],MAT_CLASSID,4);
14806bf688a0SCe Qin         PetscCheckSameComm(pc,1,RT_Pi[i],4);
14816bf688a0SCe Qin       }
14826bf688a0SCe Qin     }
14836bf688a0SCe Qin   }
14846bf688a0SCe Qin   if (ND_PiFull) {
14856bf688a0SCe Qin     PetscValidHeaderSpecific(ND_PiFull,MAT_CLASSID,5);
14866bf688a0SCe Qin     PetscCheckSameComm(pc,1,ND_PiFull,5);
14876bf688a0SCe Qin   }
14886bf688a0SCe Qin   if (ND_Pi) {
14896bf688a0SCe Qin     PetscValidPointer(ND_Pi,6);
14906bf688a0SCe Qin     for (i=0;i<dim;++i) {
14916bf688a0SCe Qin       if (ND_Pi[i]) {
14926bf688a0SCe Qin         PetscValidHeaderSpecific(ND_Pi[i],MAT_CLASSID,6);
14936bf688a0SCe Qin         PetscCheckSameComm(pc,1,ND_Pi[i],6);
14946bf688a0SCe Qin       }
14956bf688a0SCe Qin     }
14966bf688a0SCe Qin   }
14976bf688a0SCe Qin   ierr = PetscTryMethod(pc,"PCHYPRESetInterpolations_C",(PC,PetscInt,Mat,Mat[],Mat,Mat[]),(pc,dim,RT_PiFull,RT_Pi,ND_PiFull,ND_Pi));CHKERRQ(ierr);
14986bf688a0SCe Qin   PetscFunctionReturn(0);
14996bf688a0SCe Qin }
15006bf688a0SCe Qin 
15015ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha)
15024cb006feSStefano Zampini {
15034cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
15045ac14e1cSStefano Zampini   PetscBool      ishypre;
15054cb006feSStefano Zampini   PetscErrorCode ierr;
15064cb006feSStefano Zampini 
15074cb006feSStefano Zampini   PetscFunctionBegin;
15085ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr);
15095ac14e1cSStefano Zampini   if (ishypre) {
15105ac14e1cSStefano Zampini     if (isalpha) {
15115ac14e1cSStefano Zampini       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
15125ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
15135ac14e1cSStefano Zampini       jac->alpha_Poisson = A;
15145ac14e1cSStefano Zampini     } else {
15155ac14e1cSStefano Zampini       if (A) {
15165ac14e1cSStefano Zampini         ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
15175ac14e1cSStefano Zampini       } else {
15185ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
15195ac14e1cSStefano Zampini       }
15205ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
15215ac14e1cSStefano Zampini       jac->beta_Poisson = A;
15225ac14e1cSStefano Zampini     }
15235ac14e1cSStefano Zampini   } else {
15245ac14e1cSStefano Zampini     if (isalpha) {
15256bf688a0SCe Qin       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
15266bf688a0SCe Qin       ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->alpha_Poisson);CHKERRQ(ierr);
15275ac14e1cSStefano Zampini     } else {
15285ac14e1cSStefano Zampini       if (A) {
15296bf688a0SCe Qin         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
15306bf688a0SCe Qin         ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->beta_Poisson);CHKERRQ(ierr);
15315ac14e1cSStefano Zampini       } else {
15325ac14e1cSStefano Zampini         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
15335ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
15345ac14e1cSStefano Zampini       }
15355ac14e1cSStefano Zampini     }
15365ac14e1cSStefano Zampini   }
15374cb006feSStefano Zampini   PetscFunctionReturn(0);
15384cb006feSStefano Zampini }
15394cb006feSStefano Zampini 
15404cb006feSStefano Zampini /*@
15414cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
15424cb006feSStefano Zampini 
15434cb006feSStefano Zampini    Collective on PC
15444cb006feSStefano Zampini 
15454cb006feSStefano Zampini    Input Parameters:
15464cb006feSStefano Zampini +  pc - the preconditioning context
15474cb006feSStefano Zampini -  A - the matrix
15484cb006feSStefano Zampini 
15494cb006feSStefano Zampini    Level: intermediate
15504cb006feSStefano Zampini 
155195452b02SPatrick Sanan    Notes:
155295452b02SPatrick Sanan     A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
15534cb006feSStefano Zampini 
15544cb006feSStefano Zampini .seealso:
15554cb006feSStefano Zampini @*/
15564cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
15574cb006feSStefano Zampini {
15584cb006feSStefano Zampini   PetscErrorCode ierr;
15594cb006feSStefano Zampini 
15604cb006feSStefano Zampini   PetscFunctionBegin;
15614cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15624cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
15634cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
15645ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_TRUE));CHKERRQ(ierr);
15654cb006feSStefano Zampini   PetscFunctionReturn(0);
15664cb006feSStefano Zampini }
15674cb006feSStefano Zampini 
15684cb006feSStefano Zampini /*@
15694cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
15704cb006feSStefano Zampini 
15714cb006feSStefano Zampini    Collective on PC
15724cb006feSStefano Zampini 
15734cb006feSStefano Zampini    Input Parameters:
15744cb006feSStefano Zampini +  pc - the preconditioning context
15754cb006feSStefano Zampini -  A - the matrix
15764cb006feSStefano Zampini 
15774cb006feSStefano Zampini    Level: intermediate
15784cb006feSStefano Zampini 
157995452b02SPatrick Sanan    Notes:
158095452b02SPatrick Sanan     A should be obtained by discretizing the Poisson problem with linear finite elements.
15814cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
15824cb006feSStefano Zampini 
15834cb006feSStefano Zampini .seealso:
15844cb006feSStefano Zampini @*/
15854cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
15864cb006feSStefano Zampini {
15874cb006feSStefano Zampini   PetscErrorCode ierr;
15884cb006feSStefano Zampini 
15894cb006feSStefano Zampini   PetscFunctionBegin;
15904cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15914cb006feSStefano Zampini   if (A) {
15924cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
15934cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
15944cb006feSStefano Zampini   }
15955ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_FALSE));CHKERRQ(ierr);
15964cb006feSStefano Zampini   PetscFunctionReturn(0);
15974cb006feSStefano Zampini }
15984cb006feSStefano Zampini 
15995ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz, Vec zoz, Vec zzo)
16004cb006feSStefano Zampini {
16014cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
16024cb006feSStefano Zampini   PetscErrorCode     ierr;
16034cb006feSStefano Zampini 
16044cb006feSStefano Zampini   PetscFunctionBegin;
16054cb006feSStefano Zampini   /* throw away any vector if already set */
16064cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
16074cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
16084cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
16094cb006feSStefano Zampini   jac->constants[0] = NULL;
16104cb006feSStefano Zampini   jac->constants[1] = NULL;
16114cb006feSStefano Zampini   jac->constants[2] = NULL;
16124cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
16134cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
16144cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
16154cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
16165ac14e1cSStefano Zampini   jac->dim = 2;
16174cb006feSStefano Zampini   if (zzo) {
16184cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
16194cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
16205ac14e1cSStefano Zampini     jac->dim++;
16214cb006feSStefano Zampini   }
16224cb006feSStefano Zampini   PetscFunctionReturn(0);
16234cb006feSStefano Zampini }
16244cb006feSStefano Zampini 
16254cb006feSStefano Zampini /*@
16264cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
16274cb006feSStefano Zampini 
16284cb006feSStefano Zampini    Collective on PC
16294cb006feSStefano Zampini 
16304cb006feSStefano Zampini    Input Parameters:
16314cb006feSStefano Zampini +  pc - the preconditioning context
16324cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
16334cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
16344cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
16354cb006feSStefano Zampini 
16364cb006feSStefano Zampini    Level: intermediate
16374cb006feSStefano Zampini 
16384cb006feSStefano Zampini    Notes:
16394cb006feSStefano Zampini 
16404cb006feSStefano Zampini .seealso:
16414cb006feSStefano Zampini @*/
16424cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
16434cb006feSStefano Zampini {
16444cb006feSStefano Zampini   PetscErrorCode ierr;
16454cb006feSStefano Zampini 
16464cb006feSStefano Zampini   PetscFunctionBegin;
16474cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
16484cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
16494cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
16504cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
16514cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
16524cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
16534cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
16544cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
16554cb006feSStefano Zampini   PetscFunctionReturn(0);
16564cb006feSStefano Zampini }
16574cb006feSStefano Zampini 
1658863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
16594cb006feSStefano Zampini {
16604cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
16614cb006feSStefano Zampini   Vec             tv;
16624cb006feSStefano Zampini   PetscInt        i;
16634cb006feSStefano Zampini   PetscErrorCode  ierr;
16644cb006feSStefano Zampini 
16654cb006feSStefano Zampini   PetscFunctionBegin;
16664cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
16674cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
16684cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
16694cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
16705ac14e1cSStefano Zampini   jac->dim = dim;
16715ac14e1cSStefano Zampini 
16724cb006feSStefano Zampini   /* compute IJ vector for coordinates */
16734cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
16744cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
16754cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
16764cb006feSStefano Zampini   for (i=0;i<dim;i++) {
16774cb006feSStefano Zampini     PetscScalar *array;
16784cb006feSStefano Zampini     PetscInt    j;
16794cb006feSStefano Zampini 
16804cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
16814cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
16824cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
16834cb006feSStefano Zampini       array[j] = coords[j*dim+i];
16844cb006feSStefano Zampini     }
16854cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
16864cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
16874cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
16884cb006feSStefano Zampini   }
16894cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
16904cb006feSStefano Zampini   PetscFunctionReturn(0);
16914cb006feSStefano Zampini }
16924cb006feSStefano Zampini 
169316d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
169416d9e3a6SLisandro Dalcin 
1695f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
169616d9e3a6SLisandro Dalcin {
169716d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
169816d9e3a6SLisandro Dalcin 
169916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
170016d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
170116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
170216d9e3a6SLisandro Dalcin }
170316d9e3a6SLisandro Dalcin 
1704f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
170516d9e3a6SLisandro Dalcin {
170616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
170716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1708ace3abfcSBarry Smith   PetscBool      flag;
170916d9e3a6SLisandro Dalcin 
171016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
171116d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
171216d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1713ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
171416d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
171516d9e3a6SLisandro Dalcin   } else {
171616d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
171716d9e3a6SLisandro Dalcin   }
171816d9e3a6SLisandro Dalcin 
171916d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
172016d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
172116d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
172216d9e3a6SLisandro Dalcin 
172316d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
172416d9e3a6SLisandro Dalcin   if (flag) {
1725572a0576SBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1726fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
172716d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
172816d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
172916d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
173016d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
173116d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
173216d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
173316d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
173416d9e3a6SLisandro Dalcin   }
1735db966c6cSHong Zhang   ierr = PetscStrcmp("euclid",jac->hypre_type,&flag);CHKERRQ(ierr);
1736db966c6cSHong Zhang   if (flag) {
1737db966c6cSHong Zhang     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1738db966c6cSHong Zhang     PetscStackCallStandard(HYPRE_EuclidCreate,(jac->comm_hypre,&jac->hsolver));
1739db966c6cSHong Zhang     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
1740db966c6cSHong Zhang     pc->ops->view           = PCView_HYPRE_Euclid;
1741db966c6cSHong Zhang     jac->destroy            = HYPRE_EuclidDestroy;
1742db966c6cSHong Zhang     jac->setup              = HYPRE_EuclidSetup;
1743db966c6cSHong Zhang     jac->solve              = HYPRE_EuclidSolve;
1744db966c6cSHong Zhang     jac->factorrowsize      = PETSC_DEFAULT;
1745db966c6cSHong Zhang     jac->eu_level           = PETSC_DEFAULT; /* default */
1746db966c6cSHong Zhang     PetscFunctionReturn(0);
1747db966c6cSHong Zhang   }
174816d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
174916d9e3a6SLisandro Dalcin   if (flag) {
1750572a0576SBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1751fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
175216d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
175316d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
175416d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
175516d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
175616d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
175716d9e3a6SLisandro Dalcin     /* initialize */
175816d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
175916d9e3a6SLisandro Dalcin     jac->threshhold = .1;
176016d9e3a6SLisandro Dalcin     jac->filter     = .1;
176116d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
17622fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
17632fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
17642fa5cd67SKarl Rupp 
176516d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
176616d9e3a6SLisandro Dalcin     jac->symt = 0;
1767fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1768fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1769fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1770fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1771fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1772fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
177316d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
177416d9e3a6SLisandro Dalcin   }
177516d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
177616d9e3a6SLisandro Dalcin   if (flag) {
177716d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
177816d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
177916d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
178016d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
178116d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
1782*fd2dd295SFande Kong     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",PCGetInterpolations_BoomerAMG);CHKERRQ(ierr);
1783*fd2dd295SFande Kong     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",PCGetCoarseOperators_BoomerAMG);CHKERRQ(ierr);
178416d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
178516d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
178616d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
178716d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
178816d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
178916d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
179016d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
179116d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
17928f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
179316d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
179416d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
179516d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
179616d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
179716d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
17980f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
17996a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1800b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
18011810e44eSEike Mueller     jac->eu_level         = 0;
18021810e44eSEike Mueller     jac->eu_droptolerance = 0;
18031810e44eSEike Mueller     jac->eu_bj            = 0;
18048f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
18050f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
180616d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
180716d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
180816d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
18090f1074feSSatish Balay     jac->interptype       = 0;
18100f1074feSSatish Balay     jac->agg_nl           = 0;
18110f1074feSSatish Balay     jac->pmax             = 0;
18120f1074feSSatish Balay     jac->truncfactor      = 0.0;
18130f1074feSSatish Balay     jac->agg_num_paths    = 1;
18148f87f92bSBarry Smith 
181522e51d31SStefano Zampini     jac->nodal_coarsening      = 0;
181622e51d31SStefano Zampini     jac->nodal_coarsening_diag = 0;
181722e51d31SStefano Zampini     jac->vec_interp_variant    = 0;
181822e51d31SStefano Zampini     jac->vec_interp_qmax       = 0;
181922e51d31SStefano Zampini     jac->vec_interp_smooth     = PETSC_FALSE;
182022e51d31SStefano Zampini     jac->interp_refine         = 0;
18218f87f92bSBarry Smith     jac->nodal_relax           = PETSC_FALSE;
18228f87f92bSBarry Smith     jac->nodal_relax_levels    = 1;
1823fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1824fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1825fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1826fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1827fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1828fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1829fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1830fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1831fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1832fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1833fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1834fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1835fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1836fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1837fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1838fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
183916d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
184016d9e3a6SLisandro Dalcin   }
18414cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
18424cb006feSStefano Zampini   if (flag) {
18434cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
18444cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
18454cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
18464cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
18474cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
18484cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
18494cb006feSStefano Zampini     jac->coords[0]           = NULL;
18504cb006feSStefano Zampini     jac->coords[1]           = NULL;
18514cb006feSStefano Zampini     jac->coords[2]           = NULL;
18524cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1853863406b8SStefano Zampini     jac->as_print           = 0;
1854863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1855863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
18564cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
18574cb006feSStefano Zampini     /* Smoothing options */
1858863406b8SStefano Zampini     jac->as_relax_type      = 2;
1859863406b8SStefano Zampini     jac->as_relax_times     = 1;
1860863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1861863406b8SStefano Zampini     jac->as_omega           = 1.0;
18624cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1863863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1864863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
18650bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1866863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1867863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1868863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
18694cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1870863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1871863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
18720bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1873863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1874863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1875863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1876863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1877863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
18784cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1879863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1880863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1881863406b8SStefano Zampini                                                                       jac->as_relax_times,
1882863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1883863406b8SStefano Zampini                                                                       jac->as_omega));
1884863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1885863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1886863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1887863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1888863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1889863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1890863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1891863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1892863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1893863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1894863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1895863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
189623df4f25SStefano Zampini     /* Zero conductivity */
189723df4f25SStefano Zampini     jac->ams_beta_is_zero      = PETSC_FALSE;
189823df4f25SStefano Zampini     jac->ams_beta_is_zero_part = PETSC_FALSE;
18994cb006feSStefano Zampini     PetscFunctionReturn(0);
19004cb006feSStefano Zampini   }
1901863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1902863406b8SStefano Zampini   if (flag) {
1903863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1904863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1905863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1906863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1907863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1908863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1909863406b8SStefano Zampini     jac->coords[0]           = NULL;
1910863406b8SStefano Zampini     jac->coords[1]           = NULL;
1911863406b8SStefano Zampini     jac->coords[2]           = NULL;
1912863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1913863406b8SStefano Zampini     jac->as_print           = 0;
1914863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1915863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1916863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1917863406b8SStefano Zampini     /* Smoothing options */
1918863406b8SStefano Zampini     jac->as_relax_type      = 2;
1919863406b8SStefano Zampini     jac->as_relax_times     = 1;
1920863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1921863406b8SStefano Zampini     jac->as_omega           = 1.0;
1922863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1923863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1924863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1925863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1926863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1927863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1928863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1929863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1930863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1931863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1932863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1933863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1934863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1935863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1936863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1937863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1938863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1939863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1940863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1941863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1942863406b8SStefano Zampini                                                                       jac->as_relax_times,
1943863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1944863406b8SStefano Zampini                                                                       jac->as_omega));
1945863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1946863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1947863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1948863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1949863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1950863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1951863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1952863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1953863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1954863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1955863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1956863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1957863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1958863406b8SStefano Zampini     PetscFunctionReturn(0);
1959863406b8SStefano Zampini   }
1960503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
19612fa5cd67SKarl Rupp 
19620298fd71SBarry Smith   jac->hypre_type = NULL;
1963db966c6cSHong Zhang   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams",name);
196416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
196516d9e3a6SLisandro Dalcin }
196616d9e3a6SLisandro Dalcin 
196716d9e3a6SLisandro Dalcin /*
196816d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
196916d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
197016d9e3a6SLisandro Dalcin */
1971360ee056SFande Kong PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc)
197216d9e3a6SLisandro Dalcin {
197316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
19744ddd07fcSJed Brown   PetscInt       indx;
1975db966c6cSHong Zhang   const char     *type[] = {"euclid","pilut","parasails","boomeramg","ams","ads"};
1976ace3abfcSBarry Smith   PetscBool      flg;
197716d9e3a6SLisandro Dalcin 
197816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
19799fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
19809c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
198116d9e3a6SLisandro Dalcin   if (flg) {
198216d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
198302a17cd4SBarry Smith   } else {
198402a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
198516d9e3a6SLisandro Dalcin   }
198616d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
19873931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
198816d9e3a6SLisandro Dalcin   }
198916d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
199016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
199116d9e3a6SLisandro Dalcin }
199216d9e3a6SLisandro Dalcin 
199316d9e3a6SLisandro Dalcin /*@C
199416d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
199516d9e3a6SLisandro Dalcin 
199616d9e3a6SLisandro Dalcin    Input Parameters:
199716d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1998db966c6cSHong Zhang -     name - either  euclid, pilut, parasails, boomeramg, ams, ads
199916d9e3a6SLisandro Dalcin 
200016d9e3a6SLisandro Dalcin    Options Database Keys:
2001db966c6cSHong Zhang    -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
200216d9e3a6SLisandro Dalcin 
200316d9e3a6SLisandro Dalcin    Level: intermediate
200416d9e3a6SLisandro Dalcin 
200516d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
200616d9e3a6SLisandro Dalcin            PCHYPRE
200716d9e3a6SLisandro Dalcin 
200816d9e3a6SLisandro Dalcin @*/
20097087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
201016d9e3a6SLisandro Dalcin {
20114ac538c5SBarry Smith   PetscErrorCode ierr;
201216d9e3a6SLisandro Dalcin 
201316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
20140700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
201516d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
20164ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
201716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
201816d9e3a6SLisandro Dalcin }
201916d9e3a6SLisandro Dalcin 
202016d9e3a6SLisandro Dalcin /*@C
202116d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
202216d9e3a6SLisandro Dalcin 
202316d9e3a6SLisandro Dalcin    Input Parameter:
202416d9e3a6SLisandro Dalcin .     pc - the preconditioner context
202516d9e3a6SLisandro Dalcin 
202616d9e3a6SLisandro Dalcin    Output Parameter:
2027db966c6cSHong Zhang .     name - either  euclid, pilut, parasails, boomeramg, ams, ads
202816d9e3a6SLisandro Dalcin 
202916d9e3a6SLisandro Dalcin    Level: intermediate
203016d9e3a6SLisandro Dalcin 
203116d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
203216d9e3a6SLisandro Dalcin            PCHYPRE
203316d9e3a6SLisandro Dalcin 
203416d9e3a6SLisandro Dalcin @*/
20357087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
203616d9e3a6SLisandro Dalcin {
20374ac538c5SBarry Smith   PetscErrorCode ierr;
203816d9e3a6SLisandro Dalcin 
203916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
20400700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
204116d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
20424ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
204316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
204416d9e3a6SLisandro Dalcin }
204516d9e3a6SLisandro Dalcin 
204616d9e3a6SLisandro Dalcin /*MC
204716d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
204816d9e3a6SLisandro Dalcin 
204916d9e3a6SLisandro Dalcin    Options Database Keys:
2050db966c6cSHong Zhang +   -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
205116d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
205216d9e3a6SLisandro Dalcin           preconditioner
205316d9e3a6SLisandro Dalcin 
205416d9e3a6SLisandro Dalcin    Level: intermediate
205516d9e3a6SLisandro Dalcin 
205695452b02SPatrick Sanan    Notes:
205795452b02SPatrick Sanan     Apart from pc_hypre_type (for which there is PCHYPRESetType()),
205816d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
205916d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
206016d9e3a6SLisandro Dalcin 
2061c231f9e3SBarryFSmith           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_tol refer to the number of iterations
20620f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
20630f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
2064c231f9e3SBarryFSmith           (-pc_hypre_boomeramg_tol should be set to 0.0 - the default - to strictly use a fixed number of
20658f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
20660f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
20670f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
206816d9e3a6SLisandro Dalcin 
20690f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
20700f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
20710f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
207216d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
207316d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
207416d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
207516d9e3a6SLisandro Dalcin 
207616d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
207716d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
207816d9e3a6SLisandro Dalcin 
20795272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
20805272c319SBarry Smith           the two options:
20815272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
2082cbc39033SBarry Smith -   -pc_hypre_boomeramg_vec_interp_variant <v> where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
20835272c319SBarry Smith 
20845272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
20855272c319SBarry Smith 
20869e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
20879e5bc791SBarry Smith 
208816d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
20899e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
209016d9e3a6SLisandro Dalcin 
209116d9e3a6SLisandro Dalcin M*/
209216d9e3a6SLisandro Dalcin 
20938cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
209416d9e3a6SLisandro Dalcin {
209516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
209616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
209716d9e3a6SLisandro Dalcin 
209816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
2099b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
21002fa5cd67SKarl Rupp 
210116d9e3a6SLisandro Dalcin   pc->data                = jac;
21028695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
210316d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
210416d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
210516d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
210616d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
210716d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
2108bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
2109bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
21105ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
21115ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
21125ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
21136bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",PCHYPRESetInterpolations_HYPRE);CHKERRQ(ierr);
21145ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE);CHKERRQ(ierr);
21155ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",PCHYPRESetPoissonMatrix_HYPRE);CHKERRQ(ierr);
211616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
211716d9e3a6SLisandro Dalcin }
2118ebc551c0SBarry Smith 
2119f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
2120f91d8e95SBarry Smith 
2121ebc551c0SBarry Smith typedef struct {
212268326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
2123f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
21249e5bc791SBarry Smith 
21259e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
21264ddd07fcSJed Brown   PetscInt its;
21279e5bc791SBarry Smith   double   tol;
21284ddd07fcSJed Brown   PetscInt relax_type;
21294ddd07fcSJed Brown   PetscInt rap_type;
21304ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
21314ddd07fcSJed Brown   PetscInt max_levels;
2132ebc551c0SBarry Smith } PC_PFMG;
2133ebc551c0SBarry Smith 
2134ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
2135ebc551c0SBarry Smith {
2136ebc551c0SBarry Smith   PetscErrorCode ierr;
2137f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2138ebc551c0SBarry Smith 
2139ebc551c0SBarry Smith   PetscFunctionBegin;
21402fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2141f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2142c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2143ebc551c0SBarry Smith   PetscFunctionReturn(0);
2144ebc551c0SBarry Smith }
2145ebc551c0SBarry Smith 
21469e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
21479e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
21489e5bc791SBarry Smith 
2149ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
2150ebc551c0SBarry Smith {
2151ebc551c0SBarry Smith   PetscErrorCode ierr;
2152ace3abfcSBarry Smith   PetscBool      iascii;
2153f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2154ebc551c0SBarry Smith 
2155ebc551c0SBarry Smith   PetscFunctionBegin;
2156251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
21579e5bc791SBarry Smith   if (iascii) {
21589e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
2159efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max iterations %d\n",ex->its);CHKERRQ(ierr);
2160efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    tolerance %g\n",ex->tol);CHKERRQ(ierr);
2161efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2162efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
2163efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2164efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max levels %d\n",ex->max_levels);CHKERRQ(ierr);
21659e5bc791SBarry Smith   }
2166ebc551c0SBarry Smith   PetscFunctionReturn(0);
2167ebc551c0SBarry Smith }
2168ebc551c0SBarry Smith 
21694416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2170ebc551c0SBarry Smith {
2171ebc551c0SBarry Smith   PetscErrorCode ierr;
2172f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2173ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2174ebc551c0SBarry Smith 
2175ebc551c0SBarry Smith   PetscFunctionBegin;
2176e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
21770298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
217868326731SBarry Smith   if (flg) {
2179a0324ebeSBarry Smith     int level=3;
2180fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
218168326731SBarry Smith   }
21820298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2183fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
21840298fd71SBarry 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);
2185fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
21860298fd71SBarry 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);
2187fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
21889e5bc791SBarry Smith 
21890298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
2190fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
21913b46a515SGlenn Hammond 
21920298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2193fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
21940298fd71SBarry 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);
2195fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
21960298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
2197fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
2198ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
2199ebc551c0SBarry Smith   PetscFunctionReturn(0);
2200ebc551c0SBarry Smith }
2201ebc551c0SBarry Smith 
2202f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
2203f91d8e95SBarry Smith {
2204f91d8e95SBarry Smith   PetscErrorCode    ierr;
2205f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
2206d9ca1df4SBarry Smith   PetscScalar       *yy;
2207d9ca1df4SBarry Smith   const PetscScalar *xx;
22084ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
220968326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2210f91d8e95SBarry Smith 
2211f91d8e95SBarry Smith   PetscFunctionBegin;
2212dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2213aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2214f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
2215f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
2216f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
2217f91d8e95SBarry Smith 
2218f91d8e95SBarry Smith   /* copy x values over to hypre */
2219fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
2220d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2221d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
2222d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2223fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
2224fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2225f91d8e95SBarry Smith 
2226f91d8e95SBarry Smith   /* copy solution values back to PETSc */
2227f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
22288b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
2229f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2230f91d8e95SBarry Smith   PetscFunctionReturn(0);
2231f91d8e95SBarry Smith }
2232f91d8e95SBarry Smith 
2233ace3abfcSBarry 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)
22349e5bc791SBarry Smith {
22359e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
22369e5bc791SBarry Smith   PetscErrorCode ierr;
22374ddd07fcSJed Brown   PetscInt       oits;
22389e5bc791SBarry Smith 
22399e5bc791SBarry Smith   PetscFunctionBegin;
2240dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2241fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
2242fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
22439e5bc791SBarry Smith 
22449e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
22458b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
22469e5bc791SBarry Smith   *outits = oits;
22479e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
22489e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2249fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
2250fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
22519e5bc791SBarry Smith   PetscFunctionReturn(0);
22529e5bc791SBarry Smith }
22539e5bc791SBarry Smith 
22549e5bc791SBarry Smith 
22553a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
22563a32d3dbSGlenn Hammond {
22573a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
22583a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
22593a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2260ace3abfcSBarry Smith   PetscBool       flg;
22613a32d3dbSGlenn Hammond 
22623a32d3dbSGlenn Hammond   PetscFunctionBegin;
2263251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
2264ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
22653a32d3dbSGlenn Hammond 
22663a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
22672fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2268fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2269fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2270fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
22713a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
22723a32d3dbSGlenn Hammond }
22733a32d3dbSGlenn Hammond 
2274ebc551c0SBarry Smith /*MC
2275ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
2276ebc551c0SBarry Smith 
2277ebc551c0SBarry Smith    Level: advanced
2278ebc551c0SBarry Smith 
22799e5bc791SBarry Smith    Options Database:
22809e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
22819e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
22829e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
22839e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
22849e5bc791SBarry 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
22859e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
2286f91d8e95SBarry Smith 
228795452b02SPatrick Sanan    Notes:
228895452b02SPatrick Sanan     This is for CELL-centered descretizations
22899e5bc791SBarry Smith 
22908e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
2291aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
22929e5bc791SBarry Smith 
22939e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
2294ebc551c0SBarry Smith M*/
2295ebc551c0SBarry Smith 
22968cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
2297ebc551c0SBarry Smith {
2298ebc551c0SBarry Smith   PetscErrorCode ierr;
2299ebc551c0SBarry Smith   PC_PFMG        *ex;
2300ebc551c0SBarry Smith 
2301ebc551c0SBarry Smith   PetscFunctionBegin;
2302b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
230368326731SBarry Smith   pc->data = ex;
2304ebc551c0SBarry Smith 
23059e5bc791SBarry Smith   ex->its            = 1;
23069e5bc791SBarry Smith   ex->tol            = 1.e-8;
23079e5bc791SBarry Smith   ex->relax_type     = 1;
23089e5bc791SBarry Smith   ex->rap_type       = 0;
23099e5bc791SBarry Smith   ex->num_pre_relax  = 1;
23109e5bc791SBarry Smith   ex->num_post_relax = 1;
23113b46a515SGlenn Hammond   ex->max_levels     = 0;
23129e5bc791SBarry Smith 
2313ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2314ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2315ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2316f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
23179e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
231868326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
23192fa5cd67SKarl Rupp 
2320ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2321fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2322ebc551c0SBarry Smith   PetscFunctionReturn(0);
2323ebc551c0SBarry Smith }
2324d851a50bSGlenn Hammond 
2325325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2326325fc9f4SBarry Smith 
2327d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2328d851a50bSGlenn Hammond typedef struct {
2329d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2330d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2331d851a50bSGlenn Hammond 
2332d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
23334ddd07fcSJed Brown   PetscInt its;
2334d851a50bSGlenn Hammond   double   tol;
23354ddd07fcSJed Brown   PetscInt relax_type;
23364ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2337d851a50bSGlenn Hammond } PC_SysPFMG;
2338d851a50bSGlenn Hammond 
2339d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2340d851a50bSGlenn Hammond {
2341d851a50bSGlenn Hammond   PetscErrorCode ierr;
2342d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2343d851a50bSGlenn Hammond 
2344d851a50bSGlenn Hammond   PetscFunctionBegin;
23452fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2346d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2347c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2348d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2349d851a50bSGlenn Hammond }
2350d851a50bSGlenn Hammond 
2351d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2352d851a50bSGlenn Hammond 
2353d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2354d851a50bSGlenn Hammond {
2355d851a50bSGlenn Hammond   PetscErrorCode ierr;
2356ace3abfcSBarry Smith   PetscBool      iascii;
2357d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2358d851a50bSGlenn Hammond 
2359d851a50bSGlenn Hammond   PetscFunctionBegin;
2360251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2361d851a50bSGlenn Hammond   if (iascii) {
2362d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2363efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  max iterations %d\n",ex->its);CHKERRQ(ierr);
2364efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerance %g\n",ex->tol);CHKERRQ(ierr);
2365efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2366efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2367d851a50bSGlenn Hammond   }
2368d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2369d851a50bSGlenn Hammond }
2370d851a50bSGlenn Hammond 
23714416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2372d851a50bSGlenn Hammond {
2373d851a50bSGlenn Hammond   PetscErrorCode ierr;
2374d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2375ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2376d851a50bSGlenn Hammond 
2377d851a50bSGlenn Hammond   PetscFunctionBegin;
2378e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
23790298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2380d851a50bSGlenn Hammond   if (flg) {
2381d851a50bSGlenn Hammond     int level=3;
2382fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
2383d851a50bSGlenn Hammond   }
23840298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2385fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
23860298fd71SBarry 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);
2387fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
23880298fd71SBarry 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);
2389fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2390d851a50bSGlenn Hammond 
23910298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2392fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
239361710fbeSStefano 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);
2394fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2395d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2396d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2397d851a50bSGlenn Hammond }
2398d851a50bSGlenn Hammond 
2399d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2400d851a50bSGlenn Hammond {
2401d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2402d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2403d9ca1df4SBarry Smith   PetscScalar       *yy;
2404d9ca1df4SBarry Smith   const PetscScalar *xx;
24054ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
2406d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
24074ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
24084ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
24094ddd07fcSJed Brown   PetscInt          part    = 0;
24104ddd07fcSJed Brown   PetscInt          size;
24114ddd07fcSJed Brown   PetscInt          i;
2412d851a50bSGlenn Hammond 
2413d851a50bSGlenn Hammond   PetscFunctionBegin;
2414dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2415aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2416d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2417d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2418d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2419d851a50bSGlenn Hammond 
2420d851a50bSGlenn Hammond   size = 1;
24212fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
24222fa5cd67SKarl Rupp 
2423d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2424d851a50bSGlenn Hammond   if (ordering) {
2425fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2426d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2427d9ca1df4SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,(PetscScalar*)xx+(size*i)));
2428d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2429fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2430fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2431fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2432d851a50bSGlenn Hammond 
2433d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2434d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
24358b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2436d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2437a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2438d851a50bSGlenn Hammond     PetscScalar *z;
24394ddd07fcSJed Brown     PetscInt    j, k;
2440d851a50bSGlenn Hammond 
2441785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2442fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2443d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2444d851a50bSGlenn Hammond 
2445d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2446d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2447d851a50bSGlenn Hammond       k= i*nvars;
24482fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2449d851a50bSGlenn Hammond     }
24508b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2451d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2452fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2453fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2454d851a50bSGlenn Hammond 
2455d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2456d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
24578b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2458d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2459d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2460d851a50bSGlenn Hammond       k= i*nvars;
24612fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2462d851a50bSGlenn Hammond     }
2463d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2464d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2465d851a50bSGlenn Hammond   }
2466d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2467d851a50bSGlenn Hammond }
2468d851a50bSGlenn Hammond 
2469ace3abfcSBarry 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)
2470d851a50bSGlenn Hammond {
2471d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2472d851a50bSGlenn Hammond   PetscErrorCode ierr;
24734ddd07fcSJed Brown   PetscInt       oits;
2474d851a50bSGlenn Hammond 
2475d851a50bSGlenn Hammond   PetscFunctionBegin;
2476dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2477fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2478fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2479d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
24808b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2481d851a50bSGlenn Hammond   *outits = oits;
2482d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2483d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2484fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2485fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2486d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2487d851a50bSGlenn Hammond }
2488d851a50bSGlenn Hammond 
2489d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2490d851a50bSGlenn Hammond {
2491d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2492d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2493d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2494ace3abfcSBarry Smith   PetscBool        flg;
2495d851a50bSGlenn Hammond 
2496d851a50bSGlenn Hammond   PetscFunctionBegin;
2497251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2498ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2499d851a50bSGlenn Hammond 
2500d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
25012fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2502fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2503fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2504fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2505d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2506d851a50bSGlenn Hammond }
2507d851a50bSGlenn Hammond 
2508d851a50bSGlenn Hammond /*MC
2509d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2510d851a50bSGlenn Hammond 
2511d851a50bSGlenn Hammond    Level: advanced
2512d851a50bSGlenn Hammond 
2513d851a50bSGlenn Hammond    Options Database:
2514d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2515d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2516d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2517d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2518d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2519d851a50bSGlenn Hammond 
252095452b02SPatrick Sanan    Notes:
252195452b02SPatrick Sanan     This is for CELL-centered descretizations
2522d851a50bSGlenn Hammond 
2523f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2524aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2525d851a50bSGlenn Hammond            Also, only cell-centered variables.
2526d851a50bSGlenn Hammond 
2527d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2528d851a50bSGlenn Hammond M*/
2529d851a50bSGlenn Hammond 
25308cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2531d851a50bSGlenn Hammond {
2532d851a50bSGlenn Hammond   PetscErrorCode ierr;
2533d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2534d851a50bSGlenn Hammond 
2535d851a50bSGlenn Hammond   PetscFunctionBegin;
2536b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2537d851a50bSGlenn Hammond   pc->data = ex;
2538d851a50bSGlenn Hammond 
2539d851a50bSGlenn Hammond   ex->its            = 1;
2540d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2541d851a50bSGlenn Hammond   ex->relax_type     = 1;
2542d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2543d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2544d851a50bSGlenn Hammond 
2545d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2546d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2547d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2548d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2549d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2550d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
25512fa5cd67SKarl Rupp 
2552ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2553fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2554d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2555d851a50bSGlenn Hammond }
2556