xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision ddbeb582aecdc2b45035d3207f6e8998d8902f5d)
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];
1136bf688a0SCe Qin   Mat            RT_PiFull, RT_Pi[3];
1146bf688a0SCe Qin   Mat            ND_PiFull, ND_Pi[3];
1154cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
11623df4f25SStefano Zampini   PetscBool      ams_beta_is_zero_part;
11723df4f25SStefano Zampini   PetscInt       ams_proj_freq;
11816d9e3a6SLisandro Dalcin } PC_HYPRE;
11916d9e3a6SLisandro Dalcin 
120d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
121d2128fa2SBarry Smith {
122d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
123d2128fa2SBarry Smith 
124d2128fa2SBarry Smith   PetscFunctionBegin;
125d2128fa2SBarry Smith   *hsolver = jac->hsolver;
126d2128fa2SBarry Smith   PetscFunctionReturn(0);
127d2128fa2SBarry Smith }
12816d9e3a6SLisandro Dalcin 
12916d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
13016d9e3a6SLisandro Dalcin {
13116d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
13249a781f5SStefano Zampini   Mat_HYPRE          *hjac;
13316d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
13416d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
13549a781f5SStefano Zampini   PetscBool          ishypre;
13649a781f5SStefano Zampini   PetscErrorCode     ierr;
13716d9e3a6SLisandro Dalcin 
13816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
13916d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
14002a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
14116d9e3a6SLisandro Dalcin   }
1425f5c5b43SBarry Smith 
14349a781f5SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRE,&ishypre);CHKERRQ(ierr);
14449a781f5SStefano Zampini   if (!ishypre) {
1456bf688a0SCe Qin     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
1466bf688a0SCe Qin     ierr = MatConvert(pc->pmat,MATHYPRE,MAT_INITIAL_MATRIX,&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;
1976bf688a0SCe Qin     if (!jac->coords[0] && !jac->constants[0] && !(jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
1986bf688a0SCe Qin       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the edge constant vectors via PCHYPRESetEdgeConstantVectors() or the interpolation matrix via PCHYPRESetInterpolations");
1996bf688a0SCe Qin     }
2005ac14e1cSStefano Zampini     if (jac->dim) {
2015ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,jac->dim));
2025ac14e1cSStefano Zampini     }
2035ac14e1cSStefano Zampini     if (jac->constants[0]) {
2045ac14e1cSStefano Zampini       HYPRE_ParVector ozz,zoz,zzo = NULL;
2055ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&ozz)));
2065ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&zoz)));
2075ac14e1cSStefano Zampini       if (jac->constants[2]) {
2085ac14e1cSStefano Zampini         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&zzo)));
2095ac14e1cSStefano Zampini       }
2105ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,ozz,zoz,zzo));
2115ac14e1cSStefano Zampini     }
2125ac14e1cSStefano Zampini     if (jac->coords[0]) {
2135ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
2145ac14e1cSStefano Zampini       coords[0] = NULL;
2155ac14e1cSStefano Zampini       coords[1] = NULL;
2165ac14e1cSStefano Zampini       coords[2] = NULL;
2175ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
2185ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
2195ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
2205ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
2215ac14e1cSStefano Zampini     }
22249a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
2235ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
2245ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2255ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr));
2265ac14e1cSStefano Zampini     if (jac->alpha_Poisson) {
2275ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->alpha_Poisson->data);
2285ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2295ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr));
2305ac14e1cSStefano Zampini     }
2315ac14e1cSStefano Zampini     if (jac->ams_beta_is_zero) {
2325ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
2335ac14e1cSStefano Zampini     } else if (jac->beta_Poisson) {
2345ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->beta_Poisson->data);
2355ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2365ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr));
2375ac14e1cSStefano Zampini     }
2386bf688a0SCe Qin     if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) {
2396bf688a0SCe Qin       PetscInt           i;
2406bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
2416bf688a0SCe Qin       if (jac->ND_PiFull) {
2426bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
2436bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
2446bf688a0SCe Qin       } else {
2456bf688a0SCe Qin         nd_parcsrfull = NULL;
2466bf688a0SCe Qin       }
2476bf688a0SCe Qin       for (i=0;i<3;++i) {
2486bf688a0SCe Qin         if (jac->ND_Pi[i]) {
2496bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
2506bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
2516bf688a0SCe Qin         } else {
2526bf688a0SCe Qin           nd_parcsr[i] = NULL;
2536bf688a0SCe Qin         }
2546bf688a0SCe Qin       }
2556bf688a0SCe Qin       PetscStackCallStandard(HYPRE_AMSSetInterpolations,(jac->hsolver,nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]));
2566bf688a0SCe Qin     }
2574cb006feSStefano Zampini   }
258863406b8SStefano Zampini   /* special case for ADS */
259863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
2605ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2615ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
2626bf688a0SCe Qin     if (!jac->coords[0] && !((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])))) {
2636bf688a0SCe Qin       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations");
2646bf688a0SCe Qin     }
26537096e45SBarry 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");
26649a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
26749a781f5SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient");
2685ac14e1cSStefano Zampini     if (jac->coords[0]) {
2695ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
2705ac14e1cSStefano Zampini       coords[0] = NULL;
2715ac14e1cSStefano Zampini       coords[1] = NULL;
2725ac14e1cSStefano Zampini       coords[2] = NULL;
2735ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
2745ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
2755ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
2765ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_ADSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
2775ac14e1cSStefano Zampini     }
2785ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
2795ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2805ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteGradient,(jac->hsolver,parcsr));
2815ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->C->data);
2825ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2835ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteCurl,(jac->hsolver,parcsr));
2846bf688a0SCe Qin     if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
2856bf688a0SCe Qin       PetscInt           i;
2866bf688a0SCe Qin       HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3];
2876bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
2886bf688a0SCe Qin       if (jac->RT_PiFull) {
2896bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->RT_PiFull->data);
2906bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsrfull)));
2916bf688a0SCe Qin       } else {
2926bf688a0SCe Qin         rt_parcsrfull = NULL;
2936bf688a0SCe Qin       }
2946bf688a0SCe Qin       for (i=0;i<3;++i) {
2956bf688a0SCe Qin         if (jac->RT_Pi[i]) {
2966bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->RT_Pi[i]->data);
2976bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsr[i])));
2986bf688a0SCe Qin         } else {
2996bf688a0SCe Qin           rt_parcsr[i] = NULL;
3006bf688a0SCe Qin         }
3016bf688a0SCe Qin       }
3026bf688a0SCe Qin       if (jac->ND_PiFull) {
3036bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
3046bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
3056bf688a0SCe Qin       } else {
3066bf688a0SCe Qin         nd_parcsrfull = NULL;
3076bf688a0SCe Qin       }
3086bf688a0SCe Qin       for (i=0;i<3;++i) {
3096bf688a0SCe Qin         if (jac->ND_Pi[i]) {
3106bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
3116bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
3126bf688a0SCe Qin         } else {
3136bf688a0SCe Qin           nd_parcsr[i] = NULL;
3146bf688a0SCe Qin         }
3156bf688a0SCe Qin       }
3166bf688a0SCe Qin       PetscStackCallStandard(HYPRE_ADSSetInterpolations,(jac->hsolver,rt_parcsrfull,rt_parcsr[0],rt_parcsr[1],rt_parcsr[2],nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]));
3176bf688a0SCe Qin     }
318863406b8SStefano Zampini   }
31949a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
32049a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&bv));
32149a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&xv));
322fd3f9acdSBarry Smith   PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr););
32316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
32416d9e3a6SLisandro Dalcin }
32516d9e3a6SLisandro Dalcin 
32616d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
32716d9e3a6SLisandro Dalcin {
32816d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
32949a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
33016d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
33116d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
332d9ca1df4SBarry Smith   PetscScalar        *xv;
333d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
33416d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
335d9ca1df4SBarry Smith   PetscScalar        *sxv;
3364ddd07fcSJed Brown   PetscInt           hierr;
33716d9e3a6SLisandro Dalcin 
33816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
339dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
34016d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
341d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
34216d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
34358968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)bv,sbv);
34458968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
34516d9e3a6SLisandro Dalcin 
34649a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
34749a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
34849a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
349fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
35065e19b50SBarry Smith   if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
351fd3f9acdSBarry Smith   if (hierr) hypre__global_error = 0;);
35216d9e3a6SLisandro Dalcin 
35323df4f25SStefano Zampini   if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) {
3545ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSProjectOutGradients,(jac->hsolver,jxv));
35521df291bSStefano Zampini   }
35658968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)sbv,bv);
35758968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
35816d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
359d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
36016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
36116d9e3a6SLisandro Dalcin }
36216d9e3a6SLisandro Dalcin 
3638695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc)
3648695de01SBarry Smith {
3658695de01SBarry Smith   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
3668695de01SBarry Smith   PetscErrorCode ierr;
3678695de01SBarry Smith 
3688695de01SBarry Smith   PetscFunctionBegin;
36949a781f5SStefano Zampini   ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
3705ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
3715ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
3725ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
3735ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
3746bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
3756bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[0]);CHKERRQ(ierr);
3766bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[1]);CHKERRQ(ierr);
3776bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[2]);CHKERRQ(ierr);
3786bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
3796bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[0]);CHKERRQ(ierr);
3806bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[1]);CHKERRQ(ierr);
3816bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[2]);CHKERRQ(ierr);
3828695de01SBarry Smith   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); jac->coords[0] = NULL;
3838695de01SBarry Smith   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); jac->coords[1] = NULL;
3848695de01SBarry Smith   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); jac->coords[2] = NULL;
3858695de01SBarry Smith   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); jac->constants[0] = NULL;
3868695de01SBarry Smith   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); jac->constants[1] = NULL;
3878695de01SBarry Smith   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); jac->constants[2] = NULL;
388550a8b7dSBarry Smith   if (jac->n_hmnull && jac->hmnull) {
3895272c319SBarry Smith     PetscInt                 i;
390b1c1cd91SBarry Smith     PETSC_UNUSED PetscScalar *petscvecarray;
3915272c319SBarry Smith 
3925272c319SBarry Smith     for (i=0; i<jac->n_hmnull; i++) {
39358968eb6SStefano Zampini       VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],jac->hmnull_hypre_data_array[i],petscvecarray);
3945272c319SBarry Smith       PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->hmnull[i]));
3955272c319SBarry Smith     }
3965272c319SBarry Smith     ierr = PetscFree(jac->hmnull);CHKERRQ(ierr);
39772827435SBarry Smith     ierr = PetscFree(jac->hmnull_hypre_data_array);CHKERRQ(ierr);
3985272c319SBarry Smith     ierr = PetscFree(jac->phmnull);CHKERRQ(ierr);
3995272c319SBarry Smith     ierr = VecDestroy(&jac->hmnull_constant);CHKERRQ(ierr);
4005272c319SBarry Smith   }
4015ac14e1cSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
4025ac14e1cSStefano Zampini   jac->dim = 0;
4038695de01SBarry Smith   PetscFunctionReturn(0);
4048695de01SBarry Smith }
4058695de01SBarry Smith 
40616d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
40716d9e3a6SLisandro Dalcin {
40816d9e3a6SLisandro Dalcin   PC_HYPRE                 *jac = (PC_HYPRE*)pc->data;
40916d9e3a6SLisandro Dalcin   PetscErrorCode           ierr;
41016d9e3a6SLisandro Dalcin 
41116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
4128695de01SBarry Smith   ierr = PCReset_HYPRE(pc);CHKERRQ(ierr);
413226b0620SJed Brown   if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr););
414503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
41516d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
416c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
41716d9e3a6SLisandro Dalcin 
41816d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
419bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
420bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
4214cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
4224cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
423863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
4246bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",NULL);CHKERRQ(ierr);
4254cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
4265ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",NULL);CHKERRQ(ierr);
42716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
42816d9e3a6SLisandro Dalcin }
42916d9e3a6SLisandro Dalcin 
43016d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
4314416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptionItems *PetscOptionsObject,PC pc)
43216d9e3a6SLisandro Dalcin {
43316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
43416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
435ace3abfcSBarry Smith   PetscBool      flag;
43616d9e3a6SLisandro Dalcin 
43716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
438e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
43916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
440fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
44116d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
442fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
44316d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
444fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
44516d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
44616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
44716d9e3a6SLisandro Dalcin }
44816d9e3a6SLisandro Dalcin 
44916d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
45016d9e3a6SLisandro Dalcin {
45116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
45216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
453ace3abfcSBarry Smith   PetscBool      iascii;
45416d9e3a6SLisandro Dalcin 
45516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
456251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
45716d9e3a6SLisandro Dalcin   if (iascii) {
45816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
45916d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
460efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
46116d9e3a6SLisandro Dalcin     } else {
462efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default maximum number of iterations \n");CHKERRQ(ierr);
46316d9e3a6SLisandro Dalcin     }
46416d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
465efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
46616d9e3a6SLisandro Dalcin     } else {
467efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default drop tolerance \n");CHKERRQ(ierr);
46816d9e3a6SLisandro Dalcin     }
46916d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
470efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
47116d9e3a6SLisandro Dalcin     } else {
472efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default factor row size \n");CHKERRQ(ierr);
47316d9e3a6SLisandro Dalcin     }
47416d9e3a6SLisandro Dalcin   }
47516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
47616d9e3a6SLisandro Dalcin }
47716d9e3a6SLisandro Dalcin 
47816d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
479db966c6cSHong Zhang static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PetscOptionItems *PetscOptionsObject,PC pc)
480db966c6cSHong Zhang {
481db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
482db966c6cSHong Zhang   PetscErrorCode ierr;
483db966c6cSHong Zhang   PetscBool      flag;
484db966c6cSHong Zhang 
485db966c6cSHong Zhang   PetscFunctionBegin;
486db966c6cSHong Zhang   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Euclid Options");CHKERRQ(ierr);
487db966c6cSHong Zhang   ierr = PetscOptionsInt("-pc_hypre_euclid_level","Factorization levels","None",jac->eu_level,&jac->eu_level,&flag);CHKERRQ(ierr);
488db966c6cSHong Zhang   if (flag) PetscStackCallStandard(HYPRE_EuclidSetLevel,(jac->hsolver,jac->eu_level));
489db966c6cSHong Zhang   ierr = PetscOptionsTail();CHKERRQ(ierr);
490db966c6cSHong Zhang   PetscFunctionReturn(0);
491db966c6cSHong Zhang }
492db966c6cSHong Zhang 
493db966c6cSHong Zhang static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer)
494db966c6cSHong Zhang {
495db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
496db966c6cSHong Zhang   PetscErrorCode ierr;
497db966c6cSHong Zhang   PetscBool      iascii;
498db966c6cSHong Zhang 
499db966c6cSHong Zhang   PetscFunctionBegin;
500db966c6cSHong Zhang   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
501db966c6cSHong Zhang   if (iascii) {
502db966c6cSHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid preconditioning\n");CHKERRQ(ierr);
503db966c6cSHong Zhang     if (jac->eu_level != PETSC_DEFAULT) {
504db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    factorization levels %d\n",jac->eu_level);CHKERRQ(ierr);
505db966c6cSHong Zhang     } else {
506db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    default factorization levels \n");CHKERRQ(ierr);
507db966c6cSHong Zhang     }
508db966c6cSHong Zhang   }
509db966c6cSHong Zhang   PetscFunctionReturn(0);
510db966c6cSHong Zhang }
511db966c6cSHong Zhang 
512db966c6cSHong Zhang /* --------------------------------------------------------------------------------------------*/
51316d9e3a6SLisandro Dalcin 
51416d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
51516d9e3a6SLisandro Dalcin {
51616d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
51749a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
51816d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
51916d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
520d9ca1df4SBarry Smith   PetscScalar        *xv;
521d9ca1df4SBarry Smith   const PetscScalar  *bv;
52216d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
52316d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
5244ddd07fcSJed Brown   PetscInt           hierr;
52516d9e3a6SLisandro Dalcin 
52616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
527dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
52816d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
529d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
53016d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
53158968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)bv,sbv);
53258968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
53316d9e3a6SLisandro Dalcin 
53449a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
53549a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
53649a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
53716d9e3a6SLisandro Dalcin 
53816d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
53916d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
540e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
54116d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
54216d9e3a6SLisandro Dalcin 
54358968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,sbv,bv);
54458968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
54516d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
546d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
54716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
54816d9e3a6SLisandro Dalcin }
54916d9e3a6SLisandro Dalcin 
550a669f990SJed Brown /* static array length */
551a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
552a669f990SJed Brown 
55316d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
5540f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
55516d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
55665de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
5576a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]   = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
55865de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
55965de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
56065de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
5617b7fa87dSPierre Jolivet                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "l1-Gauss-Seidel" /* nonsymmetric */, "backward-l1-Gauss-Seidel" /* nonsymmetric */,
56265de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
5630f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
564e2287abbSStefano Zampini                                                   "ext+i-cc", "standard", "standard-wts", "block", "block-wtd", "FF", "FF1"};
5654416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc)
56616d9e3a6SLisandro Dalcin {
56716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
56816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
5694ddd07fcSJed Brown   PetscInt       n,indx,level;
570ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
57116d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
57216d9e3a6SLisandro Dalcin 
57316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
574e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
5754336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
57616d9e3a6SLisandro Dalcin   if (flg) {
5774336a9eeSBarry Smith     jac->cycletype = indx+1;
578fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
57916d9e3a6SLisandro Dalcin   }
58016d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
58116d9e3a6SLisandro Dalcin   if (flg) {
582ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
583fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
58416d9e3a6SLisandro Dalcin   }
58516d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
58616d9e3a6SLisandro Dalcin   if (flg) {
587ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
588fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
58916d9e3a6SLisandro Dalcin   }
5900f1074feSSatish 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);
59116d9e3a6SLisandro Dalcin   if (flg) {
59257622a8eSBarry 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);
593fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
59416d9e3a6SLisandro Dalcin   }
59516d9e3a6SLisandro Dalcin 
5960f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
59716d9e3a6SLisandro Dalcin   if (flg) {
59857622a8eSBarry 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);
599fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
60016d9e3a6SLisandro Dalcin   }
60116d9e3a6SLisandro Dalcin 
6020f1074feSSatish 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);
6030f1074feSSatish Balay   if (flg) {
60457622a8eSBarry 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);
605fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
6060f1074feSSatish Balay   }
6070f1074feSSatish Balay 
6080f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
6090f1074feSSatish Balay   if (flg) {
61057622a8eSBarry 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);
6110f1074feSSatish Balay 
612fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
6130f1074feSSatish Balay   }
6140f1074feSSatish Balay 
6150f1074feSSatish Balay 
6160f1074feSSatish 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);
6170f1074feSSatish Balay   if (flg) {
61857622a8eSBarry 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);
6190f1074feSSatish Balay 
620fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
6210f1074feSSatish Balay   }
6220f1074feSSatish Balay 
6230f1074feSSatish Balay 
62416d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
62516d9e3a6SLisandro Dalcin   if (flg) {
62657622a8eSBarry 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);
627fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
62816d9e3a6SLisandro Dalcin   }
62916d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
63016d9e3a6SLisandro Dalcin   if (flg) {
63157622a8eSBarry 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);
63257622a8eSBarry 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);
633fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
63416d9e3a6SLisandro Dalcin   }
63516d9e3a6SLisandro Dalcin 
63616d9e3a6SLisandro Dalcin   /* Grid sweeps */
6370f1074feSSatish 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);
63816d9e3a6SLisandro Dalcin   if (flg) {
639fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
64016d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
64116d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
6420f1074feSSatish Balay     jac->gridsweeps[1] = indx;
6430f1074feSSatish Balay     /*defaults coarse to 1 */
6440f1074feSSatish Balay     jac->gridsweeps[2] = 1;
64516d9e3a6SLisandro Dalcin   }
6460f1074feSSatish Balay 
6475272c319SBarry 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);
6485272c319SBarry Smith   if (flg) {
6495272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,jac->nodal_coarsening));
6505272c319SBarry Smith   }
6515272c319SBarry Smith 
652cbc39033SBarry 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);
6535272c319SBarry Smith   if (flg) {
6545272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,(jac->hsolver,jac->vec_interp_variant));
6555272c319SBarry Smith   }
6565272c319SBarry Smith 
6570f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
65816d9e3a6SLisandro Dalcin   if (flg) {
659fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
6600f1074feSSatish Balay     jac->gridsweeps[0] = indx;
66116d9e3a6SLisandro Dalcin   }
66216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
66316d9e3a6SLisandro Dalcin   if (flg) {
664fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
6650f1074feSSatish Balay     jac->gridsweeps[1] = indx;
66616d9e3a6SLisandro Dalcin   }
6670f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
66816d9e3a6SLisandro Dalcin   if (flg) {
669fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
6700f1074feSSatish Balay     jac->gridsweeps[2] = indx;
67116d9e3a6SLisandro Dalcin   }
67216d9e3a6SLisandro Dalcin 
6736a251517SEike Mueller   /* Smooth type */
6746a251517SEike Mueller   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);
6756a251517SEike Mueller   if (flg) {
6766a251517SEike Mueller     jac->smoothtype = indx;
6776a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
6788131ecf7SEike Mueller     jac->smoothnumlevels = 25;
6798131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
6808131ecf7SEike Mueller   }
6818131ecf7SEike Mueller 
6828131ecf7SEike Mueller   /* Number of smoothing levels */
6838131ecf7SEike 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);
6848131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
6858131ecf7SEike Mueller     jac->smoothnumlevels = indx;
6868131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
6876a251517SEike Mueller   }
6886a251517SEike Mueller 
6891810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
6901810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
6911810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
6921810e44eSEike Mueller     jac->eu_level = indx;
6931810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
6941810e44eSEike Mueller   }
6951810e44eSEike Mueller 
6961810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
6971810e44eSEike Mueller   double droptolerance;
6981810e44eSEike Mueller   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
6991810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
7001810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
7011810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
7021810e44eSEike Mueller   }
7031810e44eSEike Mueller 
7041810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
7051810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
7061810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
7071810e44eSEike Mueller     jac->eu_bj = tmp_truth;
708493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
7091810e44eSEike Mueller   }
7101810e44eSEike Mueller 
71116d9e3a6SLisandro Dalcin   /* Relax type */
712a669f990SJed 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);
71316d9e3a6SLisandro Dalcin   if (flg) {
7140f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
715fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
7160f1074feSSatish Balay     /* by default, coarse type set to 9 */
7170f1074feSSatish Balay     jac->relaxtype[2] = 9;
718*ddbeb582SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, 9, 3));
71916d9e3a6SLisandro Dalcin   }
720a669f990SJed 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);
72116d9e3a6SLisandro Dalcin   if (flg) {
72216d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
723fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
72416d9e3a6SLisandro Dalcin   }
725a669f990SJed 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);
72616d9e3a6SLisandro Dalcin   if (flg) {
7270f1074feSSatish Balay     jac->relaxtype[1] = indx;
728fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
72916d9e3a6SLisandro Dalcin   }
730a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
73116d9e3a6SLisandro Dalcin   if (flg) {
7320f1074feSSatish Balay     jac->relaxtype[2] = indx;
733fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
73416d9e3a6SLisandro Dalcin   }
73516d9e3a6SLisandro Dalcin 
73616d9e3a6SLisandro Dalcin   /* Relaxation Weight */
73716d9e3a6SLisandro 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);
73816d9e3a6SLisandro Dalcin   if (flg) {
739fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
74016d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
74116d9e3a6SLisandro Dalcin   }
74216d9e3a6SLisandro Dalcin 
74316d9e3a6SLisandro Dalcin   n         = 2;
74416d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
74516d9e3a6SLisandro 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);
74616d9e3a6SLisandro Dalcin   if (flg) {
74716d9e3a6SLisandro Dalcin     if (n == 2) {
74816d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
749fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
750ce94432eSBarry 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);
75116d9e3a6SLisandro Dalcin   }
75216d9e3a6SLisandro Dalcin 
75316d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
75416d9e3a6SLisandro 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);
75516d9e3a6SLisandro Dalcin   if (flg) {
756fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
75716d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
75816d9e3a6SLisandro Dalcin   }
75916d9e3a6SLisandro Dalcin 
76016d9e3a6SLisandro Dalcin   n         = 2;
76116d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
76216d9e3a6SLisandro 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);
76316d9e3a6SLisandro Dalcin   if (flg) {
76416d9e3a6SLisandro Dalcin     if (n == 2) {
76516d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
766fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
767ce94432eSBarry 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);
76816d9e3a6SLisandro Dalcin   }
76916d9e3a6SLisandro Dalcin 
77016d9e3a6SLisandro Dalcin   /* the Relax Order */
771acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
77216d9e3a6SLisandro Dalcin 
7738afaa268SBarry Smith   if (flg && tmp_truth) {
77416d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
775fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
77616d9e3a6SLisandro Dalcin   }
777a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
77816d9e3a6SLisandro Dalcin   if (flg) {
77916d9e3a6SLisandro Dalcin     jac->measuretype = indx;
780fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
78116d9e3a6SLisandro Dalcin   }
7820f1074feSSatish Balay   /* update list length 3/07 */
783a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
78416d9e3a6SLisandro Dalcin   if (flg) {
78516d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
786fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
78716d9e3a6SLisandro Dalcin   }
7880f1074feSSatish Balay 
7890f1074feSSatish Balay   /* new 3/07 */
790a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
7910f1074feSSatish Balay   if (flg) {
7920f1074feSSatish Balay     jac->interptype = indx;
793fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
7940f1074feSSatish Balay   }
7950f1074feSSatish Balay 
796b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
79716d9e3a6SLisandro Dalcin   if (flg) {
798b96a4a96SBarry Smith     level = 3;
7990298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
8002fa5cd67SKarl Rupp 
801b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
802fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
8032ae77aedSBarry Smith   }
8042ae77aedSBarry Smith 
805b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
8062ae77aedSBarry Smith   if (flg) {
807b96a4a96SBarry Smith     level = 3;
8080298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
8092fa5cd67SKarl Rupp 
810b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
811fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
81216d9e3a6SLisandro Dalcin   }
8138f87f92bSBarry Smith 
814acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
8158f87f92bSBarry Smith   if (flg && tmp_truth) {
8168f87f92bSBarry Smith     PetscInt tmp_int;
8178f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
8188f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
819fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
820fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
821fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
822fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
8238f87f92bSBarry Smith   }
8248f87f92bSBarry Smith 
82516d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
82616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
82716d9e3a6SLisandro Dalcin }
82816d9e3a6SLisandro Dalcin 
829ace3abfcSBarry 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)
83016d9e3a6SLisandro Dalcin {
83116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
83216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
8334ddd07fcSJed Brown   PetscInt       oits;
83416d9e3a6SLisandro Dalcin 
83516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
836dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
837fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
838fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
83916d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
84016d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
84116d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
8428b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
8434d0a8057SBarry Smith   *outits = oits;
8444d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
8454d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
846fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
847fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
84816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
84916d9e3a6SLisandro Dalcin }
85016d9e3a6SLisandro Dalcin 
85116d9e3a6SLisandro Dalcin 
85216d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
85316d9e3a6SLisandro Dalcin {
85416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
85516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
856ace3abfcSBarry Smith   PetscBool      iascii;
85716d9e3a6SLisandro Dalcin 
85816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
859251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
86016d9e3a6SLisandro Dalcin   if (iascii) {
86116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
862efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
863efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
864efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
865efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
866efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
867efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
868efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
869efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
870efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
8710f1074feSSatish Balay 
872efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
87316d9e3a6SLisandro Dalcin 
874efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
875efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
876efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
87716d9e3a6SLisandro Dalcin 
878efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
879efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
880efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
88116d9e3a6SLisandro Dalcin 
882efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
883efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
88416d9e3a6SLisandro Dalcin 
88516d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
886efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using CF-relaxation\n");CHKERRQ(ierr);
88716d9e3a6SLisandro Dalcin     } else {
888efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using CF-relaxation\n");CHKERRQ(ierr);
88916d9e3a6SLisandro Dalcin     }
8906a251517SEike Mueller     if (jac->smoothtype!=-1) {
891efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
892efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth num levels    %d\n",jac->smoothnumlevels);CHKERRQ(ierr);
8937e352d70SEike Mueller     } else {
894efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using more complex smoothers.\n");CHKERRQ(ierr);
8951810e44eSEike Mueller     }
8961810e44eSEike Mueller     if (jac->smoothtype==3) {
897efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) levels %d\n",jac->eu_level);CHKERRQ(ierr);
898efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) drop tolerance %g\n",jac->eu_droptolerance);CHKERRQ(ierr);
899efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU use Block-Jacobi? %d\n",jac->eu_bj);CHKERRQ(ierr);
9006a251517SEike Mueller     }
901efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
902efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
903efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
9045272c319SBarry Smith     if (jac->nodal_coarsening) {
905efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
9065272c319SBarry Smith     }
9075272c319SBarry Smith     if (jac->vec_interp_variant) {
908efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
9098f87f92bSBarry Smith     }
9108f87f92bSBarry Smith     if (jac->nodal_relax) {
911efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
9128f87f92bSBarry Smith     }
91316d9e3a6SLisandro Dalcin   }
91416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
91516d9e3a6SLisandro Dalcin }
91616d9e3a6SLisandro Dalcin 
91716d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
9184416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc)
91916d9e3a6SLisandro Dalcin {
92016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
92116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
9224ddd07fcSJed Brown   PetscInt       indx;
923ace3abfcSBarry Smith   PetscBool      flag;
92416d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
92516d9e3a6SLisandro Dalcin 
92616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
927e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
92816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
92916d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
9302fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
93116d9e3a6SLisandro Dalcin 
93216d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
9332fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
93416d9e3a6SLisandro Dalcin 
93516d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
9362fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
93716d9e3a6SLisandro Dalcin 
938acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
9392fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
94016d9e3a6SLisandro Dalcin 
941acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
9422fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
94316d9e3a6SLisandro Dalcin 
944a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
94516d9e3a6SLisandro Dalcin   if (flag) {
94616d9e3a6SLisandro Dalcin     jac->symt = indx;
947fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
94816d9e3a6SLisandro Dalcin   }
94916d9e3a6SLisandro Dalcin 
95016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
95116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
95216d9e3a6SLisandro Dalcin }
95316d9e3a6SLisandro Dalcin 
95416d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
95516d9e3a6SLisandro Dalcin {
95616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
95716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
958ace3abfcSBarry Smith   PetscBool      iascii;
95916d9e3a6SLisandro Dalcin   const char     *symt = 0;;
96016d9e3a6SLisandro Dalcin 
96116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
962251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
96316d9e3a6SLisandro Dalcin   if (iascii) {
96416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
965efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
966efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
967efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    filter %g\n",(double)jac->filter);CHKERRQ(ierr);
968efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
969efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
970efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
9712fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
9722fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
9732fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
974ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
975efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    %s\n",symt);CHKERRQ(ierr);
97616d9e3a6SLisandro Dalcin   }
97716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
97816d9e3a6SLisandro Dalcin }
9794cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
9804416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc)
9814cb006feSStefano Zampini {
9824cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
9834cb006feSStefano Zampini   PetscErrorCode ierr;
9844cb006feSStefano Zampini   PetscInt       n;
9854cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
9864cb006feSStefano Zampini 
9874cb006feSStefano Zampini   PetscFunctionBegin;
9889fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
989863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
990863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
991863406b8SStefano 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);
992863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
9934cb006feSStefano 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);
9944cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
995863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
996863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
997863406b8SStefano 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);
998863406b8SStefano 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);
999863406b8SStefano 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);
1000863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
10014cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1002863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1003863406b8SStefano Zampini                                                                       jac->as_relax_times,
1004863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1005863406b8SStefano Zampini                                                                       jac->as_omega));
10064cb006feSStefano Zampini   }
1007863406b8SStefano 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);
10084cb006feSStefano Zampini   n = 5;
1009863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
10104cb006feSStefano Zampini   if (flag || flag2) {
1011863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1012863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1013863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1014863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1015863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1016863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
10174cb006feSStefano Zampini   }
1018863406b8SStefano 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);
10194cb006feSStefano Zampini   n = 5;
1020863406b8SStefano 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);
10214cb006feSStefano Zampini   if (flag || flag2) {
1022863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1023863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1024863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1025863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1026863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1027863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
10284cb006feSStefano Zampini   }
102923df4f25SStefano 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);
103023df4f25SStefano Zampini   if (flag) { /* override HYPRE's default only if the options is used */
103123df4f25SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetProjectionFrequency,(jac->hsolver,jac->ams_proj_freq));
103223df4f25SStefano Zampini   }
10334cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
10344cb006feSStefano Zampini   PetscFunctionReturn(0);
10354cb006feSStefano Zampini }
10364cb006feSStefano Zampini 
10374cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
10384cb006feSStefano Zampini {
10394cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
10404cb006feSStefano Zampini   PetscErrorCode ierr;
10414cb006feSStefano Zampini   PetscBool      iascii;
10424cb006feSStefano Zampini 
10434cb006feSStefano Zampini   PetscFunctionBegin;
10444cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
10454cb006feSStefano Zampini   if (iascii) {
10464cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
1047efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1048efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1049efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1050efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1051efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1052efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1053efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
10544cb006feSStefano Zampini     if (jac->alpha_Poisson) {
1055efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
10564cb006feSStefano Zampini     } else {
1057efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (computed) \n");CHKERRQ(ierr);
10584cb006feSStefano Zampini     }
1059efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1060efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1061efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1062efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1063efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1064efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
10654cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
10664cb006feSStefano Zampini       if (jac->beta_Poisson) {
1067efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
10684cb006feSStefano Zampini       } else {
1069efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (computed) \n");CHKERRQ(ierr);
10704cb006feSStefano Zampini       }
1071efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1072efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1073efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1074efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1075efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1076efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
107723df4f25SStefano Zampini       if (jac->ams_beta_is_zero_part) {
1078efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"        compatible subspace projection frequency %d (-1 HYPRE uses default)\n",jac->ams_proj_freq);CHKERRQ(ierr);
107923df4f25SStefano Zampini       }
108023df4f25SStefano Zampini     } else {
1081efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver not used (zero-conductivity everywhere) \n");CHKERRQ(ierr);
10824cb006feSStefano Zampini     }
10834cb006feSStefano Zampini   }
10844cb006feSStefano Zampini   PetscFunctionReturn(0);
10854cb006feSStefano Zampini }
10864cb006feSStefano Zampini 
10874416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc)
1088863406b8SStefano Zampini {
1089863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1090863406b8SStefano Zampini   PetscErrorCode ierr;
1091863406b8SStefano Zampini   PetscInt       n;
1092863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
1093863406b8SStefano Zampini 
1094863406b8SStefano Zampini   PetscFunctionBegin;
1095863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
1096863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1097863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1098863406b8SStefano 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);
1099863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1100863406b8SStefano 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);
1101863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
1102863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1103863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1104863406b8SStefano 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);
1105863406b8SStefano 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);
1106863406b8SStefano 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);
1107863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
1108863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1109863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1110863406b8SStefano Zampini                                                                       jac->as_relax_times,
1111863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1112863406b8SStefano Zampini                                                                       jac->as_omega));
1113863406b8SStefano Zampini   }
1114863406b8SStefano 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);
1115863406b8SStefano Zampini   n = 5;
1116863406b8SStefano 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);
1117863406b8SStefano 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);
1118863406b8SStefano Zampini   if (flag || flag2 || flag3) {
1119863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
1120863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1121863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1122863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1123863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1124863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1125863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1126863406b8SStefano Zampini   }
1127863406b8SStefano 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);
1128863406b8SStefano Zampini   n = 5;
1129863406b8SStefano 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);
1130863406b8SStefano Zampini   if (flag || flag2) {
1131863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1132863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1133863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1134863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1135863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1136863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1137863406b8SStefano Zampini   }
1138863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
1139863406b8SStefano Zampini   PetscFunctionReturn(0);
1140863406b8SStefano Zampini }
1141863406b8SStefano Zampini 
1142863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1143863406b8SStefano Zampini {
1144863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1145863406b8SStefano Zampini   PetscErrorCode ierr;
1146863406b8SStefano Zampini   PetscBool      iascii;
1147863406b8SStefano Zampini 
1148863406b8SStefano Zampini   PetscFunctionBegin;
1149863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1150863406b8SStefano Zampini   if (iascii) {
1151863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
1152efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1153efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
1154efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1155efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1156efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1157efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1158efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
1159efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    AMS solver using boomerAMG\n");CHKERRQ(ierr);
1160efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1161efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1162efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1163efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1164efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1165efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1166efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
1167efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver using boomerAMG\n");CHKERRQ(ierr);
1168efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1169efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1170efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1171efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1172efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1173efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
1174863406b8SStefano Zampini   }
1175863406b8SStefano Zampini   PetscFunctionReturn(0);
1176863406b8SStefano Zampini }
1177863406b8SStefano Zampini 
1178863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
11794cb006feSStefano Zampini {
11804cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
11815ac14e1cSStefano Zampini   PetscBool      ishypre;
11824cb006feSStefano Zampini   PetscErrorCode ierr;
11834cb006feSStefano Zampini 
11844cb006feSStefano Zampini   PetscFunctionBegin;
11855ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)G,MATHYPRE,&ishypre);CHKERRQ(ierr);
11865ac14e1cSStefano Zampini   if (ishypre) {
11875ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr);
11885ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
11895ac14e1cSStefano Zampini     jac->G = G;
11905ac14e1cSStefano Zampini   } else {
11916bf688a0SCe Qin     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
11926bf688a0SCe Qin     ierr = MatConvert(G,MATHYPRE,MAT_INITIAL_MATRIX,&jac->G);CHKERRQ(ierr);
11935ac14e1cSStefano Zampini   }
11944cb006feSStefano Zampini   PetscFunctionReturn(0);
11954cb006feSStefano Zampini }
11964cb006feSStefano Zampini 
11974cb006feSStefano Zampini /*@
11984cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
11994cb006feSStefano Zampini 
12004cb006feSStefano Zampini    Collective on PC
12014cb006feSStefano Zampini 
12024cb006feSStefano Zampini    Input Parameters:
12034cb006feSStefano Zampini +  pc - the preconditioning context
12044cb006feSStefano Zampini -  G - the discrete gradient
12054cb006feSStefano Zampini 
12064cb006feSStefano Zampini    Level: intermediate
12074cb006feSStefano Zampini 
120895452b02SPatrick Sanan    Notes:
120995452b02SPatrick Sanan     G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh
1210863406b8SStefano 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
12114cb006feSStefano Zampini 
12124cb006feSStefano Zampini .seealso:
12134cb006feSStefano Zampini @*/
12144cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
12154cb006feSStefano Zampini {
12164cb006feSStefano Zampini   PetscErrorCode ierr;
12174cb006feSStefano Zampini 
12184cb006feSStefano Zampini   PetscFunctionBegin;
12194cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12204cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
12214cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
12224cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
12234cb006feSStefano Zampini   PetscFunctionReturn(0);
12244cb006feSStefano Zampini }
12254cb006feSStefano Zampini 
1226863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1227863406b8SStefano Zampini {
1228863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12295ac14e1cSStefano Zampini   PetscBool      ishypre;
1230863406b8SStefano Zampini   PetscErrorCode ierr;
1231863406b8SStefano Zampini 
1232863406b8SStefano Zampini   PetscFunctionBegin;
12335ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)C,MATHYPRE,&ishypre);CHKERRQ(ierr);
12345ac14e1cSStefano Zampini   if (ishypre) {
12355ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr);
12365ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
12375ac14e1cSStefano Zampini     jac->C = C;
12385ac14e1cSStefano Zampini   } else {
12396bf688a0SCe Qin     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
12406bf688a0SCe Qin     ierr = MatConvert(C,MATHYPRE,MAT_INITIAL_MATRIX,&jac->C);CHKERRQ(ierr);
12415ac14e1cSStefano Zampini   }
1242863406b8SStefano Zampini   PetscFunctionReturn(0);
1243863406b8SStefano Zampini }
1244863406b8SStefano Zampini 
1245863406b8SStefano Zampini /*@
1246863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1247863406b8SStefano Zampini 
1248863406b8SStefano Zampini    Collective on PC
1249863406b8SStefano Zampini 
1250863406b8SStefano Zampini    Input Parameters:
1251863406b8SStefano Zampini +  pc - the preconditioning context
1252863406b8SStefano Zampini -  C - the discrete curl
1253863406b8SStefano Zampini 
1254863406b8SStefano Zampini    Level: intermediate
1255863406b8SStefano Zampini 
125695452b02SPatrick Sanan    Notes:
125795452b02SPatrick Sanan     C should have as many rows as the number of faces and as many columns as the number of edges in the mesh
1258863406b8SStefano 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
1259863406b8SStefano Zampini 
1260863406b8SStefano Zampini .seealso:
1261863406b8SStefano Zampini @*/
1262863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1263863406b8SStefano Zampini {
1264863406b8SStefano Zampini   PetscErrorCode ierr;
1265863406b8SStefano Zampini 
1266863406b8SStefano Zampini   PetscFunctionBegin;
1267863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1268863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1269863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1270863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1271863406b8SStefano Zampini   PetscFunctionReturn(0);
1272863406b8SStefano Zampini }
1273863406b8SStefano Zampini 
12746bf688a0SCe Qin static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
12756bf688a0SCe Qin {
12766bf688a0SCe Qin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12776bf688a0SCe Qin   PetscBool      ishypre;
12786bf688a0SCe Qin   PetscErrorCode ierr;
12796bf688a0SCe Qin   PetscInt       i;
12806bf688a0SCe Qin   PetscFunctionBegin;
12816bf688a0SCe Qin 
12826bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
12836bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
12846bf688a0SCe Qin   for (i=0;i<3;++i) {
12856bf688a0SCe Qin     ierr = MatDestroy(&jac->RT_Pi[i]);CHKERRQ(ierr);
12866bf688a0SCe Qin     ierr = MatDestroy(&jac->ND_Pi[i]);CHKERRQ(ierr);
12876bf688a0SCe Qin   }
12886bf688a0SCe Qin 
12896bf688a0SCe Qin   jac->dim = dim;
12906bf688a0SCe Qin   if (RT_PiFull) {
12916bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)RT_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
12926bf688a0SCe Qin     if (ishypre) {
12936bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)RT_PiFull);CHKERRQ(ierr);
12946bf688a0SCe Qin       jac->RT_PiFull = RT_PiFull;
12956bf688a0SCe Qin     } else {
12966bf688a0SCe Qin       ierr = MatConvert(RT_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_PiFull);CHKERRQ(ierr);
12976bf688a0SCe Qin     }
12986bf688a0SCe Qin   }
12996bf688a0SCe Qin   if (RT_Pi) {
13006bf688a0SCe Qin     for (i=0;i<dim;++i) {
13016bf688a0SCe Qin       if (RT_Pi[i]) {
13026bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)RT_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
13036bf688a0SCe Qin         if (ishypre) {
13046bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)RT_Pi[i]);CHKERRQ(ierr);
13056bf688a0SCe Qin           jac->RT_Pi[i] = RT_Pi[i];
13066bf688a0SCe Qin         } else {
13076bf688a0SCe Qin           ierr = MatConvert(RT_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_Pi[i]);CHKERRQ(ierr);
13086bf688a0SCe Qin         }
13096bf688a0SCe Qin       }
13106bf688a0SCe Qin     }
13116bf688a0SCe Qin   }
13126bf688a0SCe Qin   if (ND_PiFull) {
13136bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)ND_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
13146bf688a0SCe Qin     if (ishypre) {
13156bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)ND_PiFull);CHKERRQ(ierr);
13166bf688a0SCe Qin       jac->ND_PiFull = ND_PiFull;
13176bf688a0SCe Qin     } else {
13186bf688a0SCe Qin       ierr = MatConvert(ND_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_PiFull);CHKERRQ(ierr);
13196bf688a0SCe Qin     }
13206bf688a0SCe Qin   }
13216bf688a0SCe Qin   if (ND_Pi) {
13226bf688a0SCe Qin     for (i=0;i<dim;++i) {
13236bf688a0SCe Qin       if (ND_Pi[i]) {
13246bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)ND_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
13256bf688a0SCe Qin         if (ishypre) {
13266bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)ND_Pi[i]);CHKERRQ(ierr);
13276bf688a0SCe Qin           jac->ND_Pi[i] = ND_Pi[i];
13286bf688a0SCe Qin         } else {
13296bf688a0SCe Qin           ierr = MatConvert(ND_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_Pi[i]);CHKERRQ(ierr);
13306bf688a0SCe Qin         }
13316bf688a0SCe Qin       }
13326bf688a0SCe Qin     }
13336bf688a0SCe Qin   }
13346bf688a0SCe Qin 
13356bf688a0SCe Qin   PetscFunctionReturn(0);
13366bf688a0SCe Qin }
13376bf688a0SCe Qin 
13386bf688a0SCe Qin /*@
13396bf688a0SCe Qin  PCHYPRESetInterpolations - Set interpolation matrices for AMS/ADS preconditioner
13406bf688a0SCe Qin 
13416bf688a0SCe Qin    Collective on PC
13426bf688a0SCe Qin 
13436bf688a0SCe Qin    Input Parameters:
13446bf688a0SCe Qin +  pc - the preconditioning context
13456bf688a0SCe Qin -  dim - the dimension of the problem, only used in AMS
13466bf688a0SCe Qin -  RT_PiFull - Raviart-Thomas interpolation matrix
13476bf688a0SCe Qin -  RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix
13486bf688a0SCe Qin -  ND_PiFull - Nedelec interpolation matrix
13496bf688a0SCe Qin -  ND_Pi - x/y/z component of Nedelec interpolation matrix
13506bf688a0SCe Qin 
135195452b02SPatrick Sanan    Notes:
135295452b02SPatrick Sanan     For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL.
13536bf688a0SCe Qin           For ADS, both type of interpolation matrices are needed.
13546bf688a0SCe Qin    Level: intermediate
13556bf688a0SCe Qin 
13566bf688a0SCe Qin .seealso:
13576bf688a0SCe Qin @*/
13586bf688a0SCe Qin PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
13596bf688a0SCe Qin {
13606bf688a0SCe Qin   PetscErrorCode ierr;
13616bf688a0SCe Qin   PetscInt       i;
13626bf688a0SCe Qin 
13636bf688a0SCe Qin   PetscFunctionBegin;
13646bf688a0SCe Qin   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
13656bf688a0SCe Qin   if (RT_PiFull) {
13666bf688a0SCe Qin     PetscValidHeaderSpecific(RT_PiFull,MAT_CLASSID,3);
13676bf688a0SCe Qin     PetscCheckSameComm(pc,1,RT_PiFull,3);
13686bf688a0SCe Qin   }
13696bf688a0SCe Qin   if (RT_Pi) {
13706bf688a0SCe Qin     PetscValidPointer(RT_Pi,4);
13716bf688a0SCe Qin     for (i=0;i<dim;++i) {
13726bf688a0SCe Qin       if (RT_Pi[i]) {
13736bf688a0SCe Qin         PetscValidHeaderSpecific(RT_Pi[i],MAT_CLASSID,4);
13746bf688a0SCe Qin         PetscCheckSameComm(pc,1,RT_Pi[i],4);
13756bf688a0SCe Qin       }
13766bf688a0SCe Qin     }
13776bf688a0SCe Qin   }
13786bf688a0SCe Qin   if (ND_PiFull) {
13796bf688a0SCe Qin     PetscValidHeaderSpecific(ND_PiFull,MAT_CLASSID,5);
13806bf688a0SCe Qin     PetscCheckSameComm(pc,1,ND_PiFull,5);
13816bf688a0SCe Qin   }
13826bf688a0SCe Qin   if (ND_Pi) {
13836bf688a0SCe Qin     PetscValidPointer(ND_Pi,6);
13846bf688a0SCe Qin     for (i=0;i<dim;++i) {
13856bf688a0SCe Qin       if (ND_Pi[i]) {
13866bf688a0SCe Qin         PetscValidHeaderSpecific(ND_Pi[i],MAT_CLASSID,6);
13876bf688a0SCe Qin         PetscCheckSameComm(pc,1,ND_Pi[i],6);
13886bf688a0SCe Qin       }
13896bf688a0SCe Qin     }
13906bf688a0SCe Qin   }
13916bf688a0SCe Qin   ierr = PetscTryMethod(pc,"PCHYPRESetInterpolations_C",(PC,PetscInt,Mat,Mat[],Mat,Mat[]),(pc,dim,RT_PiFull,RT_Pi,ND_PiFull,ND_Pi));CHKERRQ(ierr);
13926bf688a0SCe Qin   PetscFunctionReturn(0);
13936bf688a0SCe Qin }
13946bf688a0SCe Qin 
13955ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha)
13964cb006feSStefano Zampini {
13974cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
13985ac14e1cSStefano Zampini   PetscBool      ishypre;
13994cb006feSStefano Zampini   PetscErrorCode ierr;
14004cb006feSStefano Zampini 
14014cb006feSStefano Zampini   PetscFunctionBegin;
14025ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr);
14035ac14e1cSStefano Zampini   if (ishypre) {
14045ac14e1cSStefano Zampini     if (isalpha) {
14055ac14e1cSStefano Zampini       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
14065ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
14075ac14e1cSStefano Zampini       jac->alpha_Poisson = A;
14085ac14e1cSStefano Zampini     } else {
14095ac14e1cSStefano Zampini       if (A) {
14105ac14e1cSStefano Zampini         ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
14115ac14e1cSStefano Zampini       } else {
14125ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
14135ac14e1cSStefano Zampini       }
14145ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
14155ac14e1cSStefano Zampini       jac->beta_Poisson = A;
14165ac14e1cSStefano Zampini     }
14175ac14e1cSStefano Zampini   } else {
14185ac14e1cSStefano Zampini     if (isalpha) {
14196bf688a0SCe Qin       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
14206bf688a0SCe Qin       ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->alpha_Poisson);CHKERRQ(ierr);
14215ac14e1cSStefano Zampini     } else {
14225ac14e1cSStefano Zampini       if (A) {
14236bf688a0SCe Qin         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
14246bf688a0SCe Qin         ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->beta_Poisson);CHKERRQ(ierr);
14255ac14e1cSStefano Zampini       } else {
14265ac14e1cSStefano Zampini         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
14275ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
14285ac14e1cSStefano Zampini       }
14295ac14e1cSStefano Zampini     }
14305ac14e1cSStefano Zampini   }
14314cb006feSStefano Zampini   PetscFunctionReturn(0);
14324cb006feSStefano Zampini }
14334cb006feSStefano Zampini 
14344cb006feSStefano Zampini /*@
14354cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
14364cb006feSStefano Zampini 
14374cb006feSStefano Zampini    Collective on PC
14384cb006feSStefano Zampini 
14394cb006feSStefano Zampini    Input Parameters:
14404cb006feSStefano Zampini +  pc - the preconditioning context
14414cb006feSStefano Zampini -  A - the matrix
14424cb006feSStefano Zampini 
14434cb006feSStefano Zampini    Level: intermediate
14444cb006feSStefano Zampini 
144595452b02SPatrick Sanan    Notes:
144695452b02SPatrick Sanan     A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
14474cb006feSStefano Zampini 
14484cb006feSStefano Zampini .seealso:
14494cb006feSStefano Zampini @*/
14504cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
14514cb006feSStefano Zampini {
14524cb006feSStefano Zampini   PetscErrorCode ierr;
14534cb006feSStefano Zampini 
14544cb006feSStefano Zampini   PetscFunctionBegin;
14554cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
14564cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
14574cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
14585ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_TRUE));CHKERRQ(ierr);
14594cb006feSStefano Zampini   PetscFunctionReturn(0);
14604cb006feSStefano Zampini }
14614cb006feSStefano Zampini 
14624cb006feSStefano Zampini /*@
14634cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
14644cb006feSStefano Zampini 
14654cb006feSStefano Zampini    Collective on PC
14664cb006feSStefano Zampini 
14674cb006feSStefano Zampini    Input Parameters:
14684cb006feSStefano Zampini +  pc - the preconditioning context
14694cb006feSStefano Zampini -  A - the matrix
14704cb006feSStefano Zampini 
14714cb006feSStefano Zampini    Level: intermediate
14724cb006feSStefano Zampini 
147395452b02SPatrick Sanan    Notes:
147495452b02SPatrick Sanan     A should be obtained by discretizing the Poisson problem with linear finite elements.
14754cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
14764cb006feSStefano Zampini 
14774cb006feSStefano Zampini .seealso:
14784cb006feSStefano Zampini @*/
14794cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
14804cb006feSStefano Zampini {
14814cb006feSStefano Zampini   PetscErrorCode ierr;
14824cb006feSStefano Zampini 
14834cb006feSStefano Zampini   PetscFunctionBegin;
14844cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
14854cb006feSStefano Zampini   if (A) {
14864cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
14874cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
14884cb006feSStefano Zampini   }
14895ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_FALSE));CHKERRQ(ierr);
14904cb006feSStefano Zampini   PetscFunctionReturn(0);
14914cb006feSStefano Zampini }
14924cb006feSStefano Zampini 
14935ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz, Vec zoz, Vec zzo)
14944cb006feSStefano Zampini {
14954cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
14964cb006feSStefano Zampini   PetscErrorCode     ierr;
14974cb006feSStefano Zampini 
14984cb006feSStefano Zampini   PetscFunctionBegin;
14994cb006feSStefano Zampini   /* throw away any vector if already set */
15004cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
15014cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
15024cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
15034cb006feSStefano Zampini   jac->constants[0] = NULL;
15044cb006feSStefano Zampini   jac->constants[1] = NULL;
15054cb006feSStefano Zampini   jac->constants[2] = NULL;
15064cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
15074cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
15084cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
15094cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
15105ac14e1cSStefano Zampini   jac->dim = 2;
15114cb006feSStefano Zampini   if (zzo) {
15124cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
15134cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
15145ac14e1cSStefano Zampini     jac->dim++;
15154cb006feSStefano Zampini   }
15164cb006feSStefano Zampini   PetscFunctionReturn(0);
15174cb006feSStefano Zampini }
15184cb006feSStefano Zampini 
15194cb006feSStefano Zampini /*@
15204cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
15214cb006feSStefano Zampini 
15224cb006feSStefano Zampini    Collective on PC
15234cb006feSStefano Zampini 
15244cb006feSStefano Zampini    Input Parameters:
15254cb006feSStefano Zampini +  pc - the preconditioning context
15264cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
15274cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
15284cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
15294cb006feSStefano Zampini 
15304cb006feSStefano Zampini    Level: intermediate
15314cb006feSStefano Zampini 
15324cb006feSStefano Zampini    Notes:
15334cb006feSStefano Zampini 
15344cb006feSStefano Zampini .seealso:
15354cb006feSStefano Zampini @*/
15364cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
15374cb006feSStefano Zampini {
15384cb006feSStefano Zampini   PetscErrorCode ierr;
15394cb006feSStefano Zampini 
15404cb006feSStefano Zampini   PetscFunctionBegin;
15414cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15424cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
15434cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
15444cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
15454cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
15464cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
15474cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
15484cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
15494cb006feSStefano Zampini   PetscFunctionReturn(0);
15504cb006feSStefano Zampini }
15514cb006feSStefano Zampini 
1552863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
15534cb006feSStefano Zampini {
15544cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
15554cb006feSStefano Zampini   Vec             tv;
15564cb006feSStefano Zampini   PetscInt        i;
15574cb006feSStefano Zampini   PetscErrorCode  ierr;
15584cb006feSStefano Zampini 
15594cb006feSStefano Zampini   PetscFunctionBegin;
15604cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
15614cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
15624cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
15634cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
15645ac14e1cSStefano Zampini   jac->dim = dim;
15655ac14e1cSStefano Zampini 
15664cb006feSStefano Zampini   /* compute IJ vector for coordinates */
15674cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
15684cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
15694cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
15704cb006feSStefano Zampini   for (i=0;i<dim;i++) {
15714cb006feSStefano Zampini     PetscScalar *array;
15724cb006feSStefano Zampini     PetscInt    j;
15734cb006feSStefano Zampini 
15744cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
15754cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
15764cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
15774cb006feSStefano Zampini       array[j] = coords[j*dim+i];
15784cb006feSStefano Zampini     }
15794cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
15804cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
15814cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
15824cb006feSStefano Zampini   }
15834cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
15844cb006feSStefano Zampini   PetscFunctionReturn(0);
15854cb006feSStefano Zampini }
15864cb006feSStefano Zampini 
158716d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
158816d9e3a6SLisandro Dalcin 
1589f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
159016d9e3a6SLisandro Dalcin {
159116d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
159216d9e3a6SLisandro Dalcin 
159316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
159416d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
159516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
159616d9e3a6SLisandro Dalcin }
159716d9e3a6SLisandro Dalcin 
1598f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
159916d9e3a6SLisandro Dalcin {
160016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
160116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1602ace3abfcSBarry Smith   PetscBool      flag;
160316d9e3a6SLisandro Dalcin 
160416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
160516d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
160616d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1607ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
160816d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
160916d9e3a6SLisandro Dalcin   } else {
161016d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
161116d9e3a6SLisandro Dalcin   }
161216d9e3a6SLisandro Dalcin 
161316d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
161416d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
161516d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
161616d9e3a6SLisandro Dalcin 
161716d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
161816d9e3a6SLisandro Dalcin   if (flag) {
1619572a0576SBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1620fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
162116d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
162216d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
162316d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
162416d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
162516d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
162616d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
162716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
162816d9e3a6SLisandro Dalcin   }
1629db966c6cSHong Zhang   ierr = PetscStrcmp("euclid",jac->hypre_type,&flag);CHKERRQ(ierr);
1630db966c6cSHong Zhang   if (flag) {
1631db966c6cSHong Zhang     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1632db966c6cSHong Zhang     PetscStackCallStandard(HYPRE_EuclidCreate,(jac->comm_hypre,&jac->hsolver));
1633db966c6cSHong Zhang     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
1634db966c6cSHong Zhang     pc->ops->view           = PCView_HYPRE_Euclid;
1635db966c6cSHong Zhang     jac->destroy            = HYPRE_EuclidDestroy;
1636db966c6cSHong Zhang     jac->setup              = HYPRE_EuclidSetup;
1637db966c6cSHong Zhang     jac->solve              = HYPRE_EuclidSolve;
1638db966c6cSHong Zhang     jac->factorrowsize      = PETSC_DEFAULT;
1639db966c6cSHong Zhang     jac->eu_level           = PETSC_DEFAULT; /* default */
1640db966c6cSHong Zhang     PetscFunctionReturn(0);
1641db966c6cSHong Zhang   }
164216d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
164316d9e3a6SLisandro Dalcin   if (flag) {
1644572a0576SBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1645fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
164616d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
164716d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
164816d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
164916d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
165016d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
165116d9e3a6SLisandro Dalcin     /* initialize */
165216d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
165316d9e3a6SLisandro Dalcin     jac->threshhold = .1;
165416d9e3a6SLisandro Dalcin     jac->filter     = .1;
165516d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
16562fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
16572fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
16582fa5cd67SKarl Rupp 
165916d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
166016d9e3a6SLisandro Dalcin     jac->symt = 0;
1661fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1662fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1663fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1664fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1665fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1666fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
166716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
166816d9e3a6SLisandro Dalcin   }
166916d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
167016d9e3a6SLisandro Dalcin   if (flag) {
167116d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
167216d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
167316d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
167416d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
167516d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
167616d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
167716d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
167816d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
167916d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
168016d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
168116d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
168216d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
168316d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
16848f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
168516d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
168616d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
168716d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
168816d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
168916d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
16900f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
16916a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1692b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
16931810e44eSEike Mueller     jac->eu_level         = 0;
16941810e44eSEike Mueller     jac->eu_droptolerance = 0;
16951810e44eSEike Mueller     jac->eu_bj            = 0;
16968f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
16970f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
169816d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
169916d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
170016d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
17010f1074feSSatish Balay     jac->interptype       = 0;
17020f1074feSSatish Balay     jac->agg_nl           = 0;
17030f1074feSSatish Balay     jac->pmax             = 0;
17040f1074feSSatish Balay     jac->truncfactor      = 0.0;
17050f1074feSSatish Balay     jac->agg_num_paths    = 1;
17068f87f92bSBarry Smith 
17078f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
17088f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
17098f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1710fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1711fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1712fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1713fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1714fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1715fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1716fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1717fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1718fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1719fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1720fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1721fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1722fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1723fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1724fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1725fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
172616d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
172716d9e3a6SLisandro Dalcin   }
17284cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
17294cb006feSStefano Zampini   if (flag) {
17304cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
17314cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
17324cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
17334cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
17344cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
17354cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
17364cb006feSStefano Zampini     jac->coords[0]           = NULL;
17374cb006feSStefano Zampini     jac->coords[1]           = NULL;
17384cb006feSStefano Zampini     jac->coords[2]           = NULL;
17394cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1740863406b8SStefano Zampini     jac->as_print           = 0;
1741863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1742863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
17434cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
17444cb006feSStefano Zampini     /* Smoothing options */
1745863406b8SStefano Zampini     jac->as_relax_type      = 2;
1746863406b8SStefano Zampini     jac->as_relax_times     = 1;
1747863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1748863406b8SStefano Zampini     jac->as_omega           = 1.0;
17494cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1750863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1751863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
17520bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1753863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1754863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1755863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
17564cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1757863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1758863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
17590bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1760863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1761863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1762863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1763863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1764863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
17654cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1766863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1767863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1768863406b8SStefano Zampini                                                                       jac->as_relax_times,
1769863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1770863406b8SStefano Zampini                                                                       jac->as_omega));
1771863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1772863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1773863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1774863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1775863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1776863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1777863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1778863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1779863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1780863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1781863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1782863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
178323df4f25SStefano Zampini     /* Zero conductivity */
178423df4f25SStefano Zampini     jac->ams_beta_is_zero      = PETSC_FALSE;
178523df4f25SStefano Zampini     jac->ams_beta_is_zero_part = PETSC_FALSE;
17864cb006feSStefano Zampini     PetscFunctionReturn(0);
17874cb006feSStefano Zampini   }
1788863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1789863406b8SStefano Zampini   if (flag) {
1790863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1791863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1792863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1793863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1794863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1795863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1796863406b8SStefano Zampini     jac->coords[0]           = NULL;
1797863406b8SStefano Zampini     jac->coords[1]           = NULL;
1798863406b8SStefano Zampini     jac->coords[2]           = NULL;
1799863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1800863406b8SStefano Zampini     jac->as_print           = 0;
1801863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1802863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1803863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1804863406b8SStefano Zampini     /* Smoothing options */
1805863406b8SStefano Zampini     jac->as_relax_type      = 2;
1806863406b8SStefano Zampini     jac->as_relax_times     = 1;
1807863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1808863406b8SStefano Zampini     jac->as_omega           = 1.0;
1809863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1810863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1811863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1812863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1813863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1814863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1815863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1816863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1817863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1818863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1819863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1820863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1821863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1822863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1823863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1824863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1825863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1826863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1827863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1828863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1829863406b8SStefano Zampini                                                                       jac->as_relax_times,
1830863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1831863406b8SStefano Zampini                                                                       jac->as_omega));
1832863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1833863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1834863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1835863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1836863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1837863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1838863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1839863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1840863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1841863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1842863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1843863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1844863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1845863406b8SStefano Zampini     PetscFunctionReturn(0);
1846863406b8SStefano Zampini   }
1847503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
18482fa5cd67SKarl Rupp 
18490298fd71SBarry Smith   jac->hypre_type = NULL;
1850db966c6cSHong Zhang   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams",name);
185116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
185216d9e3a6SLisandro Dalcin }
185316d9e3a6SLisandro Dalcin 
185416d9e3a6SLisandro Dalcin /*
185516d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
185616d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
185716d9e3a6SLisandro Dalcin */
18584416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc)
185916d9e3a6SLisandro Dalcin {
186016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
18614ddd07fcSJed Brown   PetscInt       indx;
1862db966c6cSHong Zhang   const char     *type[] = {"euclid","pilut","parasails","boomeramg","ams","ads"};
1863ace3abfcSBarry Smith   PetscBool      flg;
186416d9e3a6SLisandro Dalcin 
186516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
18669fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
18679c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
186816d9e3a6SLisandro Dalcin   if (flg) {
186916d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
187002a17cd4SBarry Smith   } else {
187102a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
187216d9e3a6SLisandro Dalcin   }
187316d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
18743931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
187516d9e3a6SLisandro Dalcin   }
187616d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
187716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
187816d9e3a6SLisandro Dalcin }
187916d9e3a6SLisandro Dalcin 
188016d9e3a6SLisandro Dalcin /*@C
188116d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
188216d9e3a6SLisandro Dalcin 
188316d9e3a6SLisandro Dalcin    Input Parameters:
188416d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1885db966c6cSHong Zhang -     name - either  euclid, pilut, parasails, boomeramg, ams, ads
188616d9e3a6SLisandro Dalcin 
188716d9e3a6SLisandro Dalcin    Options Database Keys:
1888db966c6cSHong Zhang    -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
188916d9e3a6SLisandro Dalcin 
189016d9e3a6SLisandro Dalcin    Level: intermediate
189116d9e3a6SLisandro Dalcin 
189216d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
189316d9e3a6SLisandro Dalcin            PCHYPRE
189416d9e3a6SLisandro Dalcin 
189516d9e3a6SLisandro Dalcin @*/
18967087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
189716d9e3a6SLisandro Dalcin {
18984ac538c5SBarry Smith   PetscErrorCode ierr;
189916d9e3a6SLisandro Dalcin 
190016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
19010700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
190216d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
19034ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
190416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
190516d9e3a6SLisandro Dalcin }
190616d9e3a6SLisandro Dalcin 
190716d9e3a6SLisandro Dalcin /*@C
190816d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
190916d9e3a6SLisandro Dalcin 
191016d9e3a6SLisandro Dalcin    Input Parameter:
191116d9e3a6SLisandro Dalcin .     pc - the preconditioner context
191216d9e3a6SLisandro Dalcin 
191316d9e3a6SLisandro Dalcin    Output Parameter:
1914db966c6cSHong Zhang .     name - either  euclid, pilut, parasails, boomeramg, ams, ads
191516d9e3a6SLisandro Dalcin 
191616d9e3a6SLisandro Dalcin    Level: intermediate
191716d9e3a6SLisandro Dalcin 
191816d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
191916d9e3a6SLisandro Dalcin            PCHYPRE
192016d9e3a6SLisandro Dalcin 
192116d9e3a6SLisandro Dalcin @*/
19227087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
192316d9e3a6SLisandro Dalcin {
19244ac538c5SBarry Smith   PetscErrorCode ierr;
192516d9e3a6SLisandro Dalcin 
192616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
19270700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
192816d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
19294ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
193016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
193116d9e3a6SLisandro Dalcin }
193216d9e3a6SLisandro Dalcin 
193316d9e3a6SLisandro Dalcin /*MC
193416d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
193516d9e3a6SLisandro Dalcin 
193616d9e3a6SLisandro Dalcin    Options Database Keys:
1937db966c6cSHong Zhang +   -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
193816d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
193916d9e3a6SLisandro Dalcin           preconditioner
194016d9e3a6SLisandro Dalcin 
194116d9e3a6SLisandro Dalcin    Level: intermediate
194216d9e3a6SLisandro Dalcin 
194395452b02SPatrick Sanan    Notes:
194495452b02SPatrick Sanan     Apart from pc_hypre_type (for which there is PCHYPRESetType()),
194516d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
194616d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
194716d9e3a6SLisandro Dalcin 
1948c231f9e3SBarryFSmith           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_tol refer to the number of iterations
19490f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
19500f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
1951c231f9e3SBarryFSmith           (-pc_hypre_boomeramg_tol should be set to 0.0 - the default - to strictly use a fixed number of
19528f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
19530f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
19540f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
195516d9e3a6SLisandro Dalcin 
19560f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
19570f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
19580f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
195916d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
196016d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
196116d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
196216d9e3a6SLisandro Dalcin 
196316d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
196416d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
196516d9e3a6SLisandro Dalcin 
19665272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
19675272c319SBarry Smith           the two options:
19685272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
1969cbc39033SBarry Smith -   -pc_hypre_boomeramg_vec_interp_variant <v> where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
19705272c319SBarry Smith 
19715272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
19725272c319SBarry Smith 
19739e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
19749e5bc791SBarry Smith 
197516d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
19769e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
197716d9e3a6SLisandro Dalcin 
197816d9e3a6SLisandro Dalcin M*/
197916d9e3a6SLisandro Dalcin 
19808cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
198116d9e3a6SLisandro Dalcin {
198216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
198316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
198416d9e3a6SLisandro Dalcin 
198516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1986b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
19872fa5cd67SKarl Rupp 
198816d9e3a6SLisandro Dalcin   pc->data                = jac;
19898695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
199016d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
199116d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
199216d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
199316d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
199416d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
1995bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1996bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
19975ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
19985ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
19995ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
20006bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",PCHYPRESetInterpolations_HYPRE);CHKERRQ(ierr);
20015ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE);CHKERRQ(ierr);
20025ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",PCHYPRESetPoissonMatrix_HYPRE);CHKERRQ(ierr);
200316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
200416d9e3a6SLisandro Dalcin }
2005ebc551c0SBarry Smith 
2006f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
2007f91d8e95SBarry Smith 
2008ebc551c0SBarry Smith typedef struct {
200968326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
2010f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
20119e5bc791SBarry Smith 
20129e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
20134ddd07fcSJed Brown   PetscInt its;
20149e5bc791SBarry Smith   double   tol;
20154ddd07fcSJed Brown   PetscInt relax_type;
20164ddd07fcSJed Brown   PetscInt rap_type;
20174ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
20184ddd07fcSJed Brown   PetscInt max_levels;
2019ebc551c0SBarry Smith } PC_PFMG;
2020ebc551c0SBarry Smith 
2021ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
2022ebc551c0SBarry Smith {
2023ebc551c0SBarry Smith   PetscErrorCode ierr;
2024f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2025ebc551c0SBarry Smith 
2026ebc551c0SBarry Smith   PetscFunctionBegin;
20272fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2028f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2029c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2030ebc551c0SBarry Smith   PetscFunctionReturn(0);
2031ebc551c0SBarry Smith }
2032ebc551c0SBarry Smith 
20339e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
20349e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
20359e5bc791SBarry Smith 
2036ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
2037ebc551c0SBarry Smith {
2038ebc551c0SBarry Smith   PetscErrorCode ierr;
2039ace3abfcSBarry Smith   PetscBool      iascii;
2040f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2041ebc551c0SBarry Smith 
2042ebc551c0SBarry Smith   PetscFunctionBegin;
2043251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
20449e5bc791SBarry Smith   if (iascii) {
20459e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
2046efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max iterations %d\n",ex->its);CHKERRQ(ierr);
2047efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    tolerance %g\n",ex->tol);CHKERRQ(ierr);
2048efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2049efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
2050efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2051efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max levels %d\n",ex->max_levels);CHKERRQ(ierr);
20529e5bc791SBarry Smith   }
2053ebc551c0SBarry Smith   PetscFunctionReturn(0);
2054ebc551c0SBarry Smith }
2055ebc551c0SBarry Smith 
20564416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2057ebc551c0SBarry Smith {
2058ebc551c0SBarry Smith   PetscErrorCode ierr;
2059f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2060ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2061ebc551c0SBarry Smith 
2062ebc551c0SBarry Smith   PetscFunctionBegin;
2063e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
20640298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
206568326731SBarry Smith   if (flg) {
2066a0324ebeSBarry Smith     int level=3;
2067fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
206868326731SBarry Smith   }
20690298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2070fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
20710298fd71SBarry 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);
2072fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
20730298fd71SBarry 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);
2074fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
20759e5bc791SBarry Smith 
20760298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
2077fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
20783b46a515SGlenn Hammond 
20790298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2080fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
20810298fd71SBarry 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);
2082fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
20830298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
2084fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
2085ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
2086ebc551c0SBarry Smith   PetscFunctionReturn(0);
2087ebc551c0SBarry Smith }
2088ebc551c0SBarry Smith 
2089f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
2090f91d8e95SBarry Smith {
2091f91d8e95SBarry Smith   PetscErrorCode    ierr;
2092f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
2093d9ca1df4SBarry Smith   PetscScalar       *yy;
2094d9ca1df4SBarry Smith   const PetscScalar *xx;
20954ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
209668326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2097f91d8e95SBarry Smith 
2098f91d8e95SBarry Smith   PetscFunctionBegin;
2099dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2100aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2101f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
2102f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
2103f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
2104f91d8e95SBarry Smith 
2105f91d8e95SBarry Smith   /* copy x values over to hypre */
2106fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
2107d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2108d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
2109d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2110fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
2111fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2112f91d8e95SBarry Smith 
2113f91d8e95SBarry Smith   /* copy solution values back to PETSc */
2114f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
21158b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
2116f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2117f91d8e95SBarry Smith   PetscFunctionReturn(0);
2118f91d8e95SBarry Smith }
2119f91d8e95SBarry Smith 
2120ace3abfcSBarry 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)
21219e5bc791SBarry Smith {
21229e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
21239e5bc791SBarry Smith   PetscErrorCode ierr;
21244ddd07fcSJed Brown   PetscInt       oits;
21259e5bc791SBarry Smith 
21269e5bc791SBarry Smith   PetscFunctionBegin;
2127dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2128fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
2129fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
21309e5bc791SBarry Smith 
21319e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
21328b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
21339e5bc791SBarry Smith   *outits = oits;
21349e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
21359e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2136fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
2137fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
21389e5bc791SBarry Smith   PetscFunctionReturn(0);
21399e5bc791SBarry Smith }
21409e5bc791SBarry Smith 
21419e5bc791SBarry Smith 
21423a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
21433a32d3dbSGlenn Hammond {
21443a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
21453a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
21463a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2147ace3abfcSBarry Smith   PetscBool       flg;
21483a32d3dbSGlenn Hammond 
21493a32d3dbSGlenn Hammond   PetscFunctionBegin;
2150251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
2151ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
21523a32d3dbSGlenn Hammond 
21533a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
21542fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2155fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2156fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2157fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
21583a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
21593a32d3dbSGlenn Hammond }
21603a32d3dbSGlenn Hammond 
2161ebc551c0SBarry Smith /*MC
2162ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
2163ebc551c0SBarry Smith 
2164ebc551c0SBarry Smith    Level: advanced
2165ebc551c0SBarry Smith 
21669e5bc791SBarry Smith    Options Database:
21679e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
21689e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
21699e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
21709e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
21719e5bc791SBarry 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
21729e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
2173f91d8e95SBarry Smith 
217495452b02SPatrick Sanan    Notes:
217595452b02SPatrick Sanan     This is for CELL-centered descretizations
21769e5bc791SBarry Smith 
21778e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
2178aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
21799e5bc791SBarry Smith 
21809e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
2181ebc551c0SBarry Smith M*/
2182ebc551c0SBarry Smith 
21838cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
2184ebc551c0SBarry Smith {
2185ebc551c0SBarry Smith   PetscErrorCode ierr;
2186ebc551c0SBarry Smith   PC_PFMG        *ex;
2187ebc551c0SBarry Smith 
2188ebc551c0SBarry Smith   PetscFunctionBegin;
2189b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
219068326731SBarry Smith   pc->data = ex;
2191ebc551c0SBarry Smith 
21929e5bc791SBarry Smith   ex->its            = 1;
21939e5bc791SBarry Smith   ex->tol            = 1.e-8;
21949e5bc791SBarry Smith   ex->relax_type     = 1;
21959e5bc791SBarry Smith   ex->rap_type       = 0;
21969e5bc791SBarry Smith   ex->num_pre_relax  = 1;
21979e5bc791SBarry Smith   ex->num_post_relax = 1;
21983b46a515SGlenn Hammond   ex->max_levels     = 0;
21999e5bc791SBarry Smith 
2200ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2201ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2202ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2203f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
22049e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
220568326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
22062fa5cd67SKarl Rupp 
2207ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2208fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2209ebc551c0SBarry Smith   PetscFunctionReturn(0);
2210ebc551c0SBarry Smith }
2211d851a50bSGlenn Hammond 
2212325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2213325fc9f4SBarry Smith 
2214d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2215d851a50bSGlenn Hammond typedef struct {
2216d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2217d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2218d851a50bSGlenn Hammond 
2219d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
22204ddd07fcSJed Brown   PetscInt its;
2221d851a50bSGlenn Hammond   double   tol;
22224ddd07fcSJed Brown   PetscInt relax_type;
22234ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2224d851a50bSGlenn Hammond } PC_SysPFMG;
2225d851a50bSGlenn Hammond 
2226d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2227d851a50bSGlenn Hammond {
2228d851a50bSGlenn Hammond   PetscErrorCode ierr;
2229d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2230d851a50bSGlenn Hammond 
2231d851a50bSGlenn Hammond   PetscFunctionBegin;
22322fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2233d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2234c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2235d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2236d851a50bSGlenn Hammond }
2237d851a50bSGlenn Hammond 
2238d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2239d851a50bSGlenn Hammond 
2240d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2241d851a50bSGlenn Hammond {
2242d851a50bSGlenn Hammond   PetscErrorCode ierr;
2243ace3abfcSBarry Smith   PetscBool      iascii;
2244d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2245d851a50bSGlenn Hammond 
2246d851a50bSGlenn Hammond   PetscFunctionBegin;
2247251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2248d851a50bSGlenn Hammond   if (iascii) {
2249d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2250efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  max iterations %d\n",ex->its);CHKERRQ(ierr);
2251efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerance %g\n",ex->tol);CHKERRQ(ierr);
2252efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2253efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2254d851a50bSGlenn Hammond   }
2255d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2256d851a50bSGlenn Hammond }
2257d851a50bSGlenn Hammond 
22584416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2259d851a50bSGlenn Hammond {
2260d851a50bSGlenn Hammond   PetscErrorCode ierr;
2261d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2262ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2263d851a50bSGlenn Hammond 
2264d851a50bSGlenn Hammond   PetscFunctionBegin;
2265e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
22660298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2267d851a50bSGlenn Hammond   if (flg) {
2268d851a50bSGlenn Hammond     int level=3;
2269fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
2270d851a50bSGlenn Hammond   }
22710298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2272fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
22730298fd71SBarry 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);
2274fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
22750298fd71SBarry 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);
2276fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2277d851a50bSGlenn Hammond 
22780298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2279fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
228061710fbeSStefano Zampini   ierr = PetscOptionsEList("-pc_syspfmg_relax_type","Relax type for the up and down cycles","HYPRE_SStructSysPFMGSetRelaxType",SysPFMGRelaxType,ALEN(SysPFMGRelaxType),SysPFMGRelaxType[ex->relax_type],&ex->relax_type,NULL);CHKERRQ(ierr);
2281fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2282d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2283d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2284d851a50bSGlenn Hammond }
2285d851a50bSGlenn Hammond 
2286d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2287d851a50bSGlenn Hammond {
2288d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2289d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2290d9ca1df4SBarry Smith   PetscScalar       *yy;
2291d9ca1df4SBarry Smith   const PetscScalar *xx;
22924ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
2293d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
22944ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
22954ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
22964ddd07fcSJed Brown   PetscInt          part    = 0;
22974ddd07fcSJed Brown   PetscInt          size;
22984ddd07fcSJed Brown   PetscInt          i;
2299d851a50bSGlenn Hammond 
2300d851a50bSGlenn Hammond   PetscFunctionBegin;
2301dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2302aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2303d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2304d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2305d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2306d851a50bSGlenn Hammond 
2307d851a50bSGlenn Hammond   size = 1;
23082fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
23092fa5cd67SKarl Rupp 
2310d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2311d851a50bSGlenn Hammond   if (ordering) {
2312fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2313d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2314d9ca1df4SBarry 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)));
2315d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2316fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2317fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2318fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2319d851a50bSGlenn Hammond 
2320d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2321d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
23228b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2323d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2324a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2325d851a50bSGlenn Hammond     PetscScalar *z;
23264ddd07fcSJed Brown     PetscInt    j, k;
2327d851a50bSGlenn Hammond 
2328785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2329fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2330d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2331d851a50bSGlenn Hammond 
2332d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2333d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2334d851a50bSGlenn Hammond       k= i*nvars;
23352fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2336d851a50bSGlenn Hammond     }
23378b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2338d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2339fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2340fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2341d851a50bSGlenn Hammond 
2342d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2343d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
23448b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2345d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2346d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2347d851a50bSGlenn Hammond       k= i*nvars;
23482fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2349d851a50bSGlenn Hammond     }
2350d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2351d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2352d851a50bSGlenn Hammond   }
2353d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2354d851a50bSGlenn Hammond }
2355d851a50bSGlenn Hammond 
2356ace3abfcSBarry 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)
2357d851a50bSGlenn Hammond {
2358d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2359d851a50bSGlenn Hammond   PetscErrorCode ierr;
23604ddd07fcSJed Brown   PetscInt       oits;
2361d851a50bSGlenn Hammond 
2362d851a50bSGlenn Hammond   PetscFunctionBegin;
2363dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2364fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2365fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2366d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
23678b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2368d851a50bSGlenn Hammond   *outits = oits;
2369d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2370d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2371fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2372fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2373d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2374d851a50bSGlenn Hammond }
2375d851a50bSGlenn Hammond 
2376d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2377d851a50bSGlenn Hammond {
2378d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2379d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2380d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2381ace3abfcSBarry Smith   PetscBool        flg;
2382d851a50bSGlenn Hammond 
2383d851a50bSGlenn Hammond   PetscFunctionBegin;
2384251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2385ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2386d851a50bSGlenn Hammond 
2387d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
23882fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2389fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2390fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2391fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2392d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2393d851a50bSGlenn Hammond }
2394d851a50bSGlenn Hammond 
2395d851a50bSGlenn Hammond /*MC
2396d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2397d851a50bSGlenn Hammond 
2398d851a50bSGlenn Hammond    Level: advanced
2399d851a50bSGlenn Hammond 
2400d851a50bSGlenn Hammond    Options Database:
2401d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2402d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2403d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2404d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2405d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2406d851a50bSGlenn Hammond 
240795452b02SPatrick Sanan    Notes:
240895452b02SPatrick Sanan     This is for CELL-centered descretizations
2409d851a50bSGlenn Hammond 
2410f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2411aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2412d851a50bSGlenn Hammond            Also, only cell-centered variables.
2413d851a50bSGlenn Hammond 
2414d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2415d851a50bSGlenn Hammond M*/
2416d851a50bSGlenn Hammond 
24178cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2418d851a50bSGlenn Hammond {
2419d851a50bSGlenn Hammond   PetscErrorCode ierr;
2420d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2421d851a50bSGlenn Hammond 
2422d851a50bSGlenn Hammond   PetscFunctionBegin;
2423b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2424d851a50bSGlenn Hammond   pc->data = ex;
2425d851a50bSGlenn Hammond 
2426d851a50bSGlenn Hammond   ex->its            = 1;
2427d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2428d851a50bSGlenn Hammond   ex->relax_type     = 1;
2429d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2430d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2431d851a50bSGlenn Hammond 
2432d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2433d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2434d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2435d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2436d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2437d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
24382fa5cd67SKarl Rupp 
2439ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2440fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2441d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2442d851a50bSGlenn Hammond }
2443