xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 360ee056ff647363bf77f2811d7ea75daaaacc81)
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>
1516d9e3a6SLisandro Dalcin 
16dff31646SBarry Smith static PetscBool cite = PETSC_FALSE;
17a8d69d7bSBarry Smith static const char hypreCitation[] = "@manual{hypre-web-page,\n  title  = {{\\sl hypre}: High Performance Preconditioners},\n  organization = {Lawrence Livermore National Laboratory},\n  note  = {\\url{https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods}}\n}\n";
181f817a21SBarry Smith 
1916d9e3a6SLisandro Dalcin /*
2016d9e3a6SLisandro Dalcin    Private context (data structure) for the  preconditioner.
2116d9e3a6SLisandro Dalcin */
2216d9e3a6SLisandro Dalcin typedef struct {
2316d9e3a6SLisandro Dalcin   HYPRE_Solver   hsolver;
2449a781f5SStefano Zampini   Mat            hpmat; /* MatHYPRE */
2516d9e3a6SLisandro Dalcin 
264ddd07fcSJed Brown   HYPRE_Int (*destroy)(HYPRE_Solver);
274ddd07fcSJed Brown   HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
284ddd07fcSJed Brown   HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
2916d9e3a6SLisandro Dalcin 
3016d9e3a6SLisandro Dalcin   MPI_Comm comm_hypre;
3116d9e3a6SLisandro Dalcin   char     *hypre_type;
3216d9e3a6SLisandro Dalcin 
3316d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
344ddd07fcSJed Brown   PetscInt maxiter;
3516d9e3a6SLisandro Dalcin   double   tol;
3616d9e3a6SLisandro Dalcin 
3716d9e3a6SLisandro Dalcin   /* options for Pilut */
384ddd07fcSJed Brown   PetscInt factorrowsize;
3916d9e3a6SLisandro Dalcin 
4016d9e3a6SLisandro Dalcin   /* options for ParaSails */
414ddd07fcSJed Brown   PetscInt nlevels;
4216d9e3a6SLisandro Dalcin   double   threshhold;
4316d9e3a6SLisandro Dalcin   double   filter;
444ddd07fcSJed Brown   PetscInt sym;
4516d9e3a6SLisandro Dalcin   double   loadbal;
464ddd07fcSJed Brown   PetscInt logging;
474ddd07fcSJed Brown   PetscInt ruse;
484ddd07fcSJed Brown   PetscInt symt;
4916d9e3a6SLisandro Dalcin 
5022b6d1caSBarry Smith   /* options for BoomerAMG */
51ace3abfcSBarry Smith   PetscBool printstatistics;
5216d9e3a6SLisandro Dalcin 
5316d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
544ddd07fcSJed Brown   PetscInt  cycletype;
554ddd07fcSJed Brown   PetscInt  maxlevels;
5616d9e3a6SLisandro Dalcin   double    strongthreshold;
5716d9e3a6SLisandro Dalcin   double    maxrowsum;
584ddd07fcSJed Brown   PetscInt  gridsweeps[3];
594ddd07fcSJed Brown   PetscInt  coarsentype;
604ddd07fcSJed Brown   PetscInt  measuretype;
616a251517SEike Mueller   PetscInt  smoothtype;
628131ecf7SEike Mueller   PetscInt  smoothnumlevels;
63ec64516dSEike Mueller   PetscInt  eu_level;   /* Number of levels for ILU(k) in Euclid */
64ec64516dSEike Mueller   double    eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */
65ec64516dSEike Mueller   PetscInt  eu_bj;      /* Defines use of Block Jacobi ILU in Euclid */
664ddd07fcSJed Brown   PetscInt  relaxtype[3];
6716d9e3a6SLisandro Dalcin   double    relaxweight;
6816d9e3a6SLisandro Dalcin   double    outerrelaxweight;
694ddd07fcSJed Brown   PetscInt  relaxorder;
7016d9e3a6SLisandro Dalcin   double    truncfactor;
71ace3abfcSBarry Smith   PetscBool applyrichardson;
724ddd07fcSJed Brown   PetscInt  pmax;
734ddd07fcSJed Brown   PetscInt  interptype;
744ddd07fcSJed Brown   PetscInt  agg_nl;
754ddd07fcSJed Brown   PetscInt  agg_num_paths;
76ace3abfcSBarry Smith   PetscBool nodal_relax;
774ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
784cb006feSStefano Zampini 
795272c319SBarry Smith   PetscInt  nodal_coarsening;
8022e51d31SStefano Zampini   PetscInt  nodal_coarsening_diag;
815272c319SBarry Smith   PetscInt  vec_interp_variant;
8222e51d31SStefano Zampini   PetscInt  vec_interp_qmax;
8322e51d31SStefano Zampini   PetscBool vec_interp_smooth;
8422e51d31SStefano Zampini   PetscInt  interp_refine;
8522e51d31SStefano Zampini 
865272c319SBarry Smith   HYPRE_IJVector  *hmnull;
875272c319SBarry Smith   HYPRE_ParVector *phmnull;  /* near null space passed to hypre */
885272c319SBarry Smith   PetscInt        n_hmnull;
895272c319SBarry Smith   Vec             hmnull_constant;
9072827435SBarry 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 */
915272c319SBarry Smith 
92863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
93863406b8SStefano Zampini   PetscInt  as_print;
94863406b8SStefano Zampini   PetscInt  as_max_iter;
95863406b8SStefano Zampini   PetscReal as_tol;
96863406b8SStefano Zampini   PetscInt  as_relax_type;
97863406b8SStefano Zampini   PetscInt  as_relax_times;
98863406b8SStefano Zampini   PetscReal as_relax_weight;
99863406b8SStefano Zampini   PetscReal as_omega;
100863406b8SStefano 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) */
101863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
102863406b8SStefano 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) */
103863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
1044cb006feSStefano Zampini   PetscInt  ams_cycle_type;
105863406b8SStefano Zampini   PetscInt  ads_cycle_type;
1064cb006feSStefano Zampini 
1074cb006feSStefano Zampini   /* additional data */
1085ac14e1cSStefano Zampini   Mat G;             /* MatHYPRE */
1095ac14e1cSStefano Zampini   Mat C;             /* MatHYPRE */
1105ac14e1cSStefano Zampini   Mat alpha_Poisson; /* MatHYPRE */
1115ac14e1cSStefano Zampini   Mat beta_Poisson;  /* MatHYPRE */
1125ac14e1cSStefano Zampini 
1135ac14e1cSStefano Zampini   /* extra information for AMS */
1145ac14e1cSStefano Zampini   PetscInt       dim; /* geometrical dimension */
1154cb006feSStefano Zampini   HYPRE_IJVector coords[3];
1164cb006feSStefano Zampini   HYPRE_IJVector constants[3];
1176bf688a0SCe Qin   Mat            RT_PiFull, RT_Pi[3];
1186bf688a0SCe Qin   Mat            ND_PiFull, ND_Pi[3];
1194cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
12023df4f25SStefano Zampini   PetscBool      ams_beta_is_zero_part;
12123df4f25SStefano Zampini   PetscInt       ams_proj_freq;
12216d9e3a6SLisandro Dalcin } PC_HYPRE;
12316d9e3a6SLisandro Dalcin 
124d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
125d2128fa2SBarry Smith {
126d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
127d2128fa2SBarry Smith 
128d2128fa2SBarry Smith   PetscFunctionBegin;
129d2128fa2SBarry Smith   *hsolver = jac->hsolver;
130d2128fa2SBarry Smith   PetscFunctionReturn(0);
131d2128fa2SBarry Smith }
13216d9e3a6SLisandro Dalcin 
133ce6a8a0dSJed Brown /* Resets (frees) Hypre's representation of the near null space */
134ce6a8a0dSJed Brown static PetscErrorCode PCHYPREResetNearNullSpace_Private(PC pc)
135ce6a8a0dSJed Brown {
136ce6a8a0dSJed Brown   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
137ce6a8a0dSJed Brown   PetscInt       i;
1389d678128SJed Brown   PetscErrorCode ierr;
139ce6a8a0dSJed Brown   PETSC_UNUSED PetscScalar *petscvecarray;
140ce6a8a0dSJed Brown 
1419d678128SJed Brown   PetscFunctionBegin;
142ce6a8a0dSJed Brown   for (i=0; i<jac->n_hmnull; i++) {
143ce6a8a0dSJed Brown     VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],jac->hmnull_hypre_data_array[i],petscvecarray);
144ce6a8a0dSJed Brown     PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->hmnull[i]));
145ce6a8a0dSJed Brown   }
146ce6a8a0dSJed Brown   ierr = PetscFree(jac->hmnull);CHKERRQ(ierr);
147ce6a8a0dSJed Brown   ierr = PetscFree(jac->hmnull_hypre_data_array);CHKERRQ(ierr);
148ce6a8a0dSJed Brown   ierr = PetscFree(jac->phmnull);CHKERRQ(ierr);
149ce6a8a0dSJed Brown   ierr = VecDestroy(&jac->hmnull_constant);CHKERRQ(ierr);
1509d678128SJed Brown   jac->n_hmnull = 0;
151ce6a8a0dSJed Brown   PetscFunctionReturn(0);
152ce6a8a0dSJed Brown }
153ce6a8a0dSJed Brown 
15416d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
15516d9e3a6SLisandro Dalcin {
15616d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
15749a781f5SStefano Zampini   Mat_HYPRE          *hjac;
15816d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
15916d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
16049a781f5SStefano Zampini   PetscBool          ishypre;
16149a781f5SStefano Zampini   PetscErrorCode     ierr;
16216d9e3a6SLisandro Dalcin 
16316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16416d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
16502a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
16616d9e3a6SLisandro Dalcin   }
1675f5c5b43SBarry Smith 
16849a781f5SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRE,&ishypre);CHKERRQ(ierr);
16949a781f5SStefano Zampini   if (!ishypre) {
1706bf688a0SCe Qin     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
1716bf688a0SCe Qin     ierr = MatConvert(pc->pmat,MATHYPRE,MAT_INITIAL_MATRIX,&jac->hpmat);CHKERRQ(ierr);
17249a781f5SStefano Zampini   } else {
17349a781f5SStefano Zampini     ierr = PetscObjectReference((PetscObject)pc->pmat);CHKERRQ(ierr);
17449a781f5SStefano Zampini     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
17549a781f5SStefano Zampini     jac->hpmat = pc->pmat;
17616d9e3a6SLisandro Dalcin   }
17749a781f5SStefano Zampini   hjac = (Mat_HYPRE*)(jac->hpmat->data);
1785f5c5b43SBarry Smith 
17916d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
18016d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
1815272c319SBarry Smith     MatNullSpace    mnull;
1825272c319SBarry Smith     PetscBool       has_const;
18349a781f5SStefano Zampini     PetscInt        bs,nvec,i;
1845272c319SBarry Smith     const Vec       *vecs;
18572827435SBarry Smith     PetscScalar     *petscvecarray;
1865272c319SBarry Smith 
18716d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1882fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
1895272c319SBarry Smith     ierr = MatGetNearNullSpace(pc->mat, &mnull);CHKERRQ(ierr);
1905272c319SBarry Smith     if (mnull) {
191ce6a8a0dSJed Brown       ierr = PCHYPREResetNearNullSpace_Private(pc);CHKERRQ(ierr);
1925272c319SBarry Smith       ierr = MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs);CHKERRQ(ierr);
1935272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull);CHKERRQ(ierr);
19472827435SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull_hypre_data_array);CHKERRQ(ierr);
1955272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->phmnull);CHKERRQ(ierr);
1965272c319SBarry Smith       for (i=0; i<nvec; i++) {
1975272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(vecs[i],&jac->hmnull[i]);CHKERRQ(ierr);
19872827435SBarry Smith         ierr = VecGetArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
19958968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],petscvecarray,jac->hmnull_hypre_data_array[i]);
20072827435SBarry Smith         ierr = VecRestoreArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
2015272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[i],(void**)&jac->phmnull[i]));
2025272c319SBarry Smith       }
2035272c319SBarry Smith       if (has_const) {
2045272c319SBarry Smith         ierr = MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL);CHKERRQ(ierr);
2055272c319SBarry Smith         ierr = VecSet(jac->hmnull_constant,1);CHKERRQ(ierr);
2065272c319SBarry Smith         ierr = VecNormalize(jac->hmnull_constant,NULL);
2075272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(jac->hmnull_constant,&jac->hmnull[nvec]);CHKERRQ(ierr);
20872827435SBarry Smith         ierr = VecGetArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
20958968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[nvec],petscvecarray,jac->hmnull_hypre_data_array[nvec]);
21072827435SBarry Smith         ierr = VecRestoreArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
2115272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[nvec],(void**)&jac->phmnull[nvec]));
2125272c319SBarry Smith         nvec++;
2135272c319SBarry Smith       }
2145272c319SBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVectors,(jac->hsolver,nvec,jac->phmnull));
2155272c319SBarry Smith       jac->n_hmnull = nvec;
2165272c319SBarry Smith     }
2174cb006feSStefano Zampini   }
218863406b8SStefano Zampini 
2194cb006feSStefano Zampini   /* special case for AMS */
2204cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
2215ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2225ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
2236bf688a0SCe Qin     if (!jac->coords[0] && !jac->constants[0] && !(jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
2246bf688a0SCe 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");
2256bf688a0SCe Qin     }
2265ac14e1cSStefano Zampini     if (jac->dim) {
2275ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,jac->dim));
2285ac14e1cSStefano Zampini     }
2295ac14e1cSStefano Zampini     if (jac->constants[0]) {
2305ac14e1cSStefano Zampini       HYPRE_ParVector ozz,zoz,zzo = NULL;
2315ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&ozz)));
2325ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&zoz)));
2335ac14e1cSStefano Zampini       if (jac->constants[2]) {
2345ac14e1cSStefano Zampini         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&zzo)));
2355ac14e1cSStefano Zampini       }
2365ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,ozz,zoz,zzo));
2375ac14e1cSStefano Zampini     }
2385ac14e1cSStefano Zampini     if (jac->coords[0]) {
2395ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
2405ac14e1cSStefano Zampini       coords[0] = NULL;
2415ac14e1cSStefano Zampini       coords[1] = NULL;
2425ac14e1cSStefano Zampini       coords[2] = NULL;
2435ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
2445ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
2455ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
2465ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
2475ac14e1cSStefano Zampini     }
24849a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
2495ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
2505ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2515ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr));
2525ac14e1cSStefano Zampini     if (jac->alpha_Poisson) {
2535ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->alpha_Poisson->data);
2545ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2555ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr));
2565ac14e1cSStefano Zampini     }
2575ac14e1cSStefano Zampini     if (jac->ams_beta_is_zero) {
2585ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
2595ac14e1cSStefano Zampini     } else if (jac->beta_Poisson) {
2605ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->beta_Poisson->data);
2615ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2625ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr));
2635ac14e1cSStefano Zampini     }
2646bf688a0SCe Qin     if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) {
2656bf688a0SCe Qin       PetscInt           i;
2666bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
2676bf688a0SCe Qin       if (jac->ND_PiFull) {
2686bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
2696bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
2706bf688a0SCe Qin       } else {
2716bf688a0SCe Qin         nd_parcsrfull = NULL;
2726bf688a0SCe Qin       }
2736bf688a0SCe Qin       for (i=0;i<3;++i) {
2746bf688a0SCe Qin         if (jac->ND_Pi[i]) {
2756bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
2766bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
2776bf688a0SCe Qin         } else {
2786bf688a0SCe Qin           nd_parcsr[i] = NULL;
2796bf688a0SCe Qin         }
2806bf688a0SCe Qin       }
2816bf688a0SCe Qin       PetscStackCallStandard(HYPRE_AMSSetInterpolations,(jac->hsolver,nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]));
2826bf688a0SCe Qin     }
2834cb006feSStefano Zampini   }
284863406b8SStefano Zampini   /* special case for ADS */
285863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
2865ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2875ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
2886bf688a0SCe 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])))) {
2896bf688a0SCe Qin       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations");
2906bf688a0SCe Qin     }
29137096e45SBarry 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");
29249a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
29349a781f5SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient");
2945ac14e1cSStefano Zampini     if (jac->coords[0]) {
2955ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
2965ac14e1cSStefano Zampini       coords[0] = NULL;
2975ac14e1cSStefano Zampini       coords[1] = NULL;
2985ac14e1cSStefano Zampini       coords[2] = NULL;
2995ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
3005ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
3015ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
3025ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_ADSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
3035ac14e1cSStefano Zampini     }
3045ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
3055ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3065ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteGradient,(jac->hsolver,parcsr));
3075ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->C->data);
3085ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3095ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteCurl,(jac->hsolver,parcsr));
3106bf688a0SCe Qin     if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
3116bf688a0SCe Qin       PetscInt           i;
3126bf688a0SCe Qin       HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3];
3136bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
3146bf688a0SCe Qin       if (jac->RT_PiFull) {
3156bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->RT_PiFull->data);
3166bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsrfull)));
3176bf688a0SCe Qin       } else {
3186bf688a0SCe Qin         rt_parcsrfull = NULL;
3196bf688a0SCe Qin       }
3206bf688a0SCe Qin       for (i=0;i<3;++i) {
3216bf688a0SCe Qin         if (jac->RT_Pi[i]) {
3226bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->RT_Pi[i]->data);
3236bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsr[i])));
3246bf688a0SCe Qin         } else {
3256bf688a0SCe Qin           rt_parcsr[i] = NULL;
3266bf688a0SCe Qin         }
3276bf688a0SCe Qin       }
3286bf688a0SCe Qin       if (jac->ND_PiFull) {
3296bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
3306bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
3316bf688a0SCe Qin       } else {
3326bf688a0SCe Qin         nd_parcsrfull = NULL;
3336bf688a0SCe Qin       }
3346bf688a0SCe Qin       for (i=0;i<3;++i) {
3356bf688a0SCe Qin         if (jac->ND_Pi[i]) {
3366bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
3376bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
3386bf688a0SCe Qin         } else {
3396bf688a0SCe Qin           nd_parcsr[i] = NULL;
3406bf688a0SCe Qin         }
3416bf688a0SCe Qin       }
3426bf688a0SCe 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]));
3436bf688a0SCe Qin     }
344863406b8SStefano Zampini   }
34549a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
34649a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&bv));
34749a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&xv));
34822e51d31SStefano Zampini   PetscStackCallStandard(jac->setup,(jac->hsolver,hmat,bv,xv));
34916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
35016d9e3a6SLisandro Dalcin }
35116d9e3a6SLisandro Dalcin 
35216d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
35316d9e3a6SLisandro Dalcin {
35416d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
35549a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
35616d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
35716d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
358d9ca1df4SBarry Smith   PetscScalar        *xv;
359d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
36016d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
361d9ca1df4SBarry Smith   PetscScalar        *sxv;
3624ddd07fcSJed Brown   PetscInt           hierr;
36316d9e3a6SLisandro Dalcin 
36416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
365dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
36616d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
367d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
36816d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
36958968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)bv,sbv);
37058968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
37116d9e3a6SLisandro Dalcin 
37249a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
37349a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
37449a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
375fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
37665e19b50SBarry Smith   if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
377fd3f9acdSBarry Smith   if (hierr) hypre__global_error = 0;);
37816d9e3a6SLisandro Dalcin 
37923df4f25SStefano Zampini   if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) {
3805ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSProjectOutGradients,(jac->hsolver,jxv));
38121df291bSStefano Zampini   }
38258968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)sbv,bv);
38358968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
38416d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
385d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
38616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
38716d9e3a6SLisandro Dalcin }
38816d9e3a6SLisandro Dalcin 
3898695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc)
3908695de01SBarry Smith {
3918695de01SBarry Smith   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
3928695de01SBarry Smith   PetscErrorCode ierr;
3938695de01SBarry Smith 
3948695de01SBarry Smith   PetscFunctionBegin;
39549a781f5SStefano Zampini   ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
3965ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
3975ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
3985ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
3995ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
4006bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
4016bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[0]);CHKERRQ(ierr);
4026bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[1]);CHKERRQ(ierr);
4036bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[2]);CHKERRQ(ierr);
4046bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
4056bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[0]);CHKERRQ(ierr);
4066bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[1]);CHKERRQ(ierr);
4076bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[2]);CHKERRQ(ierr);
4088695de01SBarry Smith   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); jac->coords[0] = NULL;
4098695de01SBarry Smith   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); jac->coords[1] = NULL;
4108695de01SBarry Smith   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); jac->coords[2] = NULL;
4118695de01SBarry Smith   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); jac->constants[0] = NULL;
4128695de01SBarry Smith   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); jac->constants[1] = NULL;
4138695de01SBarry Smith   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); jac->constants[2] = NULL;
414ce6a8a0dSJed Brown   ierr = PCHYPREResetNearNullSpace_Private(pc);CHKERRQ(ierr);
4155ac14e1cSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
4165ac14e1cSStefano Zampini   jac->dim = 0;
4178695de01SBarry Smith   PetscFunctionReturn(0);
4188695de01SBarry Smith }
4198695de01SBarry Smith 
42016d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
42116d9e3a6SLisandro Dalcin {
42216d9e3a6SLisandro Dalcin   PC_HYPRE                 *jac = (PC_HYPRE*)pc->data;
42316d9e3a6SLisandro Dalcin   PetscErrorCode           ierr;
42416d9e3a6SLisandro Dalcin 
42516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
4268695de01SBarry Smith   ierr = PCReset_HYPRE(pc);CHKERRQ(ierr);
42722e51d31SStefano Zampini   if (jac->destroy) PetscStackCallStandard(jac->destroy,(jac->hsolver));
428503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
42916d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
430c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
43116d9e3a6SLisandro Dalcin 
43216d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
433bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
434bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
4354cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
4364cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
437863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
4386bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",NULL);CHKERRQ(ierr);
4394cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
4405ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",NULL);CHKERRQ(ierr);
44116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
44216d9e3a6SLisandro Dalcin }
44316d9e3a6SLisandro Dalcin 
44416d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
4454416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptionItems *PetscOptionsObject,PC pc)
44616d9e3a6SLisandro Dalcin {
44716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
44816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
449ace3abfcSBarry Smith   PetscBool      flag;
45016d9e3a6SLisandro Dalcin 
45116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
452e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
45316d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
454fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
45516d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
456fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
45716d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
458fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
45916d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
46016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
46116d9e3a6SLisandro Dalcin }
46216d9e3a6SLisandro Dalcin 
46316d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
46416d9e3a6SLisandro Dalcin {
46516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
46616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
467ace3abfcSBarry Smith   PetscBool      iascii;
46816d9e3a6SLisandro Dalcin 
46916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
470251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
47116d9e3a6SLisandro Dalcin   if (iascii) {
47216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
47316d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
474efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
47516d9e3a6SLisandro Dalcin     } else {
476efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default maximum number of iterations \n");CHKERRQ(ierr);
47716d9e3a6SLisandro Dalcin     }
47816d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
479efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
48016d9e3a6SLisandro Dalcin     } else {
481efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default drop tolerance \n");CHKERRQ(ierr);
48216d9e3a6SLisandro Dalcin     }
48316d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
484efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
48516d9e3a6SLisandro Dalcin     } else {
486efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default factor row size \n");CHKERRQ(ierr);
48716d9e3a6SLisandro Dalcin     }
48816d9e3a6SLisandro Dalcin   }
48916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
49016d9e3a6SLisandro Dalcin }
49116d9e3a6SLisandro Dalcin 
49216d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
493db966c6cSHong Zhang static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PetscOptionItems *PetscOptionsObject,PC pc)
494db966c6cSHong Zhang {
495db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
496db966c6cSHong Zhang   PetscErrorCode ierr;
497db966c6cSHong Zhang   PetscBool      flag;
498db966c6cSHong Zhang 
499db966c6cSHong Zhang   PetscFunctionBegin;
500db966c6cSHong Zhang   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Euclid Options");CHKERRQ(ierr);
501db966c6cSHong Zhang   ierr = PetscOptionsInt("-pc_hypre_euclid_level","Factorization levels","None",jac->eu_level,&jac->eu_level,&flag);CHKERRQ(ierr);
502db966c6cSHong Zhang   if (flag) PetscStackCallStandard(HYPRE_EuclidSetLevel,(jac->hsolver,jac->eu_level));
503db966c6cSHong Zhang   ierr = PetscOptionsTail();CHKERRQ(ierr);
504db966c6cSHong Zhang   PetscFunctionReturn(0);
505db966c6cSHong Zhang }
506db966c6cSHong Zhang 
507db966c6cSHong Zhang static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer)
508db966c6cSHong Zhang {
509db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
510db966c6cSHong Zhang   PetscErrorCode ierr;
511db966c6cSHong Zhang   PetscBool      iascii;
512db966c6cSHong Zhang 
513db966c6cSHong Zhang   PetscFunctionBegin;
514db966c6cSHong Zhang   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
515db966c6cSHong Zhang   if (iascii) {
516db966c6cSHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid preconditioning\n");CHKERRQ(ierr);
517db966c6cSHong Zhang     if (jac->eu_level != PETSC_DEFAULT) {
518db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    factorization levels %d\n",jac->eu_level);CHKERRQ(ierr);
519db966c6cSHong Zhang     } else {
520db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    default factorization levels \n");CHKERRQ(ierr);
521db966c6cSHong Zhang     }
522db966c6cSHong Zhang   }
523db966c6cSHong Zhang   PetscFunctionReturn(0);
524db966c6cSHong Zhang }
525db966c6cSHong Zhang 
526db966c6cSHong Zhang /* --------------------------------------------------------------------------------------------*/
52716d9e3a6SLisandro Dalcin 
52816d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
52916d9e3a6SLisandro Dalcin {
53016d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
53149a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
53216d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
53316d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
534d9ca1df4SBarry Smith   PetscScalar        *xv;
535d9ca1df4SBarry Smith   const PetscScalar  *bv;
53616d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
53716d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
5384ddd07fcSJed Brown   PetscInt           hierr;
53916d9e3a6SLisandro Dalcin 
54016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
541dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
54216d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
543d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
54416d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
54558968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)bv,sbv);
54658968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
54716d9e3a6SLisandro Dalcin 
54849a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
54949a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
55049a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
55116d9e3a6SLisandro Dalcin 
55216d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
55316d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
554e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
55516d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
55616d9e3a6SLisandro Dalcin 
55758968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,sbv,bv);
55858968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
55916d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
560d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
56116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
56216d9e3a6SLisandro Dalcin }
56316d9e3a6SLisandro Dalcin 
564a669f990SJed Brown /* static array length */
565a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
566a669f990SJed Brown 
56716d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
5680f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
56916d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
57065de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
5716a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]   = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
57265de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
57365de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
57465de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
5757b7fa87dSPierre Jolivet                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "l1-Gauss-Seidel" /* nonsymmetric */, "backward-l1-Gauss-Seidel" /* nonsymmetric */,
57665de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
5770f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
578e2287abbSStefano Zampini                                                   "ext+i-cc", "standard", "standard-wts", "block", "block-wtd", "FF", "FF1"};
5794416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc)
58016d9e3a6SLisandro Dalcin {
58116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
58216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
58322e51d31SStefano Zampini   PetscInt       bs,n,indx,level;
584ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
58516d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
58616d9e3a6SLisandro Dalcin 
58716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
588e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
5894336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
59016d9e3a6SLisandro Dalcin   if (flg) {
5914336a9eeSBarry Smith     jac->cycletype = indx+1;
592fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
59316d9e3a6SLisandro Dalcin   }
59416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
59516d9e3a6SLisandro Dalcin   if (flg) {
596ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
597fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
59816d9e3a6SLisandro Dalcin   }
59916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
60016d9e3a6SLisandro Dalcin   if (flg) {
601ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
602fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
60316d9e3a6SLisandro Dalcin   }
6040f1074feSSatish 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);
60516d9e3a6SLisandro Dalcin   if (flg) {
60657622a8eSBarry 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);
607fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
60816d9e3a6SLisandro Dalcin   }
60922e51d31SStefano Zampini   bs = 1;
61022e51d31SStefano Zampini   if (pc->pmat) {
61122e51d31SStefano Zampini     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
61222e51d31SStefano Zampini   }
61322e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_numfunctions","Number of functions","HYPRE_BoomerAMGSetNumFunctions",bs,&bs,&flg);CHKERRQ(ierr);
61422e51d31SStefano Zampini   if (flg) {
61522e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
61622e51d31SStefano Zampini   }
61716d9e3a6SLisandro Dalcin 
6180f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
61916d9e3a6SLisandro Dalcin   if (flg) {
62057622a8eSBarry 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);
621fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
62216d9e3a6SLisandro Dalcin   }
62316d9e3a6SLisandro Dalcin 
6240f1074feSSatish 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);
6250f1074feSSatish Balay   if (flg) {
62657622a8eSBarry 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);
627fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
6280f1074feSSatish Balay   }
6290f1074feSSatish Balay 
6300f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
6310f1074feSSatish Balay   if (flg) {
63257622a8eSBarry 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);
6330f1074feSSatish Balay 
634fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
6350f1074feSSatish Balay   }
6360f1074feSSatish Balay 
6370f1074feSSatish 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);
6380f1074feSSatish Balay   if (flg) {
63957622a8eSBarry 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);
6400f1074feSSatish Balay 
641fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
6420f1074feSSatish Balay   }
6430f1074feSSatish Balay 
6440f1074feSSatish Balay 
64516d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
64616d9e3a6SLisandro Dalcin   if (flg) {
64757622a8eSBarry 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);
648fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
64916d9e3a6SLisandro Dalcin   }
65016d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
65116d9e3a6SLisandro Dalcin   if (flg) {
65257622a8eSBarry 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);
65357622a8eSBarry 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);
654fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
65516d9e3a6SLisandro Dalcin   }
65616d9e3a6SLisandro Dalcin 
65716d9e3a6SLisandro Dalcin   /* Grid sweeps */
6580f1074feSSatish 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);
65916d9e3a6SLisandro Dalcin   if (flg) {
660fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
66116d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
66216d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
6630f1074feSSatish Balay     jac->gridsweeps[1] = indx;
6640f1074feSSatish Balay     /*defaults coarse to 1 */
6650f1074feSSatish Balay     jac->gridsweeps[2] = 1;
66616d9e3a6SLisandro Dalcin   }
6675272c319SBarry 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);
6685272c319SBarry Smith   if (flg) {
6695272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,jac->nodal_coarsening));
6705272c319SBarry Smith   }
67122e51d31SStefano 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);
67222e51d31SStefano Zampini   if (flg) {
67322e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNodalDiag,(jac->hsolver,jac->nodal_coarsening_diag));
67422e51d31SStefano Zampini   }
675cbc39033SBarry 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);
6765272c319SBarry Smith   if (flg) {
6775272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,(jac->hsolver,jac->vec_interp_variant));
6785272c319SBarry Smith   }
67922e51d31SStefano 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);
68022e51d31SStefano Zampini   if (flg) {
68122e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecQMax,(jac->hsolver,jac->vec_interp_qmax));
68222e51d31SStefano Zampini   }
68322e51d31SStefano 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);
68422e51d31SStefano Zampini   if (flg) {
68522e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothInterpVectors,(jac->hsolver,jac->vec_interp_smooth));
68622e51d31SStefano Zampini   }
68722e51d31SStefano 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);
68822e51d31SStefano Zampini   if (flg) {
68922e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpRefine,(jac->hsolver,jac->interp_refine));
69022e51d31SStefano Zampini   }
6910f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
69216d9e3a6SLisandro Dalcin   if (flg) {
693fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
6940f1074feSSatish Balay     jac->gridsweeps[0] = indx;
69516d9e3a6SLisandro Dalcin   }
69616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
69716d9e3a6SLisandro Dalcin   if (flg) {
698fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
6990f1074feSSatish Balay     jac->gridsweeps[1] = indx;
70016d9e3a6SLisandro Dalcin   }
7010f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
70216d9e3a6SLisandro Dalcin   if (flg) {
703fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
7040f1074feSSatish Balay     jac->gridsweeps[2] = indx;
70516d9e3a6SLisandro Dalcin   }
70616d9e3a6SLisandro Dalcin 
7076a251517SEike Mueller   /* Smooth type */
7086a251517SEike Mueller   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);
7096a251517SEike Mueller   if (flg) {
7106a251517SEike Mueller     jac->smoothtype = indx;
7116a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
7128131ecf7SEike Mueller     jac->smoothnumlevels = 25;
7138131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
7148131ecf7SEike Mueller   }
7158131ecf7SEike Mueller 
7168131ecf7SEike Mueller   /* Number of smoothing levels */
7178131ecf7SEike 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);
7188131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
7198131ecf7SEike Mueller     jac->smoothnumlevels = indx;
7208131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
7216a251517SEike Mueller   }
7226a251517SEike Mueller 
7231810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
7241810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
7251810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
7261810e44eSEike Mueller     jac->eu_level = indx;
7271810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
7281810e44eSEike Mueller   }
7291810e44eSEike Mueller 
7301810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
7311810e44eSEike Mueller   double droptolerance;
7321810e44eSEike Mueller   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
7331810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
7341810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
7351810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
7361810e44eSEike Mueller   }
7371810e44eSEike Mueller 
7381810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
7391810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
7401810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
7411810e44eSEike Mueller     jac->eu_bj = tmp_truth;
742493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
7431810e44eSEike Mueller   }
7441810e44eSEike Mueller 
74516d9e3a6SLisandro Dalcin   /* Relax type */
746a669f990SJed 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);
74716d9e3a6SLisandro Dalcin   if (flg) {
7480f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
749fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
7500f1074feSSatish Balay     /* by default, coarse type set to 9 */
7510f1074feSSatish Balay     jac->relaxtype[2] = 9;
752ddbeb582SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, 9, 3));
75316d9e3a6SLisandro Dalcin   }
754a669f990SJed 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);
75516d9e3a6SLisandro Dalcin   if (flg) {
75616d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
757fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
75816d9e3a6SLisandro Dalcin   }
759a669f990SJed 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);
76016d9e3a6SLisandro Dalcin   if (flg) {
7610f1074feSSatish Balay     jac->relaxtype[1] = indx;
762fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
76316d9e3a6SLisandro Dalcin   }
764a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
76516d9e3a6SLisandro Dalcin   if (flg) {
7660f1074feSSatish Balay     jac->relaxtype[2] = indx;
767fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
76816d9e3a6SLisandro Dalcin   }
76916d9e3a6SLisandro Dalcin 
77016d9e3a6SLisandro Dalcin   /* Relaxation Weight */
77116d9e3a6SLisandro 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);
77216d9e3a6SLisandro Dalcin   if (flg) {
773fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
77416d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
77516d9e3a6SLisandro Dalcin   }
77616d9e3a6SLisandro Dalcin 
77716d9e3a6SLisandro Dalcin   n         = 2;
77816d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
77916d9e3a6SLisandro 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);
78016d9e3a6SLisandro Dalcin   if (flg) {
78116d9e3a6SLisandro Dalcin     if (n == 2) {
78216d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
783fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
784ce94432eSBarry 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);
78516d9e3a6SLisandro Dalcin   }
78616d9e3a6SLisandro Dalcin 
78716d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
78816d9e3a6SLisandro 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);
78916d9e3a6SLisandro Dalcin   if (flg) {
790fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
79116d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
79216d9e3a6SLisandro Dalcin   }
79316d9e3a6SLisandro Dalcin 
79416d9e3a6SLisandro Dalcin   n         = 2;
79516d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
79616d9e3a6SLisandro 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);
79716d9e3a6SLisandro Dalcin   if (flg) {
79816d9e3a6SLisandro Dalcin     if (n == 2) {
79916d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
800fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
801ce94432eSBarry 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);
80216d9e3a6SLisandro Dalcin   }
80316d9e3a6SLisandro Dalcin 
80416d9e3a6SLisandro Dalcin   /* the Relax Order */
805acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
80616d9e3a6SLisandro Dalcin 
8078afaa268SBarry Smith   if (flg && tmp_truth) {
80816d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
809fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
81016d9e3a6SLisandro Dalcin   }
811a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
81216d9e3a6SLisandro Dalcin   if (flg) {
81316d9e3a6SLisandro Dalcin     jac->measuretype = indx;
814fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
81516d9e3a6SLisandro Dalcin   }
8160f1074feSSatish Balay   /* update list length 3/07 */
817a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
81816d9e3a6SLisandro Dalcin   if (flg) {
81916d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
820fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
82116d9e3a6SLisandro Dalcin   }
8220f1074feSSatish Balay 
8230f1074feSSatish Balay   /* new 3/07 */
824a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
8250f1074feSSatish Balay   if (flg) {
8260f1074feSSatish Balay     jac->interptype = indx;
827fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
8280f1074feSSatish Balay   }
8290f1074feSSatish Balay 
830b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
83116d9e3a6SLisandro Dalcin   if (flg) {
832b96a4a96SBarry Smith     level = 3;
8330298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
8342fa5cd67SKarl Rupp 
835b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
836fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
8372ae77aedSBarry Smith   }
8382ae77aedSBarry Smith 
839b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
8402ae77aedSBarry Smith   if (flg) {
841b96a4a96SBarry Smith     level = 3;
8420298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
8432fa5cd67SKarl Rupp 
844b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
845fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
84616d9e3a6SLisandro Dalcin   }
8478f87f92bSBarry Smith 
848acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
8498f87f92bSBarry Smith   if (flg && tmp_truth) {
8508f87f92bSBarry Smith     PetscInt tmp_int;
8518f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
8528f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
853fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
854fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
855fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
856fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
8578f87f92bSBarry Smith   }
8588f87f92bSBarry Smith 
85916d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
86016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
86116d9e3a6SLisandro Dalcin }
86216d9e3a6SLisandro Dalcin 
863ace3abfcSBarry 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)
86416d9e3a6SLisandro Dalcin {
86516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
86616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
8674ddd07fcSJed Brown   PetscInt       oits;
86816d9e3a6SLisandro Dalcin 
86916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
870dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
871fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
872fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
87316d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
87416d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
87516d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
8768b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
8774d0a8057SBarry Smith   *outits = oits;
8784d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
8794d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
880fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
881fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
88216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
88316d9e3a6SLisandro Dalcin }
88416d9e3a6SLisandro Dalcin 
88516d9e3a6SLisandro Dalcin 
88616d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
88716d9e3a6SLisandro Dalcin {
88816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
88916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
890ace3abfcSBarry Smith   PetscBool      iascii;
89116d9e3a6SLisandro Dalcin 
89216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
893251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
89416d9e3a6SLisandro Dalcin   if (iascii) {
89516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
896efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
89722e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of levels %D\n",jac->maxlevels);CHKERRQ(ierr);
89822e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of iterations PER hypre call %D\n",jac->maxiter);CHKERRQ(ierr);
899efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
900efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
901efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
90222e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: max elements per row %D\n",jac->pmax);CHKERRQ(ierr);
90322e51d31SStefano Zampini     if (jac->interp_refine) {
90422e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: number of steps of weighted refinement %D\n",jac->interp_refine);CHKERRQ(ierr);
90522e51d31SStefano Zampini     }
90622e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of levels of aggressive coarsening %D\n",jac->agg_nl);CHKERRQ(ierr);
90722e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of paths for aggressive coarsening %D\n",jac->agg_num_paths);CHKERRQ(ierr);
9080f1074feSSatish Balay 
909efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
91016d9e3a6SLisandro Dalcin 
91122e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps down         %D\n",jac->gridsweeps[0]);CHKERRQ(ierr);
91222e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps up           %D\n",jac->gridsweeps[1]);CHKERRQ(ierr);
91322e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps on coarse    %D\n",jac->gridsweeps[2]);CHKERRQ(ierr);
91416d9e3a6SLisandro Dalcin 
915efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
916efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
917efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
91816d9e3a6SLisandro Dalcin 
919efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
920efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
92116d9e3a6SLisandro Dalcin 
92216d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
923efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using CF-relaxation\n");CHKERRQ(ierr);
92416d9e3a6SLisandro Dalcin     } else {
925efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using CF-relaxation\n");CHKERRQ(ierr);
92616d9e3a6SLisandro Dalcin     }
9276a251517SEike Mueller     if (jac->smoothtype!=-1) {
928efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
92922e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth num levels    %D\n",jac->smoothnumlevels);CHKERRQ(ierr);
9307e352d70SEike Mueller     } else {
931efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using more complex smoothers.\n");CHKERRQ(ierr);
9321810e44eSEike Mueller     }
9331810e44eSEike Mueller     if (jac->smoothtype==3) {
93422e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) levels %D\n",jac->eu_level);CHKERRQ(ierr);
93522e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) drop tolerance %g\n",(double)jac->eu_droptolerance);CHKERRQ(ierr);
93622e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU use Block-Jacobi? %D\n",jac->eu_bj);CHKERRQ(ierr);
9376a251517SEike Mueller     }
938efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
939efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
940efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
9415272c319SBarry Smith     if (jac->nodal_coarsening) {
942efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
9435272c319SBarry Smith     }
9445272c319SBarry Smith     if (jac->vec_interp_variant) {
945efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
94622e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecQMax() %D\n",jac->vec_interp_qmax);CHKERRQ(ierr);
94722e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n",jac->vec_interp_smooth);CHKERRQ(ierr);
9488f87f92bSBarry Smith     }
9498f87f92bSBarry Smith     if (jac->nodal_relax) {
95022e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal relaxation via Schwarz smoothing on levels %D\n",jac->nodal_relax_levels);CHKERRQ(ierr);
9518f87f92bSBarry Smith     }
95216d9e3a6SLisandro Dalcin   }
95316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
95416d9e3a6SLisandro Dalcin }
95516d9e3a6SLisandro Dalcin 
95616d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
9574416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc)
95816d9e3a6SLisandro Dalcin {
95916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
96016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
9614ddd07fcSJed Brown   PetscInt       indx;
962ace3abfcSBarry Smith   PetscBool      flag;
96316d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
96416d9e3a6SLisandro Dalcin 
96516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
966e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
96716d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
96816d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
9692fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
97016d9e3a6SLisandro Dalcin 
97116d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
9722fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
97316d9e3a6SLisandro Dalcin 
97416d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
9752fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
97616d9e3a6SLisandro Dalcin 
977acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
9782fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
97916d9e3a6SLisandro Dalcin 
980acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
9812fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
98216d9e3a6SLisandro Dalcin 
983a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
98416d9e3a6SLisandro Dalcin   if (flag) {
98516d9e3a6SLisandro Dalcin     jac->symt = indx;
986fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
98716d9e3a6SLisandro Dalcin   }
98816d9e3a6SLisandro Dalcin 
98916d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
99016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
99116d9e3a6SLisandro Dalcin }
99216d9e3a6SLisandro Dalcin 
99316d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
99416d9e3a6SLisandro Dalcin {
99516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
99616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
997ace3abfcSBarry Smith   PetscBool      iascii;
99816d9e3a6SLisandro Dalcin   const char     *symt = 0;;
99916d9e3a6SLisandro Dalcin 
100016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1001251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
100216d9e3a6SLisandro Dalcin   if (iascii) {
100316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
1004efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
1005efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
1006efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    filter %g\n",(double)jac->filter);CHKERRQ(ierr);
1007efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
1008efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
1009efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
10102fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
10112fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
10122fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
1013ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
1014efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    %s\n",symt);CHKERRQ(ierr);
101516d9e3a6SLisandro Dalcin   }
101616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
101716d9e3a6SLisandro Dalcin }
10184cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
10194416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc)
10204cb006feSStefano Zampini {
10214cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
10224cb006feSStefano Zampini   PetscErrorCode ierr;
10234cb006feSStefano Zampini   PetscInt       n;
10244cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
10254cb006feSStefano Zampini 
10264cb006feSStefano Zampini   PetscFunctionBegin;
10279fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
1028863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1029863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1030863406b8SStefano 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);
1031863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
10324cb006feSStefano 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);
10334cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1034863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1035863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1036863406b8SStefano 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);
1037863406b8SStefano 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);
1038863406b8SStefano 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);
1039863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
10404cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1041863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1042863406b8SStefano Zampini                                                                       jac->as_relax_times,
1043863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1044863406b8SStefano Zampini                                                                       jac->as_omega));
10454cb006feSStefano Zampini   }
1046863406b8SStefano 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);
10474cb006feSStefano Zampini   n = 5;
1048863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
10494cb006feSStefano Zampini   if (flag || flag2) {
1050863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1051863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1052863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1053863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1054863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1055863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
10564cb006feSStefano Zampini   }
1057863406b8SStefano 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);
10584cb006feSStefano Zampini   n = 5;
1059863406b8SStefano 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);
10604cb006feSStefano Zampini   if (flag || flag2) {
1061863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1062863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1063863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1064863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1065863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1066863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
10674cb006feSStefano Zampini   }
106823df4f25SStefano 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);
106923df4f25SStefano Zampini   if (flag) { /* override HYPRE's default only if the options is used */
107023df4f25SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetProjectionFrequency,(jac->hsolver,jac->ams_proj_freq));
107123df4f25SStefano Zampini   }
10724cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
10734cb006feSStefano Zampini   PetscFunctionReturn(0);
10744cb006feSStefano Zampini }
10754cb006feSStefano Zampini 
10764cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
10774cb006feSStefano Zampini {
10784cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
10794cb006feSStefano Zampini   PetscErrorCode ierr;
10804cb006feSStefano Zampini   PetscBool      iascii;
10814cb006feSStefano Zampini 
10824cb006feSStefano Zampini   PetscFunctionBegin;
10834cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
10844cb006feSStefano Zampini   if (iascii) {
10854cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
1086efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1087efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1088efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1089efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1090efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1091efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1092efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
10934cb006feSStefano Zampini     if (jac->alpha_Poisson) {
1094efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
10954cb006feSStefano Zampini     } else {
1096efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (computed) \n");CHKERRQ(ierr);
10974cb006feSStefano Zampini     }
1098efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1099efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1100efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1101efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1102efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1103efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
11044cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
11054cb006feSStefano Zampini       if (jac->beta_Poisson) {
1106efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
11074cb006feSStefano Zampini       } else {
1108efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (computed) \n");CHKERRQ(ierr);
11094cb006feSStefano Zampini       }
1110efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1111efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1112efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1113efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1114efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1115efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
111623df4f25SStefano Zampini       if (jac->ams_beta_is_zero_part) {
1117efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"        compatible subspace projection frequency %d (-1 HYPRE uses default)\n",jac->ams_proj_freq);CHKERRQ(ierr);
111823df4f25SStefano Zampini       }
111923df4f25SStefano Zampini     } else {
1120efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver not used (zero-conductivity everywhere) \n");CHKERRQ(ierr);
11214cb006feSStefano Zampini     }
11224cb006feSStefano Zampini   }
11234cb006feSStefano Zampini   PetscFunctionReturn(0);
11244cb006feSStefano Zampini }
11254cb006feSStefano Zampini 
11264416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc)
1127863406b8SStefano Zampini {
1128863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1129863406b8SStefano Zampini   PetscErrorCode ierr;
1130863406b8SStefano Zampini   PetscInt       n;
1131863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
1132863406b8SStefano Zampini 
1133863406b8SStefano Zampini   PetscFunctionBegin;
1134863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
1135863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1136863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1137863406b8SStefano 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);
1138863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1139863406b8SStefano 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);
1140863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
1141863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1142863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1143863406b8SStefano 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);
1144863406b8SStefano 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);
1145863406b8SStefano 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);
1146863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
1147863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1148863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1149863406b8SStefano Zampini                                                                       jac->as_relax_times,
1150863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1151863406b8SStefano Zampini                                                                       jac->as_omega));
1152863406b8SStefano Zampini   }
1153863406b8SStefano 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);
1154863406b8SStefano Zampini   n = 5;
1155863406b8SStefano 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);
1156863406b8SStefano 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);
1157863406b8SStefano Zampini   if (flag || flag2 || flag3) {
1158863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
1159863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1160863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1161863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1162863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1163863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1164863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1165863406b8SStefano Zampini   }
1166863406b8SStefano 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);
1167863406b8SStefano Zampini   n = 5;
1168863406b8SStefano 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);
1169863406b8SStefano Zampini   if (flag || flag2) {
1170863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1171863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1172863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1173863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1174863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1175863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1176863406b8SStefano Zampini   }
1177863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
1178863406b8SStefano Zampini   PetscFunctionReturn(0);
1179863406b8SStefano Zampini }
1180863406b8SStefano Zampini 
1181863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1182863406b8SStefano Zampini {
1183863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1184863406b8SStefano Zampini   PetscErrorCode ierr;
1185863406b8SStefano Zampini   PetscBool      iascii;
1186863406b8SStefano Zampini 
1187863406b8SStefano Zampini   PetscFunctionBegin;
1188863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1189863406b8SStefano Zampini   if (iascii) {
1190863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
1191efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1192efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
1193efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1194efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1195efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1196efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1197efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
1198efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    AMS solver using boomerAMG\n");CHKERRQ(ierr);
1199efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1200efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1201efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1202efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1203efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1204efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1205efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
1206efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver using boomerAMG\n");CHKERRQ(ierr);
1207efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1208efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1209efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1210efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1211efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1212efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
1213863406b8SStefano Zampini   }
1214863406b8SStefano Zampini   PetscFunctionReturn(0);
1215863406b8SStefano Zampini }
1216863406b8SStefano Zampini 
1217863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
12184cb006feSStefano Zampini {
12194cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12205ac14e1cSStefano Zampini   PetscBool      ishypre;
12214cb006feSStefano Zampini   PetscErrorCode ierr;
12224cb006feSStefano Zampini 
12234cb006feSStefano Zampini   PetscFunctionBegin;
12245ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)G,MATHYPRE,&ishypre);CHKERRQ(ierr);
12255ac14e1cSStefano Zampini   if (ishypre) {
12265ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr);
12275ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
12285ac14e1cSStefano Zampini     jac->G = G;
12295ac14e1cSStefano Zampini   } else {
12306bf688a0SCe Qin     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
12316bf688a0SCe Qin     ierr = MatConvert(G,MATHYPRE,MAT_INITIAL_MATRIX,&jac->G);CHKERRQ(ierr);
12325ac14e1cSStefano Zampini   }
12334cb006feSStefano Zampini   PetscFunctionReturn(0);
12344cb006feSStefano Zampini }
12354cb006feSStefano Zampini 
12364cb006feSStefano Zampini /*@
12374cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
12384cb006feSStefano Zampini 
12394cb006feSStefano Zampini    Collective on PC
12404cb006feSStefano Zampini 
12414cb006feSStefano Zampini    Input Parameters:
12424cb006feSStefano Zampini +  pc - the preconditioning context
12434cb006feSStefano Zampini -  G - the discrete gradient
12444cb006feSStefano Zampini 
12454cb006feSStefano Zampini    Level: intermediate
12464cb006feSStefano Zampini 
124795452b02SPatrick Sanan    Notes:
124895452b02SPatrick Sanan     G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh
1249863406b8SStefano 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
12504cb006feSStefano Zampini 
12514cb006feSStefano Zampini .seealso:
12524cb006feSStefano Zampini @*/
12534cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
12544cb006feSStefano Zampini {
12554cb006feSStefano Zampini   PetscErrorCode ierr;
12564cb006feSStefano Zampini 
12574cb006feSStefano Zampini   PetscFunctionBegin;
12584cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12594cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
12604cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
12614cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
12624cb006feSStefano Zampini   PetscFunctionReturn(0);
12634cb006feSStefano Zampini }
12644cb006feSStefano Zampini 
1265863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1266863406b8SStefano Zampini {
1267863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12685ac14e1cSStefano Zampini   PetscBool      ishypre;
1269863406b8SStefano Zampini   PetscErrorCode ierr;
1270863406b8SStefano Zampini 
1271863406b8SStefano Zampini   PetscFunctionBegin;
12725ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)C,MATHYPRE,&ishypre);CHKERRQ(ierr);
12735ac14e1cSStefano Zampini   if (ishypre) {
12745ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr);
12755ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
12765ac14e1cSStefano Zampini     jac->C = C;
12775ac14e1cSStefano Zampini   } else {
12786bf688a0SCe Qin     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
12796bf688a0SCe Qin     ierr = MatConvert(C,MATHYPRE,MAT_INITIAL_MATRIX,&jac->C);CHKERRQ(ierr);
12805ac14e1cSStefano Zampini   }
1281863406b8SStefano Zampini   PetscFunctionReturn(0);
1282863406b8SStefano Zampini }
1283863406b8SStefano Zampini 
1284863406b8SStefano Zampini /*@
1285863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1286863406b8SStefano Zampini 
1287863406b8SStefano Zampini    Collective on PC
1288863406b8SStefano Zampini 
1289863406b8SStefano Zampini    Input Parameters:
1290863406b8SStefano Zampini +  pc - the preconditioning context
1291863406b8SStefano Zampini -  C - the discrete curl
1292863406b8SStefano Zampini 
1293863406b8SStefano Zampini    Level: intermediate
1294863406b8SStefano Zampini 
129595452b02SPatrick Sanan    Notes:
129695452b02SPatrick Sanan     C should have as many rows as the number of faces and as many columns as the number of edges in the mesh
1297863406b8SStefano 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
1298863406b8SStefano Zampini 
1299863406b8SStefano Zampini .seealso:
1300863406b8SStefano Zampini @*/
1301863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1302863406b8SStefano Zampini {
1303863406b8SStefano Zampini   PetscErrorCode ierr;
1304863406b8SStefano Zampini 
1305863406b8SStefano Zampini   PetscFunctionBegin;
1306863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1307863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1308863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1309863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1310863406b8SStefano Zampini   PetscFunctionReturn(0);
1311863406b8SStefano Zampini }
1312863406b8SStefano Zampini 
13136bf688a0SCe Qin static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
13146bf688a0SCe Qin {
13156bf688a0SCe Qin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
13166bf688a0SCe Qin   PetscBool      ishypre;
13176bf688a0SCe Qin   PetscErrorCode ierr;
13186bf688a0SCe Qin   PetscInt       i;
13196bf688a0SCe Qin   PetscFunctionBegin;
13206bf688a0SCe Qin 
13216bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
13226bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
13236bf688a0SCe Qin   for (i=0;i<3;++i) {
13246bf688a0SCe Qin     ierr = MatDestroy(&jac->RT_Pi[i]);CHKERRQ(ierr);
13256bf688a0SCe Qin     ierr = MatDestroy(&jac->ND_Pi[i]);CHKERRQ(ierr);
13266bf688a0SCe Qin   }
13276bf688a0SCe Qin 
13286bf688a0SCe Qin   jac->dim = dim;
13296bf688a0SCe Qin   if (RT_PiFull) {
13306bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)RT_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
13316bf688a0SCe Qin     if (ishypre) {
13326bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)RT_PiFull);CHKERRQ(ierr);
13336bf688a0SCe Qin       jac->RT_PiFull = RT_PiFull;
13346bf688a0SCe Qin     } else {
13356bf688a0SCe Qin       ierr = MatConvert(RT_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_PiFull);CHKERRQ(ierr);
13366bf688a0SCe Qin     }
13376bf688a0SCe Qin   }
13386bf688a0SCe Qin   if (RT_Pi) {
13396bf688a0SCe Qin     for (i=0;i<dim;++i) {
13406bf688a0SCe Qin       if (RT_Pi[i]) {
13416bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)RT_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
13426bf688a0SCe Qin         if (ishypre) {
13436bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)RT_Pi[i]);CHKERRQ(ierr);
13446bf688a0SCe Qin           jac->RT_Pi[i] = RT_Pi[i];
13456bf688a0SCe Qin         } else {
13466bf688a0SCe Qin           ierr = MatConvert(RT_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_Pi[i]);CHKERRQ(ierr);
13476bf688a0SCe Qin         }
13486bf688a0SCe Qin       }
13496bf688a0SCe Qin     }
13506bf688a0SCe Qin   }
13516bf688a0SCe Qin   if (ND_PiFull) {
13526bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)ND_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
13536bf688a0SCe Qin     if (ishypre) {
13546bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)ND_PiFull);CHKERRQ(ierr);
13556bf688a0SCe Qin       jac->ND_PiFull = ND_PiFull;
13566bf688a0SCe Qin     } else {
13576bf688a0SCe Qin       ierr = MatConvert(ND_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_PiFull);CHKERRQ(ierr);
13586bf688a0SCe Qin     }
13596bf688a0SCe Qin   }
13606bf688a0SCe Qin   if (ND_Pi) {
13616bf688a0SCe Qin     for (i=0;i<dim;++i) {
13626bf688a0SCe Qin       if (ND_Pi[i]) {
13636bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)ND_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
13646bf688a0SCe Qin         if (ishypre) {
13656bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)ND_Pi[i]);CHKERRQ(ierr);
13666bf688a0SCe Qin           jac->ND_Pi[i] = ND_Pi[i];
13676bf688a0SCe Qin         } else {
13686bf688a0SCe Qin           ierr = MatConvert(ND_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_Pi[i]);CHKERRQ(ierr);
13696bf688a0SCe Qin         }
13706bf688a0SCe Qin       }
13716bf688a0SCe Qin     }
13726bf688a0SCe Qin   }
13736bf688a0SCe Qin 
13746bf688a0SCe Qin   PetscFunctionReturn(0);
13756bf688a0SCe Qin }
13766bf688a0SCe Qin 
13776bf688a0SCe Qin /*@
13786bf688a0SCe Qin  PCHYPRESetInterpolations - Set interpolation matrices for AMS/ADS preconditioner
13796bf688a0SCe Qin 
13806bf688a0SCe Qin    Collective on PC
13816bf688a0SCe Qin 
13826bf688a0SCe Qin    Input Parameters:
13836bf688a0SCe Qin +  pc - the preconditioning context
13846bf688a0SCe Qin -  dim - the dimension of the problem, only used in AMS
13856bf688a0SCe Qin -  RT_PiFull - Raviart-Thomas interpolation matrix
13866bf688a0SCe Qin -  RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix
13876bf688a0SCe Qin -  ND_PiFull - Nedelec interpolation matrix
13886bf688a0SCe Qin -  ND_Pi - x/y/z component of Nedelec interpolation matrix
13896bf688a0SCe Qin 
139095452b02SPatrick Sanan    Notes:
139195452b02SPatrick Sanan     For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL.
13926bf688a0SCe Qin           For ADS, both type of interpolation matrices are needed.
13936bf688a0SCe Qin    Level: intermediate
13946bf688a0SCe Qin 
13956bf688a0SCe Qin .seealso:
13966bf688a0SCe Qin @*/
13976bf688a0SCe Qin PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
13986bf688a0SCe Qin {
13996bf688a0SCe Qin   PetscErrorCode ierr;
14006bf688a0SCe Qin   PetscInt       i;
14016bf688a0SCe Qin 
14026bf688a0SCe Qin   PetscFunctionBegin;
14036bf688a0SCe Qin   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
14046bf688a0SCe Qin   if (RT_PiFull) {
14056bf688a0SCe Qin     PetscValidHeaderSpecific(RT_PiFull,MAT_CLASSID,3);
14066bf688a0SCe Qin     PetscCheckSameComm(pc,1,RT_PiFull,3);
14076bf688a0SCe Qin   }
14086bf688a0SCe Qin   if (RT_Pi) {
14096bf688a0SCe Qin     PetscValidPointer(RT_Pi,4);
14106bf688a0SCe Qin     for (i=0;i<dim;++i) {
14116bf688a0SCe Qin       if (RT_Pi[i]) {
14126bf688a0SCe Qin         PetscValidHeaderSpecific(RT_Pi[i],MAT_CLASSID,4);
14136bf688a0SCe Qin         PetscCheckSameComm(pc,1,RT_Pi[i],4);
14146bf688a0SCe Qin       }
14156bf688a0SCe Qin     }
14166bf688a0SCe Qin   }
14176bf688a0SCe Qin   if (ND_PiFull) {
14186bf688a0SCe Qin     PetscValidHeaderSpecific(ND_PiFull,MAT_CLASSID,5);
14196bf688a0SCe Qin     PetscCheckSameComm(pc,1,ND_PiFull,5);
14206bf688a0SCe Qin   }
14216bf688a0SCe Qin   if (ND_Pi) {
14226bf688a0SCe Qin     PetscValidPointer(ND_Pi,6);
14236bf688a0SCe Qin     for (i=0;i<dim;++i) {
14246bf688a0SCe Qin       if (ND_Pi[i]) {
14256bf688a0SCe Qin         PetscValidHeaderSpecific(ND_Pi[i],MAT_CLASSID,6);
14266bf688a0SCe Qin         PetscCheckSameComm(pc,1,ND_Pi[i],6);
14276bf688a0SCe Qin       }
14286bf688a0SCe Qin     }
14296bf688a0SCe Qin   }
14306bf688a0SCe Qin   ierr = PetscTryMethod(pc,"PCHYPRESetInterpolations_C",(PC,PetscInt,Mat,Mat[],Mat,Mat[]),(pc,dim,RT_PiFull,RT_Pi,ND_PiFull,ND_Pi));CHKERRQ(ierr);
14316bf688a0SCe Qin   PetscFunctionReturn(0);
14326bf688a0SCe Qin }
14336bf688a0SCe Qin 
14345ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha)
14354cb006feSStefano Zampini {
14364cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
14375ac14e1cSStefano Zampini   PetscBool      ishypre;
14384cb006feSStefano Zampini   PetscErrorCode ierr;
14394cb006feSStefano Zampini 
14404cb006feSStefano Zampini   PetscFunctionBegin;
14415ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr);
14425ac14e1cSStefano Zampini   if (ishypre) {
14435ac14e1cSStefano Zampini     if (isalpha) {
14445ac14e1cSStefano Zampini       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
14455ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
14465ac14e1cSStefano Zampini       jac->alpha_Poisson = A;
14475ac14e1cSStefano Zampini     } else {
14485ac14e1cSStefano Zampini       if (A) {
14495ac14e1cSStefano Zampini         ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
14505ac14e1cSStefano Zampini       } else {
14515ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
14525ac14e1cSStefano Zampini       }
14535ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
14545ac14e1cSStefano Zampini       jac->beta_Poisson = A;
14555ac14e1cSStefano Zampini     }
14565ac14e1cSStefano Zampini   } else {
14575ac14e1cSStefano Zampini     if (isalpha) {
14586bf688a0SCe Qin       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
14596bf688a0SCe Qin       ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->alpha_Poisson);CHKERRQ(ierr);
14605ac14e1cSStefano Zampini     } else {
14615ac14e1cSStefano Zampini       if (A) {
14626bf688a0SCe Qin         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
14636bf688a0SCe Qin         ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->beta_Poisson);CHKERRQ(ierr);
14645ac14e1cSStefano Zampini       } else {
14655ac14e1cSStefano Zampini         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
14665ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
14675ac14e1cSStefano Zampini       }
14685ac14e1cSStefano Zampini     }
14695ac14e1cSStefano Zampini   }
14704cb006feSStefano Zampini   PetscFunctionReturn(0);
14714cb006feSStefano Zampini }
14724cb006feSStefano Zampini 
14734cb006feSStefano Zampini /*@
14744cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
14754cb006feSStefano Zampini 
14764cb006feSStefano Zampini    Collective on PC
14774cb006feSStefano Zampini 
14784cb006feSStefano Zampini    Input Parameters:
14794cb006feSStefano Zampini +  pc - the preconditioning context
14804cb006feSStefano Zampini -  A - the matrix
14814cb006feSStefano Zampini 
14824cb006feSStefano Zampini    Level: intermediate
14834cb006feSStefano Zampini 
148495452b02SPatrick Sanan    Notes:
148595452b02SPatrick Sanan     A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
14864cb006feSStefano Zampini 
14874cb006feSStefano Zampini .seealso:
14884cb006feSStefano Zampini @*/
14894cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
14904cb006feSStefano Zampini {
14914cb006feSStefano Zampini   PetscErrorCode ierr;
14924cb006feSStefano Zampini 
14934cb006feSStefano Zampini   PetscFunctionBegin;
14944cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
14954cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
14964cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
14975ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_TRUE));CHKERRQ(ierr);
14984cb006feSStefano Zampini   PetscFunctionReturn(0);
14994cb006feSStefano Zampini }
15004cb006feSStefano Zampini 
15014cb006feSStefano Zampini /*@
15024cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
15034cb006feSStefano Zampini 
15044cb006feSStefano Zampini    Collective on PC
15054cb006feSStefano Zampini 
15064cb006feSStefano Zampini    Input Parameters:
15074cb006feSStefano Zampini +  pc - the preconditioning context
15084cb006feSStefano Zampini -  A - the matrix
15094cb006feSStefano Zampini 
15104cb006feSStefano Zampini    Level: intermediate
15114cb006feSStefano Zampini 
151295452b02SPatrick Sanan    Notes:
151395452b02SPatrick Sanan     A should be obtained by discretizing the Poisson problem with linear finite elements.
15144cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
15154cb006feSStefano Zampini 
15164cb006feSStefano Zampini .seealso:
15174cb006feSStefano Zampini @*/
15184cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
15194cb006feSStefano Zampini {
15204cb006feSStefano Zampini   PetscErrorCode ierr;
15214cb006feSStefano Zampini 
15224cb006feSStefano Zampini   PetscFunctionBegin;
15234cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15244cb006feSStefano Zampini   if (A) {
15254cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
15264cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
15274cb006feSStefano Zampini   }
15285ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_FALSE));CHKERRQ(ierr);
15294cb006feSStefano Zampini   PetscFunctionReturn(0);
15304cb006feSStefano Zampini }
15314cb006feSStefano Zampini 
15325ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz, Vec zoz, Vec zzo)
15334cb006feSStefano Zampini {
15344cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
15354cb006feSStefano Zampini   PetscErrorCode     ierr;
15364cb006feSStefano Zampini 
15374cb006feSStefano Zampini   PetscFunctionBegin;
15384cb006feSStefano Zampini   /* throw away any vector if already set */
15394cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
15404cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
15414cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
15424cb006feSStefano Zampini   jac->constants[0] = NULL;
15434cb006feSStefano Zampini   jac->constants[1] = NULL;
15444cb006feSStefano Zampini   jac->constants[2] = NULL;
15454cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
15464cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
15474cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
15484cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
15495ac14e1cSStefano Zampini   jac->dim = 2;
15504cb006feSStefano Zampini   if (zzo) {
15514cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
15524cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
15535ac14e1cSStefano Zampini     jac->dim++;
15544cb006feSStefano Zampini   }
15554cb006feSStefano Zampini   PetscFunctionReturn(0);
15564cb006feSStefano Zampini }
15574cb006feSStefano Zampini 
15584cb006feSStefano Zampini /*@
15594cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
15604cb006feSStefano Zampini 
15614cb006feSStefano Zampini    Collective on PC
15624cb006feSStefano Zampini 
15634cb006feSStefano Zampini    Input Parameters:
15644cb006feSStefano Zampini +  pc - the preconditioning context
15654cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
15664cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
15674cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
15684cb006feSStefano Zampini 
15694cb006feSStefano Zampini    Level: intermediate
15704cb006feSStefano Zampini 
15714cb006feSStefano Zampini    Notes:
15724cb006feSStefano Zampini 
15734cb006feSStefano Zampini .seealso:
15744cb006feSStefano Zampini @*/
15754cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
15764cb006feSStefano Zampini {
15774cb006feSStefano Zampini   PetscErrorCode ierr;
15784cb006feSStefano Zampini 
15794cb006feSStefano Zampini   PetscFunctionBegin;
15804cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15814cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
15824cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
15834cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
15844cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
15854cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
15864cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
15874cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
15884cb006feSStefano Zampini   PetscFunctionReturn(0);
15894cb006feSStefano Zampini }
15904cb006feSStefano Zampini 
1591863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
15924cb006feSStefano Zampini {
15934cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
15944cb006feSStefano Zampini   Vec             tv;
15954cb006feSStefano Zampini   PetscInt        i;
15964cb006feSStefano Zampini   PetscErrorCode  ierr;
15974cb006feSStefano Zampini 
15984cb006feSStefano Zampini   PetscFunctionBegin;
15994cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
16004cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
16014cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
16024cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
16035ac14e1cSStefano Zampini   jac->dim = dim;
16045ac14e1cSStefano Zampini 
16054cb006feSStefano Zampini   /* compute IJ vector for coordinates */
16064cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
16074cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
16084cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
16094cb006feSStefano Zampini   for (i=0;i<dim;i++) {
16104cb006feSStefano Zampini     PetscScalar *array;
16114cb006feSStefano Zampini     PetscInt    j;
16124cb006feSStefano Zampini 
16134cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
16144cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
16154cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
16164cb006feSStefano Zampini       array[j] = coords[j*dim+i];
16174cb006feSStefano Zampini     }
16184cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
16194cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
16204cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
16214cb006feSStefano Zampini   }
16224cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
16234cb006feSStefano Zampini   PetscFunctionReturn(0);
16244cb006feSStefano Zampini }
16254cb006feSStefano Zampini 
162616d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
162716d9e3a6SLisandro Dalcin 
1628f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
162916d9e3a6SLisandro Dalcin {
163016d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
163116d9e3a6SLisandro Dalcin 
163216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
163316d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
163416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
163516d9e3a6SLisandro Dalcin }
163616d9e3a6SLisandro Dalcin 
1637f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
163816d9e3a6SLisandro Dalcin {
163916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
164016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1641ace3abfcSBarry Smith   PetscBool      flag;
164216d9e3a6SLisandro Dalcin 
164316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
164416d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
164516d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1646ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
164716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
164816d9e3a6SLisandro Dalcin   } else {
164916d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
165016d9e3a6SLisandro Dalcin   }
165116d9e3a6SLisandro Dalcin 
165216d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
165316d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
165416d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
165516d9e3a6SLisandro Dalcin 
165616d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
165716d9e3a6SLisandro Dalcin   if (flag) {
1658572a0576SBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1659fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
166016d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
166116d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
166216d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
166316d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
166416d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
166516d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
166616d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
166716d9e3a6SLisandro Dalcin   }
1668db966c6cSHong Zhang   ierr = PetscStrcmp("euclid",jac->hypre_type,&flag);CHKERRQ(ierr);
1669db966c6cSHong Zhang   if (flag) {
1670db966c6cSHong Zhang     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1671db966c6cSHong Zhang     PetscStackCallStandard(HYPRE_EuclidCreate,(jac->comm_hypre,&jac->hsolver));
1672db966c6cSHong Zhang     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
1673db966c6cSHong Zhang     pc->ops->view           = PCView_HYPRE_Euclid;
1674db966c6cSHong Zhang     jac->destroy            = HYPRE_EuclidDestroy;
1675db966c6cSHong Zhang     jac->setup              = HYPRE_EuclidSetup;
1676db966c6cSHong Zhang     jac->solve              = HYPRE_EuclidSolve;
1677db966c6cSHong Zhang     jac->factorrowsize      = PETSC_DEFAULT;
1678db966c6cSHong Zhang     jac->eu_level           = PETSC_DEFAULT; /* default */
1679db966c6cSHong Zhang     PetscFunctionReturn(0);
1680db966c6cSHong Zhang   }
168116d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
168216d9e3a6SLisandro Dalcin   if (flag) {
1683572a0576SBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1684fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
168516d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
168616d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
168716d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
168816d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
168916d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
169016d9e3a6SLisandro Dalcin     /* initialize */
169116d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
169216d9e3a6SLisandro Dalcin     jac->threshhold = .1;
169316d9e3a6SLisandro Dalcin     jac->filter     = .1;
169416d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
16952fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
16962fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
16972fa5cd67SKarl Rupp 
169816d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
169916d9e3a6SLisandro Dalcin     jac->symt = 0;
1700fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1701fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1702fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1703fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1704fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1705fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
170616d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
170716d9e3a6SLisandro Dalcin   }
170816d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
170916d9e3a6SLisandro Dalcin   if (flag) {
171016d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
171116d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
171216d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
171316d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
171416d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
171516d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
171616d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
171716d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
171816d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
171916d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
172016d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
172116d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
172216d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
17238f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
172416d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
172516d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
172616d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
172716d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
172816d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
17290f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
17306a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1731b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
17321810e44eSEike Mueller     jac->eu_level         = 0;
17331810e44eSEike Mueller     jac->eu_droptolerance = 0;
17341810e44eSEike Mueller     jac->eu_bj            = 0;
17358f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
17360f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
173716d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
173816d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
173916d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
17400f1074feSSatish Balay     jac->interptype       = 0;
17410f1074feSSatish Balay     jac->agg_nl           = 0;
17420f1074feSSatish Balay     jac->pmax             = 0;
17430f1074feSSatish Balay     jac->truncfactor      = 0.0;
17440f1074feSSatish Balay     jac->agg_num_paths    = 1;
17458f87f92bSBarry Smith 
174622e51d31SStefano Zampini     jac->nodal_coarsening      = 0;
174722e51d31SStefano Zampini     jac->nodal_coarsening_diag = 0;
174822e51d31SStefano Zampini     jac->vec_interp_variant    = 0;
174922e51d31SStefano Zampini     jac->vec_interp_qmax       = 0;
175022e51d31SStefano Zampini     jac->vec_interp_smooth     = PETSC_FALSE;
175122e51d31SStefano Zampini     jac->interp_refine         = 0;
17528f87f92bSBarry Smith     jac->nodal_relax           = PETSC_FALSE;
17538f87f92bSBarry Smith     jac->nodal_relax_levels    = 1;
1754fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1755fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1756fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1757fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1758fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1759fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1760fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1761fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1762fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1763fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1764fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1765fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1766fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1767fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1768fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1769fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
177016d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
177116d9e3a6SLisandro Dalcin   }
17724cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
17734cb006feSStefano Zampini   if (flag) {
17744cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
17754cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
17764cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
17774cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
17784cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
17794cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
17804cb006feSStefano Zampini     jac->coords[0]           = NULL;
17814cb006feSStefano Zampini     jac->coords[1]           = NULL;
17824cb006feSStefano Zampini     jac->coords[2]           = NULL;
17834cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1784863406b8SStefano Zampini     jac->as_print           = 0;
1785863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1786863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
17874cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
17884cb006feSStefano Zampini     /* Smoothing options */
1789863406b8SStefano Zampini     jac->as_relax_type      = 2;
1790863406b8SStefano Zampini     jac->as_relax_times     = 1;
1791863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1792863406b8SStefano Zampini     jac->as_omega           = 1.0;
17934cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1794863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1795863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
17960bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1797863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1798863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1799863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
18004cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1801863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1802863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
18030bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1804863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1805863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1806863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1807863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1808863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
18094cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1810863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1811863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1812863406b8SStefano Zampini                                                                       jac->as_relax_times,
1813863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1814863406b8SStefano Zampini                                                                       jac->as_omega));
1815863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1816863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1817863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1818863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1819863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1820863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1821863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1822863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1823863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1824863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1825863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1826863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
182723df4f25SStefano Zampini     /* Zero conductivity */
182823df4f25SStefano Zampini     jac->ams_beta_is_zero      = PETSC_FALSE;
182923df4f25SStefano Zampini     jac->ams_beta_is_zero_part = PETSC_FALSE;
18304cb006feSStefano Zampini     PetscFunctionReturn(0);
18314cb006feSStefano Zampini   }
1832863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1833863406b8SStefano Zampini   if (flag) {
1834863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1835863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1836863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1837863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1838863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1839863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1840863406b8SStefano Zampini     jac->coords[0]           = NULL;
1841863406b8SStefano Zampini     jac->coords[1]           = NULL;
1842863406b8SStefano Zampini     jac->coords[2]           = NULL;
1843863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1844863406b8SStefano Zampini     jac->as_print           = 0;
1845863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1846863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1847863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1848863406b8SStefano Zampini     /* Smoothing options */
1849863406b8SStefano Zampini     jac->as_relax_type      = 2;
1850863406b8SStefano Zampini     jac->as_relax_times     = 1;
1851863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1852863406b8SStefano Zampini     jac->as_omega           = 1.0;
1853863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1854863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1855863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1856863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1857863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1858863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1859863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1860863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1861863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1862863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1863863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1864863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1865863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1866863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1867863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1868863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1869863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1870863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1871863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1872863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1873863406b8SStefano Zampini                                                                       jac->as_relax_times,
1874863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1875863406b8SStefano Zampini                                                                       jac->as_omega));
1876863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1877863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1878863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1879863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1880863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1881863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1882863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1883863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1884863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1885863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1886863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1887863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1888863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1889863406b8SStefano Zampini     PetscFunctionReturn(0);
1890863406b8SStefano Zampini   }
1891503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
18922fa5cd67SKarl Rupp 
18930298fd71SBarry Smith   jac->hypre_type = NULL;
1894db966c6cSHong Zhang   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams",name);
189516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
189616d9e3a6SLisandro Dalcin }
189716d9e3a6SLisandro Dalcin 
189816d9e3a6SLisandro Dalcin /*
189916d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
190016d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
190116d9e3a6SLisandro Dalcin */
1902*360ee056SFande Kong PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc)
190316d9e3a6SLisandro Dalcin {
190416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
19054ddd07fcSJed Brown   PetscInt       indx;
1906db966c6cSHong Zhang   const char     *type[] = {"euclid","pilut","parasails","boomeramg","ams","ads"};
1907ace3abfcSBarry Smith   PetscBool      flg;
190816d9e3a6SLisandro Dalcin 
190916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
19109fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
19119c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
191216d9e3a6SLisandro Dalcin   if (flg) {
191316d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
191402a17cd4SBarry Smith   } else {
191502a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
191616d9e3a6SLisandro Dalcin   }
191716d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
19183931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
191916d9e3a6SLisandro Dalcin   }
192016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
192116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
192216d9e3a6SLisandro Dalcin }
192316d9e3a6SLisandro Dalcin 
192416d9e3a6SLisandro Dalcin /*@C
192516d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
192616d9e3a6SLisandro Dalcin 
192716d9e3a6SLisandro Dalcin    Input Parameters:
192816d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1929db966c6cSHong Zhang -     name - either  euclid, pilut, parasails, boomeramg, ams, ads
193016d9e3a6SLisandro Dalcin 
193116d9e3a6SLisandro Dalcin    Options Database Keys:
1932db966c6cSHong Zhang    -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
193316d9e3a6SLisandro Dalcin 
193416d9e3a6SLisandro Dalcin    Level: intermediate
193516d9e3a6SLisandro Dalcin 
193616d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
193716d9e3a6SLisandro Dalcin            PCHYPRE
193816d9e3a6SLisandro Dalcin 
193916d9e3a6SLisandro Dalcin @*/
19407087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
194116d9e3a6SLisandro Dalcin {
19424ac538c5SBarry Smith   PetscErrorCode ierr;
194316d9e3a6SLisandro Dalcin 
194416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
19450700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
194616d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
19474ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
194816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
194916d9e3a6SLisandro Dalcin }
195016d9e3a6SLisandro Dalcin 
195116d9e3a6SLisandro Dalcin /*@C
195216d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
195316d9e3a6SLisandro Dalcin 
195416d9e3a6SLisandro Dalcin    Input Parameter:
195516d9e3a6SLisandro Dalcin .     pc - the preconditioner context
195616d9e3a6SLisandro Dalcin 
195716d9e3a6SLisandro Dalcin    Output Parameter:
1958db966c6cSHong Zhang .     name - either  euclid, pilut, parasails, boomeramg, ams, ads
195916d9e3a6SLisandro Dalcin 
196016d9e3a6SLisandro Dalcin    Level: intermediate
196116d9e3a6SLisandro Dalcin 
196216d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
196316d9e3a6SLisandro Dalcin            PCHYPRE
196416d9e3a6SLisandro Dalcin 
196516d9e3a6SLisandro Dalcin @*/
19667087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
196716d9e3a6SLisandro Dalcin {
19684ac538c5SBarry Smith   PetscErrorCode ierr;
196916d9e3a6SLisandro Dalcin 
197016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
19710700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
197216d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
19734ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
197416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
197516d9e3a6SLisandro Dalcin }
197616d9e3a6SLisandro Dalcin 
197716d9e3a6SLisandro Dalcin /*MC
197816d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
197916d9e3a6SLisandro Dalcin 
198016d9e3a6SLisandro Dalcin    Options Database Keys:
1981db966c6cSHong Zhang +   -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
198216d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
198316d9e3a6SLisandro Dalcin           preconditioner
198416d9e3a6SLisandro Dalcin 
198516d9e3a6SLisandro Dalcin    Level: intermediate
198616d9e3a6SLisandro Dalcin 
198795452b02SPatrick Sanan    Notes:
198895452b02SPatrick Sanan     Apart from pc_hypre_type (for which there is PCHYPRESetType()),
198916d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
199016d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
199116d9e3a6SLisandro Dalcin 
1992c231f9e3SBarryFSmith           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_tol refer to the number of iterations
19930f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
19940f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
1995c231f9e3SBarryFSmith           (-pc_hypre_boomeramg_tol should be set to 0.0 - the default - to strictly use a fixed number of
19968f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
19970f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
19980f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
199916d9e3a6SLisandro Dalcin 
20000f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
20010f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
20020f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
200316d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
200416d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
200516d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
200616d9e3a6SLisandro Dalcin 
200716d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
200816d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
200916d9e3a6SLisandro Dalcin 
20105272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
20115272c319SBarry Smith           the two options:
20125272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
2013cbc39033SBarry Smith -   -pc_hypre_boomeramg_vec_interp_variant <v> where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
20145272c319SBarry Smith 
20155272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
20165272c319SBarry Smith 
20179e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
20189e5bc791SBarry Smith 
201916d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
20209e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
202116d9e3a6SLisandro Dalcin 
202216d9e3a6SLisandro Dalcin M*/
202316d9e3a6SLisandro Dalcin 
20248cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
202516d9e3a6SLisandro Dalcin {
202616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
202716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
202816d9e3a6SLisandro Dalcin 
202916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
2030b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
20312fa5cd67SKarl Rupp 
203216d9e3a6SLisandro Dalcin   pc->data                = jac;
20338695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
203416d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
203516d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
203616d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
203716d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
203816d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
2039bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
2040bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
20415ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
20425ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
20435ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
20446bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",PCHYPRESetInterpolations_HYPRE);CHKERRQ(ierr);
20455ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE);CHKERRQ(ierr);
20465ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",PCHYPRESetPoissonMatrix_HYPRE);CHKERRQ(ierr);
204716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
204816d9e3a6SLisandro Dalcin }
2049ebc551c0SBarry Smith 
2050f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
2051f91d8e95SBarry Smith 
2052ebc551c0SBarry Smith typedef struct {
205368326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
2054f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
20559e5bc791SBarry Smith 
20569e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
20574ddd07fcSJed Brown   PetscInt its;
20589e5bc791SBarry Smith   double   tol;
20594ddd07fcSJed Brown   PetscInt relax_type;
20604ddd07fcSJed Brown   PetscInt rap_type;
20614ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
20624ddd07fcSJed Brown   PetscInt max_levels;
2063ebc551c0SBarry Smith } PC_PFMG;
2064ebc551c0SBarry Smith 
2065ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
2066ebc551c0SBarry Smith {
2067ebc551c0SBarry Smith   PetscErrorCode ierr;
2068f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2069ebc551c0SBarry Smith 
2070ebc551c0SBarry Smith   PetscFunctionBegin;
20712fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2072f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2073c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2074ebc551c0SBarry Smith   PetscFunctionReturn(0);
2075ebc551c0SBarry Smith }
2076ebc551c0SBarry Smith 
20779e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
20789e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
20799e5bc791SBarry Smith 
2080ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
2081ebc551c0SBarry Smith {
2082ebc551c0SBarry Smith   PetscErrorCode ierr;
2083ace3abfcSBarry Smith   PetscBool      iascii;
2084f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2085ebc551c0SBarry Smith 
2086ebc551c0SBarry Smith   PetscFunctionBegin;
2087251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
20889e5bc791SBarry Smith   if (iascii) {
20899e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
2090efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max iterations %d\n",ex->its);CHKERRQ(ierr);
2091efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    tolerance %g\n",ex->tol);CHKERRQ(ierr);
2092efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2093efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
2094efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2095efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max levels %d\n",ex->max_levels);CHKERRQ(ierr);
20969e5bc791SBarry Smith   }
2097ebc551c0SBarry Smith   PetscFunctionReturn(0);
2098ebc551c0SBarry Smith }
2099ebc551c0SBarry Smith 
21004416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2101ebc551c0SBarry Smith {
2102ebc551c0SBarry Smith   PetscErrorCode ierr;
2103f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2104ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2105ebc551c0SBarry Smith 
2106ebc551c0SBarry Smith   PetscFunctionBegin;
2107e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
21080298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
210968326731SBarry Smith   if (flg) {
2110a0324ebeSBarry Smith     int level=3;
2111fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
211268326731SBarry Smith   }
21130298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2114fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
21150298fd71SBarry 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);
2116fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
21170298fd71SBarry 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);
2118fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
21199e5bc791SBarry Smith 
21200298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
2121fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
21223b46a515SGlenn Hammond 
21230298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2124fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
21250298fd71SBarry 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);
2126fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
21270298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
2128fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
2129ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
2130ebc551c0SBarry Smith   PetscFunctionReturn(0);
2131ebc551c0SBarry Smith }
2132ebc551c0SBarry Smith 
2133f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
2134f91d8e95SBarry Smith {
2135f91d8e95SBarry Smith   PetscErrorCode    ierr;
2136f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
2137d9ca1df4SBarry Smith   PetscScalar       *yy;
2138d9ca1df4SBarry Smith   const PetscScalar *xx;
21394ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
214068326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2141f91d8e95SBarry Smith 
2142f91d8e95SBarry Smith   PetscFunctionBegin;
2143dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2144aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2145f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
2146f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
2147f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
2148f91d8e95SBarry Smith 
2149f91d8e95SBarry Smith   /* copy x values over to hypre */
2150fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
2151d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2152d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
2153d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2154fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
2155fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2156f91d8e95SBarry Smith 
2157f91d8e95SBarry Smith   /* copy solution values back to PETSc */
2158f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
21598b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
2160f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2161f91d8e95SBarry Smith   PetscFunctionReturn(0);
2162f91d8e95SBarry Smith }
2163f91d8e95SBarry Smith 
2164ace3abfcSBarry 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)
21659e5bc791SBarry Smith {
21669e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
21679e5bc791SBarry Smith   PetscErrorCode ierr;
21684ddd07fcSJed Brown   PetscInt       oits;
21699e5bc791SBarry Smith 
21709e5bc791SBarry Smith   PetscFunctionBegin;
2171dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2172fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
2173fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
21749e5bc791SBarry Smith 
21759e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
21768b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
21779e5bc791SBarry Smith   *outits = oits;
21789e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
21799e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2180fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
2181fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
21829e5bc791SBarry Smith   PetscFunctionReturn(0);
21839e5bc791SBarry Smith }
21849e5bc791SBarry Smith 
21859e5bc791SBarry Smith 
21863a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
21873a32d3dbSGlenn Hammond {
21883a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
21893a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
21903a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2191ace3abfcSBarry Smith   PetscBool       flg;
21923a32d3dbSGlenn Hammond 
21933a32d3dbSGlenn Hammond   PetscFunctionBegin;
2194251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
2195ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
21963a32d3dbSGlenn Hammond 
21973a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
21982fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2199fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2200fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2201fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
22023a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
22033a32d3dbSGlenn Hammond }
22043a32d3dbSGlenn Hammond 
2205ebc551c0SBarry Smith /*MC
2206ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
2207ebc551c0SBarry Smith 
2208ebc551c0SBarry Smith    Level: advanced
2209ebc551c0SBarry Smith 
22109e5bc791SBarry Smith    Options Database:
22119e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
22129e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
22139e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
22149e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
22159e5bc791SBarry 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
22169e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
2217f91d8e95SBarry Smith 
221895452b02SPatrick Sanan    Notes:
221995452b02SPatrick Sanan     This is for CELL-centered descretizations
22209e5bc791SBarry Smith 
22218e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
2222aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
22239e5bc791SBarry Smith 
22249e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
2225ebc551c0SBarry Smith M*/
2226ebc551c0SBarry Smith 
22278cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
2228ebc551c0SBarry Smith {
2229ebc551c0SBarry Smith   PetscErrorCode ierr;
2230ebc551c0SBarry Smith   PC_PFMG        *ex;
2231ebc551c0SBarry Smith 
2232ebc551c0SBarry Smith   PetscFunctionBegin;
2233b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
223468326731SBarry Smith   pc->data = ex;
2235ebc551c0SBarry Smith 
22369e5bc791SBarry Smith   ex->its            = 1;
22379e5bc791SBarry Smith   ex->tol            = 1.e-8;
22389e5bc791SBarry Smith   ex->relax_type     = 1;
22399e5bc791SBarry Smith   ex->rap_type       = 0;
22409e5bc791SBarry Smith   ex->num_pre_relax  = 1;
22419e5bc791SBarry Smith   ex->num_post_relax = 1;
22423b46a515SGlenn Hammond   ex->max_levels     = 0;
22439e5bc791SBarry Smith 
2244ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2245ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2246ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2247f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
22489e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
224968326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
22502fa5cd67SKarl Rupp 
2251ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2252fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2253ebc551c0SBarry Smith   PetscFunctionReturn(0);
2254ebc551c0SBarry Smith }
2255d851a50bSGlenn Hammond 
2256325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2257325fc9f4SBarry Smith 
2258d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2259d851a50bSGlenn Hammond typedef struct {
2260d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2261d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2262d851a50bSGlenn Hammond 
2263d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
22644ddd07fcSJed Brown   PetscInt its;
2265d851a50bSGlenn Hammond   double   tol;
22664ddd07fcSJed Brown   PetscInt relax_type;
22674ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2268d851a50bSGlenn Hammond } PC_SysPFMG;
2269d851a50bSGlenn Hammond 
2270d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2271d851a50bSGlenn Hammond {
2272d851a50bSGlenn Hammond   PetscErrorCode ierr;
2273d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2274d851a50bSGlenn Hammond 
2275d851a50bSGlenn Hammond   PetscFunctionBegin;
22762fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2277d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2278c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2279d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2280d851a50bSGlenn Hammond }
2281d851a50bSGlenn Hammond 
2282d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2283d851a50bSGlenn Hammond 
2284d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2285d851a50bSGlenn Hammond {
2286d851a50bSGlenn Hammond   PetscErrorCode ierr;
2287ace3abfcSBarry Smith   PetscBool      iascii;
2288d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2289d851a50bSGlenn Hammond 
2290d851a50bSGlenn Hammond   PetscFunctionBegin;
2291251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2292d851a50bSGlenn Hammond   if (iascii) {
2293d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2294efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  max iterations %d\n",ex->its);CHKERRQ(ierr);
2295efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerance %g\n",ex->tol);CHKERRQ(ierr);
2296efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2297efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2298d851a50bSGlenn Hammond   }
2299d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2300d851a50bSGlenn Hammond }
2301d851a50bSGlenn Hammond 
23024416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2303d851a50bSGlenn Hammond {
2304d851a50bSGlenn Hammond   PetscErrorCode ierr;
2305d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2306ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2307d851a50bSGlenn Hammond 
2308d851a50bSGlenn Hammond   PetscFunctionBegin;
2309e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
23100298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2311d851a50bSGlenn Hammond   if (flg) {
2312d851a50bSGlenn Hammond     int level=3;
2313fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
2314d851a50bSGlenn Hammond   }
23150298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2316fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
23170298fd71SBarry 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);
2318fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
23190298fd71SBarry 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);
2320fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2321d851a50bSGlenn Hammond 
23220298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2323fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
232461710fbeSStefano 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);
2325fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2326d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2327d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2328d851a50bSGlenn Hammond }
2329d851a50bSGlenn Hammond 
2330d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2331d851a50bSGlenn Hammond {
2332d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2333d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2334d9ca1df4SBarry Smith   PetscScalar       *yy;
2335d9ca1df4SBarry Smith   const PetscScalar *xx;
23364ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
2337d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
23384ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
23394ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
23404ddd07fcSJed Brown   PetscInt          part    = 0;
23414ddd07fcSJed Brown   PetscInt          size;
23424ddd07fcSJed Brown   PetscInt          i;
2343d851a50bSGlenn Hammond 
2344d851a50bSGlenn Hammond   PetscFunctionBegin;
2345dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2346aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2347d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2348d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2349d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2350d851a50bSGlenn Hammond 
2351d851a50bSGlenn Hammond   size = 1;
23522fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
23532fa5cd67SKarl Rupp 
2354d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2355d851a50bSGlenn Hammond   if (ordering) {
2356fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2357d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2358d9ca1df4SBarry 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)));
2359d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2360fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2361fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2362fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2363d851a50bSGlenn Hammond 
2364d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2365d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
23668b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2367d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2368a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2369d851a50bSGlenn Hammond     PetscScalar *z;
23704ddd07fcSJed Brown     PetscInt    j, k;
2371d851a50bSGlenn Hammond 
2372785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2373fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2374d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2375d851a50bSGlenn Hammond 
2376d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2377d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2378d851a50bSGlenn Hammond       k= i*nvars;
23792fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2380d851a50bSGlenn Hammond     }
23818b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2382d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2383fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2384fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2385d851a50bSGlenn Hammond 
2386d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2387d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
23888b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2389d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2390d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2391d851a50bSGlenn Hammond       k= i*nvars;
23922fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2393d851a50bSGlenn Hammond     }
2394d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2395d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2396d851a50bSGlenn Hammond   }
2397d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2398d851a50bSGlenn Hammond }
2399d851a50bSGlenn Hammond 
2400ace3abfcSBarry 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)
2401d851a50bSGlenn Hammond {
2402d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2403d851a50bSGlenn Hammond   PetscErrorCode ierr;
24044ddd07fcSJed Brown   PetscInt       oits;
2405d851a50bSGlenn Hammond 
2406d851a50bSGlenn Hammond   PetscFunctionBegin;
2407dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2408fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2409fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2410d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
24118b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2412d851a50bSGlenn Hammond   *outits = oits;
2413d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2414d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2415fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2416fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2417d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2418d851a50bSGlenn Hammond }
2419d851a50bSGlenn Hammond 
2420d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2421d851a50bSGlenn Hammond {
2422d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2423d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2424d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2425ace3abfcSBarry Smith   PetscBool        flg;
2426d851a50bSGlenn Hammond 
2427d851a50bSGlenn Hammond   PetscFunctionBegin;
2428251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2429ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2430d851a50bSGlenn Hammond 
2431d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
24322fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2433fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2434fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2435fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2436d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2437d851a50bSGlenn Hammond }
2438d851a50bSGlenn Hammond 
2439d851a50bSGlenn Hammond /*MC
2440d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2441d851a50bSGlenn Hammond 
2442d851a50bSGlenn Hammond    Level: advanced
2443d851a50bSGlenn Hammond 
2444d851a50bSGlenn Hammond    Options Database:
2445d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2446d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2447d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2448d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2449d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2450d851a50bSGlenn Hammond 
245195452b02SPatrick Sanan    Notes:
245295452b02SPatrick Sanan     This is for CELL-centered descretizations
2453d851a50bSGlenn Hammond 
2454f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2455aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2456d851a50bSGlenn Hammond            Also, only cell-centered variables.
2457d851a50bSGlenn Hammond 
2458d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2459d851a50bSGlenn Hammond M*/
2460d851a50bSGlenn Hammond 
24618cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2462d851a50bSGlenn Hammond {
2463d851a50bSGlenn Hammond   PetscErrorCode ierr;
2464d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2465d851a50bSGlenn Hammond 
2466d851a50bSGlenn Hammond   PetscFunctionBegin;
2467b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2468d851a50bSGlenn Hammond   pc->data = ex;
2469d851a50bSGlenn Hammond 
2470d851a50bSGlenn Hammond   ex->its            = 1;
2471d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2472d851a50bSGlenn Hammond   ex->relax_type     = 1;
2473d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2474d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2475d851a50bSGlenn Hammond 
2476d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2477d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2478d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2479d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2480d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2481d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
24822fa5cd67SKarl Rupp 
2483ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2484fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2485d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2486d851a50bSGlenn Hammond }
2487