xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision ce6a8a0d11299235d884ff30d1562dec25d6a0e1)
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;
171f817a21SBarry 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{http://www.llnl.gov/CASC/hypre/}}\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 
133*ce6a8a0dSJed Brown /* Resets (frees) Hypre's representation of the near null space */
134*ce6a8a0dSJed Brown static PetscErrorCode PCHYPREResetNearNullSpace_Private(PC pc)
135*ce6a8a0dSJed Brown {
136*ce6a8a0dSJed Brown   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
137*ce6a8a0dSJed Brown   PetscErrorCode ierr;
138*ce6a8a0dSJed Brown 
139*ce6a8a0dSJed Brown   PetscFunctionBegin;
140*ce6a8a0dSJed Brown   if (jac->n_hmnull && jac->hmnull) {
141*ce6a8a0dSJed Brown     PetscInt                 i;
142*ce6a8a0dSJed Brown     PETSC_UNUSED PetscScalar *petscvecarray;
143*ce6a8a0dSJed Brown 
144*ce6a8a0dSJed Brown     for (i=0; i<jac->n_hmnull; i++) {
145*ce6a8a0dSJed Brown       VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],jac->hmnull_hypre_data_array[i],petscvecarray);
146*ce6a8a0dSJed Brown       PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->hmnull[i]));
147*ce6a8a0dSJed Brown     }
148*ce6a8a0dSJed Brown     ierr = PetscFree(jac->hmnull);CHKERRQ(ierr);
149*ce6a8a0dSJed Brown     ierr = PetscFree(jac->hmnull_hypre_data_array);CHKERRQ(ierr);
150*ce6a8a0dSJed Brown     ierr = PetscFree(jac->phmnull);CHKERRQ(ierr);
151*ce6a8a0dSJed Brown     ierr = VecDestroy(&jac->hmnull_constant);CHKERRQ(ierr);
152*ce6a8a0dSJed Brown   }
153*ce6a8a0dSJed Brown   PetscFunctionReturn(0);
154*ce6a8a0dSJed Brown }
155*ce6a8a0dSJed Brown 
15616d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
15716d9e3a6SLisandro Dalcin {
15816d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
15949a781f5SStefano Zampini   Mat_HYPRE          *hjac;
16016d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
16116d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
16249a781f5SStefano Zampini   PetscBool          ishypre;
16349a781f5SStefano Zampini   PetscErrorCode     ierr;
16416d9e3a6SLisandro Dalcin 
16516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16616d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
16702a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
16816d9e3a6SLisandro Dalcin   }
1695f5c5b43SBarry Smith 
17049a781f5SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRE,&ishypre);CHKERRQ(ierr);
17149a781f5SStefano Zampini   if (!ishypre) {
1726bf688a0SCe Qin     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
1736bf688a0SCe Qin     ierr = MatConvert(pc->pmat,MATHYPRE,MAT_INITIAL_MATRIX,&jac->hpmat);CHKERRQ(ierr);
17449a781f5SStefano Zampini   } else {
17549a781f5SStefano Zampini     ierr = PetscObjectReference((PetscObject)pc->pmat);CHKERRQ(ierr);
17649a781f5SStefano Zampini     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
17749a781f5SStefano Zampini     jac->hpmat = pc->pmat;
17816d9e3a6SLisandro Dalcin   }
17949a781f5SStefano Zampini   hjac = (Mat_HYPRE*)(jac->hpmat->data);
1805f5c5b43SBarry Smith 
18116d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
18216d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
1835272c319SBarry Smith     MatNullSpace    mnull;
1845272c319SBarry Smith     PetscBool       has_const;
18549a781f5SStefano Zampini     PetscInt        bs,nvec,i;
1865272c319SBarry Smith     const Vec       *vecs;
18772827435SBarry Smith     PetscScalar     *petscvecarray;
1885272c319SBarry Smith 
18916d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1902fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
1915272c319SBarry Smith     ierr = MatGetNearNullSpace(pc->mat, &mnull);CHKERRQ(ierr);
1925272c319SBarry Smith     if (mnull) {
193*ce6a8a0dSJed Brown       ierr = PCHYPREResetNearNullSpace_Private(pc);CHKERRQ(ierr);
1945272c319SBarry Smith       ierr = MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs);CHKERRQ(ierr);
1955272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull);CHKERRQ(ierr);
19672827435SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull_hypre_data_array);CHKERRQ(ierr);
1975272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->phmnull);CHKERRQ(ierr);
1985272c319SBarry Smith       for (i=0; i<nvec; i++) {
1995272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(vecs[i],&jac->hmnull[i]);CHKERRQ(ierr);
20072827435SBarry Smith         ierr = VecGetArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
20158968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],petscvecarray,jac->hmnull_hypre_data_array[i]);
20272827435SBarry Smith         ierr = VecRestoreArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
2035272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[i],(void**)&jac->phmnull[i]));
2045272c319SBarry Smith       }
2055272c319SBarry Smith       if (has_const) {
2065272c319SBarry Smith         ierr = MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL);CHKERRQ(ierr);
2075272c319SBarry Smith         ierr = VecSet(jac->hmnull_constant,1);CHKERRQ(ierr);
2085272c319SBarry Smith         ierr = VecNormalize(jac->hmnull_constant,NULL);
2095272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(jac->hmnull_constant,&jac->hmnull[nvec]);CHKERRQ(ierr);
21072827435SBarry Smith         ierr = VecGetArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
21158968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[nvec],petscvecarray,jac->hmnull_hypre_data_array[nvec]);
21272827435SBarry Smith         ierr = VecRestoreArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
2135272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[nvec],(void**)&jac->phmnull[nvec]));
2145272c319SBarry Smith         nvec++;
2155272c319SBarry Smith       }
2165272c319SBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVectors,(jac->hsolver,nvec,jac->phmnull));
2175272c319SBarry Smith       jac->n_hmnull = nvec;
2185272c319SBarry Smith     }
2194cb006feSStefano Zampini   }
220863406b8SStefano Zampini 
2214cb006feSStefano Zampini   /* special case for AMS */
2224cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
2235ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2245ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
2256bf688a0SCe Qin     if (!jac->coords[0] && !jac->constants[0] && !(jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
2266bf688a0SCe 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");
2276bf688a0SCe Qin     }
2285ac14e1cSStefano Zampini     if (jac->dim) {
2295ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,jac->dim));
2305ac14e1cSStefano Zampini     }
2315ac14e1cSStefano Zampini     if (jac->constants[0]) {
2325ac14e1cSStefano Zampini       HYPRE_ParVector ozz,zoz,zzo = NULL;
2335ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&ozz)));
2345ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&zoz)));
2355ac14e1cSStefano Zampini       if (jac->constants[2]) {
2365ac14e1cSStefano Zampini         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&zzo)));
2375ac14e1cSStefano Zampini       }
2385ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,ozz,zoz,zzo));
2395ac14e1cSStefano Zampini     }
2405ac14e1cSStefano Zampini     if (jac->coords[0]) {
2415ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
2425ac14e1cSStefano Zampini       coords[0] = NULL;
2435ac14e1cSStefano Zampini       coords[1] = NULL;
2445ac14e1cSStefano Zampini       coords[2] = NULL;
2455ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
2465ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
2475ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
2485ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
2495ac14e1cSStefano Zampini     }
25049a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
2515ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
2525ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2535ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr));
2545ac14e1cSStefano Zampini     if (jac->alpha_Poisson) {
2555ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->alpha_Poisson->data);
2565ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2575ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr));
2585ac14e1cSStefano Zampini     }
2595ac14e1cSStefano Zampini     if (jac->ams_beta_is_zero) {
2605ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
2615ac14e1cSStefano Zampini     } else if (jac->beta_Poisson) {
2625ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->beta_Poisson->data);
2635ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2645ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr));
2655ac14e1cSStefano Zampini     }
2666bf688a0SCe Qin     if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) {
2676bf688a0SCe Qin       PetscInt           i;
2686bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
2696bf688a0SCe Qin       if (jac->ND_PiFull) {
2706bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
2716bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
2726bf688a0SCe Qin       } else {
2736bf688a0SCe Qin         nd_parcsrfull = NULL;
2746bf688a0SCe Qin       }
2756bf688a0SCe Qin       for (i=0;i<3;++i) {
2766bf688a0SCe Qin         if (jac->ND_Pi[i]) {
2776bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
2786bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
2796bf688a0SCe Qin         } else {
2806bf688a0SCe Qin           nd_parcsr[i] = NULL;
2816bf688a0SCe Qin         }
2826bf688a0SCe Qin       }
2836bf688a0SCe Qin       PetscStackCallStandard(HYPRE_AMSSetInterpolations,(jac->hsolver,nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]));
2846bf688a0SCe Qin     }
2854cb006feSStefano Zampini   }
286863406b8SStefano Zampini   /* special case for ADS */
287863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
2885ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2895ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
2906bf688a0SCe 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])))) {
2916bf688a0SCe Qin       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations");
2926bf688a0SCe Qin     }
29337096e45SBarry 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");
29449a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
29549a781f5SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient");
2965ac14e1cSStefano Zampini     if (jac->coords[0]) {
2975ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
2985ac14e1cSStefano Zampini       coords[0] = NULL;
2995ac14e1cSStefano Zampini       coords[1] = NULL;
3005ac14e1cSStefano Zampini       coords[2] = NULL;
3015ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
3025ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
3035ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
3045ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_ADSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
3055ac14e1cSStefano Zampini     }
3065ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
3075ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3085ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteGradient,(jac->hsolver,parcsr));
3095ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->C->data);
3105ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3115ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteCurl,(jac->hsolver,parcsr));
3126bf688a0SCe Qin     if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
3136bf688a0SCe Qin       PetscInt           i;
3146bf688a0SCe Qin       HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3];
3156bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
3166bf688a0SCe Qin       if (jac->RT_PiFull) {
3176bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->RT_PiFull->data);
3186bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsrfull)));
3196bf688a0SCe Qin       } else {
3206bf688a0SCe Qin         rt_parcsrfull = NULL;
3216bf688a0SCe Qin       }
3226bf688a0SCe Qin       for (i=0;i<3;++i) {
3236bf688a0SCe Qin         if (jac->RT_Pi[i]) {
3246bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->RT_Pi[i]->data);
3256bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsr[i])));
3266bf688a0SCe Qin         } else {
3276bf688a0SCe Qin           rt_parcsr[i] = NULL;
3286bf688a0SCe Qin         }
3296bf688a0SCe Qin       }
3306bf688a0SCe Qin       if (jac->ND_PiFull) {
3316bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
3326bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
3336bf688a0SCe Qin       } else {
3346bf688a0SCe Qin         nd_parcsrfull = NULL;
3356bf688a0SCe Qin       }
3366bf688a0SCe Qin       for (i=0;i<3;++i) {
3376bf688a0SCe Qin         if (jac->ND_Pi[i]) {
3386bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
3396bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
3406bf688a0SCe Qin         } else {
3416bf688a0SCe Qin           nd_parcsr[i] = NULL;
3426bf688a0SCe Qin         }
3436bf688a0SCe Qin       }
3446bf688a0SCe 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]));
3456bf688a0SCe Qin     }
346863406b8SStefano Zampini   }
34749a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
34849a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&bv));
34949a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&xv));
35022e51d31SStefano Zampini   PetscStackCallStandard(jac->setup,(jac->hsolver,hmat,bv,xv));
35116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
35216d9e3a6SLisandro Dalcin }
35316d9e3a6SLisandro Dalcin 
35416d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
35516d9e3a6SLisandro Dalcin {
35616d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
35749a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
35816d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
35916d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
360d9ca1df4SBarry Smith   PetscScalar        *xv;
361d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
36216d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
363d9ca1df4SBarry Smith   PetscScalar        *sxv;
3644ddd07fcSJed Brown   PetscInt           hierr;
36516d9e3a6SLisandro Dalcin 
36616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
367dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
36816d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
369d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
37016d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
37158968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)bv,sbv);
37258968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
37316d9e3a6SLisandro Dalcin 
37449a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
37549a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
37649a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
377fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
37865e19b50SBarry Smith   if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
379fd3f9acdSBarry Smith   if (hierr) hypre__global_error = 0;);
38016d9e3a6SLisandro Dalcin 
38123df4f25SStefano Zampini   if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) {
3825ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSProjectOutGradients,(jac->hsolver,jxv));
38321df291bSStefano Zampini   }
38458968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)sbv,bv);
38558968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
38616d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
387d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
38816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
38916d9e3a6SLisandro Dalcin }
39016d9e3a6SLisandro Dalcin 
3918695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc)
3928695de01SBarry Smith {
3938695de01SBarry Smith   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
3948695de01SBarry Smith   PetscErrorCode ierr;
3958695de01SBarry Smith 
3968695de01SBarry Smith   PetscFunctionBegin;
39749a781f5SStefano Zampini   ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
3985ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
3995ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
4005ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
4015ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
4026bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
4036bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[0]);CHKERRQ(ierr);
4046bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[1]);CHKERRQ(ierr);
4056bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[2]);CHKERRQ(ierr);
4066bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
4076bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[0]);CHKERRQ(ierr);
4086bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[1]);CHKERRQ(ierr);
4096bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[2]);CHKERRQ(ierr);
4108695de01SBarry Smith   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); jac->coords[0] = NULL;
4118695de01SBarry Smith   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); jac->coords[1] = NULL;
4128695de01SBarry Smith   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); jac->coords[2] = NULL;
4138695de01SBarry Smith   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); jac->constants[0] = NULL;
4148695de01SBarry Smith   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); jac->constants[1] = NULL;
4158695de01SBarry Smith   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); jac->constants[2] = NULL;
416*ce6a8a0dSJed Brown   ierr = PCHYPREResetNearNullSpace_Private(pc);CHKERRQ(ierr);
4175ac14e1cSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
4185ac14e1cSStefano Zampini   jac->dim = 0;
4198695de01SBarry Smith   PetscFunctionReturn(0);
4208695de01SBarry Smith }
4218695de01SBarry Smith 
42216d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
42316d9e3a6SLisandro Dalcin {
42416d9e3a6SLisandro Dalcin   PC_HYPRE                 *jac = (PC_HYPRE*)pc->data;
42516d9e3a6SLisandro Dalcin   PetscErrorCode           ierr;
42616d9e3a6SLisandro Dalcin 
42716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
4288695de01SBarry Smith   ierr = PCReset_HYPRE(pc);CHKERRQ(ierr);
42922e51d31SStefano Zampini   if (jac->destroy) PetscStackCallStandard(jac->destroy,(jac->hsolver));
430503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
43116d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
432c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
43316d9e3a6SLisandro Dalcin 
43416d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
435bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
436bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
4374cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
4384cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
439863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
4406bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",NULL);CHKERRQ(ierr);
4414cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
4425ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",NULL);CHKERRQ(ierr);
44316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
44416d9e3a6SLisandro Dalcin }
44516d9e3a6SLisandro Dalcin 
44616d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
4474416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptionItems *PetscOptionsObject,PC pc)
44816d9e3a6SLisandro Dalcin {
44916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
45016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
451ace3abfcSBarry Smith   PetscBool      flag;
45216d9e3a6SLisandro Dalcin 
45316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
454e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
45516d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
456fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
45716d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
458fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
45916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
460fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
46116d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
46216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
46316d9e3a6SLisandro Dalcin }
46416d9e3a6SLisandro Dalcin 
46516d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
46616d9e3a6SLisandro Dalcin {
46716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
46816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
469ace3abfcSBarry Smith   PetscBool      iascii;
47016d9e3a6SLisandro Dalcin 
47116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
472251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
47316d9e3a6SLisandro Dalcin   if (iascii) {
47416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
47516d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
476efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
47716d9e3a6SLisandro Dalcin     } else {
478efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default maximum number of iterations \n");CHKERRQ(ierr);
47916d9e3a6SLisandro Dalcin     }
48016d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
481efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
48216d9e3a6SLisandro Dalcin     } else {
483efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default drop tolerance \n");CHKERRQ(ierr);
48416d9e3a6SLisandro Dalcin     }
48516d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
486efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
48716d9e3a6SLisandro Dalcin     } else {
488efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default factor row size \n");CHKERRQ(ierr);
48916d9e3a6SLisandro Dalcin     }
49016d9e3a6SLisandro Dalcin   }
49116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
49216d9e3a6SLisandro Dalcin }
49316d9e3a6SLisandro Dalcin 
49416d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
495db966c6cSHong Zhang static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PetscOptionItems *PetscOptionsObject,PC pc)
496db966c6cSHong Zhang {
497db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
498db966c6cSHong Zhang   PetscErrorCode ierr;
499db966c6cSHong Zhang   PetscBool      flag;
500db966c6cSHong Zhang 
501db966c6cSHong Zhang   PetscFunctionBegin;
502db966c6cSHong Zhang   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Euclid Options");CHKERRQ(ierr);
503db966c6cSHong Zhang   ierr = PetscOptionsInt("-pc_hypre_euclid_level","Factorization levels","None",jac->eu_level,&jac->eu_level,&flag);CHKERRQ(ierr);
504db966c6cSHong Zhang   if (flag) PetscStackCallStandard(HYPRE_EuclidSetLevel,(jac->hsolver,jac->eu_level));
505db966c6cSHong Zhang   ierr = PetscOptionsTail();CHKERRQ(ierr);
506db966c6cSHong Zhang   PetscFunctionReturn(0);
507db966c6cSHong Zhang }
508db966c6cSHong Zhang 
509db966c6cSHong Zhang static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer)
510db966c6cSHong Zhang {
511db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
512db966c6cSHong Zhang   PetscErrorCode ierr;
513db966c6cSHong Zhang   PetscBool      iascii;
514db966c6cSHong Zhang 
515db966c6cSHong Zhang   PetscFunctionBegin;
516db966c6cSHong Zhang   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
517db966c6cSHong Zhang   if (iascii) {
518db966c6cSHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid preconditioning\n");CHKERRQ(ierr);
519db966c6cSHong Zhang     if (jac->eu_level != PETSC_DEFAULT) {
520db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    factorization levels %d\n",jac->eu_level);CHKERRQ(ierr);
521db966c6cSHong Zhang     } else {
522db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    default factorization levels \n");CHKERRQ(ierr);
523db966c6cSHong Zhang     }
524db966c6cSHong Zhang   }
525db966c6cSHong Zhang   PetscFunctionReturn(0);
526db966c6cSHong Zhang }
527db966c6cSHong Zhang 
528db966c6cSHong Zhang /* --------------------------------------------------------------------------------------------*/
52916d9e3a6SLisandro Dalcin 
53016d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
53116d9e3a6SLisandro Dalcin {
53216d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
53349a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
53416d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
53516d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
536d9ca1df4SBarry Smith   PetscScalar        *xv;
537d9ca1df4SBarry Smith   const PetscScalar  *bv;
53816d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
53916d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
5404ddd07fcSJed Brown   PetscInt           hierr;
54116d9e3a6SLisandro Dalcin 
54216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
543dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
54416d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
545d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
54616d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
54758968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)bv,sbv);
54858968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
54916d9e3a6SLisandro Dalcin 
55049a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
55149a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
55249a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
55316d9e3a6SLisandro Dalcin 
55416d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
55516d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
556e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
55716d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
55816d9e3a6SLisandro Dalcin 
55958968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,sbv,bv);
56058968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
56116d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
562d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
56316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
56416d9e3a6SLisandro Dalcin }
56516d9e3a6SLisandro Dalcin 
566a669f990SJed Brown /* static array length */
567a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
568a669f990SJed Brown 
56916d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
5700f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
57116d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
57265de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
5736a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]   = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
57465de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
57565de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
57665de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
5777b7fa87dSPierre Jolivet                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "l1-Gauss-Seidel" /* nonsymmetric */, "backward-l1-Gauss-Seidel" /* nonsymmetric */,
57865de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
5790f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
580e2287abbSStefano Zampini                                                   "ext+i-cc", "standard", "standard-wts", "block", "block-wtd", "FF", "FF1"};
5814416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc)
58216d9e3a6SLisandro Dalcin {
58316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
58416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
58522e51d31SStefano Zampini   PetscInt       bs,n,indx,level;
586ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
58716d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
58816d9e3a6SLisandro Dalcin 
58916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
590e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
5914336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
59216d9e3a6SLisandro Dalcin   if (flg) {
5934336a9eeSBarry Smith     jac->cycletype = indx+1;
594fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
59516d9e3a6SLisandro Dalcin   }
59616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
59716d9e3a6SLisandro Dalcin   if (flg) {
598ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
599fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
60016d9e3a6SLisandro Dalcin   }
60116d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
60216d9e3a6SLisandro Dalcin   if (flg) {
603ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
604fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
60516d9e3a6SLisandro Dalcin   }
6060f1074feSSatish 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);
60716d9e3a6SLisandro Dalcin   if (flg) {
60857622a8eSBarry 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);
609fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
61016d9e3a6SLisandro Dalcin   }
61122e51d31SStefano Zampini   bs = 1;
61222e51d31SStefano Zampini   if (pc->pmat) {
61322e51d31SStefano Zampini     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
61422e51d31SStefano Zampini   }
61522e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_numfunctions","Number of functions","HYPRE_BoomerAMGSetNumFunctions",bs,&bs,&flg);CHKERRQ(ierr);
61622e51d31SStefano Zampini   if (flg) {
61722e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
61822e51d31SStefano Zampini   }
61916d9e3a6SLisandro Dalcin 
6200f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
62116d9e3a6SLisandro Dalcin   if (flg) {
62257622a8eSBarry 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);
623fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
62416d9e3a6SLisandro Dalcin   }
62516d9e3a6SLisandro Dalcin 
6260f1074feSSatish 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);
6270f1074feSSatish Balay   if (flg) {
62857622a8eSBarry 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);
629fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
6300f1074feSSatish Balay   }
6310f1074feSSatish Balay 
6320f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
6330f1074feSSatish Balay   if (flg) {
63457622a8eSBarry 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);
6350f1074feSSatish Balay 
636fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
6370f1074feSSatish Balay   }
6380f1074feSSatish Balay 
6390f1074feSSatish 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);
6400f1074feSSatish Balay   if (flg) {
64157622a8eSBarry 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);
6420f1074feSSatish Balay 
643fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
6440f1074feSSatish Balay   }
6450f1074feSSatish Balay 
6460f1074feSSatish Balay 
64716d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
64816d9e3a6SLisandro Dalcin   if (flg) {
64957622a8eSBarry 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);
650fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
65116d9e3a6SLisandro Dalcin   }
65216d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
65316d9e3a6SLisandro Dalcin   if (flg) {
65457622a8eSBarry 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);
65557622a8eSBarry 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);
656fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
65716d9e3a6SLisandro Dalcin   }
65816d9e3a6SLisandro Dalcin 
65916d9e3a6SLisandro Dalcin   /* Grid sweeps */
6600f1074feSSatish 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);
66116d9e3a6SLisandro Dalcin   if (flg) {
662fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
66316d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
66416d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
6650f1074feSSatish Balay     jac->gridsweeps[1] = indx;
6660f1074feSSatish Balay     /*defaults coarse to 1 */
6670f1074feSSatish Balay     jac->gridsweeps[2] = 1;
66816d9e3a6SLisandro Dalcin   }
6695272c319SBarry 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);
6705272c319SBarry Smith   if (flg) {
6715272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,jac->nodal_coarsening));
6725272c319SBarry Smith   }
67322e51d31SStefano 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);
67422e51d31SStefano Zampini   if (flg) {
67522e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNodalDiag,(jac->hsolver,jac->nodal_coarsening_diag));
67622e51d31SStefano Zampini   }
677cbc39033SBarry 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);
6785272c319SBarry Smith   if (flg) {
6795272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,(jac->hsolver,jac->vec_interp_variant));
6805272c319SBarry Smith   }
68122e51d31SStefano 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);
68222e51d31SStefano Zampini   if (flg) {
68322e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecQMax,(jac->hsolver,jac->vec_interp_qmax));
68422e51d31SStefano Zampini   }
68522e51d31SStefano 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);
68622e51d31SStefano Zampini   if (flg) {
68722e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothInterpVectors,(jac->hsolver,jac->vec_interp_smooth));
68822e51d31SStefano Zampini   }
68922e51d31SStefano 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);
69022e51d31SStefano Zampini   if (flg) {
69122e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpRefine,(jac->hsolver,jac->interp_refine));
69222e51d31SStefano Zampini   }
6930f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
69416d9e3a6SLisandro Dalcin   if (flg) {
695fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
6960f1074feSSatish Balay     jac->gridsweeps[0] = indx;
69716d9e3a6SLisandro Dalcin   }
69816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
69916d9e3a6SLisandro Dalcin   if (flg) {
700fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
7010f1074feSSatish Balay     jac->gridsweeps[1] = indx;
70216d9e3a6SLisandro Dalcin   }
7030f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
70416d9e3a6SLisandro Dalcin   if (flg) {
705fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
7060f1074feSSatish Balay     jac->gridsweeps[2] = indx;
70716d9e3a6SLisandro Dalcin   }
70816d9e3a6SLisandro Dalcin 
7096a251517SEike Mueller   /* Smooth type */
7106a251517SEike Mueller   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);
7116a251517SEike Mueller   if (flg) {
7126a251517SEike Mueller     jac->smoothtype = indx;
7136a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
7148131ecf7SEike Mueller     jac->smoothnumlevels = 25;
7158131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
7168131ecf7SEike Mueller   }
7178131ecf7SEike Mueller 
7188131ecf7SEike Mueller   /* Number of smoothing levels */
7198131ecf7SEike 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);
7208131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
7218131ecf7SEike Mueller     jac->smoothnumlevels = indx;
7228131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
7236a251517SEike Mueller   }
7246a251517SEike Mueller 
7251810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
7261810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
7271810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
7281810e44eSEike Mueller     jac->eu_level = indx;
7291810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
7301810e44eSEike Mueller   }
7311810e44eSEike Mueller 
7321810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
7331810e44eSEike Mueller   double droptolerance;
7341810e44eSEike Mueller   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
7351810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
7361810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
7371810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
7381810e44eSEike Mueller   }
7391810e44eSEike Mueller 
7401810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
7411810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
7421810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
7431810e44eSEike Mueller     jac->eu_bj = tmp_truth;
744493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
7451810e44eSEike Mueller   }
7461810e44eSEike Mueller 
74716d9e3a6SLisandro Dalcin   /* Relax type */
748a669f990SJed 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);
74916d9e3a6SLisandro Dalcin   if (flg) {
7500f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
751fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
7520f1074feSSatish Balay     /* by default, coarse type set to 9 */
7530f1074feSSatish Balay     jac->relaxtype[2] = 9;
754ddbeb582SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, 9, 3));
75516d9e3a6SLisandro Dalcin   }
756a669f990SJed 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);
75716d9e3a6SLisandro Dalcin   if (flg) {
75816d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
759fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
76016d9e3a6SLisandro Dalcin   }
761a669f990SJed 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);
76216d9e3a6SLisandro Dalcin   if (flg) {
7630f1074feSSatish Balay     jac->relaxtype[1] = indx;
764fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
76516d9e3a6SLisandro Dalcin   }
766a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
76716d9e3a6SLisandro Dalcin   if (flg) {
7680f1074feSSatish Balay     jac->relaxtype[2] = indx;
769fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
77016d9e3a6SLisandro Dalcin   }
77116d9e3a6SLisandro Dalcin 
77216d9e3a6SLisandro Dalcin   /* Relaxation Weight */
77316d9e3a6SLisandro 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);
77416d9e3a6SLisandro Dalcin   if (flg) {
775fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
77616d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
77716d9e3a6SLisandro Dalcin   }
77816d9e3a6SLisandro Dalcin 
77916d9e3a6SLisandro Dalcin   n         = 2;
78016d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
78116d9e3a6SLisandro 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);
78216d9e3a6SLisandro Dalcin   if (flg) {
78316d9e3a6SLisandro Dalcin     if (n == 2) {
78416d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
785fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
786ce94432eSBarry 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);
78716d9e3a6SLisandro Dalcin   }
78816d9e3a6SLisandro Dalcin 
78916d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
79016d9e3a6SLisandro 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);
79116d9e3a6SLisandro Dalcin   if (flg) {
792fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
79316d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
79416d9e3a6SLisandro Dalcin   }
79516d9e3a6SLisandro Dalcin 
79616d9e3a6SLisandro Dalcin   n         = 2;
79716d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
79816d9e3a6SLisandro 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);
79916d9e3a6SLisandro Dalcin   if (flg) {
80016d9e3a6SLisandro Dalcin     if (n == 2) {
80116d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
802fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
803ce94432eSBarry 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);
80416d9e3a6SLisandro Dalcin   }
80516d9e3a6SLisandro Dalcin 
80616d9e3a6SLisandro Dalcin   /* the Relax Order */
807acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
80816d9e3a6SLisandro Dalcin 
8098afaa268SBarry Smith   if (flg && tmp_truth) {
81016d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
811fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
81216d9e3a6SLisandro Dalcin   }
813a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
81416d9e3a6SLisandro Dalcin   if (flg) {
81516d9e3a6SLisandro Dalcin     jac->measuretype = indx;
816fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
81716d9e3a6SLisandro Dalcin   }
8180f1074feSSatish Balay   /* update list length 3/07 */
819a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
82016d9e3a6SLisandro Dalcin   if (flg) {
82116d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
822fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
82316d9e3a6SLisandro Dalcin   }
8240f1074feSSatish Balay 
8250f1074feSSatish Balay   /* new 3/07 */
826a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
8270f1074feSSatish Balay   if (flg) {
8280f1074feSSatish Balay     jac->interptype = indx;
829fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
8300f1074feSSatish Balay   }
8310f1074feSSatish Balay 
832b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
83316d9e3a6SLisandro Dalcin   if (flg) {
834b96a4a96SBarry Smith     level = 3;
8350298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
8362fa5cd67SKarl Rupp 
837b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
838fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
8392ae77aedSBarry Smith   }
8402ae77aedSBarry Smith 
841b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
8422ae77aedSBarry Smith   if (flg) {
843b96a4a96SBarry Smith     level = 3;
8440298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
8452fa5cd67SKarl Rupp 
846b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
847fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
84816d9e3a6SLisandro Dalcin   }
8498f87f92bSBarry Smith 
850acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
8518f87f92bSBarry Smith   if (flg && tmp_truth) {
8528f87f92bSBarry Smith     PetscInt tmp_int;
8538f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
8548f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
855fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
856fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
857fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
858fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
8598f87f92bSBarry Smith   }
8608f87f92bSBarry Smith 
86116d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
86216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
86316d9e3a6SLisandro Dalcin }
86416d9e3a6SLisandro Dalcin 
865ace3abfcSBarry 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)
86616d9e3a6SLisandro Dalcin {
86716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
86816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
8694ddd07fcSJed Brown   PetscInt       oits;
87016d9e3a6SLisandro Dalcin 
87116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
872dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
873fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
874fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
87516d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
87616d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
87716d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
8788b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
8794d0a8057SBarry Smith   *outits = oits;
8804d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
8814d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
882fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
883fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
88416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
88516d9e3a6SLisandro Dalcin }
88616d9e3a6SLisandro Dalcin 
88716d9e3a6SLisandro Dalcin 
88816d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
88916d9e3a6SLisandro Dalcin {
89016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
89116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
892ace3abfcSBarry Smith   PetscBool      iascii;
89316d9e3a6SLisandro Dalcin 
89416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
895251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
89616d9e3a6SLisandro Dalcin   if (iascii) {
89716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
898efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
89922e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of levels %D\n",jac->maxlevels);CHKERRQ(ierr);
90022e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of iterations PER hypre call %D\n",jac->maxiter);CHKERRQ(ierr);
901efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
902efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
903efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
90422e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: max elements per row %D\n",jac->pmax);CHKERRQ(ierr);
90522e51d31SStefano Zampini     if (jac->interp_refine) {
90622e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: number of steps of weighted refinement %D\n",jac->interp_refine);CHKERRQ(ierr);
90722e51d31SStefano Zampini     }
90822e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of levels of aggressive coarsening %D\n",jac->agg_nl);CHKERRQ(ierr);
90922e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of paths for aggressive coarsening %D\n",jac->agg_num_paths);CHKERRQ(ierr);
9100f1074feSSatish Balay 
911efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
91216d9e3a6SLisandro Dalcin 
91322e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps down         %D\n",jac->gridsweeps[0]);CHKERRQ(ierr);
91422e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps up           %D\n",jac->gridsweeps[1]);CHKERRQ(ierr);
91522e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps on coarse    %D\n",jac->gridsweeps[2]);CHKERRQ(ierr);
91616d9e3a6SLisandro Dalcin 
917efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
918efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
919efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
92016d9e3a6SLisandro Dalcin 
921efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
922efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
92316d9e3a6SLisandro Dalcin 
92416d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
925efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using CF-relaxation\n");CHKERRQ(ierr);
92616d9e3a6SLisandro Dalcin     } else {
927efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using CF-relaxation\n");CHKERRQ(ierr);
92816d9e3a6SLisandro Dalcin     }
9296a251517SEike Mueller     if (jac->smoothtype!=-1) {
930efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
93122e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth num levels    %D\n",jac->smoothnumlevels);CHKERRQ(ierr);
9327e352d70SEike Mueller     } else {
933efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using more complex smoothers.\n");CHKERRQ(ierr);
9341810e44eSEike Mueller     }
9351810e44eSEike Mueller     if (jac->smoothtype==3) {
93622e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) levels %D\n",jac->eu_level);CHKERRQ(ierr);
93722e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) drop tolerance %g\n",(double)jac->eu_droptolerance);CHKERRQ(ierr);
93822e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU use Block-Jacobi? %D\n",jac->eu_bj);CHKERRQ(ierr);
9396a251517SEike Mueller     }
940efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
941efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
942efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
9435272c319SBarry Smith     if (jac->nodal_coarsening) {
944efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
9455272c319SBarry Smith     }
9465272c319SBarry Smith     if (jac->vec_interp_variant) {
947efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
94822e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecQMax() %D\n",jac->vec_interp_qmax);CHKERRQ(ierr);
94922e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n",jac->vec_interp_smooth);CHKERRQ(ierr);
9508f87f92bSBarry Smith     }
9518f87f92bSBarry Smith     if (jac->nodal_relax) {
95222e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal relaxation via Schwarz smoothing on levels %D\n",jac->nodal_relax_levels);CHKERRQ(ierr);
9538f87f92bSBarry Smith     }
95416d9e3a6SLisandro Dalcin   }
95516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
95616d9e3a6SLisandro Dalcin }
95716d9e3a6SLisandro Dalcin 
95816d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
9594416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc)
96016d9e3a6SLisandro Dalcin {
96116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
96216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
9634ddd07fcSJed Brown   PetscInt       indx;
964ace3abfcSBarry Smith   PetscBool      flag;
96516d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
96616d9e3a6SLisandro Dalcin 
96716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
968e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
96916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
97016d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
9712fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
97216d9e3a6SLisandro Dalcin 
97316d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
9742fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
97516d9e3a6SLisandro Dalcin 
97616d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
9772fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
97816d9e3a6SLisandro Dalcin 
979acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
9802fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
98116d9e3a6SLisandro Dalcin 
982acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
9832fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
98416d9e3a6SLisandro Dalcin 
985a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
98616d9e3a6SLisandro Dalcin   if (flag) {
98716d9e3a6SLisandro Dalcin     jac->symt = indx;
988fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
98916d9e3a6SLisandro Dalcin   }
99016d9e3a6SLisandro Dalcin 
99116d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
99216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
99316d9e3a6SLisandro Dalcin }
99416d9e3a6SLisandro Dalcin 
99516d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
99616d9e3a6SLisandro Dalcin {
99716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
99816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
999ace3abfcSBarry Smith   PetscBool      iascii;
100016d9e3a6SLisandro Dalcin   const char     *symt = 0;;
100116d9e3a6SLisandro Dalcin 
100216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1003251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
100416d9e3a6SLisandro Dalcin   if (iascii) {
100516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
1006efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
1007efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
1008efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    filter %g\n",(double)jac->filter);CHKERRQ(ierr);
1009efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
1010efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
1011efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
10122fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
10132fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
10142fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
1015ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
1016efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    %s\n",symt);CHKERRQ(ierr);
101716d9e3a6SLisandro Dalcin   }
101816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
101916d9e3a6SLisandro Dalcin }
10204cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
10214416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc)
10224cb006feSStefano Zampini {
10234cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
10244cb006feSStefano Zampini   PetscErrorCode ierr;
10254cb006feSStefano Zampini   PetscInt       n;
10264cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
10274cb006feSStefano Zampini 
10284cb006feSStefano Zampini   PetscFunctionBegin;
10299fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
1030863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1031863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1032863406b8SStefano 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);
1033863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
10344cb006feSStefano 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);
10354cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1036863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1037863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1038863406b8SStefano 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);
1039863406b8SStefano 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);
1040863406b8SStefano 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);
1041863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
10424cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1043863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1044863406b8SStefano Zampini                                                                       jac->as_relax_times,
1045863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1046863406b8SStefano Zampini                                                                       jac->as_omega));
10474cb006feSStefano Zampini   }
1048863406b8SStefano 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);
10494cb006feSStefano Zampini   n = 5;
1050863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
10514cb006feSStefano Zampini   if (flag || flag2) {
1052863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1053863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1054863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1055863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1056863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1057863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
10584cb006feSStefano Zampini   }
1059863406b8SStefano 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);
10604cb006feSStefano Zampini   n = 5;
1061863406b8SStefano 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);
10624cb006feSStefano Zampini   if (flag || flag2) {
1063863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1064863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1065863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1066863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1067863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1068863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
10694cb006feSStefano Zampini   }
107023df4f25SStefano 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);
107123df4f25SStefano Zampini   if (flag) { /* override HYPRE's default only if the options is used */
107223df4f25SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetProjectionFrequency,(jac->hsolver,jac->ams_proj_freq));
107323df4f25SStefano Zampini   }
10744cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
10754cb006feSStefano Zampini   PetscFunctionReturn(0);
10764cb006feSStefano Zampini }
10774cb006feSStefano Zampini 
10784cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
10794cb006feSStefano Zampini {
10804cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
10814cb006feSStefano Zampini   PetscErrorCode ierr;
10824cb006feSStefano Zampini   PetscBool      iascii;
10834cb006feSStefano Zampini 
10844cb006feSStefano Zampini   PetscFunctionBegin;
10854cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
10864cb006feSStefano Zampini   if (iascii) {
10874cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
1088efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1089efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1090efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1091efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1092efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1093efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1094efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
10954cb006feSStefano Zampini     if (jac->alpha_Poisson) {
1096efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
10974cb006feSStefano Zampini     } else {
1098efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (computed) \n");CHKERRQ(ierr);
10994cb006feSStefano Zampini     }
1100efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1101efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1102efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1103efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1104efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1105efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
11064cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
11074cb006feSStefano Zampini       if (jac->beta_Poisson) {
1108efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
11094cb006feSStefano Zampini       } else {
1110efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (computed) \n");CHKERRQ(ierr);
11114cb006feSStefano Zampini       }
1112efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1113efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1114efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1115efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1116efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1117efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
111823df4f25SStefano Zampini       if (jac->ams_beta_is_zero_part) {
1119efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"        compatible subspace projection frequency %d (-1 HYPRE uses default)\n",jac->ams_proj_freq);CHKERRQ(ierr);
112023df4f25SStefano Zampini       }
112123df4f25SStefano Zampini     } else {
1122efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver not used (zero-conductivity everywhere) \n");CHKERRQ(ierr);
11234cb006feSStefano Zampini     }
11244cb006feSStefano Zampini   }
11254cb006feSStefano Zampini   PetscFunctionReturn(0);
11264cb006feSStefano Zampini }
11274cb006feSStefano Zampini 
11284416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc)
1129863406b8SStefano Zampini {
1130863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1131863406b8SStefano Zampini   PetscErrorCode ierr;
1132863406b8SStefano Zampini   PetscInt       n;
1133863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
1134863406b8SStefano Zampini 
1135863406b8SStefano Zampini   PetscFunctionBegin;
1136863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
1137863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1138863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1139863406b8SStefano 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);
1140863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1141863406b8SStefano 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);
1142863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
1143863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1144863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1145863406b8SStefano 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);
1146863406b8SStefano 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);
1147863406b8SStefano 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);
1148863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
1149863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1150863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1151863406b8SStefano Zampini                                                                       jac->as_relax_times,
1152863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1153863406b8SStefano Zampini                                                                       jac->as_omega));
1154863406b8SStefano Zampini   }
1155863406b8SStefano 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);
1156863406b8SStefano Zampini   n = 5;
1157863406b8SStefano 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);
1158863406b8SStefano 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);
1159863406b8SStefano Zampini   if (flag || flag2 || flag3) {
1160863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
1161863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1162863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1163863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1164863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1165863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1166863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1167863406b8SStefano Zampini   }
1168863406b8SStefano 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);
1169863406b8SStefano Zampini   n = 5;
1170863406b8SStefano 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);
1171863406b8SStefano Zampini   if (flag || flag2) {
1172863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1173863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1174863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1175863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1176863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1177863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1178863406b8SStefano Zampini   }
1179863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
1180863406b8SStefano Zampini   PetscFunctionReturn(0);
1181863406b8SStefano Zampini }
1182863406b8SStefano Zampini 
1183863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1184863406b8SStefano Zampini {
1185863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1186863406b8SStefano Zampini   PetscErrorCode ierr;
1187863406b8SStefano Zampini   PetscBool      iascii;
1188863406b8SStefano Zampini 
1189863406b8SStefano Zampini   PetscFunctionBegin;
1190863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1191863406b8SStefano Zampini   if (iascii) {
1192863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
1193efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1194efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
1195efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1196efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1197efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1198efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1199efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
1200efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    AMS solver using boomerAMG\n");CHKERRQ(ierr);
1201efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1202efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1203efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1204efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1205efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1206efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1207efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
1208efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver using boomerAMG\n");CHKERRQ(ierr);
1209efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1210efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1211efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1212efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1213efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1214efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
1215863406b8SStefano Zampini   }
1216863406b8SStefano Zampini   PetscFunctionReturn(0);
1217863406b8SStefano Zampini }
1218863406b8SStefano Zampini 
1219863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
12204cb006feSStefano Zampini {
12214cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12225ac14e1cSStefano Zampini   PetscBool      ishypre;
12234cb006feSStefano Zampini   PetscErrorCode ierr;
12244cb006feSStefano Zampini 
12254cb006feSStefano Zampini   PetscFunctionBegin;
12265ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)G,MATHYPRE,&ishypre);CHKERRQ(ierr);
12275ac14e1cSStefano Zampini   if (ishypre) {
12285ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr);
12295ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
12305ac14e1cSStefano Zampini     jac->G = G;
12315ac14e1cSStefano Zampini   } else {
12326bf688a0SCe Qin     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
12336bf688a0SCe Qin     ierr = MatConvert(G,MATHYPRE,MAT_INITIAL_MATRIX,&jac->G);CHKERRQ(ierr);
12345ac14e1cSStefano Zampini   }
12354cb006feSStefano Zampini   PetscFunctionReturn(0);
12364cb006feSStefano Zampini }
12374cb006feSStefano Zampini 
12384cb006feSStefano Zampini /*@
12394cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
12404cb006feSStefano Zampini 
12414cb006feSStefano Zampini    Collective on PC
12424cb006feSStefano Zampini 
12434cb006feSStefano Zampini    Input Parameters:
12444cb006feSStefano Zampini +  pc - the preconditioning context
12454cb006feSStefano Zampini -  G - the discrete gradient
12464cb006feSStefano Zampini 
12474cb006feSStefano Zampini    Level: intermediate
12484cb006feSStefano Zampini 
124995452b02SPatrick Sanan    Notes:
125095452b02SPatrick Sanan     G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh
1251863406b8SStefano 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
12524cb006feSStefano Zampini 
12534cb006feSStefano Zampini .seealso:
12544cb006feSStefano Zampini @*/
12554cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
12564cb006feSStefano Zampini {
12574cb006feSStefano Zampini   PetscErrorCode ierr;
12584cb006feSStefano Zampini 
12594cb006feSStefano Zampini   PetscFunctionBegin;
12604cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12614cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
12624cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
12634cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
12644cb006feSStefano Zampini   PetscFunctionReturn(0);
12654cb006feSStefano Zampini }
12664cb006feSStefano Zampini 
1267863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1268863406b8SStefano Zampini {
1269863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12705ac14e1cSStefano Zampini   PetscBool      ishypre;
1271863406b8SStefano Zampini   PetscErrorCode ierr;
1272863406b8SStefano Zampini 
1273863406b8SStefano Zampini   PetscFunctionBegin;
12745ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)C,MATHYPRE,&ishypre);CHKERRQ(ierr);
12755ac14e1cSStefano Zampini   if (ishypre) {
12765ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr);
12775ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
12785ac14e1cSStefano Zampini     jac->C = C;
12795ac14e1cSStefano Zampini   } else {
12806bf688a0SCe Qin     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
12816bf688a0SCe Qin     ierr = MatConvert(C,MATHYPRE,MAT_INITIAL_MATRIX,&jac->C);CHKERRQ(ierr);
12825ac14e1cSStefano Zampini   }
1283863406b8SStefano Zampini   PetscFunctionReturn(0);
1284863406b8SStefano Zampini }
1285863406b8SStefano Zampini 
1286863406b8SStefano Zampini /*@
1287863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1288863406b8SStefano Zampini 
1289863406b8SStefano Zampini    Collective on PC
1290863406b8SStefano Zampini 
1291863406b8SStefano Zampini    Input Parameters:
1292863406b8SStefano Zampini +  pc - the preconditioning context
1293863406b8SStefano Zampini -  C - the discrete curl
1294863406b8SStefano Zampini 
1295863406b8SStefano Zampini    Level: intermediate
1296863406b8SStefano Zampini 
129795452b02SPatrick Sanan    Notes:
129895452b02SPatrick Sanan     C should have as many rows as the number of faces and as many columns as the number of edges in the mesh
1299863406b8SStefano 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
1300863406b8SStefano Zampini 
1301863406b8SStefano Zampini .seealso:
1302863406b8SStefano Zampini @*/
1303863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1304863406b8SStefano Zampini {
1305863406b8SStefano Zampini   PetscErrorCode ierr;
1306863406b8SStefano Zampini 
1307863406b8SStefano Zampini   PetscFunctionBegin;
1308863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1309863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1310863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1311863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1312863406b8SStefano Zampini   PetscFunctionReturn(0);
1313863406b8SStefano Zampini }
1314863406b8SStefano Zampini 
13156bf688a0SCe Qin static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
13166bf688a0SCe Qin {
13176bf688a0SCe Qin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
13186bf688a0SCe Qin   PetscBool      ishypre;
13196bf688a0SCe Qin   PetscErrorCode ierr;
13206bf688a0SCe Qin   PetscInt       i;
13216bf688a0SCe Qin   PetscFunctionBegin;
13226bf688a0SCe Qin 
13236bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
13246bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
13256bf688a0SCe Qin   for (i=0;i<3;++i) {
13266bf688a0SCe Qin     ierr = MatDestroy(&jac->RT_Pi[i]);CHKERRQ(ierr);
13276bf688a0SCe Qin     ierr = MatDestroy(&jac->ND_Pi[i]);CHKERRQ(ierr);
13286bf688a0SCe Qin   }
13296bf688a0SCe Qin 
13306bf688a0SCe Qin   jac->dim = dim;
13316bf688a0SCe Qin   if (RT_PiFull) {
13326bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)RT_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
13336bf688a0SCe Qin     if (ishypre) {
13346bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)RT_PiFull);CHKERRQ(ierr);
13356bf688a0SCe Qin       jac->RT_PiFull = RT_PiFull;
13366bf688a0SCe Qin     } else {
13376bf688a0SCe Qin       ierr = MatConvert(RT_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_PiFull);CHKERRQ(ierr);
13386bf688a0SCe Qin     }
13396bf688a0SCe Qin   }
13406bf688a0SCe Qin   if (RT_Pi) {
13416bf688a0SCe Qin     for (i=0;i<dim;++i) {
13426bf688a0SCe Qin       if (RT_Pi[i]) {
13436bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)RT_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
13446bf688a0SCe Qin         if (ishypre) {
13456bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)RT_Pi[i]);CHKERRQ(ierr);
13466bf688a0SCe Qin           jac->RT_Pi[i] = RT_Pi[i];
13476bf688a0SCe Qin         } else {
13486bf688a0SCe Qin           ierr = MatConvert(RT_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_Pi[i]);CHKERRQ(ierr);
13496bf688a0SCe Qin         }
13506bf688a0SCe Qin       }
13516bf688a0SCe Qin     }
13526bf688a0SCe Qin   }
13536bf688a0SCe Qin   if (ND_PiFull) {
13546bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)ND_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
13556bf688a0SCe Qin     if (ishypre) {
13566bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)ND_PiFull);CHKERRQ(ierr);
13576bf688a0SCe Qin       jac->ND_PiFull = ND_PiFull;
13586bf688a0SCe Qin     } else {
13596bf688a0SCe Qin       ierr = MatConvert(ND_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_PiFull);CHKERRQ(ierr);
13606bf688a0SCe Qin     }
13616bf688a0SCe Qin   }
13626bf688a0SCe Qin   if (ND_Pi) {
13636bf688a0SCe Qin     for (i=0;i<dim;++i) {
13646bf688a0SCe Qin       if (ND_Pi[i]) {
13656bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)ND_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
13666bf688a0SCe Qin         if (ishypre) {
13676bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)ND_Pi[i]);CHKERRQ(ierr);
13686bf688a0SCe Qin           jac->ND_Pi[i] = ND_Pi[i];
13696bf688a0SCe Qin         } else {
13706bf688a0SCe Qin           ierr = MatConvert(ND_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_Pi[i]);CHKERRQ(ierr);
13716bf688a0SCe Qin         }
13726bf688a0SCe Qin       }
13736bf688a0SCe Qin     }
13746bf688a0SCe Qin   }
13756bf688a0SCe Qin 
13766bf688a0SCe Qin   PetscFunctionReturn(0);
13776bf688a0SCe Qin }
13786bf688a0SCe Qin 
13796bf688a0SCe Qin /*@
13806bf688a0SCe Qin  PCHYPRESetInterpolations - Set interpolation matrices for AMS/ADS preconditioner
13816bf688a0SCe Qin 
13826bf688a0SCe Qin    Collective on PC
13836bf688a0SCe Qin 
13846bf688a0SCe Qin    Input Parameters:
13856bf688a0SCe Qin +  pc - the preconditioning context
13866bf688a0SCe Qin -  dim - the dimension of the problem, only used in AMS
13876bf688a0SCe Qin -  RT_PiFull - Raviart-Thomas interpolation matrix
13886bf688a0SCe Qin -  RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix
13896bf688a0SCe Qin -  ND_PiFull - Nedelec interpolation matrix
13906bf688a0SCe Qin -  ND_Pi - x/y/z component of Nedelec interpolation matrix
13916bf688a0SCe Qin 
139295452b02SPatrick Sanan    Notes:
139395452b02SPatrick Sanan     For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL.
13946bf688a0SCe Qin           For ADS, both type of interpolation matrices are needed.
13956bf688a0SCe Qin    Level: intermediate
13966bf688a0SCe Qin 
13976bf688a0SCe Qin .seealso:
13986bf688a0SCe Qin @*/
13996bf688a0SCe Qin PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
14006bf688a0SCe Qin {
14016bf688a0SCe Qin   PetscErrorCode ierr;
14026bf688a0SCe Qin   PetscInt       i;
14036bf688a0SCe Qin 
14046bf688a0SCe Qin   PetscFunctionBegin;
14056bf688a0SCe Qin   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
14066bf688a0SCe Qin   if (RT_PiFull) {
14076bf688a0SCe Qin     PetscValidHeaderSpecific(RT_PiFull,MAT_CLASSID,3);
14086bf688a0SCe Qin     PetscCheckSameComm(pc,1,RT_PiFull,3);
14096bf688a0SCe Qin   }
14106bf688a0SCe Qin   if (RT_Pi) {
14116bf688a0SCe Qin     PetscValidPointer(RT_Pi,4);
14126bf688a0SCe Qin     for (i=0;i<dim;++i) {
14136bf688a0SCe Qin       if (RT_Pi[i]) {
14146bf688a0SCe Qin         PetscValidHeaderSpecific(RT_Pi[i],MAT_CLASSID,4);
14156bf688a0SCe Qin         PetscCheckSameComm(pc,1,RT_Pi[i],4);
14166bf688a0SCe Qin       }
14176bf688a0SCe Qin     }
14186bf688a0SCe Qin   }
14196bf688a0SCe Qin   if (ND_PiFull) {
14206bf688a0SCe Qin     PetscValidHeaderSpecific(ND_PiFull,MAT_CLASSID,5);
14216bf688a0SCe Qin     PetscCheckSameComm(pc,1,ND_PiFull,5);
14226bf688a0SCe Qin   }
14236bf688a0SCe Qin   if (ND_Pi) {
14246bf688a0SCe Qin     PetscValidPointer(ND_Pi,6);
14256bf688a0SCe Qin     for (i=0;i<dim;++i) {
14266bf688a0SCe Qin       if (ND_Pi[i]) {
14276bf688a0SCe Qin         PetscValidHeaderSpecific(ND_Pi[i],MAT_CLASSID,6);
14286bf688a0SCe Qin         PetscCheckSameComm(pc,1,ND_Pi[i],6);
14296bf688a0SCe Qin       }
14306bf688a0SCe Qin     }
14316bf688a0SCe Qin   }
14326bf688a0SCe Qin   ierr = PetscTryMethod(pc,"PCHYPRESetInterpolations_C",(PC,PetscInt,Mat,Mat[],Mat,Mat[]),(pc,dim,RT_PiFull,RT_Pi,ND_PiFull,ND_Pi));CHKERRQ(ierr);
14336bf688a0SCe Qin   PetscFunctionReturn(0);
14346bf688a0SCe Qin }
14356bf688a0SCe Qin 
14365ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha)
14374cb006feSStefano Zampini {
14384cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
14395ac14e1cSStefano Zampini   PetscBool      ishypre;
14404cb006feSStefano Zampini   PetscErrorCode ierr;
14414cb006feSStefano Zampini 
14424cb006feSStefano Zampini   PetscFunctionBegin;
14435ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr);
14445ac14e1cSStefano Zampini   if (ishypre) {
14455ac14e1cSStefano Zampini     if (isalpha) {
14465ac14e1cSStefano Zampini       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
14475ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
14485ac14e1cSStefano Zampini       jac->alpha_Poisson = A;
14495ac14e1cSStefano Zampini     } else {
14505ac14e1cSStefano Zampini       if (A) {
14515ac14e1cSStefano Zampini         ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
14525ac14e1cSStefano Zampini       } else {
14535ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
14545ac14e1cSStefano Zampini       }
14555ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
14565ac14e1cSStefano Zampini       jac->beta_Poisson = A;
14575ac14e1cSStefano Zampini     }
14585ac14e1cSStefano Zampini   } else {
14595ac14e1cSStefano Zampini     if (isalpha) {
14606bf688a0SCe Qin       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
14616bf688a0SCe Qin       ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->alpha_Poisson);CHKERRQ(ierr);
14625ac14e1cSStefano Zampini     } else {
14635ac14e1cSStefano Zampini       if (A) {
14646bf688a0SCe Qin         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
14656bf688a0SCe Qin         ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->beta_Poisson);CHKERRQ(ierr);
14665ac14e1cSStefano Zampini       } else {
14675ac14e1cSStefano Zampini         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
14685ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
14695ac14e1cSStefano Zampini       }
14705ac14e1cSStefano Zampini     }
14715ac14e1cSStefano Zampini   }
14724cb006feSStefano Zampini   PetscFunctionReturn(0);
14734cb006feSStefano Zampini }
14744cb006feSStefano Zampini 
14754cb006feSStefano Zampini /*@
14764cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
14774cb006feSStefano Zampini 
14784cb006feSStefano Zampini    Collective on PC
14794cb006feSStefano Zampini 
14804cb006feSStefano Zampini    Input Parameters:
14814cb006feSStefano Zampini +  pc - the preconditioning context
14824cb006feSStefano Zampini -  A - the matrix
14834cb006feSStefano Zampini 
14844cb006feSStefano Zampini    Level: intermediate
14854cb006feSStefano Zampini 
148695452b02SPatrick Sanan    Notes:
148795452b02SPatrick Sanan     A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
14884cb006feSStefano Zampini 
14894cb006feSStefano Zampini .seealso:
14904cb006feSStefano Zampini @*/
14914cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
14924cb006feSStefano Zampini {
14934cb006feSStefano Zampini   PetscErrorCode ierr;
14944cb006feSStefano Zampini 
14954cb006feSStefano Zampini   PetscFunctionBegin;
14964cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
14974cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
14984cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
14995ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_TRUE));CHKERRQ(ierr);
15004cb006feSStefano Zampini   PetscFunctionReturn(0);
15014cb006feSStefano Zampini }
15024cb006feSStefano Zampini 
15034cb006feSStefano Zampini /*@
15044cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
15054cb006feSStefano Zampini 
15064cb006feSStefano Zampini    Collective on PC
15074cb006feSStefano Zampini 
15084cb006feSStefano Zampini    Input Parameters:
15094cb006feSStefano Zampini +  pc - the preconditioning context
15104cb006feSStefano Zampini -  A - the matrix
15114cb006feSStefano Zampini 
15124cb006feSStefano Zampini    Level: intermediate
15134cb006feSStefano Zampini 
151495452b02SPatrick Sanan    Notes:
151595452b02SPatrick Sanan     A should be obtained by discretizing the Poisson problem with linear finite elements.
15164cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
15174cb006feSStefano Zampini 
15184cb006feSStefano Zampini .seealso:
15194cb006feSStefano Zampini @*/
15204cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
15214cb006feSStefano Zampini {
15224cb006feSStefano Zampini   PetscErrorCode ierr;
15234cb006feSStefano Zampini 
15244cb006feSStefano Zampini   PetscFunctionBegin;
15254cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15264cb006feSStefano Zampini   if (A) {
15274cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
15284cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
15294cb006feSStefano Zampini   }
15305ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_FALSE));CHKERRQ(ierr);
15314cb006feSStefano Zampini   PetscFunctionReturn(0);
15324cb006feSStefano Zampini }
15334cb006feSStefano Zampini 
15345ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz, Vec zoz, Vec zzo)
15354cb006feSStefano Zampini {
15364cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
15374cb006feSStefano Zampini   PetscErrorCode     ierr;
15384cb006feSStefano Zampini 
15394cb006feSStefano Zampini   PetscFunctionBegin;
15404cb006feSStefano Zampini   /* throw away any vector if already set */
15414cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
15424cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
15434cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
15444cb006feSStefano Zampini   jac->constants[0] = NULL;
15454cb006feSStefano Zampini   jac->constants[1] = NULL;
15464cb006feSStefano Zampini   jac->constants[2] = NULL;
15474cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
15484cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
15494cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
15504cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
15515ac14e1cSStefano Zampini   jac->dim = 2;
15524cb006feSStefano Zampini   if (zzo) {
15534cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
15544cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
15555ac14e1cSStefano Zampini     jac->dim++;
15564cb006feSStefano Zampini   }
15574cb006feSStefano Zampini   PetscFunctionReturn(0);
15584cb006feSStefano Zampini }
15594cb006feSStefano Zampini 
15604cb006feSStefano Zampini /*@
15614cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
15624cb006feSStefano Zampini 
15634cb006feSStefano Zampini    Collective on PC
15644cb006feSStefano Zampini 
15654cb006feSStefano Zampini    Input Parameters:
15664cb006feSStefano Zampini +  pc - the preconditioning context
15674cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
15684cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
15694cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
15704cb006feSStefano Zampini 
15714cb006feSStefano Zampini    Level: intermediate
15724cb006feSStefano Zampini 
15734cb006feSStefano Zampini    Notes:
15744cb006feSStefano Zampini 
15754cb006feSStefano Zampini .seealso:
15764cb006feSStefano Zampini @*/
15774cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
15784cb006feSStefano Zampini {
15794cb006feSStefano Zampini   PetscErrorCode ierr;
15804cb006feSStefano Zampini 
15814cb006feSStefano Zampini   PetscFunctionBegin;
15824cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15834cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
15844cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
15854cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
15864cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
15874cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
15884cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
15894cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
15904cb006feSStefano Zampini   PetscFunctionReturn(0);
15914cb006feSStefano Zampini }
15924cb006feSStefano Zampini 
1593863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
15944cb006feSStefano Zampini {
15954cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
15964cb006feSStefano Zampini   Vec             tv;
15974cb006feSStefano Zampini   PetscInt        i;
15984cb006feSStefano Zampini   PetscErrorCode  ierr;
15994cb006feSStefano Zampini 
16004cb006feSStefano Zampini   PetscFunctionBegin;
16014cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
16024cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
16034cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
16044cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
16055ac14e1cSStefano Zampini   jac->dim = dim;
16065ac14e1cSStefano Zampini 
16074cb006feSStefano Zampini   /* compute IJ vector for coordinates */
16084cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
16094cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
16104cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
16114cb006feSStefano Zampini   for (i=0;i<dim;i++) {
16124cb006feSStefano Zampini     PetscScalar *array;
16134cb006feSStefano Zampini     PetscInt    j;
16144cb006feSStefano Zampini 
16154cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
16164cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
16174cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
16184cb006feSStefano Zampini       array[j] = coords[j*dim+i];
16194cb006feSStefano Zampini     }
16204cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
16214cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
16224cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
16234cb006feSStefano Zampini   }
16244cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
16254cb006feSStefano Zampini   PetscFunctionReturn(0);
16264cb006feSStefano Zampini }
16274cb006feSStefano Zampini 
162816d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
162916d9e3a6SLisandro Dalcin 
1630f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
163116d9e3a6SLisandro Dalcin {
163216d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
163316d9e3a6SLisandro Dalcin 
163416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
163516d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
163616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
163716d9e3a6SLisandro Dalcin }
163816d9e3a6SLisandro Dalcin 
1639f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
164016d9e3a6SLisandro Dalcin {
164116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
164216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1643ace3abfcSBarry Smith   PetscBool      flag;
164416d9e3a6SLisandro Dalcin 
164516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
164616d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
164716d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1648ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
164916d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
165016d9e3a6SLisandro Dalcin   } else {
165116d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
165216d9e3a6SLisandro Dalcin   }
165316d9e3a6SLisandro Dalcin 
165416d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
165516d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
165616d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
165716d9e3a6SLisandro Dalcin 
165816d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
165916d9e3a6SLisandro Dalcin   if (flag) {
1660572a0576SBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1661fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
166216d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
166316d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
166416d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
166516d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
166616d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
166716d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
166816d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
166916d9e3a6SLisandro Dalcin   }
1670db966c6cSHong Zhang   ierr = PetscStrcmp("euclid",jac->hypre_type,&flag);CHKERRQ(ierr);
1671db966c6cSHong Zhang   if (flag) {
1672db966c6cSHong Zhang     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1673db966c6cSHong Zhang     PetscStackCallStandard(HYPRE_EuclidCreate,(jac->comm_hypre,&jac->hsolver));
1674db966c6cSHong Zhang     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
1675db966c6cSHong Zhang     pc->ops->view           = PCView_HYPRE_Euclid;
1676db966c6cSHong Zhang     jac->destroy            = HYPRE_EuclidDestroy;
1677db966c6cSHong Zhang     jac->setup              = HYPRE_EuclidSetup;
1678db966c6cSHong Zhang     jac->solve              = HYPRE_EuclidSolve;
1679db966c6cSHong Zhang     jac->factorrowsize      = PETSC_DEFAULT;
1680db966c6cSHong Zhang     jac->eu_level           = PETSC_DEFAULT; /* default */
1681db966c6cSHong Zhang     PetscFunctionReturn(0);
1682db966c6cSHong Zhang   }
168316d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
168416d9e3a6SLisandro Dalcin   if (flag) {
1685572a0576SBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1686fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
168716d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
168816d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
168916d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
169016d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
169116d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
169216d9e3a6SLisandro Dalcin     /* initialize */
169316d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
169416d9e3a6SLisandro Dalcin     jac->threshhold = .1;
169516d9e3a6SLisandro Dalcin     jac->filter     = .1;
169616d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
16972fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
16982fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
16992fa5cd67SKarl Rupp 
170016d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
170116d9e3a6SLisandro Dalcin     jac->symt = 0;
1702fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1703fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1704fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1705fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1706fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1707fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
170816d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
170916d9e3a6SLisandro Dalcin   }
171016d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
171116d9e3a6SLisandro Dalcin   if (flag) {
171216d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
171316d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
171416d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
171516d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
171616d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
171716d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
171816d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
171916d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
172016d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
172116d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
172216d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
172316d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
172416d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
17258f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
172616d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
172716d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
172816d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
172916d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
173016d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
17310f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
17326a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1733b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
17341810e44eSEike Mueller     jac->eu_level         = 0;
17351810e44eSEike Mueller     jac->eu_droptolerance = 0;
17361810e44eSEike Mueller     jac->eu_bj            = 0;
17378f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
17380f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
173916d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
174016d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
174116d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
17420f1074feSSatish Balay     jac->interptype       = 0;
17430f1074feSSatish Balay     jac->agg_nl           = 0;
17440f1074feSSatish Balay     jac->pmax             = 0;
17450f1074feSSatish Balay     jac->truncfactor      = 0.0;
17460f1074feSSatish Balay     jac->agg_num_paths    = 1;
17478f87f92bSBarry Smith 
174822e51d31SStefano Zampini     jac->nodal_coarsening      = 0;
174922e51d31SStefano Zampini     jac->nodal_coarsening_diag = 0;
175022e51d31SStefano Zampini     jac->vec_interp_variant    = 0;
175122e51d31SStefano Zampini     jac->vec_interp_qmax       = 0;
175222e51d31SStefano Zampini     jac->vec_interp_smooth     = PETSC_FALSE;
175322e51d31SStefano Zampini     jac->interp_refine         = 0;
17548f87f92bSBarry Smith     jac->nodal_relax           = PETSC_FALSE;
17558f87f92bSBarry Smith     jac->nodal_relax_levels    = 1;
1756fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1757fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1758fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1759fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1760fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1761fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1762fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1763fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1764fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1765fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1766fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1767fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1768fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1769fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1770fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1771fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
177216d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
177316d9e3a6SLisandro Dalcin   }
17744cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
17754cb006feSStefano Zampini   if (flag) {
17764cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
17774cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
17784cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
17794cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
17804cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
17814cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
17824cb006feSStefano Zampini     jac->coords[0]           = NULL;
17834cb006feSStefano Zampini     jac->coords[1]           = NULL;
17844cb006feSStefano Zampini     jac->coords[2]           = NULL;
17854cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1786863406b8SStefano Zampini     jac->as_print           = 0;
1787863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1788863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
17894cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
17904cb006feSStefano Zampini     /* Smoothing options */
1791863406b8SStefano Zampini     jac->as_relax_type      = 2;
1792863406b8SStefano Zampini     jac->as_relax_times     = 1;
1793863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1794863406b8SStefano Zampini     jac->as_omega           = 1.0;
17954cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1796863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1797863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
17980bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1799863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1800863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1801863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
18024cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1803863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1804863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
18050bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1806863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1807863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1808863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1809863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1810863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
18114cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1812863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1813863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1814863406b8SStefano Zampini                                                                       jac->as_relax_times,
1815863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1816863406b8SStefano Zampini                                                                       jac->as_omega));
1817863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1818863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1819863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1820863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1821863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1822863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1823863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1824863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1825863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1826863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1827863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1828863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
182923df4f25SStefano Zampini     /* Zero conductivity */
183023df4f25SStefano Zampini     jac->ams_beta_is_zero      = PETSC_FALSE;
183123df4f25SStefano Zampini     jac->ams_beta_is_zero_part = PETSC_FALSE;
18324cb006feSStefano Zampini     PetscFunctionReturn(0);
18334cb006feSStefano Zampini   }
1834863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1835863406b8SStefano Zampini   if (flag) {
1836863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1837863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1838863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1839863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1840863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1841863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1842863406b8SStefano Zampini     jac->coords[0]           = NULL;
1843863406b8SStefano Zampini     jac->coords[1]           = NULL;
1844863406b8SStefano Zampini     jac->coords[2]           = NULL;
1845863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1846863406b8SStefano Zampini     jac->as_print           = 0;
1847863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1848863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1849863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1850863406b8SStefano Zampini     /* Smoothing options */
1851863406b8SStefano Zampini     jac->as_relax_type      = 2;
1852863406b8SStefano Zampini     jac->as_relax_times     = 1;
1853863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1854863406b8SStefano Zampini     jac->as_omega           = 1.0;
1855863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1856863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1857863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1858863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1859863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1860863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1861863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1862863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1863863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1864863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1865863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1866863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1867863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1868863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1869863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1870863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1871863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1872863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1873863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1874863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1875863406b8SStefano Zampini                                                                       jac->as_relax_times,
1876863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1877863406b8SStefano Zampini                                                                       jac->as_omega));
1878863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1879863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1880863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1881863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1882863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1883863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1884863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1885863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1886863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1887863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1888863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1889863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1890863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1891863406b8SStefano Zampini     PetscFunctionReturn(0);
1892863406b8SStefano Zampini   }
1893503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
18942fa5cd67SKarl Rupp 
18950298fd71SBarry Smith   jac->hypre_type = NULL;
1896db966c6cSHong Zhang   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams",name);
189716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
189816d9e3a6SLisandro Dalcin }
189916d9e3a6SLisandro Dalcin 
190016d9e3a6SLisandro Dalcin /*
190116d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
190216d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
190316d9e3a6SLisandro Dalcin */
19044416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc)
190516d9e3a6SLisandro Dalcin {
190616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
19074ddd07fcSJed Brown   PetscInt       indx;
1908db966c6cSHong Zhang   const char     *type[] = {"euclid","pilut","parasails","boomeramg","ams","ads"};
1909ace3abfcSBarry Smith   PetscBool      flg;
191016d9e3a6SLisandro Dalcin 
191116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
19129fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
19139c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
191416d9e3a6SLisandro Dalcin   if (flg) {
191516d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
191602a17cd4SBarry Smith   } else {
191702a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
191816d9e3a6SLisandro Dalcin   }
191916d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
19203931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
192116d9e3a6SLisandro Dalcin   }
192216d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
192316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
192416d9e3a6SLisandro Dalcin }
192516d9e3a6SLisandro Dalcin 
192616d9e3a6SLisandro Dalcin /*@C
192716d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
192816d9e3a6SLisandro Dalcin 
192916d9e3a6SLisandro Dalcin    Input Parameters:
193016d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1931db966c6cSHong Zhang -     name - either  euclid, pilut, parasails, boomeramg, ams, ads
193216d9e3a6SLisandro Dalcin 
193316d9e3a6SLisandro Dalcin    Options Database Keys:
1934db966c6cSHong Zhang    -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
193516d9e3a6SLisandro Dalcin 
193616d9e3a6SLisandro Dalcin    Level: intermediate
193716d9e3a6SLisandro Dalcin 
193816d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
193916d9e3a6SLisandro Dalcin            PCHYPRE
194016d9e3a6SLisandro Dalcin 
194116d9e3a6SLisandro Dalcin @*/
19427087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
194316d9e3a6SLisandro Dalcin {
19444ac538c5SBarry Smith   PetscErrorCode ierr;
194516d9e3a6SLisandro Dalcin 
194616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
19470700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
194816d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
19494ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
195016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
195116d9e3a6SLisandro Dalcin }
195216d9e3a6SLisandro Dalcin 
195316d9e3a6SLisandro Dalcin /*@C
195416d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
195516d9e3a6SLisandro Dalcin 
195616d9e3a6SLisandro Dalcin    Input Parameter:
195716d9e3a6SLisandro Dalcin .     pc - the preconditioner context
195816d9e3a6SLisandro Dalcin 
195916d9e3a6SLisandro Dalcin    Output Parameter:
1960db966c6cSHong Zhang .     name - either  euclid, pilut, parasails, boomeramg, ams, ads
196116d9e3a6SLisandro Dalcin 
196216d9e3a6SLisandro Dalcin    Level: intermediate
196316d9e3a6SLisandro Dalcin 
196416d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
196516d9e3a6SLisandro Dalcin            PCHYPRE
196616d9e3a6SLisandro Dalcin 
196716d9e3a6SLisandro Dalcin @*/
19687087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
196916d9e3a6SLisandro Dalcin {
19704ac538c5SBarry Smith   PetscErrorCode ierr;
197116d9e3a6SLisandro Dalcin 
197216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
19730700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
197416d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
19754ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
197616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
197716d9e3a6SLisandro Dalcin }
197816d9e3a6SLisandro Dalcin 
197916d9e3a6SLisandro Dalcin /*MC
198016d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
198116d9e3a6SLisandro Dalcin 
198216d9e3a6SLisandro Dalcin    Options Database Keys:
1983db966c6cSHong Zhang +   -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
198416d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
198516d9e3a6SLisandro Dalcin           preconditioner
198616d9e3a6SLisandro Dalcin 
198716d9e3a6SLisandro Dalcin    Level: intermediate
198816d9e3a6SLisandro Dalcin 
198995452b02SPatrick Sanan    Notes:
199095452b02SPatrick Sanan     Apart from pc_hypre_type (for which there is PCHYPRESetType()),
199116d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
199216d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
199316d9e3a6SLisandro Dalcin 
1994c231f9e3SBarryFSmith           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_tol refer to the number of iterations
19950f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
19960f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
1997c231f9e3SBarryFSmith           (-pc_hypre_boomeramg_tol should be set to 0.0 - the default - to strictly use a fixed number of
19988f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
19990f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
20000f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
200116d9e3a6SLisandro Dalcin 
20020f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
20030f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
20040f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
200516d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
200616d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
200716d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
200816d9e3a6SLisandro Dalcin 
200916d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
201016d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
201116d9e3a6SLisandro Dalcin 
20125272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
20135272c319SBarry Smith           the two options:
20145272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
2015cbc39033SBarry Smith -   -pc_hypre_boomeramg_vec_interp_variant <v> where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
20165272c319SBarry Smith 
20175272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
20185272c319SBarry Smith 
20199e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
20209e5bc791SBarry Smith 
202116d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
20229e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
202316d9e3a6SLisandro Dalcin 
202416d9e3a6SLisandro Dalcin M*/
202516d9e3a6SLisandro Dalcin 
20268cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
202716d9e3a6SLisandro Dalcin {
202816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
202916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
203016d9e3a6SLisandro Dalcin 
203116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
2032b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
20332fa5cd67SKarl Rupp 
203416d9e3a6SLisandro Dalcin   pc->data                = jac;
20358695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
203616d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
203716d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
203816d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
203916d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
204016d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
2041bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
2042bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
20435ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
20445ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
20455ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
20466bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",PCHYPRESetInterpolations_HYPRE);CHKERRQ(ierr);
20475ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE);CHKERRQ(ierr);
20485ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",PCHYPRESetPoissonMatrix_HYPRE);CHKERRQ(ierr);
204916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
205016d9e3a6SLisandro Dalcin }
2051ebc551c0SBarry Smith 
2052f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
2053f91d8e95SBarry Smith 
2054ebc551c0SBarry Smith typedef struct {
205568326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
2056f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
20579e5bc791SBarry Smith 
20589e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
20594ddd07fcSJed Brown   PetscInt its;
20609e5bc791SBarry Smith   double   tol;
20614ddd07fcSJed Brown   PetscInt relax_type;
20624ddd07fcSJed Brown   PetscInt rap_type;
20634ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
20644ddd07fcSJed Brown   PetscInt max_levels;
2065ebc551c0SBarry Smith } PC_PFMG;
2066ebc551c0SBarry Smith 
2067ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
2068ebc551c0SBarry Smith {
2069ebc551c0SBarry Smith   PetscErrorCode ierr;
2070f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2071ebc551c0SBarry Smith 
2072ebc551c0SBarry Smith   PetscFunctionBegin;
20732fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2074f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2075c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2076ebc551c0SBarry Smith   PetscFunctionReturn(0);
2077ebc551c0SBarry Smith }
2078ebc551c0SBarry Smith 
20799e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
20809e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
20819e5bc791SBarry Smith 
2082ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
2083ebc551c0SBarry Smith {
2084ebc551c0SBarry Smith   PetscErrorCode ierr;
2085ace3abfcSBarry Smith   PetscBool      iascii;
2086f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2087ebc551c0SBarry Smith 
2088ebc551c0SBarry Smith   PetscFunctionBegin;
2089251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
20909e5bc791SBarry Smith   if (iascii) {
20919e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
2092efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max iterations %d\n",ex->its);CHKERRQ(ierr);
2093efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    tolerance %g\n",ex->tol);CHKERRQ(ierr);
2094efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2095efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
2096efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2097efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max levels %d\n",ex->max_levels);CHKERRQ(ierr);
20989e5bc791SBarry Smith   }
2099ebc551c0SBarry Smith   PetscFunctionReturn(0);
2100ebc551c0SBarry Smith }
2101ebc551c0SBarry Smith 
21024416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2103ebc551c0SBarry Smith {
2104ebc551c0SBarry Smith   PetscErrorCode ierr;
2105f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2106ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2107ebc551c0SBarry Smith 
2108ebc551c0SBarry Smith   PetscFunctionBegin;
2109e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
21100298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
211168326731SBarry Smith   if (flg) {
2112a0324ebeSBarry Smith     int level=3;
2113fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
211468326731SBarry Smith   }
21150298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2116fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
21170298fd71SBarry 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);
2118fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
21190298fd71SBarry 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);
2120fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
21219e5bc791SBarry Smith 
21220298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
2123fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
21243b46a515SGlenn Hammond 
21250298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2126fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
21270298fd71SBarry 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);
2128fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
21290298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
2130fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
2131ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
2132ebc551c0SBarry Smith   PetscFunctionReturn(0);
2133ebc551c0SBarry Smith }
2134ebc551c0SBarry Smith 
2135f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
2136f91d8e95SBarry Smith {
2137f91d8e95SBarry Smith   PetscErrorCode    ierr;
2138f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
2139d9ca1df4SBarry Smith   PetscScalar       *yy;
2140d9ca1df4SBarry Smith   const PetscScalar *xx;
21414ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
214268326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2143f91d8e95SBarry Smith 
2144f91d8e95SBarry Smith   PetscFunctionBegin;
2145dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2146aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2147f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
2148f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
2149f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
2150f91d8e95SBarry Smith 
2151f91d8e95SBarry Smith   /* copy x values over to hypre */
2152fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
2153d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2154d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
2155d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2156fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
2157fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2158f91d8e95SBarry Smith 
2159f91d8e95SBarry Smith   /* copy solution values back to PETSc */
2160f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
21618b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
2162f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2163f91d8e95SBarry Smith   PetscFunctionReturn(0);
2164f91d8e95SBarry Smith }
2165f91d8e95SBarry Smith 
2166ace3abfcSBarry 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)
21679e5bc791SBarry Smith {
21689e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
21699e5bc791SBarry Smith   PetscErrorCode ierr;
21704ddd07fcSJed Brown   PetscInt       oits;
21719e5bc791SBarry Smith 
21729e5bc791SBarry Smith   PetscFunctionBegin;
2173dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2174fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
2175fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
21769e5bc791SBarry Smith 
21779e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
21788b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
21799e5bc791SBarry Smith   *outits = oits;
21809e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
21819e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2182fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
2183fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
21849e5bc791SBarry Smith   PetscFunctionReturn(0);
21859e5bc791SBarry Smith }
21869e5bc791SBarry Smith 
21879e5bc791SBarry Smith 
21883a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
21893a32d3dbSGlenn Hammond {
21903a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
21913a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
21923a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2193ace3abfcSBarry Smith   PetscBool       flg;
21943a32d3dbSGlenn Hammond 
21953a32d3dbSGlenn Hammond   PetscFunctionBegin;
2196251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
2197ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
21983a32d3dbSGlenn Hammond 
21993a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
22002fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2201fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2202fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2203fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
22043a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
22053a32d3dbSGlenn Hammond }
22063a32d3dbSGlenn Hammond 
2207ebc551c0SBarry Smith /*MC
2208ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
2209ebc551c0SBarry Smith 
2210ebc551c0SBarry Smith    Level: advanced
2211ebc551c0SBarry Smith 
22129e5bc791SBarry Smith    Options Database:
22139e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
22149e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
22159e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
22169e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
22179e5bc791SBarry 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
22189e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
2219f91d8e95SBarry Smith 
222095452b02SPatrick Sanan    Notes:
222195452b02SPatrick Sanan     This is for CELL-centered descretizations
22229e5bc791SBarry Smith 
22238e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
2224aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
22259e5bc791SBarry Smith 
22269e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
2227ebc551c0SBarry Smith M*/
2228ebc551c0SBarry Smith 
22298cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
2230ebc551c0SBarry Smith {
2231ebc551c0SBarry Smith   PetscErrorCode ierr;
2232ebc551c0SBarry Smith   PC_PFMG        *ex;
2233ebc551c0SBarry Smith 
2234ebc551c0SBarry Smith   PetscFunctionBegin;
2235b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
223668326731SBarry Smith   pc->data = ex;
2237ebc551c0SBarry Smith 
22389e5bc791SBarry Smith   ex->its            = 1;
22399e5bc791SBarry Smith   ex->tol            = 1.e-8;
22409e5bc791SBarry Smith   ex->relax_type     = 1;
22419e5bc791SBarry Smith   ex->rap_type       = 0;
22429e5bc791SBarry Smith   ex->num_pre_relax  = 1;
22439e5bc791SBarry Smith   ex->num_post_relax = 1;
22443b46a515SGlenn Hammond   ex->max_levels     = 0;
22459e5bc791SBarry Smith 
2246ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2247ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2248ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2249f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
22509e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
225168326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
22522fa5cd67SKarl Rupp 
2253ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2254fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2255ebc551c0SBarry Smith   PetscFunctionReturn(0);
2256ebc551c0SBarry Smith }
2257d851a50bSGlenn Hammond 
2258325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2259325fc9f4SBarry Smith 
2260d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2261d851a50bSGlenn Hammond typedef struct {
2262d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2263d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2264d851a50bSGlenn Hammond 
2265d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
22664ddd07fcSJed Brown   PetscInt its;
2267d851a50bSGlenn Hammond   double   tol;
22684ddd07fcSJed Brown   PetscInt relax_type;
22694ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2270d851a50bSGlenn Hammond } PC_SysPFMG;
2271d851a50bSGlenn Hammond 
2272d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2273d851a50bSGlenn Hammond {
2274d851a50bSGlenn Hammond   PetscErrorCode ierr;
2275d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2276d851a50bSGlenn Hammond 
2277d851a50bSGlenn Hammond   PetscFunctionBegin;
22782fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2279d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2280c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2281d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2282d851a50bSGlenn Hammond }
2283d851a50bSGlenn Hammond 
2284d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2285d851a50bSGlenn Hammond 
2286d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2287d851a50bSGlenn Hammond {
2288d851a50bSGlenn Hammond   PetscErrorCode ierr;
2289ace3abfcSBarry Smith   PetscBool      iascii;
2290d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2291d851a50bSGlenn Hammond 
2292d851a50bSGlenn Hammond   PetscFunctionBegin;
2293251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2294d851a50bSGlenn Hammond   if (iascii) {
2295d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2296efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  max iterations %d\n",ex->its);CHKERRQ(ierr);
2297efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerance %g\n",ex->tol);CHKERRQ(ierr);
2298efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2299efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2300d851a50bSGlenn Hammond   }
2301d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2302d851a50bSGlenn Hammond }
2303d851a50bSGlenn Hammond 
23044416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2305d851a50bSGlenn Hammond {
2306d851a50bSGlenn Hammond   PetscErrorCode ierr;
2307d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2308ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2309d851a50bSGlenn Hammond 
2310d851a50bSGlenn Hammond   PetscFunctionBegin;
2311e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
23120298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2313d851a50bSGlenn Hammond   if (flg) {
2314d851a50bSGlenn Hammond     int level=3;
2315fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
2316d851a50bSGlenn Hammond   }
23170298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2318fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
23190298fd71SBarry 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);
2320fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
23210298fd71SBarry 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);
2322fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2323d851a50bSGlenn Hammond 
23240298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2325fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
232661710fbeSStefano 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);
2327fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2328d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2329d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2330d851a50bSGlenn Hammond }
2331d851a50bSGlenn Hammond 
2332d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2333d851a50bSGlenn Hammond {
2334d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2335d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2336d9ca1df4SBarry Smith   PetscScalar       *yy;
2337d9ca1df4SBarry Smith   const PetscScalar *xx;
23384ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
2339d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
23404ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
23414ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
23424ddd07fcSJed Brown   PetscInt          part    = 0;
23434ddd07fcSJed Brown   PetscInt          size;
23444ddd07fcSJed Brown   PetscInt          i;
2345d851a50bSGlenn Hammond 
2346d851a50bSGlenn Hammond   PetscFunctionBegin;
2347dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2348aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2349d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2350d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2351d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2352d851a50bSGlenn Hammond 
2353d851a50bSGlenn Hammond   size = 1;
23542fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
23552fa5cd67SKarl Rupp 
2356d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2357d851a50bSGlenn Hammond   if (ordering) {
2358fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2359d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2360d9ca1df4SBarry 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)));
2361d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2362fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2363fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2364fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2365d851a50bSGlenn Hammond 
2366d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2367d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
23688b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2369d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2370a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2371d851a50bSGlenn Hammond     PetscScalar *z;
23724ddd07fcSJed Brown     PetscInt    j, k;
2373d851a50bSGlenn Hammond 
2374785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2375fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2376d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2377d851a50bSGlenn Hammond 
2378d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2379d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2380d851a50bSGlenn Hammond       k= i*nvars;
23812fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2382d851a50bSGlenn Hammond     }
23838b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2384d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2385fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2386fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2387d851a50bSGlenn Hammond 
2388d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2389d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
23908b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2391d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2392d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2393d851a50bSGlenn Hammond       k= i*nvars;
23942fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2395d851a50bSGlenn Hammond     }
2396d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2397d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2398d851a50bSGlenn Hammond   }
2399d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2400d851a50bSGlenn Hammond }
2401d851a50bSGlenn Hammond 
2402ace3abfcSBarry 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)
2403d851a50bSGlenn Hammond {
2404d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2405d851a50bSGlenn Hammond   PetscErrorCode ierr;
24064ddd07fcSJed Brown   PetscInt       oits;
2407d851a50bSGlenn Hammond 
2408d851a50bSGlenn Hammond   PetscFunctionBegin;
2409dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2410fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2411fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2412d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
24138b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2414d851a50bSGlenn Hammond   *outits = oits;
2415d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2416d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2417fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2418fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2419d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2420d851a50bSGlenn Hammond }
2421d851a50bSGlenn Hammond 
2422d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2423d851a50bSGlenn Hammond {
2424d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2425d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2426d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2427ace3abfcSBarry Smith   PetscBool        flg;
2428d851a50bSGlenn Hammond 
2429d851a50bSGlenn Hammond   PetscFunctionBegin;
2430251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2431ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2432d851a50bSGlenn Hammond 
2433d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
24342fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2435fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2436fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2437fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2438d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2439d851a50bSGlenn Hammond }
2440d851a50bSGlenn Hammond 
2441d851a50bSGlenn Hammond /*MC
2442d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2443d851a50bSGlenn Hammond 
2444d851a50bSGlenn Hammond    Level: advanced
2445d851a50bSGlenn Hammond 
2446d851a50bSGlenn Hammond    Options Database:
2447d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2448d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2449d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2450d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2451d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2452d851a50bSGlenn Hammond 
245395452b02SPatrick Sanan    Notes:
245495452b02SPatrick Sanan     This is for CELL-centered descretizations
2455d851a50bSGlenn Hammond 
2456f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2457aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2458d851a50bSGlenn Hammond            Also, only cell-centered variables.
2459d851a50bSGlenn Hammond 
2460d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2461d851a50bSGlenn Hammond M*/
2462d851a50bSGlenn Hammond 
24638cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2464d851a50bSGlenn Hammond {
2465d851a50bSGlenn Hammond   PetscErrorCode ierr;
2466d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2467d851a50bSGlenn Hammond 
2468d851a50bSGlenn Hammond   PetscFunctionBegin;
2469b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2470d851a50bSGlenn Hammond   pc->data = ex;
2471d851a50bSGlenn Hammond 
2472d851a50bSGlenn Hammond   ex->its            = 1;
2473d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2474d851a50bSGlenn Hammond   ex->relax_type     = 1;
2475d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2476d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2477d851a50bSGlenn Hammond 
2478d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2479d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2480d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2481d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2482d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2483d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
24842fa5cd67SKarl Rupp 
2485ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2486fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2487d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2488d851a50bSGlenn Hammond }
2489