xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 58968eb64f9adfbb9837c37f043416ad2f98fae4)
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>
11*58968eb6SStefano Zampini #include <../src/vec/vec/impls/hypre/vhyp.h>
1249a781f5SStefano Zampini #include <../src/mat/impls/hypre/mhypre.h>
13c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h>
144cb006feSStefano Zampini #include <_hypre_parcsr_ls.h>
1516d9e3a6SLisandro Dalcin 
16dff31646SBarry Smith static PetscBool cite = PETSC_FALSE;
171f817a21SBarry Smith static const char hypreCitation[] = "@manual{hypre-web-page,\n  title  = {{\\sl hypre}: High Performance Preconditioners},\n  organization = {Lawrence Livermore National Laboratory},\n  note  = {\\url{http://www.llnl.gov/CASC/hypre/}}\n}\n";
181f817a21SBarry Smith 
1916d9e3a6SLisandro Dalcin /*
2016d9e3a6SLisandro Dalcin    Private context (data structure) for the  preconditioner.
2116d9e3a6SLisandro Dalcin */
2216d9e3a6SLisandro Dalcin typedef struct {
2316d9e3a6SLisandro Dalcin   HYPRE_Solver   hsolver;
2449a781f5SStefano Zampini   Mat            hpmat; /* MatHYPRE */
2516d9e3a6SLisandro Dalcin 
264ddd07fcSJed Brown   HYPRE_Int (*destroy)(HYPRE_Solver);
274ddd07fcSJed Brown   HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
284ddd07fcSJed Brown   HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
2916d9e3a6SLisandro Dalcin 
3016d9e3a6SLisandro Dalcin   MPI_Comm comm_hypre;
3116d9e3a6SLisandro Dalcin   char     *hypre_type;
3216d9e3a6SLisandro Dalcin 
3316d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
344ddd07fcSJed Brown   PetscInt maxiter;
3516d9e3a6SLisandro Dalcin   double   tol;
3616d9e3a6SLisandro Dalcin 
3716d9e3a6SLisandro Dalcin   /* options for Pilut */
384ddd07fcSJed Brown   PetscInt factorrowsize;
3916d9e3a6SLisandro Dalcin 
4016d9e3a6SLisandro Dalcin   /* options for ParaSails */
414ddd07fcSJed Brown   PetscInt nlevels;
4216d9e3a6SLisandro Dalcin   double   threshhold;
4316d9e3a6SLisandro Dalcin   double   filter;
444ddd07fcSJed Brown   PetscInt sym;
4516d9e3a6SLisandro Dalcin   double   loadbal;
464ddd07fcSJed Brown   PetscInt logging;
474ddd07fcSJed Brown   PetscInt ruse;
484ddd07fcSJed Brown   PetscInt symt;
4916d9e3a6SLisandro Dalcin 
5022b6d1caSBarry Smith   /* options for BoomerAMG */
51ace3abfcSBarry Smith   PetscBool printstatistics;
5216d9e3a6SLisandro Dalcin 
5316d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
544ddd07fcSJed Brown   PetscInt  cycletype;
554ddd07fcSJed Brown   PetscInt  maxlevels;
5616d9e3a6SLisandro Dalcin   double    strongthreshold;
5716d9e3a6SLisandro Dalcin   double    maxrowsum;
584ddd07fcSJed Brown   PetscInt  gridsweeps[3];
594ddd07fcSJed Brown   PetscInt  coarsentype;
604ddd07fcSJed Brown   PetscInt  measuretype;
616a251517SEike Mueller   PetscInt  smoothtype;
628131ecf7SEike Mueller   PetscInt  smoothnumlevels;
63ec64516dSEike Mueller   PetscInt  eu_level;   /* Number of levels for ILU(k) in Euclid */
64ec64516dSEike Mueller   double    eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */
65ec64516dSEike Mueller   PetscInt  eu_bj;      /* Defines use of Block Jacobi ILU in Euclid */
664ddd07fcSJed Brown   PetscInt  relaxtype[3];
6716d9e3a6SLisandro Dalcin   double    relaxweight;
6816d9e3a6SLisandro Dalcin   double    outerrelaxweight;
694ddd07fcSJed Brown   PetscInt  relaxorder;
7016d9e3a6SLisandro Dalcin   double    truncfactor;
71ace3abfcSBarry Smith   PetscBool applyrichardson;
724ddd07fcSJed Brown   PetscInt  pmax;
734ddd07fcSJed Brown   PetscInt  interptype;
744ddd07fcSJed Brown   PetscInt  agg_nl;
754ddd07fcSJed Brown   PetscInt  agg_num_paths;
764ddd07fcSJed Brown   PetscInt  nodal_coarsen;
77ace3abfcSBarry Smith   PetscBool nodal_relax;
784ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
794cb006feSStefano Zampini 
805272c319SBarry Smith   PetscInt  nodal_coarsening;
815272c319SBarry Smith   PetscInt  vec_interp_variant;
825272c319SBarry Smith   HYPRE_IJVector  *hmnull;
835272c319SBarry Smith   HYPRE_ParVector *phmnull;  /* near null space passed to hypre */
845272c319SBarry Smith   PetscInt        n_hmnull;
855272c319SBarry Smith   Vec             hmnull_constant;
8672827435SBarry Smith   PetscScalar     **hmnull_hypre_data_array;   /* this is the space in hmnull that was allocated by hypre, it is restored to hypre just before freeing the phmnull vectors */
875272c319SBarry Smith 
88863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
89863406b8SStefano Zampini   PetscInt  as_print;
90863406b8SStefano Zampini   PetscInt  as_max_iter;
91863406b8SStefano Zampini   PetscReal as_tol;
92863406b8SStefano Zampini   PetscInt  as_relax_type;
93863406b8SStefano Zampini   PetscInt  as_relax_times;
94863406b8SStefano Zampini   PetscReal as_relax_weight;
95863406b8SStefano Zampini   PetscReal as_omega;
96863406b8SStefano Zampini   PetscInt  as_amg_alpha_opts[5]; /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for vector Poisson (AMS) or Curl problem (ADS) */
97863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
98863406b8SStefano Zampini   PetscInt  as_amg_beta_opts[5];  /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for scalar Poisson (AMS) or vector Poisson (ADS) */
99863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
1004cb006feSStefano Zampini   PetscInt  ams_cycle_type;
101863406b8SStefano Zampini   PetscInt  ads_cycle_type;
1024cb006feSStefano Zampini 
1034cb006feSStefano Zampini   /* additional data */
1045ac14e1cSStefano Zampini   Mat G;             /* MatHYPRE */
1055ac14e1cSStefano Zampini   Mat C;             /* MatHYPRE */
1065ac14e1cSStefano Zampini   Mat alpha_Poisson; /* MatHYPRE */
1075ac14e1cSStefano Zampini   Mat beta_Poisson;  /* MatHYPRE */
1085ac14e1cSStefano Zampini 
1095ac14e1cSStefano Zampini   /* extra information for AMS */
1105ac14e1cSStefano Zampini   PetscInt       dim; /* geometrical dimension */
1114cb006feSStefano Zampini   HYPRE_IJVector coords[3];
1124cb006feSStefano Zampini   HYPRE_IJVector constants[3];
1134cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
11423df4f25SStefano Zampini   PetscBool      ams_beta_is_zero_part;
11523df4f25SStefano Zampini   PetscInt       ams_proj_freq;
11616d9e3a6SLisandro Dalcin } PC_HYPRE;
11716d9e3a6SLisandro Dalcin 
118d2128fa2SBarry Smith #undef __FUNCT__
119d2128fa2SBarry Smith #define __FUNCT__ "PCHYPREGetSolver"
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 #undef __FUNCT__
13016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE"
13116d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
13216d9e3a6SLisandro Dalcin {
13316d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
13449a781f5SStefano Zampini   Mat_HYPRE          *hjac;
13516d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
13616d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
13749a781f5SStefano Zampini   PetscBool          ishypre;
13849a781f5SStefano Zampini   PetscErrorCode     ierr;
13916d9e3a6SLisandro Dalcin 
14016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
14116d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
14202a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
14316d9e3a6SLisandro Dalcin   }
1445f5c5b43SBarry Smith 
14549a781f5SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRE,&ishypre);CHKERRQ(ierr);
14649a781f5SStefano Zampini   if (!ishypre) {
14749a781f5SStefano Zampini     MatReuse reuse;
14849a781f5SStefano Zampini     if (pc->setupcalled) reuse = MAT_REUSE_MATRIX;
14949a781f5SStefano Zampini     else reuse = MAT_INITIAL_MATRIX;
15049a781f5SStefano Zampini     ierr = MatConvert(pc->pmat,MATHYPRE,reuse,&jac->hpmat);CHKERRQ(ierr);
15149a781f5SStefano Zampini   } else {
15249a781f5SStefano Zampini     ierr = PetscObjectReference((PetscObject)pc->pmat);CHKERRQ(ierr);
15349a781f5SStefano Zampini     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
15449a781f5SStefano Zampini     jac->hpmat = pc->pmat;
15516d9e3a6SLisandro Dalcin   }
15649a781f5SStefano Zampini   hjac = (Mat_HYPRE*)(jac->hpmat->data);
1575f5c5b43SBarry Smith 
15816d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
15916d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
1605272c319SBarry Smith     MatNullSpace    mnull;
1615272c319SBarry Smith     PetscBool       has_const;
16249a781f5SStefano Zampini     PetscInt        bs,nvec,i;
1635272c319SBarry Smith     const Vec       *vecs;
16472827435SBarry Smith     PetscScalar     *petscvecarray;
1655272c319SBarry Smith 
16616d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1672fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
1685272c319SBarry Smith     ierr = MatGetNearNullSpace(pc->mat, &mnull);CHKERRQ(ierr);
1695272c319SBarry Smith     if (mnull) {
1705272c319SBarry Smith       ierr = MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs);CHKERRQ(ierr);
1715272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull);CHKERRQ(ierr);
17272827435SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull_hypre_data_array);CHKERRQ(ierr);
1735272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->phmnull);CHKERRQ(ierr);
1745272c319SBarry Smith       for (i=0; i<nvec; i++) {
1755272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(vecs[i],&jac->hmnull[i]);CHKERRQ(ierr);
17672827435SBarry Smith         ierr = VecGetArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
177*58968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],petscvecarray,jac->hmnull_hypre_data_array[i]);
17872827435SBarry Smith         ierr = VecRestoreArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
1795272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[i],(void**)&jac->phmnull[i]));
1805272c319SBarry Smith       }
1815272c319SBarry Smith       if (has_const) {
1825272c319SBarry Smith         ierr = MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL);CHKERRQ(ierr);
1835272c319SBarry Smith         ierr = VecSet(jac->hmnull_constant,1);CHKERRQ(ierr);
1845272c319SBarry Smith         ierr = VecNormalize(jac->hmnull_constant,NULL);
1855272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(jac->hmnull_constant,&jac->hmnull[nvec]);CHKERRQ(ierr);
18672827435SBarry Smith         ierr = VecGetArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
187*58968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[nvec],petscvecarray,jac->hmnull_hypre_data_array[nvec]);
18872827435SBarry Smith         ierr = VecRestoreArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
1895272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[nvec],(void**)&jac->phmnull[nvec]));
1905272c319SBarry Smith         nvec++;
1915272c319SBarry Smith       }
1925272c319SBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVectors,(jac->hsolver,nvec,jac->phmnull));
1935272c319SBarry Smith       jac->n_hmnull = nvec;
1945272c319SBarry Smith     }
1954cb006feSStefano Zampini   }
196863406b8SStefano Zampini 
1974cb006feSStefano Zampini   /* special case for AMS */
1984cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
1995ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2005ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
20149a781f5SStefano Zampini     if (!jac->coords[0] && !jac->constants[0]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the edge constant vectors via PCHYPRESetEdgeConstantVectors()");
2025ac14e1cSStefano Zampini     if (jac->dim) {
2035ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,jac->dim));
2045ac14e1cSStefano Zampini     }
2055ac14e1cSStefano Zampini     if (jac->constants[0]) {
2065ac14e1cSStefano Zampini       HYPRE_ParVector ozz,zoz,zzo = NULL;
2075ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&ozz)));
2085ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&zoz)));
2095ac14e1cSStefano Zampini       if (jac->constants[2]) {
2105ac14e1cSStefano Zampini         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&zzo)));
2115ac14e1cSStefano Zampini       }
2125ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,ozz,zoz,zzo));
2135ac14e1cSStefano Zampini     }
2145ac14e1cSStefano Zampini     if (jac->coords[0]) {
2155ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
2165ac14e1cSStefano Zampini       coords[0] = NULL;
2175ac14e1cSStefano Zampini       coords[1] = NULL;
2185ac14e1cSStefano Zampini       coords[2] = NULL;
2195ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
2205ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
2215ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
2225ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
2235ac14e1cSStefano Zampini     }
22449a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
2255ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
2265ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2275ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr));
2285ac14e1cSStefano Zampini     if (jac->alpha_Poisson) {
2295ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->alpha_Poisson->data);
2305ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2315ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr));
2325ac14e1cSStefano Zampini     }
2335ac14e1cSStefano Zampini     if (jac->ams_beta_is_zero) {
2345ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
2355ac14e1cSStefano Zampini     } else if (jac->beta_Poisson) {
2365ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->beta_Poisson->data);
2375ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2385ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr));
2395ac14e1cSStefano Zampini     }
2404cb006feSStefano Zampini   }
241863406b8SStefano Zampini   /* special case for ADS */
242863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
2435ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2445ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
24549a781f5SStefano Zampini     if (!jac->coords[0]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the coordinate vectors via PCSetCoordinates()");
24637096e45SBarry 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");
24749a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
24849a781f5SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient");
2495ac14e1cSStefano Zampini     if (jac->coords[0]) {
2505ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
2515ac14e1cSStefano Zampini       coords[0] = NULL;
2525ac14e1cSStefano Zampini       coords[1] = NULL;
2535ac14e1cSStefano Zampini       coords[2] = NULL;
2545ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
2555ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
2565ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
2575ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_ADSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
2585ac14e1cSStefano Zampini     }
2595ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
2605ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2615ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteGradient,(jac->hsolver,parcsr));
2625ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->C->data);
2635ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
2645ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteCurl,(jac->hsolver,parcsr));
265863406b8SStefano Zampini   }
26649a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
26749a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&bv));
26849a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&xv));
269fd3f9acdSBarry Smith   PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr););
27016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
27116d9e3a6SLisandro Dalcin }
27216d9e3a6SLisandro Dalcin 
27316d9e3a6SLisandro Dalcin #undef __FUNCT__
27416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE"
27516d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
27616d9e3a6SLisandro Dalcin {
27716d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
27849a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
27916d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
28016d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
281d9ca1df4SBarry Smith   PetscScalar        *xv;
282d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
28316d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
284d9ca1df4SBarry Smith   PetscScalar        *sxv;
2854ddd07fcSJed Brown   PetscInt           hierr;
28616d9e3a6SLisandro Dalcin 
28716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
288dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
28916d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
290d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
29116d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
292*58968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)bv,sbv);
293*58968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
29416d9e3a6SLisandro Dalcin 
29549a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
29649a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
29749a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
298fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
29965e19b50SBarry Smith                                if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
300fd3f9acdSBarry Smith                                if (hierr) hypre__global_error = 0;);
30116d9e3a6SLisandro Dalcin 
30223df4f25SStefano Zampini   if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) {
3035ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSProjectOutGradients,(jac->hsolver,jxv));
30421df291bSStefano Zampini   }
305*58968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)sbv,bv);
306*58968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
30716d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
308d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
30916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
31016d9e3a6SLisandro Dalcin }
31116d9e3a6SLisandro Dalcin 
31216d9e3a6SLisandro Dalcin #undef __FUNCT__
3138695de01SBarry Smith #define __FUNCT__ "PCReset_HYPRE"
3148695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc)
3158695de01SBarry Smith {
3168695de01SBarry Smith   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
3178695de01SBarry Smith   PetscErrorCode ierr;
3188695de01SBarry Smith 
3198695de01SBarry Smith   PetscFunctionBegin;
32049a781f5SStefano Zampini   ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
3215ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
3225ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
3235ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
3245ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
3258695de01SBarry Smith   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); jac->coords[0] = NULL;
3268695de01SBarry Smith   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); jac->coords[1] = NULL;
3278695de01SBarry Smith   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); jac->coords[2] = NULL;
3288695de01SBarry Smith   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); jac->constants[0] = NULL;
3298695de01SBarry Smith   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); jac->constants[1] = NULL;
3308695de01SBarry Smith   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); jac->constants[2] = NULL;
331550a8b7dSBarry Smith   if (jac->n_hmnull && jac->hmnull) {
3325272c319SBarry Smith     PetscInt                 i;
333b1c1cd91SBarry Smith     PETSC_UNUSED PetscScalar *petscvecarray;
3345272c319SBarry Smith 
3355272c319SBarry Smith     for (i=0; i<jac->n_hmnull; i++) {
336*58968eb6SStefano Zampini       VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],jac->hmnull_hypre_data_array[i],petscvecarray);
3375272c319SBarry Smith       PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->hmnull[i]));
3385272c319SBarry Smith     }
3395272c319SBarry Smith     ierr = PetscFree(jac->hmnull);CHKERRQ(ierr);
34072827435SBarry Smith     ierr = PetscFree(jac->hmnull_hypre_data_array);CHKERRQ(ierr);
3415272c319SBarry Smith     ierr = PetscFree(jac->phmnull);CHKERRQ(ierr);
3425272c319SBarry Smith     ierr = VecDestroy(&jac->hmnull_constant);CHKERRQ(ierr);
3435272c319SBarry Smith   }
3445ac14e1cSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
3455ac14e1cSStefano Zampini   jac->dim = 0;
3468695de01SBarry Smith   PetscFunctionReturn(0);
3478695de01SBarry Smith }
3488695de01SBarry Smith 
3498695de01SBarry Smith #undef __FUNCT__
35016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE"
35116d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
35216d9e3a6SLisandro Dalcin {
35316d9e3a6SLisandro Dalcin   PC_HYPRE                 *jac = (PC_HYPRE*)pc->data;
35416d9e3a6SLisandro Dalcin   PetscErrorCode           ierr;
35516d9e3a6SLisandro Dalcin 
35616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
3578695de01SBarry Smith   ierr = PCReset_HYPRE(pc);CHKERRQ(ierr);
358226b0620SJed Brown   if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr););
359503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
36016d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
361c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
36216d9e3a6SLisandro Dalcin 
36316d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
364bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
365bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
3664cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
3674cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
368863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
3694cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
3705ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",NULL);CHKERRQ(ierr);
37116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
37216d9e3a6SLisandro Dalcin }
37316d9e3a6SLisandro Dalcin 
37416d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
37516d9e3a6SLisandro Dalcin #undef __FUNCT__
37616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut"
3774416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptionItems *PetscOptionsObject,PC pc)
37816d9e3a6SLisandro Dalcin {
37916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
38016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
381ace3abfcSBarry Smith   PetscBool      flag;
38216d9e3a6SLisandro Dalcin 
38316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
384e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
38516d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
386fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
38716d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
388fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
38916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
390fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
39116d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
39216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
39316d9e3a6SLisandro Dalcin }
39416d9e3a6SLisandro Dalcin 
39516d9e3a6SLisandro Dalcin #undef __FUNCT__
39616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut"
39716d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
39816d9e3a6SLisandro Dalcin {
39916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
40016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
401ace3abfcSBarry Smith   PetscBool      iascii;
40216d9e3a6SLisandro Dalcin 
40316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
404251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
40516d9e3a6SLisandro Dalcin   if (iascii) {
40616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
40716d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
40816d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
40916d9e3a6SLisandro Dalcin     } else {
41016d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr);
41116d9e3a6SLisandro Dalcin     }
41216d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
41357622a8eSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
41416d9e3a6SLisandro Dalcin     } else {
41516d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr);
41616d9e3a6SLisandro Dalcin     }
41716d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
41816d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
41916d9e3a6SLisandro Dalcin     } else {
42016d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default factor row size \n");CHKERRQ(ierr);
42116d9e3a6SLisandro Dalcin     }
42216d9e3a6SLisandro Dalcin   }
42316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
42416d9e3a6SLisandro Dalcin }
42516d9e3a6SLisandro Dalcin 
42616d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
42716d9e3a6SLisandro Dalcin 
42816d9e3a6SLisandro Dalcin #undef __FUNCT__
42916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG"
43016d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
43116d9e3a6SLisandro Dalcin {
43216d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
43349a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
43416d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
43516d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
436d9ca1df4SBarry Smith   PetscScalar        *xv;
437d9ca1df4SBarry Smith   const PetscScalar  *bv;
43816d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
43916d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
4404ddd07fcSJed Brown   PetscInt           hierr;
44116d9e3a6SLisandro Dalcin 
44216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
443dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
44416d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
445d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
44616d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
447*58968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,(PetscScalar*)bv,sbv);
448*58968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
44916d9e3a6SLisandro Dalcin 
45049a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
45149a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
45249a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
45316d9e3a6SLisandro Dalcin 
45416d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
45516d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
456e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
45716d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
45816d9e3a6SLisandro Dalcin 
459*58968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,sbv,bv);
460*58968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
46116d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
462d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
46316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
46416d9e3a6SLisandro Dalcin }
46516d9e3a6SLisandro Dalcin 
466a669f990SJed Brown /* static array length */
467a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
468a669f990SJed Brown 
46916d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
4700f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
47116d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
47265de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
4736a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]   = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
47465de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
47565de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
47665de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
47765de4495SJed Brown                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */,
47865de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
4790f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
4800f1074feSSatish Balay                                                   "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"};
48116d9e3a6SLisandro Dalcin #undef __FUNCT__
48216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG"
4834416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc)
48416d9e3a6SLisandro Dalcin {
48516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
48616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
4874ddd07fcSJed Brown   PetscInt       n,indx,level;
488ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
48916d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
49016d9e3a6SLisandro Dalcin 
49116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
492e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
4934336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
49416d9e3a6SLisandro Dalcin   if (flg) {
4954336a9eeSBarry Smith     jac->cycletype = indx+1;
496fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
49716d9e3a6SLisandro Dalcin   }
49816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
49916d9e3a6SLisandro Dalcin   if (flg) {
500ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
501fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
50216d9e3a6SLisandro Dalcin   }
50316d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
50416d9e3a6SLisandro Dalcin   if (flg) {
505ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
506fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
50716d9e3a6SLisandro Dalcin   }
5080f1074feSSatish 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);
50916d9e3a6SLisandro Dalcin   if (flg) {
51057622a8eSBarry 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);
511fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
51216d9e3a6SLisandro Dalcin   }
51316d9e3a6SLisandro Dalcin 
5140f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
51516d9e3a6SLisandro Dalcin   if (flg) {
51657622a8eSBarry 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);
517fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
51816d9e3a6SLisandro Dalcin   }
51916d9e3a6SLisandro Dalcin 
5200f1074feSSatish 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);
5210f1074feSSatish Balay   if (flg) {
52257622a8eSBarry 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);
523fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
5240f1074feSSatish Balay   }
5250f1074feSSatish Balay 
5260f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
5270f1074feSSatish Balay   if (flg) {
52857622a8eSBarry 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);
5290f1074feSSatish Balay 
530fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
5310f1074feSSatish Balay   }
5320f1074feSSatish Balay 
5330f1074feSSatish Balay 
5340f1074feSSatish 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);
5350f1074feSSatish Balay   if (flg) {
53657622a8eSBarry 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);
5370f1074feSSatish Balay 
538fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
5390f1074feSSatish Balay   }
5400f1074feSSatish Balay 
5410f1074feSSatish Balay 
54216d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
54316d9e3a6SLisandro Dalcin   if (flg) {
54457622a8eSBarry 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);
545fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
54616d9e3a6SLisandro Dalcin   }
54716d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
54816d9e3a6SLisandro Dalcin   if (flg) {
54957622a8eSBarry 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);
55057622a8eSBarry 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);
551fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
55216d9e3a6SLisandro Dalcin   }
55316d9e3a6SLisandro Dalcin 
55416d9e3a6SLisandro Dalcin   /* Grid sweeps */
5550f1074feSSatish 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);
55616d9e3a6SLisandro Dalcin   if (flg) {
557fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
55816d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
55916d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
5600f1074feSSatish Balay     jac->gridsweeps[1] = indx;
5610f1074feSSatish Balay     /*defaults coarse to 1 */
5620f1074feSSatish Balay     jac->gridsweeps[2] = 1;
56316d9e3a6SLisandro Dalcin   }
5640f1074feSSatish Balay 
5655272c319SBarry 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);
5665272c319SBarry Smith   if (flg) {
5675272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,jac->nodal_coarsening));
5685272c319SBarry Smith   }
5695272c319SBarry Smith 
570cbc39033SBarry 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);
5715272c319SBarry Smith   if (flg) {
5725272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,(jac->hsolver,jac->vec_interp_variant));
5735272c319SBarry Smith   }
5745272c319SBarry Smith 
5750f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
57616d9e3a6SLisandro Dalcin   if (flg) {
577fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
5780f1074feSSatish Balay     jac->gridsweeps[0] = indx;
57916d9e3a6SLisandro Dalcin   }
58016d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
58116d9e3a6SLisandro Dalcin   if (flg) {
582fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
5830f1074feSSatish Balay     jac->gridsweeps[1] = indx;
58416d9e3a6SLisandro Dalcin   }
5850f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
58616d9e3a6SLisandro Dalcin   if (flg) {
587fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
5880f1074feSSatish Balay     jac->gridsweeps[2] = indx;
58916d9e3a6SLisandro Dalcin   }
59016d9e3a6SLisandro Dalcin 
5916a251517SEike Mueller   /* Smooth type */
5926a251517SEike Mueller   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);
5936a251517SEike Mueller   if (flg) {
5946a251517SEike Mueller     jac->smoothtype = indx;
5956a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
5968131ecf7SEike Mueller     jac->smoothnumlevels = 25;
5978131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
5988131ecf7SEike Mueller   }
5998131ecf7SEike Mueller 
6008131ecf7SEike Mueller   /* Number of smoothing levels */
6018131ecf7SEike 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);
6028131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
6038131ecf7SEike Mueller     jac->smoothnumlevels = indx;
6048131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
6056a251517SEike Mueller   }
6066a251517SEike Mueller 
6071810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
6081810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
6091810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
6101810e44eSEike Mueller     jac->eu_level = indx;
6111810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
6121810e44eSEike Mueller   }
6131810e44eSEike Mueller 
6141810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
6151810e44eSEike Mueller   double droptolerance;
6161810e44eSEike Mueller   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
6171810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
6181810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
6191810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
6201810e44eSEike Mueller   }
6211810e44eSEike Mueller 
6221810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
6231810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
6241810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
6251810e44eSEike Mueller     jac->eu_bj = tmp_truth;
626493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
6271810e44eSEike Mueller   }
6281810e44eSEike Mueller 
62916d9e3a6SLisandro Dalcin   /* Relax type */
630a669f990SJed 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);
63116d9e3a6SLisandro Dalcin   if (flg) {
6320f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
633fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
6340f1074feSSatish Balay     /* by default, coarse type set to 9 */
6350f1074feSSatish Balay     jac->relaxtype[2] = 9;
6360f1074feSSatish Balay 
63716d9e3a6SLisandro Dalcin   }
638a669f990SJed 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);
63916d9e3a6SLisandro Dalcin   if (flg) {
64016d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
641fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
64216d9e3a6SLisandro Dalcin   }
643a669f990SJed 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);
64416d9e3a6SLisandro Dalcin   if (flg) {
6450f1074feSSatish Balay     jac->relaxtype[1] = indx;
646fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
64716d9e3a6SLisandro Dalcin   }
648a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
64916d9e3a6SLisandro Dalcin   if (flg) {
6500f1074feSSatish Balay     jac->relaxtype[2] = indx;
651fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
65216d9e3a6SLisandro Dalcin   }
65316d9e3a6SLisandro Dalcin 
65416d9e3a6SLisandro Dalcin   /* Relaxation Weight */
65516d9e3a6SLisandro 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);
65616d9e3a6SLisandro Dalcin   if (flg) {
657fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
65816d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
65916d9e3a6SLisandro Dalcin   }
66016d9e3a6SLisandro Dalcin 
66116d9e3a6SLisandro Dalcin   n         = 2;
66216d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
66316d9e3a6SLisandro 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);
66416d9e3a6SLisandro Dalcin   if (flg) {
66516d9e3a6SLisandro Dalcin     if (n == 2) {
66616d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
667fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
668ce94432eSBarry 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);
66916d9e3a6SLisandro Dalcin   }
67016d9e3a6SLisandro Dalcin 
67116d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
67216d9e3a6SLisandro 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);
67316d9e3a6SLisandro Dalcin   if (flg) {
674fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
67516d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
67616d9e3a6SLisandro Dalcin   }
67716d9e3a6SLisandro Dalcin 
67816d9e3a6SLisandro Dalcin   n         = 2;
67916d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
68016d9e3a6SLisandro 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);
68116d9e3a6SLisandro Dalcin   if (flg) {
68216d9e3a6SLisandro Dalcin     if (n == 2) {
68316d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
684fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
685ce94432eSBarry 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);
68616d9e3a6SLisandro Dalcin   }
68716d9e3a6SLisandro Dalcin 
68816d9e3a6SLisandro Dalcin   /* the Relax Order */
689acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
69016d9e3a6SLisandro Dalcin 
6918afaa268SBarry Smith   if (flg && tmp_truth) {
69216d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
693fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
69416d9e3a6SLisandro Dalcin   }
695a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
69616d9e3a6SLisandro Dalcin   if (flg) {
69716d9e3a6SLisandro Dalcin     jac->measuretype = indx;
698fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
69916d9e3a6SLisandro Dalcin   }
7000f1074feSSatish Balay   /* update list length 3/07 */
701a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
70216d9e3a6SLisandro Dalcin   if (flg) {
70316d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
704fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
70516d9e3a6SLisandro Dalcin   }
7060f1074feSSatish Balay 
7070f1074feSSatish Balay   /* new 3/07 */
708a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
7090f1074feSSatish Balay   if (flg) {
7100f1074feSSatish Balay     jac->interptype = indx;
711fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
7120f1074feSSatish Balay   }
7130f1074feSSatish Balay 
714b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
71516d9e3a6SLisandro Dalcin   if (flg) {
716b96a4a96SBarry Smith     level = 3;
7170298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
7182fa5cd67SKarl Rupp 
719b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
720fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
7212ae77aedSBarry Smith   }
7222ae77aedSBarry Smith 
723b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
7242ae77aedSBarry Smith   if (flg) {
725b96a4a96SBarry Smith     level = 3;
7260298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
7272fa5cd67SKarl Rupp 
728b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
729fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
73016d9e3a6SLisandro Dalcin   }
7318f87f92bSBarry Smith 
732acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
7338f87f92bSBarry Smith   if (flg && tmp_truth) {
7348f87f92bSBarry Smith     PetscInt tmp_int;
7358f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
7368f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
737fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
738fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
739fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
740fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
7418f87f92bSBarry Smith   }
7428f87f92bSBarry Smith 
74316d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
74416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
74516d9e3a6SLisandro Dalcin }
74616d9e3a6SLisandro Dalcin 
74716d9e3a6SLisandro Dalcin #undef __FUNCT__
74816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG"
749ace3abfcSBarry 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)
75016d9e3a6SLisandro Dalcin {
75116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
75216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
7534ddd07fcSJed Brown   PetscInt       oits;
75416d9e3a6SLisandro Dalcin 
75516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
756dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
757fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
758fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
75916d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
76016d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
76116d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
7628b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
7634d0a8057SBarry Smith   *outits = oits;
7644d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
7654d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
766fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
767fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
76816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
76916d9e3a6SLisandro Dalcin }
77016d9e3a6SLisandro Dalcin 
77116d9e3a6SLisandro Dalcin 
77216d9e3a6SLisandro Dalcin #undef __FUNCT__
77316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG"
77416d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
77516d9e3a6SLisandro Dalcin {
77616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
77716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
778ace3abfcSBarry Smith   PetscBool      iascii;
77916d9e3a6SLisandro Dalcin 
78016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
781251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
78216d9e3a6SLisandro Dalcin   if (iascii) {
78316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
78416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
78516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
78616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
78757622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
78857622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
78957622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
7900f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
7910f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
7920f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
7930f1074feSSatish Balay 
79457622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
79516d9e3a6SLisandro Dalcin 
7960f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
7970f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
7980f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
79916d9e3a6SLisandro Dalcin 
8000f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
8010f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
8020f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
80316d9e3a6SLisandro Dalcin 
80457622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
80557622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
80616d9e3a6SLisandro Dalcin 
80716d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
80816d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr);
80916d9e3a6SLisandro Dalcin     } else {
81016d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr);
81116d9e3a6SLisandro Dalcin     }
8126a251517SEike Mueller     if (jac->smoothtype!=-1) {
8136a251517SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
8148131ecf7SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Smooth num levels    %d\n",jac->smoothnumlevels);CHKERRQ(ierr);
8157e352d70SEike Mueller     } else {
816c2bc9be0SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using more complex smoothers.\n");CHKERRQ(ierr);
8171810e44eSEike Mueller     }
8181810e44eSEike Mueller     if (jac->smoothtype==3) {
8191810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU(k) levels %d\n",jac->eu_level);CHKERRQ(ierr);
8201810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU(k) drop tolerance %g\n",jac->eu_droptolerance);CHKERRQ(ierr);
8211810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU use Block-Jacobi? %d\n",jac->eu_bj);CHKERRQ(ierr);
8226a251517SEike Mueller     }
82316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
82416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
8250f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
8265272c319SBarry Smith     if (jac->nodal_coarsening) {
8275272c319SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
8285272c319SBarry Smith     }
8295272c319SBarry Smith     if (jac->vec_interp_variant) {
8305272c319SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
8318f87f92bSBarry Smith     }
8328f87f92bSBarry Smith     if (jac->nodal_relax) {
8338f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
8348f87f92bSBarry Smith     }
83516d9e3a6SLisandro Dalcin   }
83616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
83716d9e3a6SLisandro Dalcin }
83816d9e3a6SLisandro Dalcin 
83916d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
84016d9e3a6SLisandro Dalcin #undef __FUNCT__
84116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails"
8424416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc)
84316d9e3a6SLisandro Dalcin {
84416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
84516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
8464ddd07fcSJed Brown   PetscInt       indx;
847ace3abfcSBarry Smith   PetscBool      flag;
84816d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
84916d9e3a6SLisandro Dalcin 
85016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
851e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
85216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
85316d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
8542fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
85516d9e3a6SLisandro Dalcin 
85616d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
8572fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
85816d9e3a6SLisandro Dalcin 
85916d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
8602fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
86116d9e3a6SLisandro Dalcin 
862acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
8632fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
86416d9e3a6SLisandro Dalcin 
865acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
8662fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
86716d9e3a6SLisandro Dalcin 
868a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
86916d9e3a6SLisandro Dalcin   if (flag) {
87016d9e3a6SLisandro Dalcin     jac->symt = indx;
871fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
87216d9e3a6SLisandro Dalcin   }
87316d9e3a6SLisandro Dalcin 
87416d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
87516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
87616d9e3a6SLisandro Dalcin }
87716d9e3a6SLisandro Dalcin 
87816d9e3a6SLisandro Dalcin #undef __FUNCT__
87916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails"
88016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
88116d9e3a6SLisandro Dalcin {
88216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
88316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
884ace3abfcSBarry Smith   PetscBool      iascii;
88516d9e3a6SLisandro Dalcin   const char     *symt = 0;;
88616d9e3a6SLisandro Dalcin 
88716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
888251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
88916d9e3a6SLisandro Dalcin   if (iascii) {
89016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
89116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
89257622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
89357622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: filter %g\n",(double)jac->filter);CHKERRQ(ierr);
89457622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
895ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
896ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
8972fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
8982fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
8992fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
900ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
90116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr);
90216d9e3a6SLisandro Dalcin   }
90316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
90416d9e3a6SLisandro Dalcin }
9054cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
9064cb006feSStefano Zampini #undef __FUNCT__
9074cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS"
9084416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc)
9094cb006feSStefano Zampini {
9104cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
9114cb006feSStefano Zampini   PetscErrorCode ierr;
9124cb006feSStefano Zampini   PetscInt       n;
9134cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
9144cb006feSStefano Zampini 
9154cb006feSStefano Zampini   PetscFunctionBegin;
9169fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
917863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
918863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
919863406b8SStefano 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);
920863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
9214cb006feSStefano 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);
9224cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
923863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
924863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
925863406b8SStefano 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);
926863406b8SStefano 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);
927863406b8SStefano 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);
928863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
9294cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
930863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
931863406b8SStefano Zampini                                                                       jac->as_relax_times,
932863406b8SStefano Zampini                                                                       jac->as_relax_weight,
933863406b8SStefano Zampini                                                                       jac->as_omega));
9344cb006feSStefano Zampini   }
935863406b8SStefano 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);
9364cb006feSStefano Zampini   n = 5;
937863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
9384cb006feSStefano Zampini   if (flag || flag2) {
939863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
940863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
941863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
942863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
943863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
944863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
9454cb006feSStefano Zampini   }
946863406b8SStefano 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);
9474cb006feSStefano Zampini   n = 5;
948863406b8SStefano 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);
9494cb006feSStefano Zampini   if (flag || flag2) {
950863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
951863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
952863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
953863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
954863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
955863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
9564cb006feSStefano Zampini   }
95723df4f25SStefano 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);
95823df4f25SStefano Zampini   if (flag) { /* override HYPRE's default only if the options is used */
95923df4f25SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetProjectionFrequency,(jac->hsolver,jac->ams_proj_freq));
96023df4f25SStefano Zampini   }
9614cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
9624cb006feSStefano Zampini   PetscFunctionReturn(0);
9634cb006feSStefano Zampini }
9644cb006feSStefano Zampini 
9654cb006feSStefano Zampini #undef __FUNCT__
9664cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS"
9674cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
9684cb006feSStefano Zampini {
9694cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
9704cb006feSStefano Zampini   PetscErrorCode ierr;
9714cb006feSStefano Zampini   PetscBool      iascii;
9724cb006feSStefano Zampini 
9734cb006feSStefano Zampini   PetscFunctionBegin;
9744cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
9754cb006feSStefano Zampini   if (iascii) {
9764cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
977863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
9784cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
979863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
980863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
981863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
982863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
983863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
9844cb006feSStefano Zampini     if (jac->alpha_Poisson) {
9854cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
9864cb006feSStefano Zampini     } else {
9874cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr);
9884cb006feSStefano Zampini     }
989863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
990863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
991863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
992863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
993863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
994863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
9954cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
9964cb006feSStefano Zampini       if (jac->beta_Poisson) {
9974cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
9984cb006feSStefano Zampini       } else {
9994cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr);
10004cb006feSStefano Zampini       }
1001863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1002863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1003863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1004863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1005863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1006863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
100723df4f25SStefano Zampini       if (jac->ams_beta_is_zero_part) {
100823df4f25SStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     compatible subspace projection frequency %d (-1 HYPRE uses default)\n",jac->ams_proj_freq);CHKERRQ(ierr);
100923df4f25SStefano Zampini       }
101023df4f25SStefano Zampini     } else {
101123df4f25SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver not used (zero-conductivity everywhere) \n");CHKERRQ(ierr);
10124cb006feSStefano Zampini     }
10134cb006feSStefano Zampini   }
10144cb006feSStefano Zampini   PetscFunctionReturn(0);
10154cb006feSStefano Zampini }
10164cb006feSStefano Zampini 
10174cb006feSStefano Zampini #undef __FUNCT__
1018863406b8SStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_ADS"
10194416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc)
1020863406b8SStefano Zampini {
1021863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1022863406b8SStefano Zampini   PetscErrorCode ierr;
1023863406b8SStefano Zampini   PetscInt       n;
1024863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
1025863406b8SStefano Zampini 
1026863406b8SStefano Zampini   PetscFunctionBegin;
1027863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
1028863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1029863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1030863406b8SStefano 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);
1031863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1032863406b8SStefano 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);
1033863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
1034863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1035863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1036863406b8SStefano 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);
1037863406b8SStefano 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);
1038863406b8SStefano 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);
1039863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
1040863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1041863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1042863406b8SStefano Zampini                                                                       jac->as_relax_times,
1043863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1044863406b8SStefano Zampini                                                                       jac->as_omega));
1045863406b8SStefano Zampini   }
1046863406b8SStefano 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);
1047863406b8SStefano Zampini   n = 5;
1048863406b8SStefano 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);
1049863406b8SStefano 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);
1050863406b8SStefano Zampini   if (flag || flag2 || flag3) {
1051863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
1052863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1053863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1054863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1055863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1056863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1057863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1058863406b8SStefano Zampini   }
1059863406b8SStefano 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);
1060863406b8SStefano Zampini   n = 5;
1061863406b8SStefano 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);
1062863406b8SStefano Zampini   if (flag || flag2) {
1063863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1064863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1065863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1066863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1067863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1068863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1069863406b8SStefano Zampini   }
1070863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
1071863406b8SStefano Zampini   PetscFunctionReturn(0);
1072863406b8SStefano Zampini }
1073863406b8SStefano Zampini 
1074863406b8SStefano Zampini #undef __FUNCT__
1075863406b8SStefano Zampini #define __FUNCT__ "PCView_HYPRE_ADS"
1076863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1077863406b8SStefano Zampini {
1078863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1079863406b8SStefano Zampini   PetscErrorCode ierr;
1080863406b8SStefano Zampini   PetscBool      iascii;
1081863406b8SStefano Zampini 
1082863406b8SStefano Zampini   PetscFunctionBegin;
1083863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1084863406b8SStefano Zampini   if (iascii) {
1085863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
1086863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1087863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
1088863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1089863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1090863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1091863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1092863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
1093863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: AMS solver\n");CHKERRQ(ierr);
1094863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1095863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1096863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1097863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1098863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1099863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1100863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
1101863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: vector Poisson solver\n");CHKERRQ(ierr);
1102863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1103863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1104863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1105863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1106863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1107863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
1108863406b8SStefano Zampini   }
1109863406b8SStefano Zampini   PetscFunctionReturn(0);
1110863406b8SStefano Zampini }
1111863406b8SStefano Zampini 
1112863406b8SStefano Zampini #undef __FUNCT__
1113863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE"
1114863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
11154cb006feSStefano Zampini {
11164cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
11175ac14e1cSStefano Zampini   PetscBool      ishypre;
11184cb006feSStefano Zampini   PetscErrorCode ierr;
11194cb006feSStefano Zampini 
11204cb006feSStefano Zampini   PetscFunctionBegin;
11215ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)G,MATHYPRE,&ishypre);CHKERRQ(ierr);
11225ac14e1cSStefano Zampini   if (ishypre) {
11235ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr);
11245ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
11255ac14e1cSStefano Zampini     jac->G = G;
11265ac14e1cSStefano Zampini   } else {
11275ac14e1cSStefano Zampini     MatReuse reuse = MAT_INITIAL_MATRIX;
11285ac14e1cSStefano Zampini     if (jac->G) reuse = MAT_REUSE_MATRIX;
11295ac14e1cSStefano Zampini     ierr = MatConvert(G,MATHYPRE,reuse,&jac->G);CHKERRQ(ierr);
11305ac14e1cSStefano Zampini   }
11314cb006feSStefano Zampini   PetscFunctionReturn(0);
11324cb006feSStefano Zampini }
11334cb006feSStefano Zampini 
11344cb006feSStefano Zampini #undef __FUNCT__
11354cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient"
11364cb006feSStefano Zampini /*@
11374cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
11384cb006feSStefano Zampini 
11394cb006feSStefano Zampini    Collective on PC
11404cb006feSStefano Zampini 
11414cb006feSStefano Zampini    Input Parameters:
11424cb006feSStefano Zampini +  pc - the preconditioning context
11434cb006feSStefano Zampini -  G - the discrete gradient
11444cb006feSStefano Zampini 
11454cb006feSStefano Zampini    Level: intermediate
11464cb006feSStefano Zampini 
11474cb006feSStefano Zampini    Notes: G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh
1148863406b8SStefano 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
11494cb006feSStefano Zampini 
11504cb006feSStefano Zampini .seealso:
11514cb006feSStefano Zampini @*/
11524cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
11534cb006feSStefano Zampini {
11544cb006feSStefano Zampini   PetscErrorCode ierr;
11554cb006feSStefano Zampini 
11564cb006feSStefano Zampini   PetscFunctionBegin;
11574cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11584cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
11594cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
11604cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
11614cb006feSStefano Zampini   PetscFunctionReturn(0);
11624cb006feSStefano Zampini }
11634cb006feSStefano Zampini 
11644cb006feSStefano Zampini #undef __FUNCT__
1165863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl_HYPRE"
1166863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1167863406b8SStefano Zampini {
1168863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
11695ac14e1cSStefano Zampini   PetscBool      ishypre;
1170863406b8SStefano Zampini   PetscErrorCode ierr;
1171863406b8SStefano Zampini 
1172863406b8SStefano Zampini   PetscFunctionBegin;
11735ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)C,MATHYPRE,&ishypre);CHKERRQ(ierr);
11745ac14e1cSStefano Zampini   if (ishypre) {
11755ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr);
11765ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
11775ac14e1cSStefano Zampini     jac->C = C;
11785ac14e1cSStefano Zampini   } else {
11795ac14e1cSStefano Zampini     MatReuse reuse = MAT_INITIAL_MATRIX;
11805ac14e1cSStefano Zampini     if (jac->C) reuse = MAT_REUSE_MATRIX;
11815ac14e1cSStefano Zampini     ierr = MatConvert(C,MATHYPRE,reuse,&jac->C);CHKERRQ(ierr);
11825ac14e1cSStefano Zampini   }
1183863406b8SStefano Zampini   PetscFunctionReturn(0);
1184863406b8SStefano Zampini }
1185863406b8SStefano Zampini 
1186863406b8SStefano Zampini #undef __FUNCT__
1187863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl"
1188863406b8SStefano Zampini /*@
1189863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1190863406b8SStefano Zampini 
1191863406b8SStefano Zampini    Collective on PC
1192863406b8SStefano Zampini 
1193863406b8SStefano Zampini    Input Parameters:
1194863406b8SStefano Zampini +  pc - the preconditioning context
1195863406b8SStefano Zampini -  C - the discrete curl
1196863406b8SStefano Zampini 
1197863406b8SStefano Zampini    Level: intermediate
1198863406b8SStefano Zampini 
1199863406b8SStefano Zampini    Notes: C should have as many rows as the number of faces and as many columns as the number of edges in the mesh
1200863406b8SStefano 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
1201863406b8SStefano Zampini 
1202863406b8SStefano Zampini .seealso:
1203863406b8SStefano Zampini @*/
1204863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1205863406b8SStefano Zampini {
1206863406b8SStefano Zampini   PetscErrorCode ierr;
1207863406b8SStefano Zampini 
1208863406b8SStefano Zampini   PetscFunctionBegin;
1209863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1210863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1211863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1212863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1213863406b8SStefano Zampini   PetscFunctionReturn(0);
1214863406b8SStefano Zampini }
1215863406b8SStefano Zampini 
1216863406b8SStefano Zampini #undef __FUNCT__
12175ac14e1cSStefano Zampini #define __FUNCT__ "PCHYPRESetPoissonMatrix_HYPRE"
12185ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha)
12194cb006feSStefano Zampini {
12204cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12215ac14e1cSStefano Zampini   PetscBool      ishypre;
12224cb006feSStefano Zampini   PetscErrorCode ierr;
12234cb006feSStefano Zampini 
12244cb006feSStefano Zampini   PetscFunctionBegin;
12255ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr);
12265ac14e1cSStefano Zampini   if (ishypre) {
12275ac14e1cSStefano Zampini     if (isalpha) {
12285ac14e1cSStefano Zampini       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
12295ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
12305ac14e1cSStefano Zampini       jac->alpha_Poisson = A;
12315ac14e1cSStefano Zampini     } else {
12325ac14e1cSStefano Zampini       if (A) {
12335ac14e1cSStefano Zampini         ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
12345ac14e1cSStefano Zampini       } else {
12355ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
12365ac14e1cSStefano Zampini       }
12375ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
12385ac14e1cSStefano Zampini       jac->beta_Poisson = A;
12395ac14e1cSStefano Zampini     }
12405ac14e1cSStefano Zampini   } else {
12415ac14e1cSStefano Zampini     if (isalpha) {
12425ac14e1cSStefano Zampini       MatReuse reuse = MAT_INITIAL_MATRIX;
12435ac14e1cSStefano Zampini       if (jac->alpha_Poisson) reuse = MAT_REUSE_MATRIX;
12445ac14e1cSStefano Zampini       ierr = MatConvert(A,MATHYPRE,reuse,&jac->alpha_Poisson);CHKERRQ(ierr);
12455ac14e1cSStefano Zampini     } else {
12465ac14e1cSStefano Zampini       if (A) {
12475ac14e1cSStefano Zampini         MatReuse reuse = MAT_INITIAL_MATRIX;
12485ac14e1cSStefano Zampini         if (jac->beta_Poisson) reuse = MAT_REUSE_MATRIX;
12495ac14e1cSStefano Zampini         ierr = MatConvert(A,MATHYPRE,reuse,&jac->beta_Poisson);CHKERRQ(ierr);
12505ac14e1cSStefano Zampini       } else {
12515ac14e1cSStefano Zampini         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
12525ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
12535ac14e1cSStefano Zampini       }
12545ac14e1cSStefano Zampini     }
12555ac14e1cSStefano Zampini   }
12564cb006feSStefano Zampini   PetscFunctionReturn(0);
12574cb006feSStefano Zampini }
12584cb006feSStefano Zampini 
12594cb006feSStefano Zampini #undef __FUNCT__
12604cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix"
12614cb006feSStefano Zampini /*@
12624cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
12634cb006feSStefano Zampini 
12644cb006feSStefano Zampini    Collective on PC
12654cb006feSStefano Zampini 
12664cb006feSStefano Zampini    Input Parameters:
12674cb006feSStefano Zampini +  pc - the preconditioning context
12684cb006feSStefano Zampini -  A - the matrix
12694cb006feSStefano Zampini 
12704cb006feSStefano Zampini    Level: intermediate
12714cb006feSStefano Zampini 
12724cb006feSStefano Zampini    Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
12734cb006feSStefano Zampini 
12744cb006feSStefano Zampini .seealso:
12754cb006feSStefano Zampini @*/
12764cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
12774cb006feSStefano Zampini {
12784cb006feSStefano Zampini   PetscErrorCode ierr;
12794cb006feSStefano Zampini 
12804cb006feSStefano Zampini   PetscFunctionBegin;
12814cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12824cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
12834cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
12845ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_TRUE));CHKERRQ(ierr);
12854cb006feSStefano Zampini   PetscFunctionReturn(0);
12864cb006feSStefano Zampini }
12874cb006feSStefano Zampini 
12884cb006feSStefano Zampini #undef __FUNCT__
12894cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix"
12904cb006feSStefano Zampini /*@
12914cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
12924cb006feSStefano Zampini 
12934cb006feSStefano Zampini    Collective on PC
12944cb006feSStefano Zampini 
12954cb006feSStefano Zampini    Input Parameters:
12964cb006feSStefano Zampini +  pc - the preconditioning context
12974cb006feSStefano Zampini -  A - the matrix
12984cb006feSStefano Zampini 
12994cb006feSStefano Zampini    Level: intermediate
13004cb006feSStefano Zampini 
13014cb006feSStefano Zampini    Notes: A should be obtained by discretizing the Poisson problem with linear finite elements.
13024cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
13034cb006feSStefano Zampini 
13044cb006feSStefano Zampini .seealso:
13054cb006feSStefano Zampini @*/
13064cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
13074cb006feSStefano Zampini {
13084cb006feSStefano Zampini   PetscErrorCode ierr;
13094cb006feSStefano Zampini 
13104cb006feSStefano Zampini   PetscFunctionBegin;
13114cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
13124cb006feSStefano Zampini   if (A) {
13134cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
13144cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
13154cb006feSStefano Zampini   }
13165ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_FALSE));CHKERRQ(ierr);
13174cb006feSStefano Zampini   PetscFunctionReturn(0);
13184cb006feSStefano Zampini }
13194cb006feSStefano Zampini 
13204cb006feSStefano Zampini #undef __FUNCT__
13215ac14e1cSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE"
13225ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz, Vec zoz, Vec zzo)
13234cb006feSStefano Zampini {
13244cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
13254cb006feSStefano Zampini   PetscErrorCode     ierr;
13264cb006feSStefano Zampini 
13274cb006feSStefano Zampini   PetscFunctionBegin;
13284cb006feSStefano Zampini   /* throw away any vector if already set */
13294cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
13304cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
13314cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
13324cb006feSStefano Zampini   jac->constants[0] = NULL;
13334cb006feSStefano Zampini   jac->constants[1] = NULL;
13344cb006feSStefano Zampini   jac->constants[2] = NULL;
13354cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
13364cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
13374cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
13384cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
13395ac14e1cSStefano Zampini   jac->dim = 2;
13404cb006feSStefano Zampini   if (zzo) {
13414cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
13424cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
13435ac14e1cSStefano Zampini     jac->dim++;
13444cb006feSStefano Zampini   }
13454cb006feSStefano Zampini   PetscFunctionReturn(0);
13464cb006feSStefano Zampini }
13474cb006feSStefano Zampini 
13484cb006feSStefano Zampini #undef __FUNCT__
13494cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors"
13504cb006feSStefano Zampini /*@
13514cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
13524cb006feSStefano Zampini 
13534cb006feSStefano Zampini    Collective on PC
13544cb006feSStefano Zampini 
13554cb006feSStefano Zampini    Input Parameters:
13564cb006feSStefano Zampini +  pc - the preconditioning context
13574cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
13584cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
13594cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
13604cb006feSStefano Zampini 
13614cb006feSStefano Zampini    Level: intermediate
13624cb006feSStefano Zampini 
13634cb006feSStefano Zampini    Notes:
13644cb006feSStefano Zampini 
13654cb006feSStefano Zampini .seealso:
13664cb006feSStefano Zampini @*/
13674cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
13684cb006feSStefano Zampini {
13694cb006feSStefano Zampini   PetscErrorCode ierr;
13704cb006feSStefano Zampini 
13714cb006feSStefano Zampini   PetscFunctionBegin;
13724cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
13734cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
13744cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
13754cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
13764cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
13774cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
13784cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
13794cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
13804cb006feSStefano Zampini   PetscFunctionReturn(0);
13814cb006feSStefano Zampini }
13824cb006feSStefano Zampini 
13834cb006feSStefano Zampini #undef __FUNCT__
1384863406b8SStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE"
1385863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
13864cb006feSStefano Zampini {
13874cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
13884cb006feSStefano Zampini   Vec             tv;
13894cb006feSStefano Zampini   PetscInt        i;
13904cb006feSStefano Zampini   PetscErrorCode  ierr;
13914cb006feSStefano Zampini 
13924cb006feSStefano Zampini   PetscFunctionBegin;
13934cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
13944cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
13954cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
13964cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
13975ac14e1cSStefano Zampini   jac->dim = dim;
13985ac14e1cSStefano Zampini 
13994cb006feSStefano Zampini   /* compute IJ vector for coordinates */
14004cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
14014cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
14024cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
14034cb006feSStefano Zampini   for (i=0;i<dim;i++) {
14044cb006feSStefano Zampini     PetscScalar *array;
14054cb006feSStefano Zampini     PetscInt    j;
14064cb006feSStefano Zampini 
14074cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
14084cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
14094cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
14104cb006feSStefano Zampini       array[j] = coords[j*dim+i];
14114cb006feSStefano Zampini     }
14124cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
14134cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
14144cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
14154cb006feSStefano Zampini   }
14164cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
14174cb006feSStefano Zampini   PetscFunctionReturn(0);
14184cb006feSStefano Zampini }
14194cb006feSStefano Zampini 
142016d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
142116d9e3a6SLisandro Dalcin 
142216d9e3a6SLisandro Dalcin #undef __FUNCT__
142316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
1424f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
142516d9e3a6SLisandro Dalcin {
142616d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
142716d9e3a6SLisandro Dalcin 
142816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
142916d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
143016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
143116d9e3a6SLisandro Dalcin }
143216d9e3a6SLisandro Dalcin 
143316d9e3a6SLisandro Dalcin #undef __FUNCT__
143416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
1435f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
143616d9e3a6SLisandro Dalcin {
143716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
143816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1439ace3abfcSBarry Smith   PetscBool      flag;
144016d9e3a6SLisandro Dalcin 
144116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
144216d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
144316d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1444ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
144516d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
144616d9e3a6SLisandro Dalcin   } else {
144716d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
144816d9e3a6SLisandro Dalcin   }
144916d9e3a6SLisandro Dalcin 
145016d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
145116d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
145216d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
145316d9e3a6SLisandro Dalcin 
145416d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
145516d9e3a6SLisandro Dalcin   if (flag) {
1456fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
145716d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
145816d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
145916d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
146016d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
146116d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
146216d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
146316d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
146416d9e3a6SLisandro Dalcin   }
146516d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
146616d9e3a6SLisandro Dalcin   if (flag) {
1467fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
146816d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
146916d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
147016d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
147116d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
147216d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
147316d9e3a6SLisandro Dalcin     /* initialize */
147416d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
147516d9e3a6SLisandro Dalcin     jac->threshhold = .1;
147616d9e3a6SLisandro Dalcin     jac->filter     = .1;
147716d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
14782fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
14792fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
14802fa5cd67SKarl Rupp 
148116d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
148216d9e3a6SLisandro Dalcin     jac->symt = 0;
1483fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1484fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1485fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1486fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1487fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1488fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
148916d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
149016d9e3a6SLisandro Dalcin   }
149116d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
149216d9e3a6SLisandro Dalcin   if (flag) {
149316d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
149416d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
149516d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
149616d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
149716d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
149816d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
149916d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
150016d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
150116d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
150216d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
150316d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
150416d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
150516d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
15068f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
150716d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
150816d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
150916d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
151016d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
151116d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
15120f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
15136a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1514b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
15151810e44eSEike Mueller     jac->eu_level         = 0;
15161810e44eSEike Mueller     jac->eu_droptolerance = 0;
15171810e44eSEike Mueller     jac->eu_bj            = 0;
15188f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
15190f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
152016d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
152116d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
152216d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
15230f1074feSSatish Balay     jac->interptype       = 0;
15240f1074feSSatish Balay     jac->agg_nl           = 0;
15250f1074feSSatish Balay     jac->pmax             = 0;
15260f1074feSSatish Balay     jac->truncfactor      = 0.0;
15270f1074feSSatish Balay     jac->agg_num_paths    = 1;
15288f87f92bSBarry Smith 
15298f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
15308f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
15318f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1532fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1533fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1534fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1535fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1536fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1537fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1538fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1539fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1540fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1541fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1542fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1543fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1544fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1545fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1546fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1547fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
154816d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
154916d9e3a6SLisandro Dalcin   }
15504cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
15514cb006feSStefano Zampini   if (flag) {
15524cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
15534cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
15544cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
15554cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
15564cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
15574cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
15584cb006feSStefano Zampini     jac->coords[0]           = NULL;
15594cb006feSStefano Zampini     jac->coords[1]           = NULL;
15604cb006feSStefano Zampini     jac->coords[2]           = NULL;
15614cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1562863406b8SStefano Zampini     jac->as_print           = 0;
1563863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1564863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
15654cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
15664cb006feSStefano Zampini     /* Smoothing options */
1567863406b8SStefano Zampini     jac->as_relax_type      = 2;
1568863406b8SStefano Zampini     jac->as_relax_times     = 1;
1569863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1570863406b8SStefano Zampini     jac->as_omega           = 1.0;
15714cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1572863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1573863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
15740bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1575863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1576863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1577863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
15784cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1579863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1580863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
15810bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1582863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1583863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1584863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1585863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1586863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
15874cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1588863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1589863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1590863406b8SStefano Zampini                                                                       jac->as_relax_times,
1591863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1592863406b8SStefano Zampini                                                                       jac->as_omega));
1593863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1594863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1595863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1596863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1597863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1598863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1599863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1600863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1601863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1602863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1603863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1604863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
160523df4f25SStefano Zampini     /* Zero conductivity */
160623df4f25SStefano Zampini     jac->ams_beta_is_zero      = PETSC_FALSE;
160723df4f25SStefano Zampini     jac->ams_beta_is_zero_part = PETSC_FALSE;
16084cb006feSStefano Zampini     PetscFunctionReturn(0);
16094cb006feSStefano Zampini   }
1610863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1611863406b8SStefano Zampini   if (flag) {
1612863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1613863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1614863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1615863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1616863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1617863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1618863406b8SStefano Zampini     jac->coords[0]           = NULL;
1619863406b8SStefano Zampini     jac->coords[1]           = NULL;
1620863406b8SStefano Zampini     jac->coords[2]           = NULL;
1621863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1622863406b8SStefano Zampini     jac->as_print           = 0;
1623863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1624863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1625863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1626863406b8SStefano Zampini     /* Smoothing options */
1627863406b8SStefano Zampini     jac->as_relax_type      = 2;
1628863406b8SStefano Zampini     jac->as_relax_times     = 1;
1629863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1630863406b8SStefano Zampini     jac->as_omega           = 1.0;
1631863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1632863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1633863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1634863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1635863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1636863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1637863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1638863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1639863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1640863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1641863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1642863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1643863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1644863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1645863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1646863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1647863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1648863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1649863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1650863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1651863406b8SStefano Zampini                                                                       jac->as_relax_times,
1652863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1653863406b8SStefano Zampini                                                                       jac->as_omega));
1654863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1655863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1656863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1657863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1658863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1659863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1660863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1661863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1662863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1663863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1664863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1665863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1666863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1667863406b8SStefano Zampini     PetscFunctionReturn(0);
1668863406b8SStefano Zampini   }
1669503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
16702fa5cd67SKarl Rupp 
16710298fd71SBarry Smith   jac->hypre_type = NULL;
167233263987SBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, boomeramg, ams",name);
167316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
167416d9e3a6SLisandro Dalcin }
167516d9e3a6SLisandro Dalcin 
167616d9e3a6SLisandro Dalcin /*
167716d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
167816d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
167916d9e3a6SLisandro Dalcin */
168016d9e3a6SLisandro Dalcin #undef __FUNCT__
168116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
16824416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc)
168316d9e3a6SLisandro Dalcin {
168416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
16854ddd07fcSJed Brown   PetscInt       indx;
1686863406b8SStefano Zampini   const char     *type[] = {"pilut","parasails","boomeramg","ams","ads"};
1687ace3abfcSBarry Smith   PetscBool      flg;
168816d9e3a6SLisandro Dalcin 
168916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16909fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
16919c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
169216d9e3a6SLisandro Dalcin   if (flg) {
169316d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
169402a17cd4SBarry Smith   } else {
169502a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
169616d9e3a6SLisandro Dalcin   }
169716d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
16983931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
169916d9e3a6SLisandro Dalcin   }
170016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
170116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
170216d9e3a6SLisandro Dalcin }
170316d9e3a6SLisandro Dalcin 
170416d9e3a6SLisandro Dalcin #undef __FUNCT__
170516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
170616d9e3a6SLisandro Dalcin /*@C
170716d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
170816d9e3a6SLisandro Dalcin 
170916d9e3a6SLisandro Dalcin    Input Parameters:
171016d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1711863406b8SStefano Zampini -     name - either  pilut, parasails, boomeramg, ams, ads
171216d9e3a6SLisandro Dalcin 
171316d9e3a6SLisandro Dalcin    Options Database Keys:
1714863406b8SStefano Zampini    -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
171516d9e3a6SLisandro Dalcin 
171616d9e3a6SLisandro Dalcin    Level: intermediate
171716d9e3a6SLisandro Dalcin 
171816d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
171916d9e3a6SLisandro Dalcin            PCHYPRE
172016d9e3a6SLisandro Dalcin 
172116d9e3a6SLisandro Dalcin @*/
17227087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
172316d9e3a6SLisandro Dalcin {
17244ac538c5SBarry Smith   PetscErrorCode ierr;
172516d9e3a6SLisandro Dalcin 
172616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
17270700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
172816d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
17294ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
173016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
173116d9e3a6SLisandro Dalcin }
173216d9e3a6SLisandro Dalcin 
173316d9e3a6SLisandro Dalcin #undef __FUNCT__
173416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
173516d9e3a6SLisandro Dalcin /*@C
173616d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
173716d9e3a6SLisandro Dalcin 
173816d9e3a6SLisandro Dalcin    Input Parameter:
173916d9e3a6SLisandro Dalcin .     pc - the preconditioner context
174016d9e3a6SLisandro Dalcin 
174116d9e3a6SLisandro Dalcin    Output Parameter:
1742863406b8SStefano Zampini .     name - either  pilut, parasails, boomeramg, ams, ads
174316d9e3a6SLisandro Dalcin 
174416d9e3a6SLisandro Dalcin    Level: intermediate
174516d9e3a6SLisandro Dalcin 
174616d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
174716d9e3a6SLisandro Dalcin            PCHYPRE
174816d9e3a6SLisandro Dalcin 
174916d9e3a6SLisandro Dalcin @*/
17507087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
175116d9e3a6SLisandro Dalcin {
17524ac538c5SBarry Smith   PetscErrorCode ierr;
175316d9e3a6SLisandro Dalcin 
175416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
17550700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
175616d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
17574ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
175816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
175916d9e3a6SLisandro Dalcin }
176016d9e3a6SLisandro Dalcin 
176116d9e3a6SLisandro Dalcin /*MC
176216d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
176316d9e3a6SLisandro Dalcin 
176416d9e3a6SLisandro Dalcin    Options Database Keys:
1765863406b8SStefano Zampini +   -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
176616d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
176716d9e3a6SLisandro Dalcin           preconditioner
176816d9e3a6SLisandro Dalcin 
176916d9e3a6SLisandro Dalcin    Level: intermediate
177016d9e3a6SLisandro Dalcin 
177116d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
177216d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
177316d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
177416d9e3a6SLisandro Dalcin 
177516d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
17760f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
17770f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
17780f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
17798f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
17800f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
17810f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
178216d9e3a6SLisandro Dalcin 
17830f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
17840f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
17850f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
178616d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
178716d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
178816d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
178916d9e3a6SLisandro Dalcin 
179016d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
179116d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
179216d9e3a6SLisandro Dalcin 
17935272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
17945272c319SBarry Smith           the two options:
17955272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
1796cbc39033SBarry Smith -   -pc_hypre_boomeramg_vec_interp_variant <v> where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
17975272c319SBarry Smith 
17985272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
17995272c319SBarry Smith 
18009e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
18019e5bc791SBarry Smith 
180216d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
18039e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
180416d9e3a6SLisandro Dalcin 
180516d9e3a6SLisandro Dalcin M*/
180616d9e3a6SLisandro Dalcin 
180716d9e3a6SLisandro Dalcin #undef __FUNCT__
180816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
18098cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
181016d9e3a6SLisandro Dalcin {
181116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
181216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
181316d9e3a6SLisandro Dalcin 
181416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1815b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
18162fa5cd67SKarl Rupp 
181716d9e3a6SLisandro Dalcin   pc->data                = jac;
18188695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
181916d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
182016d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
182116d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
182216d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
182316d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
18244cb006feSStefano Zampini   jac->coords[0]          = NULL;
18254cb006feSStefano Zampini   jac->coords[1]          = NULL;
18264cb006feSStefano Zampini   jac->coords[2]          = NULL;
18274cb006feSStefano Zampini   jac->constants[0]       = NULL;
18284cb006feSStefano Zampini   jac->constants[1]       = NULL;
18294cb006feSStefano Zampini   jac->constants[2]       = NULL;
18305272c319SBarry Smith   jac->hmnull             = NULL;
18315272c319SBarry Smith   jac->n_hmnull           = 0;
183216d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1833ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1834bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1835bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
18365ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
18375ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
18385ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
18395ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE);CHKERRQ(ierr);
18405ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",PCHYPRESetPoissonMatrix_HYPRE);CHKERRQ(ierr);
184116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
184216d9e3a6SLisandro Dalcin }
1843ebc551c0SBarry Smith 
1844f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1845f91d8e95SBarry Smith 
1846ebc551c0SBarry Smith typedef struct {
184768326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1848f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
18499e5bc791SBarry Smith 
18509e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
18514ddd07fcSJed Brown   PetscInt its;
18529e5bc791SBarry Smith   double   tol;
18534ddd07fcSJed Brown   PetscInt relax_type;
18544ddd07fcSJed Brown   PetscInt rap_type;
18554ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
18564ddd07fcSJed Brown   PetscInt max_levels;
1857ebc551c0SBarry Smith } PC_PFMG;
1858ebc551c0SBarry Smith 
1859ebc551c0SBarry Smith #undef __FUNCT__
1860ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1861ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1862ebc551c0SBarry Smith {
1863ebc551c0SBarry Smith   PetscErrorCode ierr;
1864f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1865ebc551c0SBarry Smith 
1866ebc551c0SBarry Smith   PetscFunctionBegin;
18672fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1868f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1869c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1870ebc551c0SBarry Smith   PetscFunctionReturn(0);
1871ebc551c0SBarry Smith }
1872ebc551c0SBarry Smith 
18739e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
18749e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
18759e5bc791SBarry Smith 
1876ebc551c0SBarry Smith #undef __FUNCT__
1877ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1878ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1879ebc551c0SBarry Smith {
1880ebc551c0SBarry Smith   PetscErrorCode ierr;
1881ace3abfcSBarry Smith   PetscBool      iascii;
1882f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1883ebc551c0SBarry Smith 
1884ebc551c0SBarry Smith   PetscFunctionBegin;
1885251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
18869e5bc791SBarry Smith   if (iascii) {
18879e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
18889e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
18899e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
18909e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
18919e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
18929e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
18933b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
18949e5bc791SBarry Smith   }
1895ebc551c0SBarry Smith   PetscFunctionReturn(0);
1896ebc551c0SBarry Smith }
1897ebc551c0SBarry Smith 
18989e5bc791SBarry Smith 
1899ebc551c0SBarry Smith #undef __FUNCT__
1900ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
19014416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc)
1902ebc551c0SBarry Smith {
1903ebc551c0SBarry Smith   PetscErrorCode ierr;
1904f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1905ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1906ebc551c0SBarry Smith 
1907ebc551c0SBarry Smith   PetscFunctionBegin;
1908e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
19090298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
191068326731SBarry Smith   if (flg) {
1911a0324ebeSBarry Smith     int level=3;
1912fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
191368326731SBarry Smith   }
19140298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1915fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
19160298fd71SBarry 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);
1917fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
19180298fd71SBarry 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);
1919fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
19209e5bc791SBarry Smith 
19210298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
1922fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
19233b46a515SGlenn Hammond 
19240298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1925fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
19260298fd71SBarry 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);
1927fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
19280298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
1929fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1930ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1931ebc551c0SBarry Smith   PetscFunctionReturn(0);
1932ebc551c0SBarry Smith }
1933ebc551c0SBarry Smith 
1934f91d8e95SBarry Smith #undef __FUNCT__
1935f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1936f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1937f91d8e95SBarry Smith {
1938f91d8e95SBarry Smith   PetscErrorCode    ierr;
1939f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
1940d9ca1df4SBarry Smith   PetscScalar       *yy;
1941d9ca1df4SBarry Smith   const PetscScalar *xx;
19424ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
194368326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1944f91d8e95SBarry Smith 
1945f91d8e95SBarry Smith   PetscFunctionBegin;
1946dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1947aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1948f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1949f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1950f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1951f91d8e95SBarry Smith 
1952f91d8e95SBarry Smith   /* copy x values over to hypre */
1953fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1954d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1955d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
1956d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1957fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
1958fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1959f91d8e95SBarry Smith 
1960f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1961f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
19628b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
1963f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1964f91d8e95SBarry Smith   PetscFunctionReturn(0);
1965f91d8e95SBarry Smith }
1966f91d8e95SBarry Smith 
19679e5bc791SBarry Smith #undef __FUNCT__
19689e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1969ace3abfcSBarry 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)
19709e5bc791SBarry Smith {
19719e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
19729e5bc791SBarry Smith   PetscErrorCode ierr;
19734ddd07fcSJed Brown   PetscInt       oits;
19749e5bc791SBarry Smith 
19759e5bc791SBarry Smith   PetscFunctionBegin;
1976dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1977fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1978fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
19799e5bc791SBarry Smith 
19809e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
19818b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
19829e5bc791SBarry Smith   *outits = oits;
19839e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
19849e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1985fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1986fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
19879e5bc791SBarry Smith   PetscFunctionReturn(0);
19889e5bc791SBarry Smith }
19899e5bc791SBarry Smith 
19909e5bc791SBarry Smith 
19913a32d3dbSGlenn Hammond #undef __FUNCT__
19923a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
19933a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
19943a32d3dbSGlenn Hammond {
19953a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
19963a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
19973a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1998ace3abfcSBarry Smith   PetscBool       flg;
19993a32d3dbSGlenn Hammond 
20003a32d3dbSGlenn Hammond   PetscFunctionBegin;
2001251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
2002ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
20033a32d3dbSGlenn Hammond 
20043a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
20052fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2006fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2007fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2008fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
20093a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
20103a32d3dbSGlenn Hammond }
20113a32d3dbSGlenn Hammond 
2012ebc551c0SBarry Smith 
2013ebc551c0SBarry Smith /*MC
2014ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
2015ebc551c0SBarry Smith 
2016ebc551c0SBarry Smith    Level: advanced
2017ebc551c0SBarry Smith 
20189e5bc791SBarry Smith    Options Database:
20199e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
20209e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
20219e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
20229e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
20239e5bc791SBarry 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
20249e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
2025f91d8e95SBarry Smith 
20269e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
20279e5bc791SBarry Smith 
20288e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
2029aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
20309e5bc791SBarry Smith 
20319e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
2032ebc551c0SBarry Smith M*/
2033ebc551c0SBarry Smith 
2034ebc551c0SBarry Smith #undef __FUNCT__
2035ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
20368cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
2037ebc551c0SBarry Smith {
2038ebc551c0SBarry Smith   PetscErrorCode ierr;
2039ebc551c0SBarry Smith   PC_PFMG        *ex;
2040ebc551c0SBarry Smith 
2041ebc551c0SBarry Smith   PetscFunctionBegin;
2042b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
204368326731SBarry Smith   pc->data = ex;
2044ebc551c0SBarry Smith 
20459e5bc791SBarry Smith   ex->its            = 1;
20469e5bc791SBarry Smith   ex->tol            = 1.e-8;
20479e5bc791SBarry Smith   ex->relax_type     = 1;
20489e5bc791SBarry Smith   ex->rap_type       = 0;
20499e5bc791SBarry Smith   ex->num_pre_relax  = 1;
20509e5bc791SBarry Smith   ex->num_post_relax = 1;
20513b46a515SGlenn Hammond   ex->max_levels     = 0;
20529e5bc791SBarry Smith 
2053ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2054ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2055ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2056f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
20579e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
205868326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
20592fa5cd67SKarl Rupp 
2060ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2061fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2062ebc551c0SBarry Smith   PetscFunctionReturn(0);
2063ebc551c0SBarry Smith }
2064d851a50bSGlenn Hammond 
2065325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2066325fc9f4SBarry Smith 
2067d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2068d851a50bSGlenn Hammond typedef struct {
2069d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2070d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2071d851a50bSGlenn Hammond 
2072d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
20734ddd07fcSJed Brown   PetscInt its;
2074d851a50bSGlenn Hammond   double   tol;
20754ddd07fcSJed Brown   PetscInt relax_type;
20764ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2077d851a50bSGlenn Hammond } PC_SysPFMG;
2078d851a50bSGlenn Hammond 
2079d851a50bSGlenn Hammond #undef __FUNCT__
2080d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
2081d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2082d851a50bSGlenn Hammond {
2083d851a50bSGlenn Hammond   PetscErrorCode ierr;
2084d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2085d851a50bSGlenn Hammond 
2086d851a50bSGlenn Hammond   PetscFunctionBegin;
20872fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2088d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2089c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2090d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2091d851a50bSGlenn Hammond }
2092d851a50bSGlenn Hammond 
2093d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2094d851a50bSGlenn Hammond 
2095d851a50bSGlenn Hammond #undef __FUNCT__
2096d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
2097d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2098d851a50bSGlenn Hammond {
2099d851a50bSGlenn Hammond   PetscErrorCode ierr;
2100ace3abfcSBarry Smith   PetscBool      iascii;
2101d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2102d851a50bSGlenn Hammond 
2103d851a50bSGlenn Hammond   PetscFunctionBegin;
2104251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2105d851a50bSGlenn Hammond   if (iascii) {
2106d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2107d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
2108d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
2109d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2110d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2111d851a50bSGlenn Hammond   }
2112d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2113d851a50bSGlenn Hammond }
2114d851a50bSGlenn Hammond 
2115d851a50bSGlenn Hammond 
2116d851a50bSGlenn Hammond #undef __FUNCT__
2117d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
21184416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2119d851a50bSGlenn Hammond {
2120d851a50bSGlenn Hammond   PetscErrorCode ierr;
2121d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2122ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2123d851a50bSGlenn Hammond 
2124d851a50bSGlenn Hammond   PetscFunctionBegin;
2125e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
21260298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2127d851a50bSGlenn Hammond   if (flg) {
2128d851a50bSGlenn Hammond     int level=3;
2129fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
2130d851a50bSGlenn Hammond   }
21310298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2132fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
21330298fd71SBarry 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);
2134fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
21350298fd71SBarry 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);
2136fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2137d851a50bSGlenn Hammond 
21380298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2139fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
21400298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_syspfmg_relax_type","Relax type for the up and down cycles","HYPRE_SStructSysPFMGSetRelaxType",SysPFMGRelaxType,4,SysPFMGRelaxType[ex->relax_type],&ex->relax_type,NULL);CHKERRQ(ierr);
2141fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2142d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2143d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2144d851a50bSGlenn Hammond }
2145d851a50bSGlenn Hammond 
2146d851a50bSGlenn Hammond #undef __FUNCT__
2147d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
2148d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2149d851a50bSGlenn Hammond {
2150d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2151d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2152d9ca1df4SBarry Smith   PetscScalar       *yy;
2153d9ca1df4SBarry Smith   const PetscScalar *xx;
21544ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
2155d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
21564ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
21574ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
21584ddd07fcSJed Brown   PetscInt          part    = 0;
21594ddd07fcSJed Brown   PetscInt          size;
21604ddd07fcSJed Brown   PetscInt          i;
2161d851a50bSGlenn Hammond 
2162d851a50bSGlenn Hammond   PetscFunctionBegin;
2163dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2164aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2165d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2166d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2167d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2168d851a50bSGlenn Hammond 
2169d851a50bSGlenn Hammond   size = 1;
21702fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
21712fa5cd67SKarl Rupp 
2172d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2173d851a50bSGlenn Hammond   if (ordering) {
2174fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2175d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2176d9ca1df4SBarry 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)));
2177d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2178fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2179fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2180fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2181d851a50bSGlenn Hammond 
2182d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2183d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
21848b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2185d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2186a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2187d851a50bSGlenn Hammond     PetscScalar *z;
21884ddd07fcSJed Brown     PetscInt    j, k;
2189d851a50bSGlenn Hammond 
2190785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2191fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2192d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2193d851a50bSGlenn Hammond 
2194d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2195d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2196d851a50bSGlenn Hammond       k= i*nvars;
21972fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2198d851a50bSGlenn Hammond     }
21998b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2200d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2201fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2202fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2203d851a50bSGlenn Hammond 
2204d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2205d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
22068b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2207d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2208d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2209d851a50bSGlenn Hammond       k= i*nvars;
22102fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2211d851a50bSGlenn Hammond     }
2212d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2213d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2214d851a50bSGlenn Hammond   }
2215d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2216d851a50bSGlenn Hammond }
2217d851a50bSGlenn Hammond 
2218d851a50bSGlenn Hammond #undef __FUNCT__
2219d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
2220ace3abfcSBarry 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)
2221d851a50bSGlenn Hammond {
2222d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2223d851a50bSGlenn Hammond   PetscErrorCode ierr;
22244ddd07fcSJed Brown   PetscInt       oits;
2225d851a50bSGlenn Hammond 
2226d851a50bSGlenn Hammond   PetscFunctionBegin;
2227dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2228fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2229fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2230d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
22318b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2232d851a50bSGlenn Hammond   *outits = oits;
2233d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2234d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2235fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2236fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2237d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2238d851a50bSGlenn Hammond }
2239d851a50bSGlenn Hammond 
2240d851a50bSGlenn Hammond 
2241d851a50bSGlenn Hammond #undef __FUNCT__
2242d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
2243d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2244d851a50bSGlenn Hammond {
2245d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2246d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2247d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2248ace3abfcSBarry Smith   PetscBool        flg;
2249d851a50bSGlenn Hammond 
2250d851a50bSGlenn Hammond   PetscFunctionBegin;
2251251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2252ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2253d851a50bSGlenn Hammond 
2254d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
22552fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2256fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2257fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2258fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2259d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2260d851a50bSGlenn Hammond }
2261d851a50bSGlenn Hammond 
2262d851a50bSGlenn Hammond 
2263d851a50bSGlenn Hammond /*MC
2264d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2265d851a50bSGlenn Hammond 
2266d851a50bSGlenn Hammond    Level: advanced
2267d851a50bSGlenn Hammond 
2268d851a50bSGlenn Hammond    Options Database:
2269d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2270d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2271d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2272d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2273d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2274d851a50bSGlenn Hammond 
2275d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
2276d851a50bSGlenn Hammond 
2277f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2278aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2279d851a50bSGlenn Hammond            Also, only cell-centered variables.
2280d851a50bSGlenn Hammond 
2281d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2282d851a50bSGlenn Hammond M*/
2283d851a50bSGlenn Hammond 
2284d851a50bSGlenn Hammond #undef __FUNCT__
2285d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
22868cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2287d851a50bSGlenn Hammond {
2288d851a50bSGlenn Hammond   PetscErrorCode ierr;
2289d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2290d851a50bSGlenn Hammond 
2291d851a50bSGlenn Hammond   PetscFunctionBegin;
2292b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2293d851a50bSGlenn Hammond   pc->data = ex;
2294d851a50bSGlenn Hammond 
2295d851a50bSGlenn Hammond   ex->its            = 1;
2296d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2297d851a50bSGlenn Hammond   ex->relax_type     = 1;
2298d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2299d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2300d851a50bSGlenn Hammond 
2301d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2302d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2303d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2304d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2305d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2306d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
23072fa5cd67SKarl Rupp 
2308ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2309fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2310d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2311d851a50bSGlenn Hammond }
2312