xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 39accc25aaf2146529485bd135fab92bd3f3f926)
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;
35*39accc25SStefano Zampini   PetscReal tol;
3616d9e3a6SLisandro Dalcin 
3716d9e3a6SLisandro Dalcin   /* options for Pilut */
384ddd07fcSJed Brown   PetscInt factorrowsize;
3916d9e3a6SLisandro Dalcin 
4016d9e3a6SLisandro Dalcin   /* options for ParaSails */
414ddd07fcSJed Brown   PetscInt  nlevels;
42*39accc25SStefano Zampini   PetscReal threshhold;
43*39accc25SStefano Zampini   PetscReal filter;
444ddd07fcSJed Brown   PetscInt  sym;
45*39accc25SStefano Zampini   PetscReal 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;
56*39accc25SStefano Zampini   PetscReal strongthreshold;
57*39accc25SStefano Zampini   PetscReal 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 */
64*39accc25SStefano Zampini   PetscReal 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];
67*39accc25SStefano Zampini   PetscReal relaxweight;
68*39accc25SStefano Zampini   PetscReal outerrelaxweight;
694ddd07fcSJed Brown   PetscInt  relaxorder;
70*39accc25SStefano Zampini   PetscReal 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;
90*39accc25SStefano Zampini   HYPRE_Complex   **hmnull_hypre_data_array;   /* this is the space in hmnull that was allocated by hypre, it is restored to hypre just before freeing the phmnull vectors */
915272c319SBarry Smith 
92863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
93863406b8SStefano Zampini   PetscInt  as_print;
94863406b8SStefano Zampini   PetscInt  as_max_iter;
95863406b8SStefano Zampini   PetscReal as_tol;
96863406b8SStefano Zampini   PetscInt  as_relax_type;
97863406b8SStefano Zampini   PetscInt  as_relax_times;
98863406b8SStefano Zampini   PetscReal as_relax_weight;
99863406b8SStefano Zampini   PetscReal as_omega;
100863406b8SStefano Zampini   PetscInt  as_amg_alpha_opts[5]; /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for vector Poisson (AMS) or Curl problem (ADS) */
101863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
102863406b8SStefano Zampini   PetscInt  as_amg_beta_opts[5];  /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for scalar Poisson (AMS) or vector Poisson (ADS) */
103863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
1044cb006feSStefano Zampini   PetscInt  ams_cycle_type;
105863406b8SStefano Zampini   PetscInt  ads_cycle_type;
1064cb006feSStefano Zampini 
1074cb006feSStefano Zampini   /* additional data */
1085ac14e1cSStefano Zampini   Mat G;             /* MatHYPRE */
1095ac14e1cSStefano Zampini   Mat C;             /* MatHYPRE */
1105ac14e1cSStefano Zampini   Mat alpha_Poisson; /* MatHYPRE */
1115ac14e1cSStefano Zampini   Mat beta_Poisson;  /* MatHYPRE */
1125ac14e1cSStefano Zampini 
1135ac14e1cSStefano Zampini   /* extra information for AMS */
1145ac14e1cSStefano Zampini   PetscInt       dim; /* geometrical dimension */
1154cb006feSStefano Zampini   HYPRE_IJVector coords[3];
1164cb006feSStefano Zampini   HYPRE_IJVector constants[3];
1176bf688a0SCe Qin   Mat            RT_PiFull, RT_Pi[3];
1186bf688a0SCe Qin   Mat            ND_PiFull, ND_Pi[3];
1194cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
12023df4f25SStefano Zampini   PetscBool      ams_beta_is_zero_part;
12123df4f25SStefano Zampini   PetscInt       ams_proj_freq;
12216d9e3a6SLisandro Dalcin } PC_HYPRE;
12316d9e3a6SLisandro Dalcin 
124d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
125d2128fa2SBarry Smith {
126d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
127d2128fa2SBarry Smith 
128d2128fa2SBarry Smith   PetscFunctionBegin;
129d2128fa2SBarry Smith   *hsolver = jac->hsolver;
130d2128fa2SBarry Smith   PetscFunctionReturn(0);
131d2128fa2SBarry Smith }
13216d9e3a6SLisandro Dalcin 
133ce6a8a0dSJed Brown /* Resets (frees) Hypre's representation of the near null space */
134ce6a8a0dSJed Brown static PetscErrorCode PCHYPREResetNearNullSpace_Private(PC pc)
135ce6a8a0dSJed Brown {
136ce6a8a0dSJed Brown   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
137ce6a8a0dSJed Brown   PetscInt       i;
1389d678128SJed Brown   PetscErrorCode ierr;
139ce6a8a0dSJed Brown 
1409d678128SJed Brown   PetscFunctionBegin;
141ce6a8a0dSJed Brown   for (i=0; i<jac->n_hmnull; i++) {
142*39accc25SStefano Zampini     PETSC_UNUSED HYPRE_Complex *harray;
143*39accc25SStefano Zampini     VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],jac->hmnull_hypre_data_array[i],harray);
144ce6a8a0dSJed Brown     PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->hmnull[i]));
145ce6a8a0dSJed Brown   }
146ce6a8a0dSJed Brown   ierr = PetscFree(jac->hmnull);CHKERRQ(ierr);
147ce6a8a0dSJed Brown   ierr = PetscFree(jac->hmnull_hypre_data_array);CHKERRQ(ierr);
148ce6a8a0dSJed Brown   ierr = PetscFree(jac->phmnull);CHKERRQ(ierr);
149ce6a8a0dSJed Brown   ierr = VecDestroy(&jac->hmnull_constant);CHKERRQ(ierr);
1509d678128SJed Brown   jac->n_hmnull = 0;
151ce6a8a0dSJed Brown   PetscFunctionReturn(0);
152ce6a8a0dSJed Brown }
153ce6a8a0dSJed Brown 
15416d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
15516d9e3a6SLisandro Dalcin {
15616d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
15749a781f5SStefano Zampini   Mat_HYPRE          *hjac;
15816d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
15916d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
16049a781f5SStefano Zampini   PetscBool          ishypre;
16149a781f5SStefano Zampini   PetscErrorCode     ierr;
16216d9e3a6SLisandro Dalcin 
16316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16416d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
16502a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
16616d9e3a6SLisandro Dalcin   }
1675f5c5b43SBarry Smith 
16849a781f5SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRE,&ishypre);CHKERRQ(ierr);
16949a781f5SStefano Zampini   if (!ishypre) {
1706bf688a0SCe Qin     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
1716bf688a0SCe Qin     ierr = MatConvert(pc->pmat,MATHYPRE,MAT_INITIAL_MATRIX,&jac->hpmat);CHKERRQ(ierr);
17249a781f5SStefano Zampini   } else {
17349a781f5SStefano Zampini     ierr = PetscObjectReference((PetscObject)pc->pmat);CHKERRQ(ierr);
17449a781f5SStefano Zampini     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
17549a781f5SStefano Zampini     jac->hpmat = pc->pmat;
17616d9e3a6SLisandro Dalcin   }
17749a781f5SStefano Zampini   hjac = (Mat_HYPRE*)(jac->hpmat->data);
1785f5c5b43SBarry Smith 
17916d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
18016d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
1815272c319SBarry Smith     MatNullSpace    mnull;
1825272c319SBarry Smith     PetscBool       has_const;
18349a781f5SStefano Zampini     PetscInt        bs,nvec,i;
1845272c319SBarry Smith     const Vec       *vecs;
185*39accc25SStefano Zampini     HYPRE_Complex   *petscvecarray;
1865272c319SBarry Smith 
18716d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1882fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
1895272c319SBarry Smith     ierr = MatGetNearNullSpace(pc->mat, &mnull);CHKERRQ(ierr);
1905272c319SBarry Smith     if (mnull) {
191ce6a8a0dSJed Brown       ierr = PCHYPREResetNearNullSpace_Private(pc);CHKERRQ(ierr);
1925272c319SBarry Smith       ierr = MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs);CHKERRQ(ierr);
1935272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull);CHKERRQ(ierr);
19472827435SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull_hypre_data_array);CHKERRQ(ierr);
1955272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->phmnull);CHKERRQ(ierr);
1965272c319SBarry Smith       for (i=0; i<nvec; i++) {
1975272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(vecs[i],&jac->hmnull[i]);CHKERRQ(ierr);
19872827435SBarry Smith         ierr = VecGetArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
19958968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],petscvecarray,jac->hmnull_hypre_data_array[i]);
20072827435SBarry Smith         ierr = VecRestoreArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
2015272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[i],(void**)&jac->phmnull[i]));
2025272c319SBarry Smith       }
2035272c319SBarry Smith       if (has_const) {
2045272c319SBarry Smith         ierr = MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL);CHKERRQ(ierr);
2055272c319SBarry Smith         ierr = VecSet(jac->hmnull_constant,1);CHKERRQ(ierr);
2065272c319SBarry Smith         ierr = VecNormalize(jac->hmnull_constant,NULL);
2075272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(jac->hmnull_constant,&jac->hmnull[nvec]);CHKERRQ(ierr);
20872827435SBarry Smith         ierr = VecGetArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
20958968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[nvec],petscvecarray,jac->hmnull_hypre_data_array[nvec]);
21072827435SBarry Smith         ierr = VecRestoreArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
2115272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[nvec],(void**)&jac->phmnull[nvec]));
2125272c319SBarry Smith         nvec++;
2135272c319SBarry Smith       }
2145272c319SBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVectors,(jac->hsolver,nvec,jac->phmnull));
2155272c319SBarry Smith       jac->n_hmnull = nvec;
2165272c319SBarry Smith     }
2174cb006feSStefano Zampini   }
218863406b8SStefano Zampini 
2194cb006feSStefano Zampini   /* special case for AMS */
2204cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
2215ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2225ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
2236bf688a0SCe Qin     if (!jac->coords[0] && !jac->constants[0] && !(jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
2246bf688a0SCe Qin       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the edge constant vectors via PCHYPRESetEdgeConstantVectors() or the interpolation matrix via PCHYPRESetInterpolations");
2256bf688a0SCe Qin     }
2265ac14e1cSStefano Zampini     if (jac->dim) {
2275ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,jac->dim));
2285ac14e1cSStefano Zampini     }
2295ac14e1cSStefano Zampini     if (jac->constants[0]) {
2305ac14e1cSStefano Zampini       HYPRE_ParVector ozz,zoz,zzo = NULL;
2315ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&ozz)));
2325ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&zoz)));
2335ac14e1cSStefano Zampini       if (jac->constants[2]) {
2345ac14e1cSStefano Zampini         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&zzo)));
2355ac14e1cSStefano Zampini       }
2365ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,ozz,zoz,zzo));
2375ac14e1cSStefano Zampini     }
2385ac14e1cSStefano Zampini     if (jac->coords[0]) {
2395ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
2405ac14e1cSStefano Zampini       coords[0] = NULL;
2415ac14e1cSStefano Zampini       coords[1] = NULL;
2425ac14e1cSStefano Zampini       coords[2] = NULL;
2435ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
2445ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
2455ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
2465ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
2475ac14e1cSStefano Zampini     }
24849a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
2495ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
2505ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2515ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr));
2525ac14e1cSStefano Zampini     if (jac->alpha_Poisson) {
2535ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->alpha_Poisson->data);
2545ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2555ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr));
2565ac14e1cSStefano Zampini     }
2575ac14e1cSStefano Zampini     if (jac->ams_beta_is_zero) {
2585ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
2595ac14e1cSStefano Zampini     } else if (jac->beta_Poisson) {
2605ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->beta_Poisson->data);
2615ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2625ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr));
2635ac14e1cSStefano Zampini     }
2646bf688a0SCe Qin     if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) {
2656bf688a0SCe Qin       PetscInt           i;
2666bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
2676bf688a0SCe Qin       if (jac->ND_PiFull) {
2686bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
2696bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
2706bf688a0SCe Qin       } else {
2716bf688a0SCe Qin         nd_parcsrfull = NULL;
2726bf688a0SCe Qin       }
2736bf688a0SCe Qin       for (i=0;i<3;++i) {
2746bf688a0SCe Qin         if (jac->ND_Pi[i]) {
2756bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
2766bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
2776bf688a0SCe Qin         } else {
2786bf688a0SCe Qin           nd_parcsr[i] = NULL;
2796bf688a0SCe Qin         }
2806bf688a0SCe Qin       }
2816bf688a0SCe Qin       PetscStackCallStandard(HYPRE_AMSSetInterpolations,(jac->hsolver,nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]));
2826bf688a0SCe Qin     }
2834cb006feSStefano Zampini   }
284863406b8SStefano Zampini   /* special case for ADS */
285863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
2865ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2875ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
2886bf688a0SCe Qin     if (!jac->coords[0] && !((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])))) {
2896bf688a0SCe Qin       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations");
2906bf688a0SCe Qin     }
29137096e45SBarry Smith     else if (!jac->coords[1] || !jac->coords[2]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner has been designed for three dimensional problems! For two dimensional problems, use HYPRE AMS instead");
29249a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
29349a781f5SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient");
2945ac14e1cSStefano Zampini     if (jac->coords[0]) {
2955ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
2965ac14e1cSStefano Zampini       coords[0] = NULL;
2975ac14e1cSStefano Zampini       coords[1] = NULL;
2985ac14e1cSStefano Zampini       coords[2] = NULL;
2995ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
3005ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
3015ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
3025ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_ADSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
3035ac14e1cSStefano Zampini     }
3045ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
3055ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3065ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteGradient,(jac->hsolver,parcsr));
3075ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->C->data);
3085ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3095ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteCurl,(jac->hsolver,parcsr));
3106bf688a0SCe Qin     if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
3116bf688a0SCe Qin       PetscInt           i;
3126bf688a0SCe Qin       HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3];
3136bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
3146bf688a0SCe Qin       if (jac->RT_PiFull) {
3156bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->RT_PiFull->data);
3166bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsrfull)));
3176bf688a0SCe Qin       } else {
3186bf688a0SCe Qin         rt_parcsrfull = NULL;
3196bf688a0SCe Qin       }
3206bf688a0SCe Qin       for (i=0;i<3;++i) {
3216bf688a0SCe Qin         if (jac->RT_Pi[i]) {
3226bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->RT_Pi[i]->data);
3236bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsr[i])));
3246bf688a0SCe Qin         } else {
3256bf688a0SCe Qin           rt_parcsr[i] = NULL;
3266bf688a0SCe Qin         }
3276bf688a0SCe Qin       }
3286bf688a0SCe Qin       if (jac->ND_PiFull) {
3296bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
3306bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
3316bf688a0SCe Qin       } else {
3326bf688a0SCe Qin         nd_parcsrfull = NULL;
3336bf688a0SCe Qin       }
3346bf688a0SCe Qin       for (i=0;i<3;++i) {
3356bf688a0SCe Qin         if (jac->ND_Pi[i]) {
3366bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
3376bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
3386bf688a0SCe Qin         } else {
3396bf688a0SCe Qin           nd_parcsr[i] = NULL;
3406bf688a0SCe Qin         }
3416bf688a0SCe Qin       }
3426bf688a0SCe Qin       PetscStackCallStandard(HYPRE_ADSSetInterpolations,(jac->hsolver,rt_parcsrfull,rt_parcsr[0],rt_parcsr[1],rt_parcsr[2],nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]));
3436bf688a0SCe Qin     }
344863406b8SStefano Zampini   }
34549a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
34649a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&bv));
34749a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&xv));
34822e51d31SStefano Zampini   PetscStackCallStandard(jac->setup,(jac->hsolver,hmat,bv,xv));
34916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
35016d9e3a6SLisandro Dalcin }
35116d9e3a6SLisandro Dalcin 
35216d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
35316d9e3a6SLisandro Dalcin {
35416d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
35549a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
35616d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
35716d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
358*39accc25SStefano Zampini   HYPRE_Complex      *xv,*sxv;
359*39accc25SStefano Zampini   HYPRE_Complex      *bv,*sbv;
36016d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
3614ddd07fcSJed Brown   PetscInt           hierr;
36216d9e3a6SLisandro Dalcin 
36316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
364dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
36516d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
366*39accc25SStefano Zampini   ierr = VecGetArrayRead(b,(const PetscScalar **)&bv);CHKERRQ(ierr);
367*39accc25SStefano Zampini   ierr = VecGetArray(x,(PetscScalar **)&xv);CHKERRQ(ierr);
368*39accc25SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,bv,sbv);
36958968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
37016d9e3a6SLisandro Dalcin 
37149a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
37249a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
37349a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
374fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
37565e19b50SBarry Smith   if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
376fd3f9acdSBarry Smith   if (hierr) hypre__global_error = 0;);
37716d9e3a6SLisandro Dalcin 
37823df4f25SStefano Zampini   if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) {
3795ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSProjectOutGradients,(jac->hsolver,jxv));
38021df291bSStefano Zampini   }
381*39accc25SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,sbv,bv);
38258968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
383*39accc25SStefano Zampini   ierr = VecRestoreArray(x,(PetscScalar **)&xv);CHKERRQ(ierr);
384*39accc25SStefano Zampini   ierr = VecRestoreArrayRead(b,(const PetscScalar **)&bv);CHKERRQ(ierr);
38516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
38616d9e3a6SLisandro Dalcin }
38716d9e3a6SLisandro Dalcin 
3888695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc)
3898695de01SBarry Smith {
3908695de01SBarry Smith   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
3918695de01SBarry Smith   PetscErrorCode ierr;
3928695de01SBarry Smith 
3938695de01SBarry Smith   PetscFunctionBegin;
39449a781f5SStefano Zampini   ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
3955ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
3965ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
3975ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
3985ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
3996bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
4006bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[0]);CHKERRQ(ierr);
4016bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[1]);CHKERRQ(ierr);
4026bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[2]);CHKERRQ(ierr);
4036bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
4046bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[0]);CHKERRQ(ierr);
4056bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[1]);CHKERRQ(ierr);
4066bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[2]);CHKERRQ(ierr);
4078695de01SBarry Smith   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); jac->coords[0] = NULL;
4088695de01SBarry Smith   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); jac->coords[1] = NULL;
4098695de01SBarry Smith   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); jac->coords[2] = NULL;
4108695de01SBarry Smith   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); jac->constants[0] = NULL;
4118695de01SBarry Smith   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); jac->constants[1] = NULL;
4128695de01SBarry Smith   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); jac->constants[2] = NULL;
413ce6a8a0dSJed Brown   ierr = PCHYPREResetNearNullSpace_Private(pc);CHKERRQ(ierr);
4145ac14e1cSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
4155ac14e1cSStefano Zampini   jac->dim = 0;
4168695de01SBarry Smith   PetscFunctionReturn(0);
4178695de01SBarry Smith }
4188695de01SBarry Smith 
41916d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
42016d9e3a6SLisandro Dalcin {
42116d9e3a6SLisandro Dalcin   PC_HYPRE                 *jac = (PC_HYPRE*)pc->data;
42216d9e3a6SLisandro Dalcin   PetscErrorCode           ierr;
42316d9e3a6SLisandro Dalcin 
42416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
4258695de01SBarry Smith   ierr = PCReset_HYPRE(pc);CHKERRQ(ierr);
42622e51d31SStefano Zampini   if (jac->destroy) PetscStackCallStandard(jac->destroy,(jac->hsolver));
427503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
42816d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
429c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
43016d9e3a6SLisandro Dalcin 
43116d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
432bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
433bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
4344cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
4354cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
436863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
4376bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",NULL);CHKERRQ(ierr);
4384cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
4395ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",NULL);CHKERRQ(ierr);
44016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
44116d9e3a6SLisandro Dalcin }
44216d9e3a6SLisandro Dalcin 
44316d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
4444416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptionItems *PetscOptionsObject,PC pc)
44516d9e3a6SLisandro Dalcin {
44616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
44716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
448ace3abfcSBarry Smith   PetscBool      flag;
44916d9e3a6SLisandro Dalcin 
45016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
451e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
45216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
453fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
45416d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
455fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
45616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
457fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
45816d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
45916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
46016d9e3a6SLisandro Dalcin }
46116d9e3a6SLisandro Dalcin 
46216d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
46316d9e3a6SLisandro Dalcin {
46416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
46516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
466ace3abfcSBarry Smith   PetscBool      iascii;
46716d9e3a6SLisandro Dalcin 
46816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
469251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
47016d9e3a6SLisandro Dalcin   if (iascii) {
47116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
47216d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
473efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
47416d9e3a6SLisandro Dalcin     } else {
475efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default maximum number of iterations \n");CHKERRQ(ierr);
47616d9e3a6SLisandro Dalcin     }
47716d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
478efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
47916d9e3a6SLisandro Dalcin     } else {
480efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default drop tolerance \n");CHKERRQ(ierr);
48116d9e3a6SLisandro Dalcin     }
48216d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
483efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
48416d9e3a6SLisandro Dalcin     } else {
485efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default factor row size \n");CHKERRQ(ierr);
48616d9e3a6SLisandro Dalcin     }
48716d9e3a6SLisandro Dalcin   }
48816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
48916d9e3a6SLisandro Dalcin }
49016d9e3a6SLisandro Dalcin 
49116d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
492db966c6cSHong Zhang static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PetscOptionItems *PetscOptionsObject,PC pc)
493db966c6cSHong Zhang {
494db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
495db966c6cSHong Zhang   PetscErrorCode ierr;
496db966c6cSHong Zhang   PetscBool      flag;
497db966c6cSHong Zhang 
498db966c6cSHong Zhang   PetscFunctionBegin;
499db966c6cSHong Zhang   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Euclid Options");CHKERRQ(ierr);
500db966c6cSHong Zhang   ierr = PetscOptionsInt("-pc_hypre_euclid_level","Factorization levels","None",jac->eu_level,&jac->eu_level,&flag);CHKERRQ(ierr);
501db966c6cSHong Zhang   if (flag) PetscStackCallStandard(HYPRE_EuclidSetLevel,(jac->hsolver,jac->eu_level));
502db966c6cSHong Zhang   ierr = PetscOptionsTail();CHKERRQ(ierr);
503db966c6cSHong Zhang   PetscFunctionReturn(0);
504db966c6cSHong Zhang }
505db966c6cSHong Zhang 
506db966c6cSHong Zhang static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer)
507db966c6cSHong Zhang {
508db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
509db966c6cSHong Zhang   PetscErrorCode ierr;
510db966c6cSHong Zhang   PetscBool      iascii;
511db966c6cSHong Zhang 
512db966c6cSHong Zhang   PetscFunctionBegin;
513db966c6cSHong Zhang   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
514db966c6cSHong Zhang   if (iascii) {
515db966c6cSHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid preconditioning\n");CHKERRQ(ierr);
516db966c6cSHong Zhang     if (jac->eu_level != PETSC_DEFAULT) {
517db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    factorization levels %d\n",jac->eu_level);CHKERRQ(ierr);
518db966c6cSHong Zhang     } else {
519db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    default factorization levels \n");CHKERRQ(ierr);
520db966c6cSHong Zhang     }
521db966c6cSHong Zhang   }
522db966c6cSHong Zhang   PetscFunctionReturn(0);
523db966c6cSHong Zhang }
524db966c6cSHong Zhang 
525db966c6cSHong Zhang /* --------------------------------------------------------------------------------------------*/
52616d9e3a6SLisandro Dalcin 
52716d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
52816d9e3a6SLisandro Dalcin {
52916d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
53049a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
53116d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
53216d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
533*39accc25SStefano Zampini   HYPRE_Complex      *xv,*bv;
534*39accc25SStefano Zampini   HYPRE_Complex      *sbv,*sxv;
53516d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
5364ddd07fcSJed Brown   PetscInt           hierr;
53716d9e3a6SLisandro Dalcin 
53816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
539dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
54016d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
541*39accc25SStefano Zampini   ierr = VecGetArrayRead(b,(const PetscScalar**)&bv);CHKERRQ(ierr);
542*39accc25SStefano Zampini   ierr = VecGetArray(x,(PetscScalar**)&xv);CHKERRQ(ierr);
543*39accc25SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,bv,sbv);
54458968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
54516d9e3a6SLisandro Dalcin 
54649a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
54749a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
54849a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
54916d9e3a6SLisandro Dalcin 
55016d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
55116d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
552e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
55316d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
55416d9e3a6SLisandro Dalcin 
55558968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,sbv,bv);
55658968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
557*39accc25SStefano Zampini   ierr = VecRestoreArray(x,(PetscScalar**)&xv);CHKERRQ(ierr);
558*39accc25SStefano Zampini   ierr = VecRestoreArrayRead(b,(const PetscScalar**)&bv);CHKERRQ(ierr);
55916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
56016d9e3a6SLisandro Dalcin }
56116d9e3a6SLisandro Dalcin 
562a669f990SJed Brown /* static array length */
563a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
564a669f990SJed Brown 
56516d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
5660f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
56716d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
56865de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
5696a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]   = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
57065de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
57165de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
57265de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
5737b7fa87dSPierre Jolivet                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "l1-Gauss-Seidel" /* nonsymmetric */, "backward-l1-Gauss-Seidel" /* nonsymmetric */,
57465de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
5750f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
576e2287abbSStefano Zampini                                                   "ext+i-cc", "standard", "standard-wts", "block", "block-wtd", "FF", "FF1"};
5774416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc)
57816d9e3a6SLisandro Dalcin {
57916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
58016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
58122e51d31SStefano Zampini   PetscInt       bs,n,indx,level;
582ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
58316d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
58416d9e3a6SLisandro Dalcin 
58516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
586e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
5874336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
58816d9e3a6SLisandro Dalcin   if (flg) {
5894336a9eeSBarry Smith     jac->cycletype = indx+1;
590fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
59116d9e3a6SLisandro Dalcin   }
59216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
59316d9e3a6SLisandro Dalcin   if (flg) {
594ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
595fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
59616d9e3a6SLisandro Dalcin   }
59716d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
59816d9e3a6SLisandro Dalcin   if (flg) {
599ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
600fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
60116d9e3a6SLisandro Dalcin   }
602*39accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_tol","Convergence tolerance PER hypre call (0.0 = use a fixed number of iterations)","None",jac->tol,&jac->tol,&flg);CHKERRQ(ierr);
60316d9e3a6SLisandro Dalcin   if (flg) {
60457622a8eSBarry 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);
605fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
60616d9e3a6SLisandro Dalcin   }
60722e51d31SStefano Zampini   bs = 1;
60822e51d31SStefano Zampini   if (pc->pmat) {
60922e51d31SStefano Zampini     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
61022e51d31SStefano Zampini   }
61122e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_numfunctions","Number of functions","HYPRE_BoomerAMGSetNumFunctions",bs,&bs,&flg);CHKERRQ(ierr);
61222e51d31SStefano Zampini   if (flg) {
61322e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
61422e51d31SStefano Zampini   }
61516d9e3a6SLisandro Dalcin 
616*39accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
61716d9e3a6SLisandro Dalcin   if (flg) {
61857622a8eSBarry 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);
619fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
62016d9e3a6SLisandro Dalcin   }
62116d9e3a6SLisandro Dalcin 
6220f1074feSSatish 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);
6230f1074feSSatish Balay   if (flg) {
62457622a8eSBarry 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);
625fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
6260f1074feSSatish Balay   }
6270f1074feSSatish Balay 
6280f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
6290f1074feSSatish Balay   if (flg) {
63057622a8eSBarry 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);
6310f1074feSSatish Balay 
632fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
6330f1074feSSatish Balay   }
6340f1074feSSatish Balay 
6350f1074feSSatish 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);
6360f1074feSSatish Balay   if (flg) {
63757622a8eSBarry 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);
6380f1074feSSatish Balay 
639fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
6400f1074feSSatish Balay   }
6410f1074feSSatish Balay 
6420f1074feSSatish Balay 
643*39accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
64416d9e3a6SLisandro Dalcin   if (flg) {
64557622a8eSBarry 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);
646fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
64716d9e3a6SLisandro Dalcin   }
648*39accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
64916d9e3a6SLisandro Dalcin   if (flg) {
65057622a8eSBarry 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);
65157622a8eSBarry 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);
652fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
65316d9e3a6SLisandro Dalcin   }
65416d9e3a6SLisandro Dalcin 
65516d9e3a6SLisandro Dalcin   /* Grid sweeps */
6560f1074feSSatish 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);
65716d9e3a6SLisandro Dalcin   if (flg) {
658fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
65916d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
66016d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
6610f1074feSSatish Balay     jac->gridsweeps[1] = indx;
6620f1074feSSatish Balay     /*defaults coarse to 1 */
6630f1074feSSatish Balay     jac->gridsweeps[2] = 1;
66416d9e3a6SLisandro Dalcin   }
6655272c319SBarry 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);
6665272c319SBarry Smith   if (flg) {
6675272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,jac->nodal_coarsening));
6685272c319SBarry Smith   }
66922e51d31SStefano 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);
67022e51d31SStefano Zampini   if (flg) {
67122e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNodalDiag,(jac->hsolver,jac->nodal_coarsening_diag));
67222e51d31SStefano Zampini   }
673cbc39033SBarry 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);
6745272c319SBarry Smith   if (flg) {
6755272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,(jac->hsolver,jac->vec_interp_variant));
6765272c319SBarry Smith   }
67722e51d31SStefano 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);
67822e51d31SStefano Zampini   if (flg) {
67922e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecQMax,(jac->hsolver,jac->vec_interp_qmax));
68022e51d31SStefano Zampini   }
68122e51d31SStefano 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);
68222e51d31SStefano Zampini   if (flg) {
68322e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothInterpVectors,(jac->hsolver,jac->vec_interp_smooth));
68422e51d31SStefano Zampini   }
68522e51d31SStefano 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);
68622e51d31SStefano Zampini   if (flg) {
68722e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpRefine,(jac->hsolver,jac->interp_refine));
68822e51d31SStefano Zampini   }
6890f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
69016d9e3a6SLisandro Dalcin   if (flg) {
691fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
6920f1074feSSatish Balay     jac->gridsweeps[0] = indx;
69316d9e3a6SLisandro Dalcin   }
69416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
69516d9e3a6SLisandro Dalcin   if (flg) {
696fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
6970f1074feSSatish Balay     jac->gridsweeps[1] = indx;
69816d9e3a6SLisandro Dalcin   }
6990f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
70016d9e3a6SLisandro Dalcin   if (flg) {
701fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
7020f1074feSSatish Balay     jac->gridsweeps[2] = indx;
70316d9e3a6SLisandro Dalcin   }
70416d9e3a6SLisandro Dalcin 
7056a251517SEike Mueller   /* Smooth type */
7066a251517SEike Mueller   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);
7076a251517SEike Mueller   if (flg) {
7086a251517SEike Mueller     jac->smoothtype = indx;
7096a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
7108131ecf7SEike Mueller     jac->smoothnumlevels = 25;
7118131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
7128131ecf7SEike Mueller   }
7138131ecf7SEike Mueller 
7148131ecf7SEike Mueller   /* Number of smoothing levels */
7158131ecf7SEike 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);
7168131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
7178131ecf7SEike Mueller     jac->smoothnumlevels = indx;
7188131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
7196a251517SEike Mueller   }
7206a251517SEike Mueller 
7211810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
7221810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
7231810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
7241810e44eSEike Mueller     jac->eu_level = indx;
7251810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
7261810e44eSEike Mueller   }
7271810e44eSEike Mueller 
7281810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
7291810e44eSEike Mueller   double droptolerance;
730*39accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
7311810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
7321810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
7331810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
7341810e44eSEike Mueller   }
7351810e44eSEike Mueller 
7361810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
7371810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
7381810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
7391810e44eSEike Mueller     jac->eu_bj = tmp_truth;
740493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
7411810e44eSEike Mueller   }
7421810e44eSEike Mueller 
74316d9e3a6SLisandro Dalcin   /* Relax type */
744a669f990SJed 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);
74516d9e3a6SLisandro Dalcin   if (flg) {
7460f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
747fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
7480f1074feSSatish Balay     /* by default, coarse type set to 9 */
7490f1074feSSatish Balay     jac->relaxtype[2] = 9;
750ddbeb582SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, 9, 3));
75116d9e3a6SLisandro Dalcin   }
752a669f990SJed 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);
75316d9e3a6SLisandro Dalcin   if (flg) {
75416d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
755fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
75616d9e3a6SLisandro Dalcin   }
757a669f990SJed 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);
75816d9e3a6SLisandro Dalcin   if (flg) {
7590f1074feSSatish Balay     jac->relaxtype[1] = indx;
760fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
76116d9e3a6SLisandro Dalcin   }
762a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
76316d9e3a6SLisandro Dalcin   if (flg) {
7640f1074feSSatish Balay     jac->relaxtype[2] = indx;
765fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
76616d9e3a6SLisandro Dalcin   }
76716d9e3a6SLisandro Dalcin 
76816d9e3a6SLisandro Dalcin   /* Relaxation Weight */
76916d9e3a6SLisandro 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);
77016d9e3a6SLisandro Dalcin   if (flg) {
771fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
77216d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
77316d9e3a6SLisandro Dalcin   }
77416d9e3a6SLisandro Dalcin 
77516d9e3a6SLisandro Dalcin   n         = 2;
77616d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
77716d9e3a6SLisandro 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);
77816d9e3a6SLisandro Dalcin   if (flg) {
77916d9e3a6SLisandro Dalcin     if (n == 2) {
78016d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
781fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
782ce94432eSBarry 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);
78316d9e3a6SLisandro Dalcin   }
78416d9e3a6SLisandro Dalcin 
78516d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
78616d9e3a6SLisandro 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);
78716d9e3a6SLisandro Dalcin   if (flg) {
788fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
78916d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
79016d9e3a6SLisandro Dalcin   }
79116d9e3a6SLisandro Dalcin 
79216d9e3a6SLisandro Dalcin   n         = 2;
79316d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
79416d9e3a6SLisandro 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);
79516d9e3a6SLisandro Dalcin   if (flg) {
79616d9e3a6SLisandro Dalcin     if (n == 2) {
79716d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
798fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
799ce94432eSBarry 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);
80016d9e3a6SLisandro Dalcin   }
80116d9e3a6SLisandro Dalcin 
80216d9e3a6SLisandro Dalcin   /* the Relax Order */
803acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
80416d9e3a6SLisandro Dalcin 
8058afaa268SBarry Smith   if (flg && tmp_truth) {
80616d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
807fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
80816d9e3a6SLisandro Dalcin   }
809a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
81016d9e3a6SLisandro Dalcin   if (flg) {
81116d9e3a6SLisandro Dalcin     jac->measuretype = indx;
812fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
81316d9e3a6SLisandro Dalcin   }
8140f1074feSSatish Balay   /* update list length 3/07 */
815a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
81616d9e3a6SLisandro Dalcin   if (flg) {
81716d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
818fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
81916d9e3a6SLisandro Dalcin   }
8200f1074feSSatish Balay 
8210f1074feSSatish Balay   /* new 3/07 */
822a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
8230f1074feSSatish Balay   if (flg) {
8240f1074feSSatish Balay     jac->interptype = indx;
825fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
8260f1074feSSatish Balay   }
8270f1074feSSatish Balay 
828b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
82916d9e3a6SLisandro Dalcin   if (flg) {
830b96a4a96SBarry Smith     level = 3;
8310298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
8322fa5cd67SKarl Rupp 
833b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
834fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
8352ae77aedSBarry Smith   }
8362ae77aedSBarry Smith 
837b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
8382ae77aedSBarry Smith   if (flg) {
839b96a4a96SBarry Smith     level = 3;
8400298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
8412fa5cd67SKarl Rupp 
842b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
843fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
84416d9e3a6SLisandro Dalcin   }
8458f87f92bSBarry Smith 
846acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
8478f87f92bSBarry Smith   if (flg && tmp_truth) {
8488f87f92bSBarry Smith     PetscInt tmp_int;
8498f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
8508f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
851fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
852fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
853fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
854fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
8558f87f92bSBarry Smith   }
8568f87f92bSBarry Smith 
85716d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
85816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
85916d9e3a6SLisandro Dalcin }
86016d9e3a6SLisandro Dalcin 
861ace3abfcSBarry 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)
86216d9e3a6SLisandro Dalcin {
86316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
86416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
8652cf14000SStefano Zampini   HYPRE_Int      oits;
86616d9e3a6SLisandro Dalcin 
86716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
868dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
869fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
870fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
87116d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
87216d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
87316d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
8742cf14000SStefano Zampini   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,&oits));
8754d0a8057SBarry Smith   *outits = oits;
8764d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
8774d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
878fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
879fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
88016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
88116d9e3a6SLisandro Dalcin }
88216d9e3a6SLisandro Dalcin 
88316d9e3a6SLisandro Dalcin 
88416d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
88516d9e3a6SLisandro Dalcin {
88616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
88716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
888ace3abfcSBarry Smith   PetscBool      iascii;
88916d9e3a6SLisandro Dalcin 
89016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
891251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
89216d9e3a6SLisandro Dalcin   if (iascii) {
89316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
894efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
89522e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of levels %D\n",jac->maxlevels);CHKERRQ(ierr);
89622e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of iterations PER hypre call %D\n",jac->maxiter);CHKERRQ(ierr);
897efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
898efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
899efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
90022e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: max elements per row %D\n",jac->pmax);CHKERRQ(ierr);
90122e51d31SStefano Zampini     if (jac->interp_refine) {
90222e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: number of steps of weighted refinement %D\n",jac->interp_refine);CHKERRQ(ierr);
90322e51d31SStefano Zampini     }
90422e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of levels of aggressive coarsening %D\n",jac->agg_nl);CHKERRQ(ierr);
90522e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of paths for aggressive coarsening %D\n",jac->agg_num_paths);CHKERRQ(ierr);
9060f1074feSSatish Balay 
907efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
90816d9e3a6SLisandro Dalcin 
90922e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps down         %D\n",jac->gridsweeps[0]);CHKERRQ(ierr);
91022e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps up           %D\n",jac->gridsweeps[1]);CHKERRQ(ierr);
91122e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps on coarse    %D\n",jac->gridsweeps[2]);CHKERRQ(ierr);
91216d9e3a6SLisandro Dalcin 
913efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
914efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
915efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
91616d9e3a6SLisandro Dalcin 
917efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
918efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
91916d9e3a6SLisandro Dalcin 
92016d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
921efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using CF-relaxation\n");CHKERRQ(ierr);
92216d9e3a6SLisandro Dalcin     } else {
923efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using CF-relaxation\n");CHKERRQ(ierr);
92416d9e3a6SLisandro Dalcin     }
9256a251517SEike Mueller     if (jac->smoothtype!=-1) {
926efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
92722e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth num levels    %D\n",jac->smoothnumlevels);CHKERRQ(ierr);
9287e352d70SEike Mueller     } else {
929efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using more complex smoothers.\n");CHKERRQ(ierr);
9301810e44eSEike Mueller     }
9311810e44eSEike Mueller     if (jac->smoothtype==3) {
93222e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) levels %D\n",jac->eu_level);CHKERRQ(ierr);
93322e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) drop tolerance %g\n",(double)jac->eu_droptolerance);CHKERRQ(ierr);
93422e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU use Block-Jacobi? %D\n",jac->eu_bj);CHKERRQ(ierr);
9356a251517SEike Mueller     }
936efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
937efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
938efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
9395272c319SBarry Smith     if (jac->nodal_coarsening) {
940efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
9415272c319SBarry Smith     }
9425272c319SBarry Smith     if (jac->vec_interp_variant) {
943efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
94422e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecQMax() %D\n",jac->vec_interp_qmax);CHKERRQ(ierr);
94522e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n",jac->vec_interp_smooth);CHKERRQ(ierr);
9468f87f92bSBarry Smith     }
9478f87f92bSBarry Smith     if (jac->nodal_relax) {
94822e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal relaxation via Schwarz smoothing on levels %D\n",jac->nodal_relax_levels);CHKERRQ(ierr);
9498f87f92bSBarry Smith     }
95016d9e3a6SLisandro Dalcin   }
95116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
95216d9e3a6SLisandro Dalcin }
95316d9e3a6SLisandro Dalcin 
95416d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
9554416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc)
95616d9e3a6SLisandro Dalcin {
95716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
95816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
9594ddd07fcSJed Brown   PetscInt       indx;
960ace3abfcSBarry Smith   PetscBool      flag;
96116d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
96216d9e3a6SLisandro Dalcin 
96316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
964e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
96516d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
96616d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
9672fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
96816d9e3a6SLisandro Dalcin 
96916d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
9702fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
97116d9e3a6SLisandro Dalcin 
97216d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
9732fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
97416d9e3a6SLisandro Dalcin 
975acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
9762fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
97716d9e3a6SLisandro Dalcin 
978acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
9792fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
98016d9e3a6SLisandro Dalcin 
981a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
98216d9e3a6SLisandro Dalcin   if (flag) {
98316d9e3a6SLisandro Dalcin     jac->symt = indx;
984fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
98516d9e3a6SLisandro Dalcin   }
98616d9e3a6SLisandro Dalcin 
98716d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
98816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
98916d9e3a6SLisandro Dalcin }
99016d9e3a6SLisandro Dalcin 
99116d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
99216d9e3a6SLisandro Dalcin {
99316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
99416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
995ace3abfcSBarry Smith   PetscBool      iascii;
99616d9e3a6SLisandro Dalcin   const char     *symt = 0;;
99716d9e3a6SLisandro Dalcin 
99816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
999251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
100016d9e3a6SLisandro Dalcin   if (iascii) {
100116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
1002efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
1003efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
1004efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    filter %g\n",(double)jac->filter);CHKERRQ(ierr);
1005efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
1006efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
1007efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
10082fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
10092fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
10102fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
1011ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
1012efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    %s\n",symt);CHKERRQ(ierr);
101316d9e3a6SLisandro Dalcin   }
101416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
101516d9e3a6SLisandro Dalcin }
10164cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
10174416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc)
10184cb006feSStefano Zampini {
10194cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
10204cb006feSStefano Zampini   PetscErrorCode ierr;
10214cb006feSStefano Zampini   PetscInt       n;
10224cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
10234cb006feSStefano Zampini 
10244cb006feSStefano Zampini   PetscFunctionBegin;
10259fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
1026863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1027863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1028863406b8SStefano 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);
1029863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
10304cb006feSStefano 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);
10314cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1032863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1033863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1034863406b8SStefano 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);
1035863406b8SStefano 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);
1036863406b8SStefano 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);
1037863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
10384cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1039863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1040863406b8SStefano Zampini                                                                       jac->as_relax_times,
1041863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1042863406b8SStefano Zampini                                                                       jac->as_omega));
10434cb006feSStefano Zampini   }
1044863406b8SStefano 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);
10454cb006feSStefano Zampini   n = 5;
1046863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
10474cb006feSStefano Zampini   if (flag || flag2) {
1048863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1049863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1050863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1051863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1052863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1053863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
10544cb006feSStefano Zampini   }
1055863406b8SStefano 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);
10564cb006feSStefano Zampini   n = 5;
1057863406b8SStefano 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);
10584cb006feSStefano Zampini   if (flag || flag2) {
1059863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1060863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1061863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1062863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1063863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1064863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
10654cb006feSStefano Zampini   }
106623df4f25SStefano 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);
106723df4f25SStefano Zampini   if (flag) { /* override HYPRE's default only if the options is used */
106823df4f25SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetProjectionFrequency,(jac->hsolver,jac->ams_proj_freq));
106923df4f25SStefano Zampini   }
10704cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
10714cb006feSStefano Zampini   PetscFunctionReturn(0);
10724cb006feSStefano Zampini }
10734cb006feSStefano Zampini 
10744cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
10754cb006feSStefano Zampini {
10764cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
10774cb006feSStefano Zampini   PetscErrorCode ierr;
10784cb006feSStefano Zampini   PetscBool      iascii;
10794cb006feSStefano Zampini 
10804cb006feSStefano Zampini   PetscFunctionBegin;
10814cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
10824cb006feSStefano Zampini   if (iascii) {
10834cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
1084efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1085efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1086efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1087efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1088efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1089efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1090efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
10914cb006feSStefano Zampini     if (jac->alpha_Poisson) {
1092efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
10934cb006feSStefano Zampini     } else {
1094efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (computed) \n");CHKERRQ(ierr);
10954cb006feSStefano Zampini     }
1096efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1097efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1098efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1099efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1100efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1101efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
11024cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
11034cb006feSStefano Zampini       if (jac->beta_Poisson) {
1104efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
11054cb006feSStefano Zampini       } else {
1106efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (computed) \n");CHKERRQ(ierr);
11074cb006feSStefano Zampini       }
1108efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1109efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1110efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1111efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1112efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1113efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
111423df4f25SStefano Zampini       if (jac->ams_beta_is_zero_part) {
1115efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"        compatible subspace projection frequency %d (-1 HYPRE uses default)\n",jac->ams_proj_freq);CHKERRQ(ierr);
111623df4f25SStefano Zampini       }
111723df4f25SStefano Zampini     } else {
1118efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver not used (zero-conductivity everywhere) \n");CHKERRQ(ierr);
11194cb006feSStefano Zampini     }
11204cb006feSStefano Zampini   }
11214cb006feSStefano Zampini   PetscFunctionReturn(0);
11224cb006feSStefano Zampini }
11234cb006feSStefano Zampini 
11244416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc)
1125863406b8SStefano Zampini {
1126863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1127863406b8SStefano Zampini   PetscErrorCode ierr;
1128863406b8SStefano Zampini   PetscInt       n;
1129863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
1130863406b8SStefano Zampini 
1131863406b8SStefano Zampini   PetscFunctionBegin;
1132863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
1133863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1134863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1135863406b8SStefano 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);
1136863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1137863406b8SStefano 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);
1138863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
1139863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1140863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1141863406b8SStefano 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);
1142863406b8SStefano 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);
1143863406b8SStefano 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);
1144863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
1145863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1146863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1147863406b8SStefano Zampini                                                                       jac->as_relax_times,
1148863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1149863406b8SStefano Zampini                                                                       jac->as_omega));
1150863406b8SStefano Zampini   }
1151863406b8SStefano 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);
1152863406b8SStefano Zampini   n = 5;
1153863406b8SStefano 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);
1154863406b8SStefano 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);
1155863406b8SStefano Zampini   if (flag || flag2 || flag3) {
1156863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
1157863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1158863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1159863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1160863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1161863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1162863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1163863406b8SStefano Zampini   }
1164863406b8SStefano 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);
1165863406b8SStefano Zampini   n = 5;
1166863406b8SStefano 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);
1167863406b8SStefano Zampini   if (flag || flag2) {
1168863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1169863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1170863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1171863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1172863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1173863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1174863406b8SStefano Zampini   }
1175863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
1176863406b8SStefano Zampini   PetscFunctionReturn(0);
1177863406b8SStefano Zampini }
1178863406b8SStefano Zampini 
1179863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1180863406b8SStefano Zampini {
1181863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1182863406b8SStefano Zampini   PetscErrorCode ierr;
1183863406b8SStefano Zampini   PetscBool      iascii;
1184863406b8SStefano Zampini 
1185863406b8SStefano Zampini   PetscFunctionBegin;
1186863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1187863406b8SStefano Zampini   if (iascii) {
1188863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
1189efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1190efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
1191efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1192efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1193efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1194efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1195efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
1196efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    AMS solver using boomerAMG\n");CHKERRQ(ierr);
1197efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1198efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1199efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1200efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1201efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1202efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1203efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
1204efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver using boomerAMG\n");CHKERRQ(ierr);
1205efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1206efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1207efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1208efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1209efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1210efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
1211863406b8SStefano Zampini   }
1212863406b8SStefano Zampini   PetscFunctionReturn(0);
1213863406b8SStefano Zampini }
1214863406b8SStefano Zampini 
1215863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
12164cb006feSStefano Zampini {
12174cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12185ac14e1cSStefano Zampini   PetscBool      ishypre;
12194cb006feSStefano Zampini   PetscErrorCode ierr;
12204cb006feSStefano Zampini 
12214cb006feSStefano Zampini   PetscFunctionBegin;
12225ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)G,MATHYPRE,&ishypre);CHKERRQ(ierr);
12235ac14e1cSStefano Zampini   if (ishypre) {
12245ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr);
12255ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
12265ac14e1cSStefano Zampini     jac->G = G;
12275ac14e1cSStefano Zampini   } else {
12286bf688a0SCe Qin     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
12296bf688a0SCe Qin     ierr = MatConvert(G,MATHYPRE,MAT_INITIAL_MATRIX,&jac->G);CHKERRQ(ierr);
12305ac14e1cSStefano Zampini   }
12314cb006feSStefano Zampini   PetscFunctionReturn(0);
12324cb006feSStefano Zampini }
12334cb006feSStefano Zampini 
12344cb006feSStefano Zampini /*@
12354cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
12364cb006feSStefano Zampini 
12374cb006feSStefano Zampini    Collective on PC
12384cb006feSStefano Zampini 
12394cb006feSStefano Zampini    Input Parameters:
12404cb006feSStefano Zampini +  pc - the preconditioning context
12414cb006feSStefano Zampini -  G - the discrete gradient
12424cb006feSStefano Zampini 
12434cb006feSStefano Zampini    Level: intermediate
12444cb006feSStefano Zampini 
124595452b02SPatrick Sanan    Notes:
124695452b02SPatrick Sanan     G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh
1247863406b8SStefano 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
12484cb006feSStefano Zampini 
12494cb006feSStefano Zampini .seealso:
12504cb006feSStefano Zampini @*/
12514cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
12524cb006feSStefano Zampini {
12534cb006feSStefano Zampini   PetscErrorCode ierr;
12544cb006feSStefano Zampini 
12554cb006feSStefano Zampini   PetscFunctionBegin;
12564cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12574cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
12584cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
12594cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
12604cb006feSStefano Zampini   PetscFunctionReturn(0);
12614cb006feSStefano Zampini }
12624cb006feSStefano Zampini 
1263863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1264863406b8SStefano Zampini {
1265863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12665ac14e1cSStefano Zampini   PetscBool      ishypre;
1267863406b8SStefano Zampini   PetscErrorCode ierr;
1268863406b8SStefano Zampini 
1269863406b8SStefano Zampini   PetscFunctionBegin;
12705ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)C,MATHYPRE,&ishypre);CHKERRQ(ierr);
12715ac14e1cSStefano Zampini   if (ishypre) {
12725ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr);
12735ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
12745ac14e1cSStefano Zampini     jac->C = C;
12755ac14e1cSStefano Zampini   } else {
12766bf688a0SCe Qin     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
12776bf688a0SCe Qin     ierr = MatConvert(C,MATHYPRE,MAT_INITIAL_MATRIX,&jac->C);CHKERRQ(ierr);
12785ac14e1cSStefano Zampini   }
1279863406b8SStefano Zampini   PetscFunctionReturn(0);
1280863406b8SStefano Zampini }
1281863406b8SStefano Zampini 
1282863406b8SStefano Zampini /*@
1283863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1284863406b8SStefano Zampini 
1285863406b8SStefano Zampini    Collective on PC
1286863406b8SStefano Zampini 
1287863406b8SStefano Zampini    Input Parameters:
1288863406b8SStefano Zampini +  pc - the preconditioning context
1289863406b8SStefano Zampini -  C - the discrete curl
1290863406b8SStefano Zampini 
1291863406b8SStefano Zampini    Level: intermediate
1292863406b8SStefano Zampini 
129395452b02SPatrick Sanan    Notes:
129495452b02SPatrick Sanan     C should have as many rows as the number of faces and as many columns as the number of edges in the mesh
1295863406b8SStefano 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
1296863406b8SStefano Zampini 
1297863406b8SStefano Zampini .seealso:
1298863406b8SStefano Zampini @*/
1299863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1300863406b8SStefano Zampini {
1301863406b8SStefano Zampini   PetscErrorCode ierr;
1302863406b8SStefano Zampini 
1303863406b8SStefano Zampini   PetscFunctionBegin;
1304863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1305863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1306863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1307863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1308863406b8SStefano Zampini   PetscFunctionReturn(0);
1309863406b8SStefano Zampini }
1310863406b8SStefano Zampini 
13116bf688a0SCe Qin static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
13126bf688a0SCe Qin {
13136bf688a0SCe Qin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
13146bf688a0SCe Qin   PetscBool      ishypre;
13156bf688a0SCe Qin   PetscErrorCode ierr;
13166bf688a0SCe Qin   PetscInt       i;
13176bf688a0SCe Qin   PetscFunctionBegin;
13186bf688a0SCe Qin 
13196bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
13206bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
13216bf688a0SCe Qin   for (i=0;i<3;++i) {
13226bf688a0SCe Qin     ierr = MatDestroy(&jac->RT_Pi[i]);CHKERRQ(ierr);
13236bf688a0SCe Qin     ierr = MatDestroy(&jac->ND_Pi[i]);CHKERRQ(ierr);
13246bf688a0SCe Qin   }
13256bf688a0SCe Qin 
13266bf688a0SCe Qin   jac->dim = dim;
13276bf688a0SCe Qin   if (RT_PiFull) {
13286bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)RT_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
13296bf688a0SCe Qin     if (ishypre) {
13306bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)RT_PiFull);CHKERRQ(ierr);
13316bf688a0SCe Qin       jac->RT_PiFull = RT_PiFull;
13326bf688a0SCe Qin     } else {
13336bf688a0SCe Qin       ierr = MatConvert(RT_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_PiFull);CHKERRQ(ierr);
13346bf688a0SCe Qin     }
13356bf688a0SCe Qin   }
13366bf688a0SCe Qin   if (RT_Pi) {
13376bf688a0SCe Qin     for (i=0;i<dim;++i) {
13386bf688a0SCe Qin       if (RT_Pi[i]) {
13396bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)RT_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
13406bf688a0SCe Qin         if (ishypre) {
13416bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)RT_Pi[i]);CHKERRQ(ierr);
13426bf688a0SCe Qin           jac->RT_Pi[i] = RT_Pi[i];
13436bf688a0SCe Qin         } else {
13446bf688a0SCe Qin           ierr = MatConvert(RT_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_Pi[i]);CHKERRQ(ierr);
13456bf688a0SCe Qin         }
13466bf688a0SCe Qin       }
13476bf688a0SCe Qin     }
13486bf688a0SCe Qin   }
13496bf688a0SCe Qin   if (ND_PiFull) {
13506bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)ND_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
13516bf688a0SCe Qin     if (ishypre) {
13526bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)ND_PiFull);CHKERRQ(ierr);
13536bf688a0SCe Qin       jac->ND_PiFull = ND_PiFull;
13546bf688a0SCe Qin     } else {
13556bf688a0SCe Qin       ierr = MatConvert(ND_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_PiFull);CHKERRQ(ierr);
13566bf688a0SCe Qin     }
13576bf688a0SCe Qin   }
13586bf688a0SCe Qin   if (ND_Pi) {
13596bf688a0SCe Qin     for (i=0;i<dim;++i) {
13606bf688a0SCe Qin       if (ND_Pi[i]) {
13616bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)ND_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
13626bf688a0SCe Qin         if (ishypre) {
13636bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)ND_Pi[i]);CHKERRQ(ierr);
13646bf688a0SCe Qin           jac->ND_Pi[i] = ND_Pi[i];
13656bf688a0SCe Qin         } else {
13666bf688a0SCe Qin           ierr = MatConvert(ND_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_Pi[i]);CHKERRQ(ierr);
13676bf688a0SCe Qin         }
13686bf688a0SCe Qin       }
13696bf688a0SCe Qin     }
13706bf688a0SCe Qin   }
13716bf688a0SCe Qin 
13726bf688a0SCe Qin   PetscFunctionReturn(0);
13736bf688a0SCe Qin }
13746bf688a0SCe Qin 
13756bf688a0SCe Qin /*@
13766bf688a0SCe Qin  PCHYPRESetInterpolations - Set interpolation matrices for AMS/ADS preconditioner
13776bf688a0SCe Qin 
13786bf688a0SCe Qin    Collective on PC
13796bf688a0SCe Qin 
13806bf688a0SCe Qin    Input Parameters:
13816bf688a0SCe Qin +  pc - the preconditioning context
13826bf688a0SCe Qin -  dim - the dimension of the problem, only used in AMS
13836bf688a0SCe Qin -  RT_PiFull - Raviart-Thomas interpolation matrix
13846bf688a0SCe Qin -  RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix
13856bf688a0SCe Qin -  ND_PiFull - Nedelec interpolation matrix
13866bf688a0SCe Qin -  ND_Pi - x/y/z component of Nedelec interpolation matrix
13876bf688a0SCe Qin 
138895452b02SPatrick Sanan    Notes:
138995452b02SPatrick Sanan     For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL.
13906bf688a0SCe Qin           For ADS, both type of interpolation matrices are needed.
13916bf688a0SCe Qin    Level: intermediate
13926bf688a0SCe Qin 
13936bf688a0SCe Qin .seealso:
13946bf688a0SCe Qin @*/
13956bf688a0SCe Qin PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
13966bf688a0SCe Qin {
13976bf688a0SCe Qin   PetscErrorCode ierr;
13986bf688a0SCe Qin   PetscInt       i;
13996bf688a0SCe Qin 
14006bf688a0SCe Qin   PetscFunctionBegin;
14016bf688a0SCe Qin   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
14026bf688a0SCe Qin   if (RT_PiFull) {
14036bf688a0SCe Qin     PetscValidHeaderSpecific(RT_PiFull,MAT_CLASSID,3);
14046bf688a0SCe Qin     PetscCheckSameComm(pc,1,RT_PiFull,3);
14056bf688a0SCe Qin   }
14066bf688a0SCe Qin   if (RT_Pi) {
14076bf688a0SCe Qin     PetscValidPointer(RT_Pi,4);
14086bf688a0SCe Qin     for (i=0;i<dim;++i) {
14096bf688a0SCe Qin       if (RT_Pi[i]) {
14106bf688a0SCe Qin         PetscValidHeaderSpecific(RT_Pi[i],MAT_CLASSID,4);
14116bf688a0SCe Qin         PetscCheckSameComm(pc,1,RT_Pi[i],4);
14126bf688a0SCe Qin       }
14136bf688a0SCe Qin     }
14146bf688a0SCe Qin   }
14156bf688a0SCe Qin   if (ND_PiFull) {
14166bf688a0SCe Qin     PetscValidHeaderSpecific(ND_PiFull,MAT_CLASSID,5);
14176bf688a0SCe Qin     PetscCheckSameComm(pc,1,ND_PiFull,5);
14186bf688a0SCe Qin   }
14196bf688a0SCe Qin   if (ND_Pi) {
14206bf688a0SCe Qin     PetscValidPointer(ND_Pi,6);
14216bf688a0SCe Qin     for (i=0;i<dim;++i) {
14226bf688a0SCe Qin       if (ND_Pi[i]) {
14236bf688a0SCe Qin         PetscValidHeaderSpecific(ND_Pi[i],MAT_CLASSID,6);
14246bf688a0SCe Qin         PetscCheckSameComm(pc,1,ND_Pi[i],6);
14256bf688a0SCe Qin       }
14266bf688a0SCe Qin     }
14276bf688a0SCe Qin   }
14286bf688a0SCe Qin   ierr = PetscTryMethod(pc,"PCHYPRESetInterpolations_C",(PC,PetscInt,Mat,Mat[],Mat,Mat[]),(pc,dim,RT_PiFull,RT_Pi,ND_PiFull,ND_Pi));CHKERRQ(ierr);
14296bf688a0SCe Qin   PetscFunctionReturn(0);
14306bf688a0SCe Qin }
14316bf688a0SCe Qin 
14325ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha)
14334cb006feSStefano Zampini {
14344cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
14355ac14e1cSStefano Zampini   PetscBool      ishypre;
14364cb006feSStefano Zampini   PetscErrorCode ierr;
14374cb006feSStefano Zampini 
14384cb006feSStefano Zampini   PetscFunctionBegin;
14395ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr);
14405ac14e1cSStefano Zampini   if (ishypre) {
14415ac14e1cSStefano Zampini     if (isalpha) {
14425ac14e1cSStefano Zampini       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
14435ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
14445ac14e1cSStefano Zampini       jac->alpha_Poisson = A;
14455ac14e1cSStefano Zampini     } else {
14465ac14e1cSStefano Zampini       if (A) {
14475ac14e1cSStefano Zampini         ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
14485ac14e1cSStefano Zampini       } else {
14495ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
14505ac14e1cSStefano Zampini       }
14515ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
14525ac14e1cSStefano Zampini       jac->beta_Poisson = A;
14535ac14e1cSStefano Zampini     }
14545ac14e1cSStefano Zampini   } else {
14555ac14e1cSStefano Zampini     if (isalpha) {
14566bf688a0SCe Qin       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
14576bf688a0SCe Qin       ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->alpha_Poisson);CHKERRQ(ierr);
14585ac14e1cSStefano Zampini     } else {
14595ac14e1cSStefano Zampini       if (A) {
14606bf688a0SCe Qin         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
14616bf688a0SCe Qin         ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->beta_Poisson);CHKERRQ(ierr);
14625ac14e1cSStefano Zampini       } else {
14635ac14e1cSStefano Zampini         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
14645ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
14655ac14e1cSStefano Zampini       }
14665ac14e1cSStefano Zampini     }
14675ac14e1cSStefano Zampini   }
14684cb006feSStefano Zampini   PetscFunctionReturn(0);
14694cb006feSStefano Zampini }
14704cb006feSStefano Zampini 
14714cb006feSStefano Zampini /*@
14724cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
14734cb006feSStefano Zampini 
14744cb006feSStefano Zampini    Collective on PC
14754cb006feSStefano Zampini 
14764cb006feSStefano Zampini    Input Parameters:
14774cb006feSStefano Zampini +  pc - the preconditioning context
14784cb006feSStefano Zampini -  A - the matrix
14794cb006feSStefano Zampini 
14804cb006feSStefano Zampini    Level: intermediate
14814cb006feSStefano Zampini 
148295452b02SPatrick Sanan    Notes:
148395452b02SPatrick Sanan     A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
14844cb006feSStefano Zampini 
14854cb006feSStefano Zampini .seealso:
14864cb006feSStefano Zampini @*/
14874cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
14884cb006feSStefano Zampini {
14894cb006feSStefano Zampini   PetscErrorCode ierr;
14904cb006feSStefano Zampini 
14914cb006feSStefano Zampini   PetscFunctionBegin;
14924cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
14934cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
14944cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
14955ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_TRUE));CHKERRQ(ierr);
14964cb006feSStefano Zampini   PetscFunctionReturn(0);
14974cb006feSStefano Zampini }
14984cb006feSStefano Zampini 
14994cb006feSStefano Zampini /*@
15004cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
15014cb006feSStefano Zampini 
15024cb006feSStefano Zampini    Collective on PC
15034cb006feSStefano Zampini 
15044cb006feSStefano Zampini    Input Parameters:
15054cb006feSStefano Zampini +  pc - the preconditioning context
15064cb006feSStefano Zampini -  A - the matrix
15074cb006feSStefano Zampini 
15084cb006feSStefano Zampini    Level: intermediate
15094cb006feSStefano Zampini 
151095452b02SPatrick Sanan    Notes:
151195452b02SPatrick Sanan     A should be obtained by discretizing the Poisson problem with linear finite elements.
15124cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
15134cb006feSStefano Zampini 
15144cb006feSStefano Zampini .seealso:
15154cb006feSStefano Zampini @*/
15164cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
15174cb006feSStefano Zampini {
15184cb006feSStefano Zampini   PetscErrorCode ierr;
15194cb006feSStefano Zampini 
15204cb006feSStefano Zampini   PetscFunctionBegin;
15214cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15224cb006feSStefano Zampini   if (A) {
15234cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
15244cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
15254cb006feSStefano Zampini   }
15265ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_FALSE));CHKERRQ(ierr);
15274cb006feSStefano Zampini   PetscFunctionReturn(0);
15284cb006feSStefano Zampini }
15294cb006feSStefano Zampini 
15305ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz, Vec zoz, Vec zzo)
15314cb006feSStefano Zampini {
15324cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
15334cb006feSStefano Zampini   PetscErrorCode     ierr;
15344cb006feSStefano Zampini 
15354cb006feSStefano Zampini   PetscFunctionBegin;
15364cb006feSStefano Zampini   /* throw away any vector if already set */
15374cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
15384cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
15394cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
15404cb006feSStefano Zampini   jac->constants[0] = NULL;
15414cb006feSStefano Zampini   jac->constants[1] = NULL;
15424cb006feSStefano Zampini   jac->constants[2] = NULL;
15434cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
15444cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
15454cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
15464cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
15475ac14e1cSStefano Zampini   jac->dim = 2;
15484cb006feSStefano Zampini   if (zzo) {
15494cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
15504cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
15515ac14e1cSStefano Zampini     jac->dim++;
15524cb006feSStefano Zampini   }
15534cb006feSStefano Zampini   PetscFunctionReturn(0);
15544cb006feSStefano Zampini }
15554cb006feSStefano Zampini 
15564cb006feSStefano Zampini /*@
15574cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
15584cb006feSStefano Zampini 
15594cb006feSStefano Zampini    Collective on PC
15604cb006feSStefano Zampini 
15614cb006feSStefano Zampini    Input Parameters:
15624cb006feSStefano Zampini +  pc - the preconditioning context
15634cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
15644cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
15654cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
15664cb006feSStefano Zampini 
15674cb006feSStefano Zampini    Level: intermediate
15684cb006feSStefano Zampini 
15694cb006feSStefano Zampini    Notes:
15704cb006feSStefano Zampini 
15714cb006feSStefano Zampini .seealso:
15724cb006feSStefano Zampini @*/
15734cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
15744cb006feSStefano Zampini {
15754cb006feSStefano Zampini   PetscErrorCode ierr;
15764cb006feSStefano Zampini 
15774cb006feSStefano Zampini   PetscFunctionBegin;
15784cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15794cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
15804cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
15814cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
15824cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
15834cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
15844cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
15854cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
15864cb006feSStefano Zampini   PetscFunctionReturn(0);
15874cb006feSStefano Zampini }
15884cb006feSStefano Zampini 
1589863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
15904cb006feSStefano Zampini {
15914cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
15924cb006feSStefano Zampini   Vec             tv;
15934cb006feSStefano Zampini   PetscInt        i;
15944cb006feSStefano Zampini   PetscErrorCode  ierr;
15954cb006feSStefano Zampini 
15964cb006feSStefano Zampini   PetscFunctionBegin;
15974cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
15984cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
15994cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
16004cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
16015ac14e1cSStefano Zampini   jac->dim = dim;
16025ac14e1cSStefano Zampini 
16034cb006feSStefano Zampini   /* compute IJ vector for coordinates */
16044cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
16054cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
16064cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
16074cb006feSStefano Zampini   for (i=0;i<dim;i++) {
16084cb006feSStefano Zampini     PetscScalar *array;
16094cb006feSStefano Zampini     PetscInt    j;
16104cb006feSStefano Zampini 
16114cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
16124cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
16134cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
16144cb006feSStefano Zampini       array[j] = coords[j*dim+i];
16154cb006feSStefano Zampini     }
1616*39accc25SStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,(HYPRE_Complex*)array));
16174cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
16184cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
16194cb006feSStefano Zampini   }
16204cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
16214cb006feSStefano Zampini   PetscFunctionReturn(0);
16224cb006feSStefano Zampini }
16234cb006feSStefano Zampini 
162416d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
162516d9e3a6SLisandro Dalcin 
1626f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
162716d9e3a6SLisandro Dalcin {
162816d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
162916d9e3a6SLisandro Dalcin 
163016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
163116d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
163216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
163316d9e3a6SLisandro Dalcin }
163416d9e3a6SLisandro Dalcin 
1635f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
163616d9e3a6SLisandro Dalcin {
163716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
163816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1639ace3abfcSBarry Smith   PetscBool      flag;
164016d9e3a6SLisandro Dalcin 
164116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
164216d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
164316d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1644ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
164516d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
164616d9e3a6SLisandro Dalcin   } else {
164716d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
164816d9e3a6SLisandro Dalcin   }
164916d9e3a6SLisandro Dalcin 
165016d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
165116d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
165216d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
165316d9e3a6SLisandro Dalcin 
165416d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
165516d9e3a6SLisandro Dalcin   if (flag) {
1656572a0576SBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1657fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
165816d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
165916d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
166016d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
166116d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
166216d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
166316d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
166416d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
166516d9e3a6SLisandro Dalcin   }
1666db966c6cSHong Zhang   ierr = PetscStrcmp("euclid",jac->hypre_type,&flag);CHKERRQ(ierr);
1667db966c6cSHong Zhang   if (flag) {
1668db966c6cSHong Zhang     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1669db966c6cSHong Zhang     PetscStackCallStandard(HYPRE_EuclidCreate,(jac->comm_hypre,&jac->hsolver));
1670db966c6cSHong Zhang     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
1671db966c6cSHong Zhang     pc->ops->view           = PCView_HYPRE_Euclid;
1672db966c6cSHong Zhang     jac->destroy            = HYPRE_EuclidDestroy;
1673db966c6cSHong Zhang     jac->setup              = HYPRE_EuclidSetup;
1674db966c6cSHong Zhang     jac->solve              = HYPRE_EuclidSolve;
1675db966c6cSHong Zhang     jac->factorrowsize      = PETSC_DEFAULT;
1676db966c6cSHong Zhang     jac->eu_level           = PETSC_DEFAULT; /* default */
1677db966c6cSHong Zhang     PetscFunctionReturn(0);
1678db966c6cSHong Zhang   }
167916d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
168016d9e3a6SLisandro Dalcin   if (flag) {
1681572a0576SBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1682fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
168316d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
168416d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
168516d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
168616d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
168716d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
168816d9e3a6SLisandro Dalcin     /* initialize */
168916d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
169016d9e3a6SLisandro Dalcin     jac->threshhold = .1;
169116d9e3a6SLisandro Dalcin     jac->filter     = .1;
169216d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
16932fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
16942fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
16952fa5cd67SKarl Rupp 
169616d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
169716d9e3a6SLisandro Dalcin     jac->symt = 0;
1698fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1699fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1700fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1701fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1702fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1703fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
170416d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
170516d9e3a6SLisandro Dalcin   }
170616d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
170716d9e3a6SLisandro Dalcin   if (flag) {
170816d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
170916d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
171016d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
171116d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
171216d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
171316d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
171416d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
171516d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
171616d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
171716d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
171816d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
171916d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
172016d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
17218f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
172216d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
172316d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
172416d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
172516d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
172616d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
17270f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
17286a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1729b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
17301810e44eSEike Mueller     jac->eu_level         = 0;
17311810e44eSEike Mueller     jac->eu_droptolerance = 0;
17321810e44eSEike Mueller     jac->eu_bj            = 0;
17338f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
17340f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
173516d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
173616d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
173716d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
17380f1074feSSatish Balay     jac->interptype       = 0;
17390f1074feSSatish Balay     jac->agg_nl           = 0;
17400f1074feSSatish Balay     jac->pmax             = 0;
17410f1074feSSatish Balay     jac->truncfactor      = 0.0;
17420f1074feSSatish Balay     jac->agg_num_paths    = 1;
17438f87f92bSBarry Smith 
174422e51d31SStefano Zampini     jac->nodal_coarsening      = 0;
174522e51d31SStefano Zampini     jac->nodal_coarsening_diag = 0;
174622e51d31SStefano Zampini     jac->vec_interp_variant    = 0;
174722e51d31SStefano Zampini     jac->vec_interp_qmax       = 0;
174822e51d31SStefano Zampini     jac->vec_interp_smooth     = PETSC_FALSE;
174922e51d31SStefano Zampini     jac->interp_refine         = 0;
17508f87f92bSBarry Smith     jac->nodal_relax           = PETSC_FALSE;
17518f87f92bSBarry Smith     jac->nodal_relax_levels    = 1;
1752fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1753fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1754fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1755fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1756fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1757fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1758fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1759fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1760fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1761fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1762fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1763fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1764fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1765fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1766fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1767fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
176816d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
176916d9e3a6SLisandro Dalcin   }
17704cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
17714cb006feSStefano Zampini   if (flag) {
17724cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
17734cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
17744cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
17754cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
17764cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
17774cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
17784cb006feSStefano Zampini     jac->coords[0]           = NULL;
17794cb006feSStefano Zampini     jac->coords[1]           = NULL;
17804cb006feSStefano Zampini     jac->coords[2]           = NULL;
17814cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1782863406b8SStefano Zampini     jac->as_print           = 0;
1783863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1784863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
17854cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
17864cb006feSStefano Zampini     /* Smoothing options */
1787863406b8SStefano Zampini     jac->as_relax_type      = 2;
1788863406b8SStefano Zampini     jac->as_relax_times     = 1;
1789863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1790863406b8SStefano Zampini     jac->as_omega           = 1.0;
17914cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1792863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1793863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
17940bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1795863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1796863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1797863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
17984cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1799863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1800863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
18010bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1802863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1803863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1804863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1805863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1806863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
18074cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1808863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1809863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1810863406b8SStefano Zampini                                                                       jac->as_relax_times,
1811863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1812863406b8SStefano Zampini                                                                       jac->as_omega));
1813863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1814863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1815863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1816863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1817863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1818863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1819863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1820863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1821863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1822863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1823863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1824863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
182523df4f25SStefano Zampini     /* Zero conductivity */
182623df4f25SStefano Zampini     jac->ams_beta_is_zero      = PETSC_FALSE;
182723df4f25SStefano Zampini     jac->ams_beta_is_zero_part = PETSC_FALSE;
18284cb006feSStefano Zampini     PetscFunctionReturn(0);
18294cb006feSStefano Zampini   }
1830863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1831863406b8SStefano Zampini   if (flag) {
1832863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1833863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1834863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1835863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1836863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1837863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1838863406b8SStefano Zampini     jac->coords[0]           = NULL;
1839863406b8SStefano Zampini     jac->coords[1]           = NULL;
1840863406b8SStefano Zampini     jac->coords[2]           = NULL;
1841863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1842863406b8SStefano Zampini     jac->as_print           = 0;
1843863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1844863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1845863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1846863406b8SStefano Zampini     /* Smoothing options */
1847863406b8SStefano Zampini     jac->as_relax_type      = 2;
1848863406b8SStefano Zampini     jac->as_relax_times     = 1;
1849863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1850863406b8SStefano Zampini     jac->as_omega           = 1.0;
1851863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1852863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1853863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1854863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1855863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1856863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1857863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1858863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1859863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1860863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1861863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1862863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1863863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1864863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1865863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1866863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1867863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1868863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1869863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1870863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1871863406b8SStefano Zampini                                                                       jac->as_relax_times,
1872863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1873863406b8SStefano Zampini                                                                       jac->as_omega));
1874863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1875863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1876863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1877863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1878863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1879863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1880863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1881863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1882863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1883863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1884863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1885863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1886863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1887863406b8SStefano Zampini     PetscFunctionReturn(0);
1888863406b8SStefano Zampini   }
1889503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
18902fa5cd67SKarl Rupp 
18910298fd71SBarry Smith   jac->hypre_type = NULL;
1892db966c6cSHong Zhang   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams",name);
189316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
189416d9e3a6SLisandro Dalcin }
189516d9e3a6SLisandro Dalcin 
189616d9e3a6SLisandro Dalcin /*
189716d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
189816d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
189916d9e3a6SLisandro Dalcin */
19004416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc)
190116d9e3a6SLisandro Dalcin {
190216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
19034ddd07fcSJed Brown   PetscInt       indx;
1904db966c6cSHong Zhang   const char     *type[] = {"euclid","pilut","parasails","boomeramg","ams","ads"};
1905ace3abfcSBarry Smith   PetscBool      flg;
190616d9e3a6SLisandro Dalcin 
190716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
19089fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
19099c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
191016d9e3a6SLisandro Dalcin   if (flg) {
191116d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
191202a17cd4SBarry Smith   } else {
191302a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
191416d9e3a6SLisandro Dalcin   }
191516d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
19163931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
191716d9e3a6SLisandro Dalcin   }
191816d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
191916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
192016d9e3a6SLisandro Dalcin }
192116d9e3a6SLisandro Dalcin 
192216d9e3a6SLisandro Dalcin /*@C
192316d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
192416d9e3a6SLisandro Dalcin 
192516d9e3a6SLisandro Dalcin    Input Parameters:
192616d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1927db966c6cSHong Zhang -     name - either  euclid, pilut, parasails, boomeramg, ams, ads
192816d9e3a6SLisandro Dalcin 
192916d9e3a6SLisandro Dalcin    Options Database Keys:
1930db966c6cSHong Zhang    -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
193116d9e3a6SLisandro Dalcin 
193216d9e3a6SLisandro Dalcin    Level: intermediate
193316d9e3a6SLisandro Dalcin 
193416d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
193516d9e3a6SLisandro Dalcin            PCHYPRE
193616d9e3a6SLisandro Dalcin 
193716d9e3a6SLisandro Dalcin @*/
19387087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
193916d9e3a6SLisandro Dalcin {
19404ac538c5SBarry Smith   PetscErrorCode ierr;
194116d9e3a6SLisandro Dalcin 
194216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
19430700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
194416d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
19454ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
194616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
194716d9e3a6SLisandro Dalcin }
194816d9e3a6SLisandro Dalcin 
194916d9e3a6SLisandro Dalcin /*@C
195016d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
195116d9e3a6SLisandro Dalcin 
195216d9e3a6SLisandro Dalcin    Input Parameter:
195316d9e3a6SLisandro Dalcin .     pc - the preconditioner context
195416d9e3a6SLisandro Dalcin 
195516d9e3a6SLisandro Dalcin    Output Parameter:
1956db966c6cSHong Zhang .     name - either  euclid, pilut, parasails, boomeramg, ams, ads
195716d9e3a6SLisandro Dalcin 
195816d9e3a6SLisandro Dalcin    Level: intermediate
195916d9e3a6SLisandro Dalcin 
196016d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
196116d9e3a6SLisandro Dalcin            PCHYPRE
196216d9e3a6SLisandro Dalcin 
196316d9e3a6SLisandro Dalcin @*/
19647087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
196516d9e3a6SLisandro Dalcin {
19664ac538c5SBarry Smith   PetscErrorCode ierr;
196716d9e3a6SLisandro Dalcin 
196816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
19690700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
197016d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
19714ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
197216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
197316d9e3a6SLisandro Dalcin }
197416d9e3a6SLisandro Dalcin 
197516d9e3a6SLisandro Dalcin /*MC
197616d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
197716d9e3a6SLisandro Dalcin 
197816d9e3a6SLisandro Dalcin    Options Database Keys:
1979db966c6cSHong Zhang +   -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
198016d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
198116d9e3a6SLisandro Dalcin           preconditioner
198216d9e3a6SLisandro Dalcin 
198316d9e3a6SLisandro Dalcin    Level: intermediate
198416d9e3a6SLisandro Dalcin 
198595452b02SPatrick Sanan    Notes:
198695452b02SPatrick Sanan     Apart from pc_hypre_type (for which there is PCHYPRESetType()),
198716d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
198816d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
198916d9e3a6SLisandro Dalcin 
1990c231f9e3SBarryFSmith           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_tol refer to the number of iterations
19910f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
19920f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
1993c231f9e3SBarryFSmith           (-pc_hypre_boomeramg_tol should be set to 0.0 - the default - to strictly use a fixed number of
19948f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
19950f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
19960f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
199716d9e3a6SLisandro Dalcin 
19980f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
19990f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
20000f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
200116d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
200216d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
200316d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
200416d9e3a6SLisandro Dalcin 
200516d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
200616d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
200716d9e3a6SLisandro Dalcin 
20085272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
20095272c319SBarry Smith           the two options:
20105272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
2011cbc39033SBarry Smith -   -pc_hypre_boomeramg_vec_interp_variant <v> where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
20125272c319SBarry Smith 
20135272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
20145272c319SBarry Smith 
20159e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
20169e5bc791SBarry Smith 
201716d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
20189e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
201916d9e3a6SLisandro Dalcin 
202016d9e3a6SLisandro Dalcin M*/
202116d9e3a6SLisandro Dalcin 
20228cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
202316d9e3a6SLisandro Dalcin {
202416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
202516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
202616d9e3a6SLisandro Dalcin 
202716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
2028b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
20292fa5cd67SKarl Rupp 
203016d9e3a6SLisandro Dalcin   pc->data                = jac;
20318695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
203216d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
203316d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
203416d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
203516d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
203616d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
2037bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
2038bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
20395ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
20405ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
20415ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
20426bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",PCHYPRESetInterpolations_HYPRE);CHKERRQ(ierr);
20435ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE);CHKERRQ(ierr);
20445ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",PCHYPRESetPoissonMatrix_HYPRE);CHKERRQ(ierr);
204516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
204616d9e3a6SLisandro Dalcin }
2047ebc551c0SBarry Smith 
2048f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
2049f91d8e95SBarry Smith 
2050ebc551c0SBarry Smith typedef struct {
205168326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
2052f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
20539e5bc791SBarry Smith 
20549e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
20554ddd07fcSJed Brown   PetscInt its;
20569e5bc791SBarry Smith   double   tol;
20574ddd07fcSJed Brown   PetscInt relax_type;
20584ddd07fcSJed Brown   PetscInt rap_type;
20594ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
20604ddd07fcSJed Brown   PetscInt max_levels;
2061ebc551c0SBarry Smith } PC_PFMG;
2062ebc551c0SBarry Smith 
2063ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
2064ebc551c0SBarry Smith {
2065ebc551c0SBarry Smith   PetscErrorCode ierr;
2066f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2067ebc551c0SBarry Smith 
2068ebc551c0SBarry Smith   PetscFunctionBegin;
20692fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2070f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2071c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2072ebc551c0SBarry Smith   PetscFunctionReturn(0);
2073ebc551c0SBarry Smith }
2074ebc551c0SBarry Smith 
20759e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
20769e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
20779e5bc791SBarry Smith 
2078ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
2079ebc551c0SBarry Smith {
2080ebc551c0SBarry Smith   PetscErrorCode ierr;
2081ace3abfcSBarry Smith   PetscBool      iascii;
2082f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2083ebc551c0SBarry Smith 
2084ebc551c0SBarry Smith   PetscFunctionBegin;
2085251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
20869e5bc791SBarry Smith   if (iascii) {
20879e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
2088efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max iterations %d\n",ex->its);CHKERRQ(ierr);
2089efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    tolerance %g\n",ex->tol);CHKERRQ(ierr);
2090efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2091efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
2092efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2093efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max levels %d\n",ex->max_levels);CHKERRQ(ierr);
20949e5bc791SBarry Smith   }
2095ebc551c0SBarry Smith   PetscFunctionReturn(0);
2096ebc551c0SBarry Smith }
2097ebc551c0SBarry Smith 
20984416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2099ebc551c0SBarry Smith {
2100ebc551c0SBarry Smith   PetscErrorCode ierr;
2101f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2102ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2103ebc551c0SBarry Smith 
2104ebc551c0SBarry Smith   PetscFunctionBegin;
2105e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
21060298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
210768326731SBarry Smith   if (flg) {
2108a0324ebeSBarry Smith     int level=3;
2109fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
211068326731SBarry Smith   }
21110298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2112fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
21130298fd71SBarry 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);
2114fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
21150298fd71SBarry 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);
2116fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
21179e5bc791SBarry Smith 
21180298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
2119fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
21203b46a515SGlenn Hammond 
21210298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2122fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
21230298fd71SBarry 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);
2124fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
21250298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
2126fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
2127ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
2128ebc551c0SBarry Smith   PetscFunctionReturn(0);
2129ebc551c0SBarry Smith }
2130ebc551c0SBarry Smith 
2131f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
2132f91d8e95SBarry Smith {
2133f91d8e95SBarry Smith   PetscErrorCode    ierr;
2134f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
2135d9ca1df4SBarry Smith   PetscScalar       *yy;
2136d9ca1df4SBarry Smith   const PetscScalar *xx;
21374ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
21382cf14000SStefano Zampini   HYPRE_Int         hlower[3],hupper[3];
213968326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2140f91d8e95SBarry Smith 
2141f91d8e95SBarry Smith   PetscFunctionBegin;
2142dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2143aa219208SBarry Smith   ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
21442cf14000SStefano Zampini   /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
2145f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
2146f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
2147f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
21482cf14000SStefano Zampini   hlower[0]  = (HYPRE_Int)ilower[0];
21492cf14000SStefano Zampini   hlower[1]  = (HYPRE_Int)ilower[1];
21502cf14000SStefano Zampini   hlower[2]  = (HYPRE_Int)ilower[2];
21512cf14000SStefano Zampini   hupper[0]  = (HYPRE_Int)iupper[0];
21522cf14000SStefano Zampini   hupper[1]  = (HYPRE_Int)iupper[1];
21532cf14000SStefano Zampini   hupper[2]  = (HYPRE_Int)iupper[2];
2154f91d8e95SBarry Smith 
2155f91d8e95SBarry Smith   /* copy x values over to hypre */
2156fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
2157d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2158*39accc25SStefano Zampini   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,hlower,hupper,(HYPRE_Complex*)xx));
2159d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2160fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
2161fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2162f91d8e95SBarry Smith 
2163f91d8e95SBarry Smith   /* copy solution values back to PETSc */
2164f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
2165*39accc25SStefano Zampini   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,hlower,hupper,(HYPRE_Complex*)yy));
2166f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2167f91d8e95SBarry Smith   PetscFunctionReturn(0);
2168f91d8e95SBarry Smith }
2169f91d8e95SBarry Smith 
2170ace3abfcSBarry 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)
21719e5bc791SBarry Smith {
21729e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
21739e5bc791SBarry Smith   PetscErrorCode ierr;
21742cf14000SStefano Zampini   HYPRE_Int      oits;
21759e5bc791SBarry Smith 
21769e5bc791SBarry Smith   PetscFunctionBegin;
2177dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2178fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
2179fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
21809e5bc791SBarry Smith 
21819e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
21822cf14000SStefano Zampini   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,&oits));
21839e5bc791SBarry Smith   *outits = oits;
21849e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
21859e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2186fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
2187fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
21889e5bc791SBarry Smith   PetscFunctionReturn(0);
21899e5bc791SBarry Smith }
21909e5bc791SBarry Smith 
21919e5bc791SBarry Smith 
21923a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
21933a32d3dbSGlenn Hammond {
21943a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
21953a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
21963a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2197ace3abfcSBarry Smith   PetscBool       flg;
21983a32d3dbSGlenn Hammond 
21993a32d3dbSGlenn Hammond   PetscFunctionBegin;
2200251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
2201ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
22023a32d3dbSGlenn Hammond 
22033a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
22042fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2205fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2206fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2207fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
22083a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
22093a32d3dbSGlenn Hammond }
22103a32d3dbSGlenn Hammond 
2211ebc551c0SBarry Smith /*MC
2212ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
2213ebc551c0SBarry Smith 
2214ebc551c0SBarry Smith    Level: advanced
2215ebc551c0SBarry Smith 
22169e5bc791SBarry Smith    Options Database:
22179e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
22189e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
22199e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
22209e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
22219e5bc791SBarry 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
22229e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
2223f91d8e95SBarry Smith 
222495452b02SPatrick Sanan    Notes:
222595452b02SPatrick Sanan     This is for CELL-centered descretizations
22269e5bc791SBarry Smith 
22278e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
2228aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
22299e5bc791SBarry Smith 
22309e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
2231ebc551c0SBarry Smith M*/
2232ebc551c0SBarry Smith 
22338cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
2234ebc551c0SBarry Smith {
2235ebc551c0SBarry Smith   PetscErrorCode ierr;
2236ebc551c0SBarry Smith   PC_PFMG        *ex;
2237ebc551c0SBarry Smith 
2238ebc551c0SBarry Smith   PetscFunctionBegin;
2239b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
224068326731SBarry Smith   pc->data = ex;
2241ebc551c0SBarry Smith 
22429e5bc791SBarry Smith   ex->its            = 1;
22439e5bc791SBarry Smith   ex->tol            = 1.e-8;
22449e5bc791SBarry Smith   ex->relax_type     = 1;
22459e5bc791SBarry Smith   ex->rap_type       = 0;
22469e5bc791SBarry Smith   ex->num_pre_relax  = 1;
22479e5bc791SBarry Smith   ex->num_post_relax = 1;
22483b46a515SGlenn Hammond   ex->max_levels     = 0;
22499e5bc791SBarry Smith 
2250ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2251ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2252ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2253f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
22549e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
225568326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
22562fa5cd67SKarl Rupp 
2257ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2258fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2259ebc551c0SBarry Smith   PetscFunctionReturn(0);
2260ebc551c0SBarry Smith }
2261d851a50bSGlenn Hammond 
2262325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2263325fc9f4SBarry Smith 
2264d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2265d851a50bSGlenn Hammond typedef struct {
2266d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2267d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2268d851a50bSGlenn Hammond 
2269d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
22704ddd07fcSJed Brown   PetscInt its;
2271d851a50bSGlenn Hammond   double   tol;
22724ddd07fcSJed Brown   PetscInt relax_type;
22734ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2274d851a50bSGlenn Hammond } PC_SysPFMG;
2275d851a50bSGlenn Hammond 
2276d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2277d851a50bSGlenn Hammond {
2278d851a50bSGlenn Hammond   PetscErrorCode ierr;
2279d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2280d851a50bSGlenn Hammond 
2281d851a50bSGlenn Hammond   PetscFunctionBegin;
22822fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2283d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2284c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2285d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2286d851a50bSGlenn Hammond }
2287d851a50bSGlenn Hammond 
2288d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2289d851a50bSGlenn Hammond 
2290d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2291d851a50bSGlenn Hammond {
2292d851a50bSGlenn Hammond   PetscErrorCode ierr;
2293ace3abfcSBarry Smith   PetscBool      iascii;
2294d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2295d851a50bSGlenn Hammond 
2296d851a50bSGlenn Hammond   PetscFunctionBegin;
2297251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2298d851a50bSGlenn Hammond   if (iascii) {
2299d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2300efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  max iterations %d\n",ex->its);CHKERRQ(ierr);
2301efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerance %g\n",ex->tol);CHKERRQ(ierr);
2302efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2303efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2304d851a50bSGlenn Hammond   }
2305d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2306d851a50bSGlenn Hammond }
2307d851a50bSGlenn Hammond 
23084416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2309d851a50bSGlenn Hammond {
2310d851a50bSGlenn Hammond   PetscErrorCode ierr;
2311d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2312ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2313d851a50bSGlenn Hammond 
2314d851a50bSGlenn Hammond   PetscFunctionBegin;
2315e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
23160298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2317d851a50bSGlenn Hammond   if (flg) {
2318d851a50bSGlenn Hammond     int level=3;
2319fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
2320d851a50bSGlenn Hammond   }
23210298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2322fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
23230298fd71SBarry 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);
2324fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
23250298fd71SBarry 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);
2326fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2327d851a50bSGlenn Hammond 
23280298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2329fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
233061710fbeSStefano 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);
2331fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2332d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2333d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2334d851a50bSGlenn Hammond }
2335d851a50bSGlenn Hammond 
2336d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2337d851a50bSGlenn Hammond {
2338d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2339d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2340d9ca1df4SBarry Smith   PetscScalar       *yy;
2341d9ca1df4SBarry Smith   const PetscScalar *xx;
23424ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
23432cf14000SStefano Zampini   HYPRE_Int         hlower[3],hupper[3];
2344d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
23454ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
23464ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
23474ddd07fcSJed Brown   PetscInt          part    = 0;
23484ddd07fcSJed Brown   PetscInt          size;
23494ddd07fcSJed Brown   PetscInt          i;
2350d851a50bSGlenn Hammond 
2351d851a50bSGlenn Hammond   PetscFunctionBegin;
2352dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2353aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
23542cf14000SStefano Zampini   /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
2355d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2356d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2357d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
23582cf14000SStefano Zampini   hlower[0]  = (HYPRE_Int)ilower[0];
23592cf14000SStefano Zampini   hlower[1]  = (HYPRE_Int)ilower[1];
23602cf14000SStefano Zampini   hlower[2]  = (HYPRE_Int)ilower[2];
23612cf14000SStefano Zampini   hupper[0]  = (HYPRE_Int)iupper[0];
23622cf14000SStefano Zampini   hupper[1]  = (HYPRE_Int)iupper[1];
23632cf14000SStefano Zampini   hupper[2]  = (HYPRE_Int)iupper[2];
2364d851a50bSGlenn Hammond 
2365d851a50bSGlenn Hammond   size = 1;
23662fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
23672fa5cd67SKarl Rupp 
2368d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2369d851a50bSGlenn Hammond   if (ordering) {
2370fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2371d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2372*39accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(xx+(size*i))));
2373d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2374fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2375fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2376fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2377d851a50bSGlenn Hammond 
2378d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2379d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
2380*39accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(yy+(size*i))));
2381d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2382a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2383d851a50bSGlenn Hammond     PetscScalar *z;
23844ddd07fcSJed Brown     PetscInt    j, k;
2385d851a50bSGlenn Hammond 
2386785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2387fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2388d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2389d851a50bSGlenn Hammond 
2390d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2391d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2392d851a50bSGlenn Hammond       k= i*nvars;
23932fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2394d851a50bSGlenn Hammond     }
2395*39accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i))));
2396d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2397fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2398fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2399d851a50bSGlenn Hammond 
2400d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2401d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
2402*39accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i))));
2403d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2404d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2405d851a50bSGlenn Hammond       k= i*nvars;
24062fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2407d851a50bSGlenn Hammond     }
2408d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2409d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2410d851a50bSGlenn Hammond   }
2411d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2412d851a50bSGlenn Hammond }
2413d851a50bSGlenn Hammond 
2414ace3abfcSBarry 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)
2415d851a50bSGlenn Hammond {
2416d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2417d851a50bSGlenn Hammond   PetscErrorCode ierr;
24182cf14000SStefano Zampini   HYPRE_Int      oits;
2419d851a50bSGlenn Hammond 
2420d851a50bSGlenn Hammond   PetscFunctionBegin;
2421dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2422fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2423fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2424d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
24252cf14000SStefano Zampini   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,&oits));
2426d851a50bSGlenn Hammond   *outits = oits;
2427d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2428d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2429fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2430fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2431d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2432d851a50bSGlenn Hammond }
2433d851a50bSGlenn Hammond 
2434d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2435d851a50bSGlenn Hammond {
2436d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2437d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2438d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2439ace3abfcSBarry Smith   PetscBool        flg;
2440d851a50bSGlenn Hammond 
2441d851a50bSGlenn Hammond   PetscFunctionBegin;
2442251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2443ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2444d851a50bSGlenn Hammond 
2445d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
24462fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2447fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2448fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2449fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2450d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2451d851a50bSGlenn Hammond }
2452d851a50bSGlenn Hammond 
2453d851a50bSGlenn Hammond /*MC
2454d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2455d851a50bSGlenn Hammond 
2456d851a50bSGlenn Hammond    Level: advanced
2457d851a50bSGlenn Hammond 
2458d851a50bSGlenn Hammond    Options Database:
2459d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2460d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2461d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2462d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2463d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2464d851a50bSGlenn Hammond 
246595452b02SPatrick Sanan    Notes:
246695452b02SPatrick Sanan     This is for CELL-centered descretizations
2467d851a50bSGlenn Hammond 
2468f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2469aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2470d851a50bSGlenn Hammond            Also, only cell-centered variables.
2471d851a50bSGlenn Hammond 
2472d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2473d851a50bSGlenn Hammond M*/
2474d851a50bSGlenn Hammond 
24758cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2476d851a50bSGlenn Hammond {
2477d851a50bSGlenn Hammond   PetscErrorCode ierr;
2478d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2479d851a50bSGlenn Hammond 
2480d851a50bSGlenn Hammond   PetscFunctionBegin;
2481b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2482d851a50bSGlenn Hammond   pc->data = ex;
2483d851a50bSGlenn Hammond 
2484d851a50bSGlenn Hammond   ex->its            = 1;
2485d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2486d851a50bSGlenn Hammond   ex->relax_type     = 1;
2487d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2488d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2489d851a50bSGlenn Hammond 
2490d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2491d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2492d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2493d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2494d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2495d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
24962fa5cd67SKarl Rupp 
2497ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2498fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2499d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2500d851a50bSGlenn Hammond }
2501