xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision efd4aadf157bf1ba2d80c2be092fcf4247860003)
116d9e3a6SLisandro Dalcin 
216d9e3a6SLisandro Dalcin /*
316d9e3a6SLisandro Dalcin    Provides an interface to the LLNL package hypre
416d9e3a6SLisandro Dalcin */
50f1074feSSatish Balay 
60f1074feSSatish Balay /* Must use hypre 2.0.0 or more recent. */
70f1074feSSatish Balay 
8af0996ceSBarry Smith #include <petsc/private/pcimpl.h>          /*I "petscpc.h" I*/
949a781f5SStefano Zampini /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1049a781f5SStefano Zampini #include <petsc/private/matimpl.h>
1158968eb6SStefano Zampini #include <../src/vec/vec/impls/hypre/vhyp.h>
1249a781f5SStefano Zampini #include <../src/mat/impls/hypre/mhypre.h>
13c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h>
144cb006feSStefano Zampini #include <_hypre_parcsr_ls.h>
1516d9e3a6SLisandro Dalcin 
16dff31646SBarry Smith static PetscBool cite = PETSC_FALSE;
171f817a21SBarry Smith static const char hypreCitation[] = "@manual{hypre-web-page,\n  title  = {{\\sl hypre}: High Performance Preconditioners},\n  organization = {Lawrence Livermore National Laboratory},\n  note  = {\\url{http://www.llnl.gov/CASC/hypre/}}\n}\n";
181f817a21SBarry Smith 
1916d9e3a6SLisandro Dalcin /*
2016d9e3a6SLisandro Dalcin    Private context (data structure) for the  preconditioner.
2116d9e3a6SLisandro Dalcin */
2216d9e3a6SLisandro Dalcin typedef struct {
2316d9e3a6SLisandro Dalcin   HYPRE_Solver   hsolver;
2449a781f5SStefano Zampini   Mat            hpmat; /* MatHYPRE */
2516d9e3a6SLisandro Dalcin 
264ddd07fcSJed Brown   HYPRE_Int (*destroy)(HYPRE_Solver);
274ddd07fcSJed Brown   HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
284ddd07fcSJed Brown   HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
2916d9e3a6SLisandro Dalcin 
3016d9e3a6SLisandro Dalcin   MPI_Comm comm_hypre;
3116d9e3a6SLisandro Dalcin   char     *hypre_type;
3216d9e3a6SLisandro Dalcin 
3316d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
344ddd07fcSJed Brown   PetscInt maxiter;
3516d9e3a6SLisandro Dalcin   double   tol;
3616d9e3a6SLisandro Dalcin 
3716d9e3a6SLisandro Dalcin   /* options for Pilut */
384ddd07fcSJed Brown   PetscInt factorrowsize;
3916d9e3a6SLisandro Dalcin 
4016d9e3a6SLisandro Dalcin   /* options for ParaSails */
414ddd07fcSJed Brown   PetscInt nlevels;
4216d9e3a6SLisandro Dalcin   double   threshhold;
4316d9e3a6SLisandro Dalcin   double   filter;
444ddd07fcSJed Brown   PetscInt sym;
4516d9e3a6SLisandro Dalcin   double   loadbal;
464ddd07fcSJed Brown   PetscInt logging;
474ddd07fcSJed Brown   PetscInt ruse;
484ddd07fcSJed Brown   PetscInt symt;
4916d9e3a6SLisandro Dalcin 
5022b6d1caSBarry Smith   /* options for BoomerAMG */
51ace3abfcSBarry Smith   PetscBool printstatistics;
5216d9e3a6SLisandro Dalcin 
5316d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
544ddd07fcSJed Brown   PetscInt  cycletype;
554ddd07fcSJed Brown   PetscInt  maxlevels;
5616d9e3a6SLisandro Dalcin   double    strongthreshold;
5716d9e3a6SLisandro Dalcin   double    maxrowsum;
584ddd07fcSJed Brown   PetscInt  gridsweeps[3];
594ddd07fcSJed Brown   PetscInt  coarsentype;
604ddd07fcSJed Brown   PetscInt  measuretype;
616a251517SEike Mueller   PetscInt  smoothtype;
628131ecf7SEike Mueller   PetscInt  smoothnumlevels;
63ec64516dSEike Mueller   PetscInt  eu_level;   /* Number of levels for ILU(k) in Euclid */
64ec64516dSEike Mueller   double    eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */
65ec64516dSEike Mueller   PetscInt  eu_bj;      /* Defines use of Block Jacobi ILU in Euclid */
664ddd07fcSJed Brown   PetscInt  relaxtype[3];
6716d9e3a6SLisandro Dalcin   double    relaxweight;
6816d9e3a6SLisandro Dalcin   double    outerrelaxweight;
694ddd07fcSJed Brown   PetscInt  relaxorder;
7016d9e3a6SLisandro Dalcin   double    truncfactor;
71ace3abfcSBarry Smith   PetscBool applyrichardson;
724ddd07fcSJed Brown   PetscInt  pmax;
734ddd07fcSJed Brown   PetscInt  interptype;
744ddd07fcSJed Brown   PetscInt  agg_nl;
754ddd07fcSJed Brown   PetscInt  agg_num_paths;
764ddd07fcSJed Brown   PetscInt  nodal_coarsen;
77ace3abfcSBarry Smith   PetscBool nodal_relax;
784ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
794cb006feSStefano Zampini 
805272c319SBarry Smith   PetscInt  nodal_coarsening;
815272c319SBarry Smith   PetscInt  vec_interp_variant;
825272c319SBarry Smith   HYPRE_IJVector  *hmnull;
835272c319SBarry Smith   HYPRE_ParVector *phmnull;  /* near null space passed to hypre */
845272c319SBarry Smith   PetscInt        n_hmnull;
855272c319SBarry Smith   Vec             hmnull_constant;
8672827435SBarry Smith   PetscScalar     **hmnull_hypre_data_array;   /* this is the space in hmnull that was allocated by hypre, it is restored to hypre just before freeing the phmnull vectors */
875272c319SBarry Smith 
88863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
89863406b8SStefano Zampini   PetscInt  as_print;
90863406b8SStefano Zampini   PetscInt  as_max_iter;
91863406b8SStefano Zampini   PetscReal as_tol;
92863406b8SStefano Zampini   PetscInt  as_relax_type;
93863406b8SStefano Zampini   PetscInt  as_relax_times;
94863406b8SStefano Zampini   PetscReal as_relax_weight;
95863406b8SStefano Zampini   PetscReal as_omega;
96863406b8SStefano 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) */
97863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
98863406b8SStefano 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) */
99863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
1004cb006feSStefano Zampini   PetscInt  ams_cycle_type;
101863406b8SStefano Zampini   PetscInt  ads_cycle_type;
1024cb006feSStefano Zampini 
1034cb006feSStefano Zampini   /* additional data */
1045ac14e1cSStefano Zampini   Mat G;             /* MatHYPRE */
1055ac14e1cSStefano Zampini   Mat C;             /* MatHYPRE */
1065ac14e1cSStefano Zampini   Mat alpha_Poisson; /* MatHYPRE */
1075ac14e1cSStefano Zampini   Mat beta_Poisson;  /* MatHYPRE */
1085ac14e1cSStefano Zampini 
1095ac14e1cSStefano Zampini   /* extra information for AMS */
1105ac14e1cSStefano Zampini   PetscInt       dim; /* geometrical dimension */
1114cb006feSStefano Zampini   HYPRE_IJVector coords[3];
1124cb006feSStefano Zampini   HYPRE_IJVector constants[3];
1134cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
11423df4f25SStefano Zampini   PetscBool      ams_beta_is_zero_part;
11523df4f25SStefano Zampini   PetscInt       ams_proj_freq;
11616d9e3a6SLisandro Dalcin } PC_HYPRE;
11716d9e3a6SLisandro Dalcin 
118d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
119d2128fa2SBarry Smith {
120d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
121d2128fa2SBarry Smith 
122d2128fa2SBarry Smith   PetscFunctionBegin;
123d2128fa2SBarry Smith   *hsolver = jac->hsolver;
124d2128fa2SBarry Smith   PetscFunctionReturn(0);
125d2128fa2SBarry Smith }
12616d9e3a6SLisandro Dalcin 
12716d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
12816d9e3a6SLisandro Dalcin {
12916d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
13049a781f5SStefano Zampini   Mat_HYPRE          *hjac;
13116d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
13216d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
13349a781f5SStefano Zampini   PetscBool          ishypre;
13449a781f5SStefano Zampini   PetscErrorCode     ierr;
13516d9e3a6SLisandro Dalcin 
13616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
13716d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
13802a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
13916d9e3a6SLisandro Dalcin   }
1405f5c5b43SBarry Smith 
14149a781f5SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRE,&ishypre);CHKERRQ(ierr);
14249a781f5SStefano Zampini   if (!ishypre) {
14349a781f5SStefano Zampini     MatReuse reuse;
14449a781f5SStefano Zampini     if (pc->setupcalled) reuse = MAT_REUSE_MATRIX;
14549a781f5SStefano Zampini     else reuse = MAT_INITIAL_MATRIX;
14649a781f5SStefano Zampini     ierr = MatConvert(pc->pmat,MATHYPRE,reuse,&jac->hpmat);CHKERRQ(ierr);
14749a781f5SStefano Zampini   } else {
14849a781f5SStefano Zampini     ierr = PetscObjectReference((PetscObject)pc->pmat);CHKERRQ(ierr);
14949a781f5SStefano Zampini     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
15049a781f5SStefano Zampini     jac->hpmat = pc->pmat;
15116d9e3a6SLisandro Dalcin   }
15249a781f5SStefano Zampini   hjac = (Mat_HYPRE*)(jac->hpmat->data);
1535f5c5b43SBarry Smith 
15416d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
15516d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
1565272c319SBarry Smith     MatNullSpace    mnull;
1575272c319SBarry Smith     PetscBool       has_const;
15849a781f5SStefano Zampini     PetscInt        bs,nvec,i;
1595272c319SBarry Smith     const Vec       *vecs;
16072827435SBarry Smith     PetscScalar     *petscvecarray;
1615272c319SBarry Smith 
16216d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1632fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
1645272c319SBarry Smith     ierr = MatGetNearNullSpace(pc->mat, &mnull);CHKERRQ(ierr);
1655272c319SBarry Smith     if (mnull) {
1665272c319SBarry Smith       ierr = MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs);CHKERRQ(ierr);
1675272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull);CHKERRQ(ierr);
16872827435SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull_hypre_data_array);CHKERRQ(ierr);
1695272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->phmnull);CHKERRQ(ierr);
1705272c319SBarry Smith       for (i=0; i<nvec; i++) {
1715272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(vecs[i],&jac->hmnull[i]);CHKERRQ(ierr);
17272827435SBarry Smith         ierr = VecGetArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
17358968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],petscvecarray,jac->hmnull_hypre_data_array[i]);
17472827435SBarry Smith         ierr = VecRestoreArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
1755272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[i],(void**)&jac->phmnull[i]));
1765272c319SBarry Smith       }
1775272c319SBarry Smith       if (has_const) {
1785272c319SBarry Smith         ierr = MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL);CHKERRQ(ierr);
1795272c319SBarry Smith         ierr = VecSet(jac->hmnull_constant,1);CHKERRQ(ierr);
1805272c319SBarry Smith         ierr = VecNormalize(jac->hmnull_constant,NULL);
1815272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(jac->hmnull_constant,&jac->hmnull[nvec]);CHKERRQ(ierr);
18272827435SBarry Smith         ierr = VecGetArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
18358968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[nvec],petscvecarray,jac->hmnull_hypre_data_array[nvec]);
18472827435SBarry Smith         ierr = VecRestoreArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
1855272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[nvec],(void**)&jac->phmnull[nvec]));
1865272c319SBarry Smith         nvec++;
1875272c319SBarry Smith       }
1885272c319SBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVectors,(jac->hsolver,nvec,jac->phmnull));
1895272c319SBarry Smith       jac->n_hmnull = nvec;
1905272c319SBarry Smith     }
1914cb006feSStefano Zampini   }
192863406b8SStefano Zampini 
1934cb006feSStefano Zampini   /* special case for AMS */
1944cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
1955ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
1965ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
19749a781f5SStefano Zampini     if (!jac->coords[0] && !jac->constants[0]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the edge constant vectors via PCHYPRESetEdgeConstantVectors()");
1985ac14e1cSStefano Zampini     if (jac->dim) {
1995ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,jac->dim));
2005ac14e1cSStefano Zampini     }
2015ac14e1cSStefano Zampini     if (jac->constants[0]) {
2025ac14e1cSStefano Zampini       HYPRE_ParVector ozz,zoz,zzo = NULL;
2035ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&ozz)));
2045ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&zoz)));
2055ac14e1cSStefano Zampini       if (jac->constants[2]) {
2065ac14e1cSStefano Zampini         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&zzo)));
2075ac14e1cSStefano Zampini       }
2085ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,ozz,zoz,zzo));
2095ac14e1cSStefano Zampini     }
2105ac14e1cSStefano Zampini     if (jac->coords[0]) {
2115ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
2125ac14e1cSStefano Zampini       coords[0] = NULL;
2135ac14e1cSStefano Zampini       coords[1] = NULL;
2145ac14e1cSStefano Zampini       coords[2] = NULL;
2155ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
2165ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
2175ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
2185ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
2195ac14e1cSStefano Zampini     }
22049a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
2215ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
2225ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2235ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr));
2245ac14e1cSStefano Zampini     if (jac->alpha_Poisson) {
2255ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->alpha_Poisson->data);
2265ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2275ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr));
2285ac14e1cSStefano Zampini     }
2295ac14e1cSStefano Zampini     if (jac->ams_beta_is_zero) {
2305ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
2315ac14e1cSStefano Zampini     } else if (jac->beta_Poisson) {
2325ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->beta_Poisson->data);
2335ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2345ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr));
2355ac14e1cSStefano Zampini     }
2364cb006feSStefano Zampini   }
237863406b8SStefano Zampini   /* special case for ADS */
238863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
2395ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2405ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
24149a781f5SStefano Zampini     if (!jac->coords[0]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the coordinate vectors via PCSetCoordinates()");
24237096e45SBarry 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");
24349a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
24449a781f5SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient");
2455ac14e1cSStefano Zampini     if (jac->coords[0]) {
2465ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
2475ac14e1cSStefano Zampini       coords[0] = NULL;
2485ac14e1cSStefano Zampini       coords[1] = NULL;
2495ac14e1cSStefano Zampini       coords[2] = NULL;
2505ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
2515ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
2525ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
2535ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_ADSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
2545ac14e1cSStefano Zampini     }
2555ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
2565ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2575ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteGradient,(jac->hsolver,parcsr));
2585ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->C->data);
2595ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2605ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteCurl,(jac->hsolver,parcsr));
261863406b8SStefano Zampini   }
26249a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
26349a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&bv));
26449a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&xv));
265fd3f9acdSBarry Smith   PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr););
26616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
26716d9e3a6SLisandro Dalcin }
26816d9e3a6SLisandro Dalcin 
26916d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
27016d9e3a6SLisandro Dalcin {
27116d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
27249a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
27316d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
27416d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
275d9ca1df4SBarry Smith   PetscScalar        *xv;
276d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
27716d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
278d9ca1df4SBarry Smith   PetscScalar        *sxv;
2794ddd07fcSJed Brown   PetscInt           hierr;
28016d9e3a6SLisandro Dalcin 
28116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
282dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
28316d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
284d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
28516d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
28658968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)bv,sbv);
28758968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
28816d9e3a6SLisandro Dalcin 
28949a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
29049a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
29149a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
292fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
29365e19b50SBarry Smith                                if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
294fd3f9acdSBarry Smith                                if (hierr) hypre__global_error = 0;);
29516d9e3a6SLisandro Dalcin 
29623df4f25SStefano Zampini   if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) {
2975ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSProjectOutGradients,(jac->hsolver,jxv));
29821df291bSStefano Zampini   }
29958968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)sbv,bv);
30058968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
30116d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
302d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
30316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
30416d9e3a6SLisandro Dalcin }
30516d9e3a6SLisandro Dalcin 
3068695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc)
3078695de01SBarry Smith {
3088695de01SBarry Smith   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
3098695de01SBarry Smith   PetscErrorCode ierr;
3108695de01SBarry Smith 
3118695de01SBarry Smith   PetscFunctionBegin;
31249a781f5SStefano Zampini   ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
3135ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
3145ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
3155ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
3165ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
3178695de01SBarry Smith   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); jac->coords[0] = NULL;
3188695de01SBarry Smith   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); jac->coords[1] = NULL;
3198695de01SBarry Smith   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); jac->coords[2] = NULL;
3208695de01SBarry Smith   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); jac->constants[0] = NULL;
3218695de01SBarry Smith   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); jac->constants[1] = NULL;
3228695de01SBarry Smith   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); jac->constants[2] = NULL;
323550a8b7dSBarry Smith   if (jac->n_hmnull && jac->hmnull) {
3245272c319SBarry Smith     PetscInt                 i;
325b1c1cd91SBarry Smith     PETSC_UNUSED PetscScalar *petscvecarray;
3265272c319SBarry Smith 
3275272c319SBarry Smith     for (i=0; i<jac->n_hmnull; i++) {
32858968eb6SStefano Zampini       VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],jac->hmnull_hypre_data_array[i],petscvecarray);
3295272c319SBarry Smith       PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->hmnull[i]));
3305272c319SBarry Smith     }
3315272c319SBarry Smith     ierr = PetscFree(jac->hmnull);CHKERRQ(ierr);
33272827435SBarry Smith     ierr = PetscFree(jac->hmnull_hypre_data_array);CHKERRQ(ierr);
3335272c319SBarry Smith     ierr = PetscFree(jac->phmnull);CHKERRQ(ierr);
3345272c319SBarry Smith     ierr = VecDestroy(&jac->hmnull_constant);CHKERRQ(ierr);
3355272c319SBarry Smith   }
3365ac14e1cSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
3375ac14e1cSStefano Zampini   jac->dim = 0;
3388695de01SBarry Smith   PetscFunctionReturn(0);
3398695de01SBarry Smith }
3408695de01SBarry Smith 
34116d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
34216d9e3a6SLisandro Dalcin {
34316d9e3a6SLisandro Dalcin   PC_HYPRE                 *jac = (PC_HYPRE*)pc->data;
34416d9e3a6SLisandro Dalcin   PetscErrorCode           ierr;
34516d9e3a6SLisandro Dalcin 
34616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
3478695de01SBarry Smith   ierr = PCReset_HYPRE(pc);CHKERRQ(ierr);
348226b0620SJed Brown   if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr););
349503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
35016d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
351c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
35216d9e3a6SLisandro Dalcin 
35316d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
354bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
355bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
3564cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
3574cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
358863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
3594cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
3605ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",NULL);CHKERRQ(ierr);
36116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
36216d9e3a6SLisandro Dalcin }
36316d9e3a6SLisandro Dalcin 
36416d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
3654416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptionItems *PetscOptionsObject,PC pc)
36616d9e3a6SLisandro Dalcin {
36716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
36816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
369ace3abfcSBarry Smith   PetscBool      flag;
37016d9e3a6SLisandro Dalcin 
37116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
372e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
37316d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
374fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
37516d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
376fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
37716d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
378fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
37916d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
38016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
38116d9e3a6SLisandro Dalcin }
38216d9e3a6SLisandro Dalcin 
38316d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
38416d9e3a6SLisandro Dalcin {
38516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
38616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
387ace3abfcSBarry Smith   PetscBool      iascii;
38816d9e3a6SLisandro Dalcin 
38916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
390251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
39116d9e3a6SLisandro Dalcin   if (iascii) {
39216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
39316d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
394*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
39516d9e3a6SLisandro Dalcin     } else {
396*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default maximum number of iterations \n");CHKERRQ(ierr);
39716d9e3a6SLisandro Dalcin     }
39816d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
399*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
40016d9e3a6SLisandro Dalcin     } else {
401*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default drop tolerance \n");CHKERRQ(ierr);
40216d9e3a6SLisandro Dalcin     }
40316d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
404*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
40516d9e3a6SLisandro Dalcin     } else {
406*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default factor row size \n");CHKERRQ(ierr);
40716d9e3a6SLisandro Dalcin     }
40816d9e3a6SLisandro Dalcin   }
40916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
41016d9e3a6SLisandro Dalcin }
41116d9e3a6SLisandro Dalcin 
41216d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
41316d9e3a6SLisandro Dalcin 
41416d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
41516d9e3a6SLisandro Dalcin {
41616d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
41749a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
41816d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
41916d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
420d9ca1df4SBarry Smith   PetscScalar        *xv;
421d9ca1df4SBarry Smith   const PetscScalar  *bv;
42216d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
42316d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
4244ddd07fcSJed Brown   PetscInt           hierr;
42516d9e3a6SLisandro Dalcin 
42616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
427dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
42816d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
429d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
43016d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
43158968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)bv,sbv);
43258968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
43316d9e3a6SLisandro Dalcin 
43449a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
43549a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
43649a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
43716d9e3a6SLisandro Dalcin 
43816d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
43916d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
440e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
44116d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
44216d9e3a6SLisandro Dalcin 
44358968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,sbv,bv);
44458968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
44516d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
446d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
44716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
44816d9e3a6SLisandro Dalcin }
44916d9e3a6SLisandro Dalcin 
450a669f990SJed Brown /* static array length */
451a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
452a669f990SJed Brown 
45316d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
4540f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
45516d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
45665de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
4576a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]   = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
45865de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
45965de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
46065de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
46165de4495SJed Brown                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */,
46265de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
4630f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
464e2287abbSStefano Zampini                                                   "ext+i-cc", "standard", "standard-wts", "block", "block-wtd", "FF", "FF1"};
4654416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc)
46616d9e3a6SLisandro Dalcin {
46716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
46816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
4694ddd07fcSJed Brown   PetscInt       n,indx,level;
470ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
47116d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
47216d9e3a6SLisandro Dalcin 
47316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
474e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
4754336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
47616d9e3a6SLisandro Dalcin   if (flg) {
4774336a9eeSBarry Smith     jac->cycletype = indx+1;
478fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
47916d9e3a6SLisandro Dalcin   }
48016d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
48116d9e3a6SLisandro Dalcin   if (flg) {
482ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
483fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
48416d9e3a6SLisandro Dalcin   }
48516d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
48616d9e3a6SLisandro Dalcin   if (flg) {
487ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
488fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
48916d9e3a6SLisandro Dalcin   }
4900f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_tol","Convergence tolerance PER hypre call (0.0 = use a fixed number of iterations)","None",jac->tol,&jac->tol,&flg);CHKERRQ(ierr);
49116d9e3a6SLisandro Dalcin   if (flg) {
49257622a8eSBarry 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);
493fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
49416d9e3a6SLisandro Dalcin   }
49516d9e3a6SLisandro Dalcin 
4960f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
49716d9e3a6SLisandro Dalcin   if (flg) {
49857622a8eSBarry 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);
499fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
50016d9e3a6SLisandro Dalcin   }
50116d9e3a6SLisandro Dalcin 
5020f1074feSSatish 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);
5030f1074feSSatish Balay   if (flg) {
50457622a8eSBarry 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);
505fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
5060f1074feSSatish Balay   }
5070f1074feSSatish Balay 
5080f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
5090f1074feSSatish Balay   if (flg) {
51057622a8eSBarry 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);
5110f1074feSSatish Balay 
512fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
5130f1074feSSatish Balay   }
5140f1074feSSatish Balay 
5150f1074feSSatish Balay 
5160f1074feSSatish 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);
5170f1074feSSatish Balay   if (flg) {
51857622a8eSBarry 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);
5190f1074feSSatish Balay 
520fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
5210f1074feSSatish Balay   }
5220f1074feSSatish Balay 
5230f1074feSSatish Balay 
52416d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
52516d9e3a6SLisandro Dalcin   if (flg) {
52657622a8eSBarry 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);
527fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
52816d9e3a6SLisandro Dalcin   }
52916d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
53016d9e3a6SLisandro Dalcin   if (flg) {
53157622a8eSBarry 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);
53257622a8eSBarry 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);
533fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
53416d9e3a6SLisandro Dalcin   }
53516d9e3a6SLisandro Dalcin 
53616d9e3a6SLisandro Dalcin   /* Grid sweeps */
5370f1074feSSatish 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);
53816d9e3a6SLisandro Dalcin   if (flg) {
539fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
54016d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
54116d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
5420f1074feSSatish Balay     jac->gridsweeps[1] = indx;
5430f1074feSSatish Balay     /*defaults coarse to 1 */
5440f1074feSSatish Balay     jac->gridsweeps[2] = 1;
54516d9e3a6SLisandro Dalcin   }
5460f1074feSSatish Balay 
5475272c319SBarry 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);
5485272c319SBarry Smith   if (flg) {
5495272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,jac->nodal_coarsening));
5505272c319SBarry Smith   }
5515272c319SBarry Smith 
552cbc39033SBarry 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);
5535272c319SBarry Smith   if (flg) {
5545272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,(jac->hsolver,jac->vec_interp_variant));
5555272c319SBarry Smith   }
5565272c319SBarry Smith 
5570f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
55816d9e3a6SLisandro Dalcin   if (flg) {
559fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
5600f1074feSSatish Balay     jac->gridsweeps[0] = indx;
56116d9e3a6SLisandro Dalcin   }
56216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
56316d9e3a6SLisandro Dalcin   if (flg) {
564fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
5650f1074feSSatish Balay     jac->gridsweeps[1] = indx;
56616d9e3a6SLisandro Dalcin   }
5670f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
56816d9e3a6SLisandro Dalcin   if (flg) {
569fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
5700f1074feSSatish Balay     jac->gridsweeps[2] = indx;
57116d9e3a6SLisandro Dalcin   }
57216d9e3a6SLisandro Dalcin 
5736a251517SEike Mueller   /* Smooth type */
5746a251517SEike Mueller   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);
5756a251517SEike Mueller   if (flg) {
5766a251517SEike Mueller     jac->smoothtype = indx;
5776a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
5788131ecf7SEike Mueller     jac->smoothnumlevels = 25;
5798131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
5808131ecf7SEike Mueller   }
5818131ecf7SEike Mueller 
5828131ecf7SEike Mueller   /* Number of smoothing levels */
5838131ecf7SEike 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);
5848131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
5858131ecf7SEike Mueller     jac->smoothnumlevels = indx;
5868131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
5876a251517SEike Mueller   }
5886a251517SEike Mueller 
5891810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
5901810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
5911810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
5921810e44eSEike Mueller     jac->eu_level = indx;
5931810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
5941810e44eSEike Mueller   }
5951810e44eSEike Mueller 
5961810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
5971810e44eSEike Mueller   double droptolerance;
5981810e44eSEike Mueller   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
5991810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
6001810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
6011810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
6021810e44eSEike Mueller   }
6031810e44eSEike Mueller 
6041810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
6051810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
6061810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
6071810e44eSEike Mueller     jac->eu_bj = tmp_truth;
608493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
6091810e44eSEike Mueller   }
6101810e44eSEike Mueller 
61116d9e3a6SLisandro Dalcin   /* Relax type */
612a669f990SJed 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);
61316d9e3a6SLisandro Dalcin   if (flg) {
6140f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
615fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
6160f1074feSSatish Balay     /* by default, coarse type set to 9 */
6170f1074feSSatish Balay     jac->relaxtype[2] = 9;
6180f1074feSSatish Balay 
61916d9e3a6SLisandro Dalcin   }
620a669f990SJed 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);
62116d9e3a6SLisandro Dalcin   if (flg) {
62216d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
623fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
62416d9e3a6SLisandro Dalcin   }
625a669f990SJed 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);
62616d9e3a6SLisandro Dalcin   if (flg) {
6270f1074feSSatish Balay     jac->relaxtype[1] = indx;
628fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
62916d9e3a6SLisandro Dalcin   }
630a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
63116d9e3a6SLisandro Dalcin   if (flg) {
6320f1074feSSatish Balay     jac->relaxtype[2] = indx;
633fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
63416d9e3a6SLisandro Dalcin   }
63516d9e3a6SLisandro Dalcin 
63616d9e3a6SLisandro Dalcin   /* Relaxation Weight */
63716d9e3a6SLisandro 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);
63816d9e3a6SLisandro Dalcin   if (flg) {
639fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
64016d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
64116d9e3a6SLisandro Dalcin   }
64216d9e3a6SLisandro Dalcin 
64316d9e3a6SLisandro Dalcin   n         = 2;
64416d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
64516d9e3a6SLisandro 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);
64616d9e3a6SLisandro Dalcin   if (flg) {
64716d9e3a6SLisandro Dalcin     if (n == 2) {
64816d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
649fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
650ce94432eSBarry 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);
65116d9e3a6SLisandro Dalcin   }
65216d9e3a6SLisandro Dalcin 
65316d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
65416d9e3a6SLisandro 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);
65516d9e3a6SLisandro Dalcin   if (flg) {
656fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
65716d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
65816d9e3a6SLisandro Dalcin   }
65916d9e3a6SLisandro Dalcin 
66016d9e3a6SLisandro Dalcin   n         = 2;
66116d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
66216d9e3a6SLisandro 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);
66316d9e3a6SLisandro Dalcin   if (flg) {
66416d9e3a6SLisandro Dalcin     if (n == 2) {
66516d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
666fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
667ce94432eSBarry 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);
66816d9e3a6SLisandro Dalcin   }
66916d9e3a6SLisandro Dalcin 
67016d9e3a6SLisandro Dalcin   /* the Relax Order */
671acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
67216d9e3a6SLisandro Dalcin 
6738afaa268SBarry Smith   if (flg && tmp_truth) {
67416d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
675fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
67616d9e3a6SLisandro Dalcin   }
677a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
67816d9e3a6SLisandro Dalcin   if (flg) {
67916d9e3a6SLisandro Dalcin     jac->measuretype = indx;
680fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
68116d9e3a6SLisandro Dalcin   }
6820f1074feSSatish Balay   /* update list length 3/07 */
683a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
68416d9e3a6SLisandro Dalcin   if (flg) {
68516d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
686fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
68716d9e3a6SLisandro Dalcin   }
6880f1074feSSatish Balay 
6890f1074feSSatish Balay   /* new 3/07 */
690a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
6910f1074feSSatish Balay   if (flg) {
6920f1074feSSatish Balay     jac->interptype = indx;
693fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
6940f1074feSSatish Balay   }
6950f1074feSSatish Balay 
696b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
69716d9e3a6SLisandro Dalcin   if (flg) {
698b96a4a96SBarry Smith     level = 3;
6990298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
7002fa5cd67SKarl Rupp 
701b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
702fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
7032ae77aedSBarry Smith   }
7042ae77aedSBarry Smith 
705b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
7062ae77aedSBarry Smith   if (flg) {
707b96a4a96SBarry Smith     level = 3;
7080298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
7092fa5cd67SKarl Rupp 
710b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
711fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
71216d9e3a6SLisandro Dalcin   }
7138f87f92bSBarry Smith 
714acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
7158f87f92bSBarry Smith   if (flg && tmp_truth) {
7168f87f92bSBarry Smith     PetscInt tmp_int;
7178f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
7188f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
719fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
720fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
721fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
722fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
7238f87f92bSBarry Smith   }
7248f87f92bSBarry Smith 
72516d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
72616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
72716d9e3a6SLisandro Dalcin }
72816d9e3a6SLisandro Dalcin 
729ace3abfcSBarry 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)
73016d9e3a6SLisandro Dalcin {
73116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
73216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
7334ddd07fcSJed Brown   PetscInt       oits;
73416d9e3a6SLisandro Dalcin 
73516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
736dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
737fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
738fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
73916d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
74016d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
74116d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
7428b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
7434d0a8057SBarry Smith   *outits = oits;
7444d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
7454d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
746fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
747fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
74816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
74916d9e3a6SLisandro Dalcin }
75016d9e3a6SLisandro Dalcin 
75116d9e3a6SLisandro Dalcin 
75216d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
75316d9e3a6SLisandro Dalcin {
75416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
75516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
756ace3abfcSBarry Smith   PetscBool      iascii;
75716d9e3a6SLisandro Dalcin 
75816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
759251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
76016d9e3a6SLisandro Dalcin   if (iascii) {
76116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
762*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
763*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
764*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
765*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
766*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
767*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
768*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
769*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
770*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
7710f1074feSSatish Balay 
772*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
77316d9e3a6SLisandro Dalcin 
774*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
775*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
776*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
77716d9e3a6SLisandro Dalcin 
778*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
779*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
780*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
78116d9e3a6SLisandro Dalcin 
782*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
783*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
78416d9e3a6SLisandro Dalcin 
78516d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
786*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using CF-relaxation\n");CHKERRQ(ierr);
78716d9e3a6SLisandro Dalcin     } else {
788*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using CF-relaxation\n");CHKERRQ(ierr);
78916d9e3a6SLisandro Dalcin     }
7906a251517SEike Mueller     if (jac->smoothtype!=-1) {
791*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
792*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth num levels    %d\n",jac->smoothnumlevels);CHKERRQ(ierr);
7937e352d70SEike Mueller     } else {
794*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using more complex smoothers.\n");CHKERRQ(ierr);
7951810e44eSEike Mueller     }
7961810e44eSEike Mueller     if (jac->smoothtype==3) {
797*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) levels %d\n",jac->eu_level);CHKERRQ(ierr);
798*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) drop tolerance %g\n",jac->eu_droptolerance);CHKERRQ(ierr);
799*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU use Block-Jacobi? %d\n",jac->eu_bj);CHKERRQ(ierr);
8006a251517SEike Mueller     }
801*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
802*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
803*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
8045272c319SBarry Smith     if (jac->nodal_coarsening) {
805*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
8065272c319SBarry Smith     }
8075272c319SBarry Smith     if (jac->vec_interp_variant) {
808*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
8098f87f92bSBarry Smith     }
8108f87f92bSBarry Smith     if (jac->nodal_relax) {
811*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
8128f87f92bSBarry Smith     }
81316d9e3a6SLisandro Dalcin   }
81416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
81516d9e3a6SLisandro Dalcin }
81616d9e3a6SLisandro Dalcin 
81716d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
8184416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc)
81916d9e3a6SLisandro Dalcin {
82016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
82116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
8224ddd07fcSJed Brown   PetscInt       indx;
823ace3abfcSBarry Smith   PetscBool      flag;
82416d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
82516d9e3a6SLisandro Dalcin 
82616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
827e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
82816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
82916d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
8302fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
83116d9e3a6SLisandro Dalcin 
83216d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
8332fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
83416d9e3a6SLisandro Dalcin 
83516d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
8362fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
83716d9e3a6SLisandro Dalcin 
838acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
8392fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
84016d9e3a6SLisandro Dalcin 
841acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
8422fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
84316d9e3a6SLisandro Dalcin 
844a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
84516d9e3a6SLisandro Dalcin   if (flag) {
84616d9e3a6SLisandro Dalcin     jac->symt = indx;
847fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
84816d9e3a6SLisandro Dalcin   }
84916d9e3a6SLisandro Dalcin 
85016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
85116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
85216d9e3a6SLisandro Dalcin }
85316d9e3a6SLisandro Dalcin 
85416d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
85516d9e3a6SLisandro Dalcin {
85616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
85716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
858ace3abfcSBarry Smith   PetscBool      iascii;
85916d9e3a6SLisandro Dalcin   const char     *symt = 0;;
86016d9e3a6SLisandro Dalcin 
86116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
862251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
86316d9e3a6SLisandro Dalcin   if (iascii) {
86416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
865*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
866*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
867*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    filter %g\n",(double)jac->filter);CHKERRQ(ierr);
868*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
869*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
870*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
8712fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
8722fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
8732fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
874ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
875*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    %s\n",symt);CHKERRQ(ierr);
87616d9e3a6SLisandro Dalcin   }
87716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
87816d9e3a6SLisandro Dalcin }
8794cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
8804416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc)
8814cb006feSStefano Zampini {
8824cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
8834cb006feSStefano Zampini   PetscErrorCode ierr;
8844cb006feSStefano Zampini   PetscInt       n;
8854cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
8864cb006feSStefano Zampini 
8874cb006feSStefano Zampini   PetscFunctionBegin;
8889fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
889863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
890863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
891863406b8SStefano 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);
892863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
8934cb006feSStefano 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);
8944cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
895863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
896863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
897863406b8SStefano 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);
898863406b8SStefano 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);
899863406b8SStefano 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);
900863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
9014cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
902863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
903863406b8SStefano Zampini                                                                       jac->as_relax_times,
904863406b8SStefano Zampini                                                                       jac->as_relax_weight,
905863406b8SStefano Zampini                                                                       jac->as_omega));
9064cb006feSStefano Zampini   }
907863406b8SStefano 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);
9084cb006feSStefano Zampini   n = 5;
909863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
9104cb006feSStefano Zampini   if (flag || flag2) {
911863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
912863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
913863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
914863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
915863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
916863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
9174cb006feSStefano Zampini   }
918863406b8SStefano 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);
9194cb006feSStefano Zampini   n = 5;
920863406b8SStefano 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);
9214cb006feSStefano Zampini   if (flag || flag2) {
922863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
923863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
924863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
925863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
926863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
927863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
9284cb006feSStefano Zampini   }
92923df4f25SStefano 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);
93023df4f25SStefano Zampini   if (flag) { /* override HYPRE's default only if the options is used */
93123df4f25SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetProjectionFrequency,(jac->hsolver,jac->ams_proj_freq));
93223df4f25SStefano Zampini   }
9334cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
9344cb006feSStefano Zampini   PetscFunctionReturn(0);
9354cb006feSStefano Zampini }
9364cb006feSStefano Zampini 
9374cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
9384cb006feSStefano Zampini {
9394cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
9404cb006feSStefano Zampini   PetscErrorCode ierr;
9414cb006feSStefano Zampini   PetscBool      iascii;
9424cb006feSStefano Zampini 
9434cb006feSStefano Zampini   PetscFunctionBegin;
9444cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
9454cb006feSStefano Zampini   if (iascii) {
9464cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
947*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
948*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
949*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
950*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
951*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
952*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
953*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
9544cb006feSStefano Zampini     if (jac->alpha_Poisson) {
955*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
9564cb006feSStefano Zampini     } else {
957*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (computed) \n");CHKERRQ(ierr);
9584cb006feSStefano Zampini     }
959*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
960*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
961*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
962*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
963*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
964*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
9654cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
9664cb006feSStefano Zampini       if (jac->beta_Poisson) {
967*efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
9684cb006feSStefano Zampini       } else {
969*efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (computed) \n");CHKERRQ(ierr);
9704cb006feSStefano Zampini       }
971*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
972*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
973*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
974*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
975*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
976*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
97723df4f25SStefano Zampini       if (jac->ams_beta_is_zero_part) {
978*efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"        compatible subspace projection frequency %d (-1 HYPRE uses default)\n",jac->ams_proj_freq);CHKERRQ(ierr);
97923df4f25SStefano Zampini       }
98023df4f25SStefano Zampini     } else {
981*efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver not used (zero-conductivity everywhere) \n");CHKERRQ(ierr);
9824cb006feSStefano Zampini     }
9834cb006feSStefano Zampini   }
9844cb006feSStefano Zampini   PetscFunctionReturn(0);
9854cb006feSStefano Zampini }
9864cb006feSStefano Zampini 
9874416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc)
988863406b8SStefano Zampini {
989863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
990863406b8SStefano Zampini   PetscErrorCode ierr;
991863406b8SStefano Zampini   PetscInt       n;
992863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
993863406b8SStefano Zampini 
994863406b8SStefano Zampini   PetscFunctionBegin;
995863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
996863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
997863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
998863406b8SStefano 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);
999863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1000863406b8SStefano 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);
1001863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
1002863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1003863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1004863406b8SStefano 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);
1005863406b8SStefano 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);
1006863406b8SStefano 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);
1007863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
1008863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1009863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1010863406b8SStefano Zampini                                                                       jac->as_relax_times,
1011863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1012863406b8SStefano Zampini                                                                       jac->as_omega));
1013863406b8SStefano Zampini   }
1014863406b8SStefano 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);
1015863406b8SStefano Zampini   n = 5;
1016863406b8SStefano 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);
1017863406b8SStefano 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);
1018863406b8SStefano Zampini   if (flag || flag2 || flag3) {
1019863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
1020863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1021863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1022863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1023863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1024863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1025863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1026863406b8SStefano Zampini   }
1027863406b8SStefano 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);
1028863406b8SStefano Zampini   n = 5;
1029863406b8SStefano 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);
1030863406b8SStefano Zampini   if (flag || flag2) {
1031863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1032863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1033863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1034863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1035863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1036863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1037863406b8SStefano Zampini   }
1038863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
1039863406b8SStefano Zampini   PetscFunctionReturn(0);
1040863406b8SStefano Zampini }
1041863406b8SStefano Zampini 
1042863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1043863406b8SStefano Zampini {
1044863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1045863406b8SStefano Zampini   PetscErrorCode ierr;
1046863406b8SStefano Zampini   PetscBool      iascii;
1047863406b8SStefano Zampini 
1048863406b8SStefano Zampini   PetscFunctionBegin;
1049863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1050863406b8SStefano Zampini   if (iascii) {
1051863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
1052*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1053*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
1054*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1055*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1056*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1057*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1058*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
1059*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    AMS solver using boomerAMG\n");CHKERRQ(ierr);
1060*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1061*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1062*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1063*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1064*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1065*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1066*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
1067*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver using boomerAMG\n");CHKERRQ(ierr);
1068*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1069*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1070*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1071*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1072*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1073*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
1074863406b8SStefano Zampini   }
1075863406b8SStefano Zampini   PetscFunctionReturn(0);
1076863406b8SStefano Zampini }
1077863406b8SStefano Zampini 
1078863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
10794cb006feSStefano Zampini {
10804cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
10815ac14e1cSStefano Zampini   PetscBool      ishypre;
10824cb006feSStefano Zampini   PetscErrorCode ierr;
10834cb006feSStefano Zampini 
10844cb006feSStefano Zampini   PetscFunctionBegin;
10855ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)G,MATHYPRE,&ishypre);CHKERRQ(ierr);
10865ac14e1cSStefano Zampini   if (ishypre) {
10875ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr);
10885ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
10895ac14e1cSStefano Zampini     jac->G = G;
10905ac14e1cSStefano Zampini   } else {
10915ac14e1cSStefano Zampini     MatReuse reuse = MAT_INITIAL_MATRIX;
10925ac14e1cSStefano Zampini     if (jac->G) reuse = MAT_REUSE_MATRIX;
10935ac14e1cSStefano Zampini     ierr = MatConvert(G,MATHYPRE,reuse,&jac->G);CHKERRQ(ierr);
10945ac14e1cSStefano Zampini   }
10954cb006feSStefano Zampini   PetscFunctionReturn(0);
10964cb006feSStefano Zampini }
10974cb006feSStefano Zampini 
10984cb006feSStefano Zampini /*@
10994cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
11004cb006feSStefano Zampini 
11014cb006feSStefano Zampini    Collective on PC
11024cb006feSStefano Zampini 
11034cb006feSStefano Zampini    Input Parameters:
11044cb006feSStefano Zampini +  pc - the preconditioning context
11054cb006feSStefano Zampini -  G - the discrete gradient
11064cb006feSStefano Zampini 
11074cb006feSStefano Zampini    Level: intermediate
11084cb006feSStefano Zampini 
11094cb006feSStefano Zampini    Notes: G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh
1110863406b8SStefano 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
11114cb006feSStefano Zampini 
11124cb006feSStefano Zampini .seealso:
11134cb006feSStefano Zampini @*/
11144cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
11154cb006feSStefano Zampini {
11164cb006feSStefano Zampini   PetscErrorCode ierr;
11174cb006feSStefano Zampini 
11184cb006feSStefano Zampini   PetscFunctionBegin;
11194cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11204cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
11214cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
11224cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
11234cb006feSStefano Zampini   PetscFunctionReturn(0);
11244cb006feSStefano Zampini }
11254cb006feSStefano Zampini 
1126863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1127863406b8SStefano Zampini {
1128863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
11295ac14e1cSStefano Zampini   PetscBool      ishypre;
1130863406b8SStefano Zampini   PetscErrorCode ierr;
1131863406b8SStefano Zampini 
1132863406b8SStefano Zampini   PetscFunctionBegin;
11335ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)C,MATHYPRE,&ishypre);CHKERRQ(ierr);
11345ac14e1cSStefano Zampini   if (ishypre) {
11355ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr);
11365ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
11375ac14e1cSStefano Zampini     jac->C = C;
11385ac14e1cSStefano Zampini   } else {
11395ac14e1cSStefano Zampini     MatReuse reuse = MAT_INITIAL_MATRIX;
11405ac14e1cSStefano Zampini     if (jac->C) reuse = MAT_REUSE_MATRIX;
11415ac14e1cSStefano Zampini     ierr = MatConvert(C,MATHYPRE,reuse,&jac->C);CHKERRQ(ierr);
11425ac14e1cSStefano Zampini   }
1143863406b8SStefano Zampini   PetscFunctionReturn(0);
1144863406b8SStefano Zampini }
1145863406b8SStefano Zampini 
1146863406b8SStefano Zampini /*@
1147863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1148863406b8SStefano Zampini 
1149863406b8SStefano Zampini    Collective on PC
1150863406b8SStefano Zampini 
1151863406b8SStefano Zampini    Input Parameters:
1152863406b8SStefano Zampini +  pc - the preconditioning context
1153863406b8SStefano Zampini -  C - the discrete curl
1154863406b8SStefano Zampini 
1155863406b8SStefano Zampini    Level: intermediate
1156863406b8SStefano Zampini 
1157863406b8SStefano Zampini    Notes: C should have as many rows as the number of faces and as many columns as the number of edges in the mesh
1158863406b8SStefano 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
1159863406b8SStefano Zampini 
1160863406b8SStefano Zampini .seealso:
1161863406b8SStefano Zampini @*/
1162863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1163863406b8SStefano Zampini {
1164863406b8SStefano Zampini   PetscErrorCode ierr;
1165863406b8SStefano Zampini 
1166863406b8SStefano Zampini   PetscFunctionBegin;
1167863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1168863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1169863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1170863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1171863406b8SStefano Zampini   PetscFunctionReturn(0);
1172863406b8SStefano Zampini }
1173863406b8SStefano Zampini 
11745ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha)
11754cb006feSStefano Zampini {
11764cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
11775ac14e1cSStefano Zampini   PetscBool      ishypre;
11784cb006feSStefano Zampini   PetscErrorCode ierr;
11794cb006feSStefano Zampini 
11804cb006feSStefano Zampini   PetscFunctionBegin;
11815ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr);
11825ac14e1cSStefano Zampini   if (ishypre) {
11835ac14e1cSStefano Zampini     if (isalpha) {
11845ac14e1cSStefano Zampini       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
11855ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
11865ac14e1cSStefano Zampini       jac->alpha_Poisson = A;
11875ac14e1cSStefano Zampini     } else {
11885ac14e1cSStefano Zampini       if (A) {
11895ac14e1cSStefano Zampini         ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
11905ac14e1cSStefano Zampini       } else {
11915ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
11925ac14e1cSStefano Zampini       }
11935ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
11945ac14e1cSStefano Zampini       jac->beta_Poisson = A;
11955ac14e1cSStefano Zampini     }
11965ac14e1cSStefano Zampini   } else {
11975ac14e1cSStefano Zampini     if (isalpha) {
11985ac14e1cSStefano Zampini       MatReuse reuse = MAT_INITIAL_MATRIX;
11995ac14e1cSStefano Zampini       if (jac->alpha_Poisson) reuse = MAT_REUSE_MATRIX;
12005ac14e1cSStefano Zampini       ierr = MatConvert(A,MATHYPRE,reuse,&jac->alpha_Poisson);CHKERRQ(ierr);
12015ac14e1cSStefano Zampini     } else {
12025ac14e1cSStefano Zampini       if (A) {
12035ac14e1cSStefano Zampini         MatReuse reuse = MAT_INITIAL_MATRIX;
12045ac14e1cSStefano Zampini         if (jac->beta_Poisson) reuse = MAT_REUSE_MATRIX;
12055ac14e1cSStefano Zampini         ierr = MatConvert(A,MATHYPRE,reuse,&jac->beta_Poisson);CHKERRQ(ierr);
12065ac14e1cSStefano Zampini       } else {
12075ac14e1cSStefano Zampini         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
12085ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
12095ac14e1cSStefano Zampini       }
12105ac14e1cSStefano Zampini     }
12115ac14e1cSStefano Zampini   }
12124cb006feSStefano Zampini   PetscFunctionReturn(0);
12134cb006feSStefano Zampini }
12144cb006feSStefano Zampini 
12154cb006feSStefano Zampini /*@
12164cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
12174cb006feSStefano Zampini 
12184cb006feSStefano Zampini    Collective on PC
12194cb006feSStefano Zampini 
12204cb006feSStefano Zampini    Input Parameters:
12214cb006feSStefano Zampini +  pc - the preconditioning context
12224cb006feSStefano Zampini -  A - the matrix
12234cb006feSStefano Zampini 
12244cb006feSStefano Zampini    Level: intermediate
12254cb006feSStefano Zampini 
12264cb006feSStefano Zampini    Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
12274cb006feSStefano Zampini 
12284cb006feSStefano Zampini .seealso:
12294cb006feSStefano Zampini @*/
12304cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
12314cb006feSStefano Zampini {
12324cb006feSStefano Zampini   PetscErrorCode ierr;
12334cb006feSStefano Zampini 
12344cb006feSStefano Zampini   PetscFunctionBegin;
12354cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12364cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
12374cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
12385ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_TRUE));CHKERRQ(ierr);
12394cb006feSStefano Zampini   PetscFunctionReturn(0);
12404cb006feSStefano Zampini }
12414cb006feSStefano Zampini 
12424cb006feSStefano Zampini /*@
12434cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
12444cb006feSStefano Zampini 
12454cb006feSStefano Zampini    Collective on PC
12464cb006feSStefano Zampini 
12474cb006feSStefano Zampini    Input Parameters:
12484cb006feSStefano Zampini +  pc - the preconditioning context
12494cb006feSStefano Zampini -  A - the matrix
12504cb006feSStefano Zampini 
12514cb006feSStefano Zampini    Level: intermediate
12524cb006feSStefano Zampini 
12534cb006feSStefano Zampini    Notes: A should be obtained by discretizing the Poisson problem with linear finite elements.
12544cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
12554cb006feSStefano Zampini 
12564cb006feSStefano Zampini .seealso:
12574cb006feSStefano Zampini @*/
12584cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
12594cb006feSStefano Zampini {
12604cb006feSStefano Zampini   PetscErrorCode ierr;
12614cb006feSStefano Zampini 
12624cb006feSStefano Zampini   PetscFunctionBegin;
12634cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12644cb006feSStefano Zampini   if (A) {
12654cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
12664cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
12674cb006feSStefano Zampini   }
12685ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_FALSE));CHKERRQ(ierr);
12694cb006feSStefano Zampini   PetscFunctionReturn(0);
12704cb006feSStefano Zampini }
12714cb006feSStefano Zampini 
12725ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz, Vec zoz, Vec zzo)
12734cb006feSStefano Zampini {
12744cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
12754cb006feSStefano Zampini   PetscErrorCode     ierr;
12764cb006feSStefano Zampini 
12774cb006feSStefano Zampini   PetscFunctionBegin;
12784cb006feSStefano Zampini   /* throw away any vector if already set */
12794cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
12804cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
12814cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
12824cb006feSStefano Zampini   jac->constants[0] = NULL;
12834cb006feSStefano Zampini   jac->constants[1] = NULL;
12844cb006feSStefano Zampini   jac->constants[2] = NULL;
12854cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
12864cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
12874cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
12884cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
12895ac14e1cSStefano Zampini   jac->dim = 2;
12904cb006feSStefano Zampini   if (zzo) {
12914cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
12924cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
12935ac14e1cSStefano Zampini     jac->dim++;
12944cb006feSStefano Zampini   }
12954cb006feSStefano Zampini   PetscFunctionReturn(0);
12964cb006feSStefano Zampini }
12974cb006feSStefano Zampini 
12984cb006feSStefano Zampini /*@
12994cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
13004cb006feSStefano Zampini 
13014cb006feSStefano Zampini    Collective on PC
13024cb006feSStefano Zampini 
13034cb006feSStefano Zampini    Input Parameters:
13044cb006feSStefano Zampini +  pc - the preconditioning context
13054cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
13064cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
13074cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
13084cb006feSStefano Zampini 
13094cb006feSStefano Zampini    Level: intermediate
13104cb006feSStefano Zampini 
13114cb006feSStefano Zampini    Notes:
13124cb006feSStefano Zampini 
13134cb006feSStefano Zampini .seealso:
13144cb006feSStefano Zampini @*/
13154cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
13164cb006feSStefano Zampini {
13174cb006feSStefano Zampini   PetscErrorCode ierr;
13184cb006feSStefano Zampini 
13194cb006feSStefano Zampini   PetscFunctionBegin;
13204cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
13214cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
13224cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
13234cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
13244cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
13254cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
13264cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
13274cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
13284cb006feSStefano Zampini   PetscFunctionReturn(0);
13294cb006feSStefano Zampini }
13304cb006feSStefano Zampini 
1331863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
13324cb006feSStefano Zampini {
13334cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
13344cb006feSStefano Zampini   Vec             tv;
13354cb006feSStefano Zampini   PetscInt        i;
13364cb006feSStefano Zampini   PetscErrorCode  ierr;
13374cb006feSStefano Zampini 
13384cb006feSStefano Zampini   PetscFunctionBegin;
13394cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
13404cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
13414cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
13424cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
13435ac14e1cSStefano Zampini   jac->dim = dim;
13445ac14e1cSStefano Zampini 
13454cb006feSStefano Zampini   /* compute IJ vector for coordinates */
13464cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
13474cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
13484cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
13494cb006feSStefano Zampini   for (i=0;i<dim;i++) {
13504cb006feSStefano Zampini     PetscScalar *array;
13514cb006feSStefano Zampini     PetscInt    j;
13524cb006feSStefano Zampini 
13534cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
13544cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
13554cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
13564cb006feSStefano Zampini       array[j] = coords[j*dim+i];
13574cb006feSStefano Zampini     }
13584cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
13594cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
13604cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
13614cb006feSStefano Zampini   }
13624cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
13634cb006feSStefano Zampini   PetscFunctionReturn(0);
13644cb006feSStefano Zampini }
13654cb006feSStefano Zampini 
136616d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
136716d9e3a6SLisandro Dalcin 
1368f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
136916d9e3a6SLisandro Dalcin {
137016d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
137116d9e3a6SLisandro Dalcin 
137216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
137316d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
137416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
137516d9e3a6SLisandro Dalcin }
137616d9e3a6SLisandro Dalcin 
1377f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
137816d9e3a6SLisandro Dalcin {
137916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
138016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1381ace3abfcSBarry Smith   PetscBool      flag;
138216d9e3a6SLisandro Dalcin 
138316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
138416d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
138516d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1386ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
138716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
138816d9e3a6SLisandro Dalcin   } else {
138916d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
139016d9e3a6SLisandro Dalcin   }
139116d9e3a6SLisandro Dalcin 
139216d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
139316d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
139416d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
139516d9e3a6SLisandro Dalcin 
139616d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
139716d9e3a6SLisandro Dalcin   if (flag) {
1398fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
139916d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
140016d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
140116d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
140216d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
140316d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
140416d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
140516d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
140616d9e3a6SLisandro Dalcin   }
140716d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
140816d9e3a6SLisandro Dalcin   if (flag) {
1409fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
141016d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
141116d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
141216d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
141316d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
141416d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
141516d9e3a6SLisandro Dalcin     /* initialize */
141616d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
141716d9e3a6SLisandro Dalcin     jac->threshhold = .1;
141816d9e3a6SLisandro Dalcin     jac->filter     = .1;
141916d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
14202fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
14212fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
14222fa5cd67SKarl Rupp 
142316d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
142416d9e3a6SLisandro Dalcin     jac->symt = 0;
1425fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1426fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1427fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1428fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1429fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1430fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
143116d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
143216d9e3a6SLisandro Dalcin   }
143316d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
143416d9e3a6SLisandro Dalcin   if (flag) {
143516d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
143616d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
143716d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
143816d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
143916d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
144016d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
144116d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
144216d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
144316d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
144416d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
144516d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
144616d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
144716d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
14488f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
144916d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
145016d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
145116d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
145216d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
145316d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
14540f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
14556a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1456b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
14571810e44eSEike Mueller     jac->eu_level         = 0;
14581810e44eSEike Mueller     jac->eu_droptolerance = 0;
14591810e44eSEike Mueller     jac->eu_bj            = 0;
14608f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
14610f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
146216d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
146316d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
146416d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
14650f1074feSSatish Balay     jac->interptype       = 0;
14660f1074feSSatish Balay     jac->agg_nl           = 0;
14670f1074feSSatish Balay     jac->pmax             = 0;
14680f1074feSSatish Balay     jac->truncfactor      = 0.0;
14690f1074feSSatish Balay     jac->agg_num_paths    = 1;
14708f87f92bSBarry Smith 
14718f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
14728f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
14738f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1474fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1475fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1476fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1477fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1478fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1479fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1480fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1481fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1482fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1483fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1484fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1485fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1486fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1487fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1488fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1489fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
149016d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
149116d9e3a6SLisandro Dalcin   }
14924cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
14934cb006feSStefano Zampini   if (flag) {
14944cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
14954cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
14964cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
14974cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
14984cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
14994cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
15004cb006feSStefano Zampini     jac->coords[0]           = NULL;
15014cb006feSStefano Zampini     jac->coords[1]           = NULL;
15024cb006feSStefano Zampini     jac->coords[2]           = NULL;
15034cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1504863406b8SStefano Zampini     jac->as_print           = 0;
1505863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1506863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
15074cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
15084cb006feSStefano Zampini     /* Smoothing options */
1509863406b8SStefano Zampini     jac->as_relax_type      = 2;
1510863406b8SStefano Zampini     jac->as_relax_times     = 1;
1511863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1512863406b8SStefano Zampini     jac->as_omega           = 1.0;
15134cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1514863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1515863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
15160bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1517863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1518863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1519863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
15204cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1521863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1522863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
15230bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1524863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1525863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1526863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1527863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1528863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
15294cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1530863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1531863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1532863406b8SStefano Zampini                                                                       jac->as_relax_times,
1533863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1534863406b8SStefano Zampini                                                                       jac->as_omega));
1535863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1536863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1537863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1538863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1539863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1540863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1541863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1542863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1543863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1544863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1545863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1546863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
154723df4f25SStefano Zampini     /* Zero conductivity */
154823df4f25SStefano Zampini     jac->ams_beta_is_zero      = PETSC_FALSE;
154923df4f25SStefano Zampini     jac->ams_beta_is_zero_part = PETSC_FALSE;
15504cb006feSStefano Zampini     PetscFunctionReturn(0);
15514cb006feSStefano Zampini   }
1552863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1553863406b8SStefano Zampini   if (flag) {
1554863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1555863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1556863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1557863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1558863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1559863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1560863406b8SStefano Zampini     jac->coords[0]           = NULL;
1561863406b8SStefano Zampini     jac->coords[1]           = NULL;
1562863406b8SStefano Zampini     jac->coords[2]           = NULL;
1563863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1564863406b8SStefano Zampini     jac->as_print           = 0;
1565863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1566863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1567863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1568863406b8SStefano Zampini     /* Smoothing options */
1569863406b8SStefano Zampini     jac->as_relax_type      = 2;
1570863406b8SStefano Zampini     jac->as_relax_times     = 1;
1571863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1572863406b8SStefano Zampini     jac->as_omega           = 1.0;
1573863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1574863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1575863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1576863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1577863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1578863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1579863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1580863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1581863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1582863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1583863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1584863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1585863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1586863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1587863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1588863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1589863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1590863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1591863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1592863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1593863406b8SStefano Zampini                                                                       jac->as_relax_times,
1594863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1595863406b8SStefano Zampini                                                                       jac->as_omega));
1596863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1597863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1598863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1599863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1600863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1601863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1602863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1603863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1604863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1605863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1606863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1607863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1608863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1609863406b8SStefano Zampini     PetscFunctionReturn(0);
1610863406b8SStefano Zampini   }
1611503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
16122fa5cd67SKarl Rupp 
16130298fd71SBarry Smith   jac->hypre_type = NULL;
161433263987SBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, boomeramg, ams",name);
161516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
161616d9e3a6SLisandro Dalcin }
161716d9e3a6SLisandro Dalcin 
161816d9e3a6SLisandro Dalcin /*
161916d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
162016d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
162116d9e3a6SLisandro Dalcin */
16224416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc)
162316d9e3a6SLisandro Dalcin {
162416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
16254ddd07fcSJed Brown   PetscInt       indx;
1626863406b8SStefano Zampini   const char     *type[] = {"pilut","parasails","boomeramg","ams","ads"};
1627ace3abfcSBarry Smith   PetscBool      flg;
162816d9e3a6SLisandro Dalcin 
162916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16309fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
16319c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
163216d9e3a6SLisandro Dalcin   if (flg) {
163316d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
163402a17cd4SBarry Smith   } else {
163502a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
163616d9e3a6SLisandro Dalcin   }
163716d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
16383931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
163916d9e3a6SLisandro Dalcin   }
164016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
164116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
164216d9e3a6SLisandro Dalcin }
164316d9e3a6SLisandro Dalcin 
164416d9e3a6SLisandro Dalcin /*@C
164516d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
164616d9e3a6SLisandro Dalcin 
164716d9e3a6SLisandro Dalcin    Input Parameters:
164816d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1649863406b8SStefano Zampini -     name - either  pilut, parasails, boomeramg, ams, ads
165016d9e3a6SLisandro Dalcin 
165116d9e3a6SLisandro Dalcin    Options Database Keys:
1652863406b8SStefano Zampini    -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
165316d9e3a6SLisandro Dalcin 
165416d9e3a6SLisandro Dalcin    Level: intermediate
165516d9e3a6SLisandro Dalcin 
165616d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
165716d9e3a6SLisandro Dalcin            PCHYPRE
165816d9e3a6SLisandro Dalcin 
165916d9e3a6SLisandro Dalcin @*/
16607087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
166116d9e3a6SLisandro Dalcin {
16624ac538c5SBarry Smith   PetscErrorCode ierr;
166316d9e3a6SLisandro Dalcin 
166416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16650700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
166616d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
16674ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
166816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
166916d9e3a6SLisandro Dalcin }
167016d9e3a6SLisandro Dalcin 
167116d9e3a6SLisandro Dalcin /*@C
167216d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
167316d9e3a6SLisandro Dalcin 
167416d9e3a6SLisandro Dalcin    Input Parameter:
167516d9e3a6SLisandro Dalcin .     pc - the preconditioner context
167616d9e3a6SLisandro Dalcin 
167716d9e3a6SLisandro Dalcin    Output Parameter:
1678863406b8SStefano Zampini .     name - either  pilut, parasails, boomeramg, ams, ads
167916d9e3a6SLisandro Dalcin 
168016d9e3a6SLisandro Dalcin    Level: intermediate
168116d9e3a6SLisandro Dalcin 
168216d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
168316d9e3a6SLisandro Dalcin            PCHYPRE
168416d9e3a6SLisandro Dalcin 
168516d9e3a6SLisandro Dalcin @*/
16867087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
168716d9e3a6SLisandro Dalcin {
16884ac538c5SBarry Smith   PetscErrorCode ierr;
168916d9e3a6SLisandro Dalcin 
169016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16910700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
169216d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
16934ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
169416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
169516d9e3a6SLisandro Dalcin }
169616d9e3a6SLisandro Dalcin 
169716d9e3a6SLisandro Dalcin /*MC
169816d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
169916d9e3a6SLisandro Dalcin 
170016d9e3a6SLisandro Dalcin    Options Database Keys:
1701863406b8SStefano Zampini +   -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
170216d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
170316d9e3a6SLisandro Dalcin           preconditioner
170416d9e3a6SLisandro Dalcin 
170516d9e3a6SLisandro Dalcin    Level: intermediate
170616d9e3a6SLisandro Dalcin 
170716d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
170816d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
170916d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
171016d9e3a6SLisandro Dalcin 
1711c231f9e3SBarryFSmith           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_tol refer to the number of iterations
17120f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
17130f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
1714c231f9e3SBarryFSmith           (-pc_hypre_boomeramg_tol should be set to 0.0 - the default - to strictly use a fixed number of
17158f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
17160f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
17170f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
171816d9e3a6SLisandro Dalcin 
17190f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
17200f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
17210f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
172216d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
172316d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
172416d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
172516d9e3a6SLisandro Dalcin 
172616d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
172716d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
172816d9e3a6SLisandro Dalcin 
17295272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
17305272c319SBarry Smith           the two options:
17315272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
1732cbc39033SBarry Smith -   -pc_hypre_boomeramg_vec_interp_variant <v> where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
17335272c319SBarry Smith 
17345272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
17355272c319SBarry Smith 
17369e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
17379e5bc791SBarry Smith 
173816d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
17399e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
174016d9e3a6SLisandro Dalcin 
174116d9e3a6SLisandro Dalcin M*/
174216d9e3a6SLisandro Dalcin 
17438cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
174416d9e3a6SLisandro Dalcin {
174516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
174616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
174716d9e3a6SLisandro Dalcin 
174816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1749b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
17502fa5cd67SKarl Rupp 
175116d9e3a6SLisandro Dalcin   pc->data                = jac;
17528695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
175316d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
175416d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
175516d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
175616d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
175716d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
17584cb006feSStefano Zampini   jac->coords[0]          = NULL;
17594cb006feSStefano Zampini   jac->coords[1]          = NULL;
17604cb006feSStefano Zampini   jac->coords[2]          = NULL;
17614cb006feSStefano Zampini   jac->constants[0]       = NULL;
17624cb006feSStefano Zampini   jac->constants[1]       = NULL;
17634cb006feSStefano Zampini   jac->constants[2]       = NULL;
17645272c319SBarry Smith   jac->hmnull             = NULL;
17655272c319SBarry Smith   jac->n_hmnull           = 0;
176616d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1767ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1768bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1769bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
17705ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
17715ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
17725ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
17735ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE);CHKERRQ(ierr);
17745ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",PCHYPRESetPoissonMatrix_HYPRE);CHKERRQ(ierr);
177516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
177616d9e3a6SLisandro Dalcin }
1777ebc551c0SBarry Smith 
1778f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1779f91d8e95SBarry Smith 
1780ebc551c0SBarry Smith typedef struct {
178168326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1782f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
17839e5bc791SBarry Smith 
17849e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
17854ddd07fcSJed Brown   PetscInt its;
17869e5bc791SBarry Smith   double   tol;
17874ddd07fcSJed Brown   PetscInt relax_type;
17884ddd07fcSJed Brown   PetscInt rap_type;
17894ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
17904ddd07fcSJed Brown   PetscInt max_levels;
1791ebc551c0SBarry Smith } PC_PFMG;
1792ebc551c0SBarry Smith 
1793ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1794ebc551c0SBarry Smith {
1795ebc551c0SBarry Smith   PetscErrorCode ierr;
1796f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1797ebc551c0SBarry Smith 
1798ebc551c0SBarry Smith   PetscFunctionBegin;
17992fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1800f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1801c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1802ebc551c0SBarry Smith   PetscFunctionReturn(0);
1803ebc551c0SBarry Smith }
1804ebc551c0SBarry Smith 
18059e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
18069e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
18079e5bc791SBarry Smith 
1808ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1809ebc551c0SBarry Smith {
1810ebc551c0SBarry Smith   PetscErrorCode ierr;
1811ace3abfcSBarry Smith   PetscBool      iascii;
1812f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1813ebc551c0SBarry Smith 
1814ebc551c0SBarry Smith   PetscFunctionBegin;
1815251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
18169e5bc791SBarry Smith   if (iascii) {
18179e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
1818*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max iterations %d\n",ex->its);CHKERRQ(ierr);
1819*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    tolerance %g\n",ex->tol);CHKERRQ(ierr);
1820*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
1821*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
1822*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
1823*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max levels %d\n",ex->max_levels);CHKERRQ(ierr);
18249e5bc791SBarry Smith   }
1825ebc551c0SBarry Smith   PetscFunctionReturn(0);
1826ebc551c0SBarry Smith }
1827ebc551c0SBarry Smith 
18289e5bc791SBarry Smith 
18294416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc)
1830ebc551c0SBarry Smith {
1831ebc551c0SBarry Smith   PetscErrorCode ierr;
1832f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1833ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1834ebc551c0SBarry Smith 
1835ebc551c0SBarry Smith   PetscFunctionBegin;
1836e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
18370298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
183868326731SBarry Smith   if (flg) {
1839a0324ebeSBarry Smith     int level=3;
1840fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
184168326731SBarry Smith   }
18420298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1843fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
18440298fd71SBarry 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);
1845fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
18460298fd71SBarry 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);
1847fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
18489e5bc791SBarry Smith 
18490298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
1850fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
18513b46a515SGlenn Hammond 
18520298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1853fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
18540298fd71SBarry 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);
1855fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
18560298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
1857fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1858ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1859ebc551c0SBarry Smith   PetscFunctionReturn(0);
1860ebc551c0SBarry Smith }
1861ebc551c0SBarry Smith 
1862f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1863f91d8e95SBarry Smith {
1864f91d8e95SBarry Smith   PetscErrorCode    ierr;
1865f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
1866d9ca1df4SBarry Smith   PetscScalar       *yy;
1867d9ca1df4SBarry Smith   const PetscScalar *xx;
18684ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
186968326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1870f91d8e95SBarry Smith 
1871f91d8e95SBarry Smith   PetscFunctionBegin;
1872dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1873aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1874f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1875f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1876f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1877f91d8e95SBarry Smith 
1878f91d8e95SBarry Smith   /* copy x values over to hypre */
1879fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1880d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1881d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
1882d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1883fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
1884fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1885f91d8e95SBarry Smith 
1886f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1887f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
18888b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
1889f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1890f91d8e95SBarry Smith   PetscFunctionReturn(0);
1891f91d8e95SBarry Smith }
1892f91d8e95SBarry Smith 
1893ace3abfcSBarry 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)
18949e5bc791SBarry Smith {
18959e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
18969e5bc791SBarry Smith   PetscErrorCode ierr;
18974ddd07fcSJed Brown   PetscInt       oits;
18989e5bc791SBarry Smith 
18999e5bc791SBarry Smith   PetscFunctionBegin;
1900dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1901fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1902fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
19039e5bc791SBarry Smith 
19049e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
19058b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
19069e5bc791SBarry Smith   *outits = oits;
19079e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
19089e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1909fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1910fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
19119e5bc791SBarry Smith   PetscFunctionReturn(0);
19129e5bc791SBarry Smith }
19139e5bc791SBarry Smith 
19149e5bc791SBarry Smith 
19153a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
19163a32d3dbSGlenn Hammond {
19173a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
19183a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
19193a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1920ace3abfcSBarry Smith   PetscBool       flg;
19213a32d3dbSGlenn Hammond 
19223a32d3dbSGlenn Hammond   PetscFunctionBegin;
1923251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1924ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
19253a32d3dbSGlenn Hammond 
19263a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
19272fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1928fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1929fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1930fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
19313a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
19323a32d3dbSGlenn Hammond }
19333a32d3dbSGlenn Hammond 
1934ebc551c0SBarry Smith 
1935ebc551c0SBarry Smith /*MC
1936ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1937ebc551c0SBarry Smith 
1938ebc551c0SBarry Smith    Level: advanced
1939ebc551c0SBarry Smith 
19409e5bc791SBarry Smith    Options Database:
19419e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
19429e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
19439e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
19449e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
19459e5bc791SBarry 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
19469e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
1947f91d8e95SBarry Smith 
19489e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
19499e5bc791SBarry Smith 
19508e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
1951aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
19529e5bc791SBarry Smith 
19539e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
1954ebc551c0SBarry Smith M*/
1955ebc551c0SBarry Smith 
19568cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
1957ebc551c0SBarry Smith {
1958ebc551c0SBarry Smith   PetscErrorCode ierr;
1959ebc551c0SBarry Smith   PC_PFMG        *ex;
1960ebc551c0SBarry Smith 
1961ebc551c0SBarry Smith   PetscFunctionBegin;
1962b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
196368326731SBarry Smith   pc->data = ex;
1964ebc551c0SBarry Smith 
19659e5bc791SBarry Smith   ex->its            = 1;
19669e5bc791SBarry Smith   ex->tol            = 1.e-8;
19679e5bc791SBarry Smith   ex->relax_type     = 1;
19689e5bc791SBarry Smith   ex->rap_type       = 0;
19699e5bc791SBarry Smith   ex->num_pre_relax  = 1;
19709e5bc791SBarry Smith   ex->num_post_relax = 1;
19713b46a515SGlenn Hammond   ex->max_levels     = 0;
19729e5bc791SBarry Smith 
1973ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
1974ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
1975ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
1976f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
19779e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
197868326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
19792fa5cd67SKarl Rupp 
1980ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
1981fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1982ebc551c0SBarry Smith   PetscFunctionReturn(0);
1983ebc551c0SBarry Smith }
1984d851a50bSGlenn Hammond 
1985325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
1986325fc9f4SBarry Smith 
1987d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
1988d851a50bSGlenn Hammond typedef struct {
1989d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
1990d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
1991d851a50bSGlenn Hammond 
1992d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
19934ddd07fcSJed Brown   PetscInt its;
1994d851a50bSGlenn Hammond   double   tol;
19954ddd07fcSJed Brown   PetscInt relax_type;
19964ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
1997d851a50bSGlenn Hammond } PC_SysPFMG;
1998d851a50bSGlenn Hammond 
1999d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2000d851a50bSGlenn Hammond {
2001d851a50bSGlenn Hammond   PetscErrorCode ierr;
2002d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2003d851a50bSGlenn Hammond 
2004d851a50bSGlenn Hammond   PetscFunctionBegin;
20052fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2006d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2007c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2008d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2009d851a50bSGlenn Hammond }
2010d851a50bSGlenn Hammond 
2011d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2012d851a50bSGlenn Hammond 
2013d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2014d851a50bSGlenn Hammond {
2015d851a50bSGlenn Hammond   PetscErrorCode ierr;
2016ace3abfcSBarry Smith   PetscBool      iascii;
2017d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2018d851a50bSGlenn Hammond 
2019d851a50bSGlenn Hammond   PetscFunctionBegin;
2020251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2021d851a50bSGlenn Hammond   if (iascii) {
2022d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2023*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  max iterations %d\n",ex->its);CHKERRQ(ierr);
2024*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerance %g\n",ex->tol);CHKERRQ(ierr);
2025*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2026*efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2027d851a50bSGlenn Hammond   }
2028d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2029d851a50bSGlenn Hammond }
2030d851a50bSGlenn Hammond 
2031d851a50bSGlenn Hammond 
20324416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2033d851a50bSGlenn Hammond {
2034d851a50bSGlenn Hammond   PetscErrorCode ierr;
2035d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2036ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2037d851a50bSGlenn Hammond 
2038d851a50bSGlenn Hammond   PetscFunctionBegin;
2039e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
20400298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2041d851a50bSGlenn Hammond   if (flg) {
2042d851a50bSGlenn Hammond     int level=3;
2043fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
2044d851a50bSGlenn Hammond   }
20450298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2046fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
20470298fd71SBarry 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);
2048fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
20490298fd71SBarry 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);
2050fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2051d851a50bSGlenn Hammond 
20520298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2053fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
20540298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_syspfmg_relax_type","Relax type for the up and down cycles","HYPRE_SStructSysPFMGSetRelaxType",SysPFMGRelaxType,4,SysPFMGRelaxType[ex->relax_type],&ex->relax_type,NULL);CHKERRQ(ierr);
2055fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2056d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2057d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2058d851a50bSGlenn Hammond }
2059d851a50bSGlenn Hammond 
2060d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2061d851a50bSGlenn Hammond {
2062d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2063d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2064d9ca1df4SBarry Smith   PetscScalar       *yy;
2065d9ca1df4SBarry Smith   const PetscScalar *xx;
20664ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
2067d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
20684ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
20694ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
20704ddd07fcSJed Brown   PetscInt          part    = 0;
20714ddd07fcSJed Brown   PetscInt          size;
20724ddd07fcSJed Brown   PetscInt          i;
2073d851a50bSGlenn Hammond 
2074d851a50bSGlenn Hammond   PetscFunctionBegin;
2075dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2076aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2077d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2078d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2079d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2080d851a50bSGlenn Hammond 
2081d851a50bSGlenn Hammond   size = 1;
20822fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
20832fa5cd67SKarl Rupp 
2084d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2085d851a50bSGlenn Hammond   if (ordering) {
2086fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2087d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2088d9ca1df4SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,(PetscScalar*)xx+(size*i)));
2089d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2090fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2091fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2092fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2093d851a50bSGlenn Hammond 
2094d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2095d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
20968b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2097d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2098a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2099d851a50bSGlenn Hammond     PetscScalar *z;
21004ddd07fcSJed Brown     PetscInt    j, k;
2101d851a50bSGlenn Hammond 
2102785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2103fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2104d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2105d851a50bSGlenn Hammond 
2106d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2107d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2108d851a50bSGlenn Hammond       k= i*nvars;
21092fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2110d851a50bSGlenn Hammond     }
21118b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2112d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2113fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2114fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2115d851a50bSGlenn Hammond 
2116d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2117d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
21188b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2119d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2120d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2121d851a50bSGlenn Hammond       k= i*nvars;
21222fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2123d851a50bSGlenn Hammond     }
2124d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2125d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2126d851a50bSGlenn Hammond   }
2127d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2128d851a50bSGlenn Hammond }
2129d851a50bSGlenn Hammond 
2130ace3abfcSBarry 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)
2131d851a50bSGlenn Hammond {
2132d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2133d851a50bSGlenn Hammond   PetscErrorCode ierr;
21344ddd07fcSJed Brown   PetscInt       oits;
2135d851a50bSGlenn Hammond 
2136d851a50bSGlenn Hammond   PetscFunctionBegin;
2137dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2138fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2139fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2140d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
21418b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2142d851a50bSGlenn Hammond   *outits = oits;
2143d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2144d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2145fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2146fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2147d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2148d851a50bSGlenn Hammond }
2149d851a50bSGlenn Hammond 
2150d851a50bSGlenn Hammond 
2151d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2152d851a50bSGlenn Hammond {
2153d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2154d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2155d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2156ace3abfcSBarry Smith   PetscBool        flg;
2157d851a50bSGlenn Hammond 
2158d851a50bSGlenn Hammond   PetscFunctionBegin;
2159251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2160ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2161d851a50bSGlenn Hammond 
2162d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
21632fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2164fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2165fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2166fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2167d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2168d851a50bSGlenn Hammond }
2169d851a50bSGlenn Hammond 
2170d851a50bSGlenn Hammond 
2171d851a50bSGlenn Hammond /*MC
2172d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2173d851a50bSGlenn Hammond 
2174d851a50bSGlenn Hammond    Level: advanced
2175d851a50bSGlenn Hammond 
2176d851a50bSGlenn Hammond    Options Database:
2177d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2178d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2179d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2180d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2181d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2182d851a50bSGlenn Hammond 
2183d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
2184d851a50bSGlenn Hammond 
2185f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2186aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2187d851a50bSGlenn Hammond            Also, only cell-centered variables.
2188d851a50bSGlenn Hammond 
2189d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2190d851a50bSGlenn Hammond M*/
2191d851a50bSGlenn Hammond 
21928cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2193d851a50bSGlenn Hammond {
2194d851a50bSGlenn Hammond   PetscErrorCode ierr;
2195d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2196d851a50bSGlenn Hammond 
2197d851a50bSGlenn Hammond   PetscFunctionBegin;
2198b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2199d851a50bSGlenn Hammond   pc->data = ex;
2200d851a50bSGlenn Hammond 
2201d851a50bSGlenn Hammond   ex->its            = 1;
2202d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2203d851a50bSGlenn Hammond   ex->relax_type     = 1;
2204d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2205d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2206d851a50bSGlenn Hammond 
2207d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2208d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2209d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2210d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2211d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2212d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
22132fa5cd67SKarl Rupp 
2214ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2215fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2216d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2217d851a50bSGlenn Hammond }
2218