xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision cbc39033ba0e292bc3db43eb4f4fdf40cf5f7955)
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*/
9c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h>
104cb006feSStefano Zampini #include <_hypre_parcsr_ls.h>
1116d9e3a6SLisandro Dalcin 
12dff31646SBarry Smith static PetscBool cite = PETSC_FALSE;
131f817a21SBarry 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";
141f817a21SBarry Smith 
1516d9e3a6SLisandro Dalcin /*
1616d9e3a6SLisandro Dalcin    Private context (data structure) for the  preconditioner.
1716d9e3a6SLisandro Dalcin */
1816d9e3a6SLisandro Dalcin typedef struct {
1916d9e3a6SLisandro Dalcin   HYPRE_Solver   hsolver;
2016d9e3a6SLisandro Dalcin   HYPRE_IJMatrix ij;
2116d9e3a6SLisandro Dalcin   HYPRE_IJVector b,x;
2216d9e3a6SLisandro Dalcin 
234ddd07fcSJed Brown   HYPRE_Int (*destroy)(HYPRE_Solver);
244ddd07fcSJed Brown   HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
254ddd07fcSJed Brown   HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
26863406b8SStefano Zampini   HYPRE_Int (*setdgrad)(HYPRE_Solver,HYPRE_ParCSRMatrix);
27863406b8SStefano Zampini   HYPRE_Int (*setdcurl)(HYPRE_Solver,HYPRE_ParCSRMatrix);
28863406b8SStefano Zampini   HYPRE_Int (*setcoord)(HYPRE_Solver,HYPRE_ParVector,HYPRE_ParVector,HYPRE_ParVector);
29863406b8SStefano Zampini   HYPRE_Int (*setdim)(HYPRE_Solver,HYPRE_Int);
3016d9e3a6SLisandro Dalcin 
3116d9e3a6SLisandro Dalcin   MPI_Comm comm_hypre;
3216d9e3a6SLisandro Dalcin   char     *hypre_type;
3316d9e3a6SLisandro Dalcin 
3416d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
354ddd07fcSJed Brown   PetscInt maxiter;
3616d9e3a6SLisandro Dalcin   double   tol;
3716d9e3a6SLisandro Dalcin 
3816d9e3a6SLisandro Dalcin   /* options for Pilut */
394ddd07fcSJed Brown   PetscInt factorrowsize;
4016d9e3a6SLisandro Dalcin 
4116d9e3a6SLisandro Dalcin   /* options for ParaSails */
424ddd07fcSJed Brown   PetscInt nlevels;
4316d9e3a6SLisandro Dalcin   double   threshhold;
4416d9e3a6SLisandro Dalcin   double   filter;
454ddd07fcSJed Brown   PetscInt sym;
4616d9e3a6SLisandro Dalcin   double   loadbal;
474ddd07fcSJed Brown   PetscInt logging;
484ddd07fcSJed Brown   PetscInt ruse;
494ddd07fcSJed Brown   PetscInt symt;
5016d9e3a6SLisandro Dalcin 
5122b6d1caSBarry Smith   /* options for BoomerAMG */
52ace3abfcSBarry Smith   PetscBool printstatistics;
5316d9e3a6SLisandro Dalcin 
5416d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
554ddd07fcSJed Brown   PetscInt  cycletype;
564ddd07fcSJed Brown   PetscInt  maxlevels;
5716d9e3a6SLisandro Dalcin   double    strongthreshold;
5816d9e3a6SLisandro Dalcin   double    maxrowsum;
594ddd07fcSJed Brown   PetscInt  gridsweeps[3];
604ddd07fcSJed Brown   PetscInt  coarsentype;
614ddd07fcSJed Brown   PetscInt  measuretype;
626a251517SEike Mueller   PetscInt  smoothtype;
638131ecf7SEike Mueller   PetscInt  smoothnumlevels;
64ec64516dSEike Mueller   PetscInt  eu_level;   /* Number of levels for ILU(k) in Euclid */
65ec64516dSEike Mueller   double    eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */
66ec64516dSEike Mueller   PetscInt  eu_bj;      /* Defines use of Block Jacobi ILU in Euclid */
674ddd07fcSJed Brown   PetscInt  relaxtype[3];
6816d9e3a6SLisandro Dalcin   double    relaxweight;
6916d9e3a6SLisandro Dalcin   double    outerrelaxweight;
704ddd07fcSJed Brown   PetscInt  relaxorder;
7116d9e3a6SLisandro Dalcin   double    truncfactor;
72ace3abfcSBarry Smith   PetscBool applyrichardson;
734ddd07fcSJed Brown   PetscInt  pmax;
744ddd07fcSJed Brown   PetscInt  interptype;
754ddd07fcSJed Brown   PetscInt  agg_nl;
764ddd07fcSJed Brown   PetscInt  agg_num_paths;
774ddd07fcSJed Brown   PetscInt  nodal_coarsen;
78ace3abfcSBarry Smith   PetscBool nodal_relax;
794ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
804cb006feSStefano Zampini 
815272c319SBarry Smith   PetscInt  nodal_coarsening;
825272c319SBarry Smith   PetscInt  vec_interp_variant;
835272c319SBarry Smith   HYPRE_IJVector  *hmnull;
845272c319SBarry Smith   HYPRE_ParVector *phmnull;  /* near null space passed to hypre */
855272c319SBarry Smith   PetscInt        n_hmnull;
865272c319SBarry Smith   Vec             hmnull_constant;
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 */
1044cb006feSStefano Zampini   HYPRE_IJVector coords[3];
1054cb006feSStefano Zampini   HYPRE_IJVector constants[3];
1064cb006feSStefano Zampini   HYPRE_IJMatrix G;
107863406b8SStefano Zampini   HYPRE_IJMatrix C;
1084cb006feSStefano Zampini   HYPRE_IJMatrix alpha_Poisson;
1094cb006feSStefano Zampini   HYPRE_IJMatrix beta_Poisson;
1104cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
11116d9e3a6SLisandro Dalcin } PC_HYPRE;
11216d9e3a6SLisandro Dalcin 
113d2128fa2SBarry Smith #undef __FUNCT__
114d2128fa2SBarry Smith #define __FUNCT__ "PCHYPREGetSolver"
115d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
116d2128fa2SBarry Smith {
117d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
118d2128fa2SBarry Smith 
119d2128fa2SBarry Smith   PetscFunctionBegin;
120d2128fa2SBarry Smith   *hsolver = jac->hsolver;
121d2128fa2SBarry Smith   PetscFunctionReturn(0);
122d2128fa2SBarry Smith }
12316d9e3a6SLisandro Dalcin 
12416d9e3a6SLisandro Dalcin #undef __FUNCT__
12516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE"
12616d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
12716d9e3a6SLisandro Dalcin {
12816d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
12916d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
13016d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
13116d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
13216d9e3a6SLisandro Dalcin   PetscInt           bs;
13316d9e3a6SLisandro Dalcin 
13416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
13516d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
13602a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
13716d9e3a6SLisandro Dalcin   }
1385f5c5b43SBarry Smith 
1395f5c5b43SBarry Smith   if (pc->setupcalled) {
1405f5c5b43SBarry Smith     /* always destroy the old matrix and create a new memory;
1415f5c5b43SBarry Smith        hope this does not churn the memory too much. The problem
1425f5c5b43SBarry Smith        is I do not know if it is possible to put the matrix back to
1435f5c5b43SBarry Smith        its initial state so that we can directly copy the values
1445f5c5b43SBarry Smith        the second time through. */
145fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
1465f5c5b43SBarry Smith     jac->ij = 0;
14716d9e3a6SLisandro Dalcin   }
1485f5c5b43SBarry Smith 
14916d9e3a6SLisandro Dalcin   if (!jac->ij) { /* create the matrix the first time through */
15016d9e3a6SLisandro Dalcin     ierr = MatHYPRE_IJMatrixCreate(pc->pmat,&jac->ij);CHKERRQ(ierr);
15116d9e3a6SLisandro Dalcin   }
15216d9e3a6SLisandro Dalcin   if (!jac->b) { /* create the vectors the first time through */
15316d9e3a6SLisandro Dalcin     Vec x,b;
1542a7a6963SBarry Smith     ierr = MatCreateVecs(pc->pmat,&x,&b);CHKERRQ(ierr);
15516d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(x,&jac->x);CHKERRQ(ierr);
15616d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(b,&jac->b);CHKERRQ(ierr);
1576bf464f9SBarry Smith     ierr = VecDestroy(&x);CHKERRQ(ierr);
1586bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
15916d9e3a6SLisandro Dalcin   }
1605f5c5b43SBarry Smith 
16116d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
16216d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
1635272c319SBarry Smith     MatNullSpace    mnull;
1645272c319SBarry Smith     PetscBool       has_const;
1655272c319SBarry Smith     PetscInt        nvec,i;
1665272c319SBarry Smith     const Vec       *vecs;
1675272c319SBarry Smith 
16816d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1692fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
1705272c319SBarry Smith     ierr = MatGetNearNullSpace(pc->mat, &mnull);CHKERRQ(ierr);
1715272c319SBarry Smith     if (mnull) {
1725272c319SBarry Smith       ierr = MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs);CHKERRQ(ierr);
1735272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull);CHKERRQ(ierr);
1745272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->phmnull);CHKERRQ(ierr);
1755272c319SBarry Smith       for (i=0; i<nvec; i++) {
1765272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(vecs[i],&jac->hmnull[i]);CHKERRQ(ierr);
1775272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[i],(void**)&jac->phmnull[i]));
1785272c319SBarry Smith       }
1795272c319SBarry Smith       if (has_const) {
1805272c319SBarry Smith         ierr = MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL);CHKERRQ(ierr);
1815272c319SBarry Smith         ierr = VecSet(jac->hmnull_constant,1);CHKERRQ(ierr);
1825272c319SBarry Smith         ierr = VecNormalize(jac->hmnull_constant,NULL);
1835272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(jac->hmnull_constant,&jac->hmnull[nvec]);CHKERRQ(ierr);
1845272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[nvec],(void**)&jac->phmnull[nvec]));
1855272c319SBarry Smith         nvec++;
1865272c319SBarry Smith       }
1875272c319SBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVectors,(jac->hsolver,nvec,jac->phmnull));
1885272c319SBarry Smith       jac->n_hmnull = nvec;
1895272c319SBarry Smith     }
1904cb006feSStefano Zampini   }
191863406b8SStefano Zampini 
1924cb006feSStefano Zampini   /* special case for AMS */
1934cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
1944cb006feSStefano Zampini     if (!jac->coords[0] && !jac->constants[0]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs either coordinate vectors via PCSetCoordinates() or edge constant vectors via PCHYPRESetEdgeConstantVectors()");
1954cb006feSStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
1964cb006feSStefano Zampini   }
197863406b8SStefano Zampini   /* special case for ADS */
198863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
19937096e45SBarry Smith     if (!jac->coords[0]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs coordinate vectors via PCSetCoordinates()");
20037096e45SBarry 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");
201863406b8SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
202863406b8SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete curl operator via PCHYPRESetDiscreteGradient");
203863406b8SStefano Zampini   }
20416d9e3a6SLisandro Dalcin   ierr = MatHYPRE_IJMatrixCopy(pc->pmat,jac->ij);CHKERRQ(ierr);
205fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
206fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&bv));
207fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&xv));
208fd3f9acdSBarry Smith   PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr););
20916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
21016d9e3a6SLisandro Dalcin }
21116d9e3a6SLisandro Dalcin 
21216d9e3a6SLisandro Dalcin /*
21316d9e3a6SLisandro Dalcin     Replaces the address where the HYPRE vector points to its data with the address of
21416d9e3a6SLisandro Dalcin   PETSc's data. Saves the old address so it can be reset when we are finished with it.
21516d9e3a6SLisandro Dalcin   Allows use to get the data into a HYPRE vector without the cost of memcopies
21616d9e3a6SLisandro Dalcin */
21716d9e3a6SLisandro Dalcin #define HYPREReplacePointer(b,newvalue,savedvalue) { \
21816d9e3a6SLisandro Dalcin     hypre_ParVector *par_vector   = (hypre_ParVector*)hypre_IJVectorObject(((hypre_IJVector*)b)); \
21916d9e3a6SLisandro Dalcin     hypre_Vector    *local_vector = hypre_ParVectorLocalVector(par_vector); \
22016d9e3a6SLisandro Dalcin     savedvalue         = local_vector->data; \
2210ad7597dSKarl Rupp     local_vector->data = newvalue;          \
2220ad7597dSKarl Rupp }
22316d9e3a6SLisandro Dalcin 
22416d9e3a6SLisandro Dalcin #undef __FUNCT__
22516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE"
22616d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
22716d9e3a6SLisandro Dalcin {
22816d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
22916d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
23016d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
231d9ca1df4SBarry Smith   PetscScalar        *xv;
232d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
23316d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
234d9ca1df4SBarry Smith   PetscScalar        *sxv;
2354ddd07fcSJed Brown   PetscInt           hierr;
23616d9e3a6SLisandro Dalcin 
23716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
238dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
23916d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
240d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
24116d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
242d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
24316d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
24416d9e3a6SLisandro Dalcin 
245fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
246fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
247fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
248fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
24965e19b50SBarry Smith                                if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
250fd3f9acdSBarry Smith                                if (hierr) hypre__global_error = 0;);
25116d9e3a6SLisandro Dalcin 
252d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)sbv,bv);
25316d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
25416d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
255d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
25616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
25716d9e3a6SLisandro Dalcin }
25816d9e3a6SLisandro Dalcin 
25916d9e3a6SLisandro Dalcin #undef __FUNCT__
26016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE"
26116d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
26216d9e3a6SLisandro Dalcin {
26316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
26416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
26516d9e3a6SLisandro Dalcin 
26616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
267fd3f9acdSBarry Smith   if (jac->ij) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
268fd3f9acdSBarry Smith   if (jac->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->b));
269fd3f9acdSBarry Smith   if (jac->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->x));
2704cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
2714cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
2724cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
2734cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
2744cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
2754cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
2764cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
277863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
2784cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
2794cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
2805272c319SBarry Smith   if (jac->n_hmnull) {
2815272c319SBarry Smith     PetscInt i;
2825272c319SBarry Smith 
2835272c319SBarry Smith     for (i=0; i<jac->n_hmnull; i++) {
2845272c319SBarry Smith       PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->hmnull[i]));
2855272c319SBarry Smith     }
2865272c319SBarry Smith     ierr = PetscFree(jac->hmnull);CHKERRQ(ierr);
2875272c319SBarry Smith     ierr = PetscFree(jac->phmnull);CHKERRQ(ierr);
2885272c319SBarry Smith     ierr = VecDestroy(&jac->hmnull_constant);CHKERRQ(ierr);
2895272c319SBarry Smith   }
290226b0620SJed Brown   if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr););
291503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
29216d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
293c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
29416d9e3a6SLisandro Dalcin 
29516d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
296bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
297bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
2984cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
2994cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
300863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
3014cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
3024cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",NULL);CHKERRQ(ierr);
3034cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",NULL);CHKERRQ(ierr);
30416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
30516d9e3a6SLisandro Dalcin }
30616d9e3a6SLisandro Dalcin 
30716d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
30816d9e3a6SLisandro Dalcin #undef __FUNCT__
30916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut"
3108c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptions *PetscOptionsObject,PC pc)
31116d9e3a6SLisandro Dalcin {
31216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
31316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
314ace3abfcSBarry Smith   PetscBool      flag;
31516d9e3a6SLisandro Dalcin 
31616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
317e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
31816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
319fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
32016d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
321fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
32216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
323fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
32416d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
32516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
32616d9e3a6SLisandro Dalcin }
32716d9e3a6SLisandro Dalcin 
32816d9e3a6SLisandro Dalcin #undef __FUNCT__
32916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut"
33016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
33116d9e3a6SLisandro Dalcin {
33216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
33316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
334ace3abfcSBarry Smith   PetscBool      iascii;
33516d9e3a6SLisandro Dalcin 
33616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
337251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
33816d9e3a6SLisandro Dalcin   if (iascii) {
33916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
34016d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
34116d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
34216d9e3a6SLisandro Dalcin     } else {
34316d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr);
34416d9e3a6SLisandro Dalcin     }
34516d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
34657622a8eSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
34716d9e3a6SLisandro Dalcin     } else {
34816d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr);
34916d9e3a6SLisandro Dalcin     }
35016d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
35116d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
35216d9e3a6SLisandro Dalcin     } else {
35316d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default factor row size \n");CHKERRQ(ierr);
35416d9e3a6SLisandro Dalcin     }
35516d9e3a6SLisandro Dalcin   }
35616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
35716d9e3a6SLisandro Dalcin }
35816d9e3a6SLisandro Dalcin 
35916d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
36016d9e3a6SLisandro Dalcin 
36116d9e3a6SLisandro Dalcin #undef __FUNCT__
36216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG"
36316d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
36416d9e3a6SLisandro Dalcin {
36516d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
36616d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
36716d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
368d9ca1df4SBarry Smith   PetscScalar        *xv;
369d9ca1df4SBarry Smith   const PetscScalar  *bv;
37016d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
37116d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
3724ddd07fcSJed Brown   PetscInt           hierr;
37316d9e3a6SLisandro Dalcin 
37416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
375dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
37616d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
377d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
37816d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
379d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
38016d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
38116d9e3a6SLisandro Dalcin 
382fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
383fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
384fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
38516d9e3a6SLisandro Dalcin 
38616d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
38716d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
388e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
38916d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
39016d9e3a6SLisandro Dalcin 
39116d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
39216d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
39316d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
394d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
39516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
39616d9e3a6SLisandro Dalcin }
39716d9e3a6SLisandro Dalcin 
398a669f990SJed Brown /* static array length */
399a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
400a669f990SJed Brown 
40116d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
4020f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
40316d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
40465de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
4056a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]   = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
40665de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
40765de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
40865de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
40965de4495SJed Brown                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */,
41065de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
4110f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
4120f1074feSSatish Balay                                                   "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"};
41316d9e3a6SLisandro Dalcin #undef __FUNCT__
41416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG"
4158c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptions *PetscOptionsObject,PC pc)
41616d9e3a6SLisandro Dalcin {
41716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
41816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
4194ddd07fcSJed Brown   PetscInt       n,indx,level;
420ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
42116d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
42216d9e3a6SLisandro Dalcin 
42316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
424e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
4254336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
42616d9e3a6SLisandro Dalcin   if (flg) {
4274336a9eeSBarry Smith     jac->cycletype = indx+1;
428fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
42916d9e3a6SLisandro Dalcin   }
43016d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
43116d9e3a6SLisandro Dalcin   if (flg) {
432ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
433fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
43416d9e3a6SLisandro Dalcin   }
43516d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
43616d9e3a6SLisandro Dalcin   if (flg) {
437ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
438fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
43916d9e3a6SLisandro Dalcin   }
4400f1074feSSatish 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);
44116d9e3a6SLisandro Dalcin   if (flg) {
44257622a8eSBarry 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);
443fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
44416d9e3a6SLisandro Dalcin   }
44516d9e3a6SLisandro Dalcin 
4460f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
44716d9e3a6SLisandro Dalcin   if (flg) {
44857622a8eSBarry 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);
449fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
45016d9e3a6SLisandro Dalcin   }
45116d9e3a6SLisandro Dalcin 
4520f1074feSSatish 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);
4530f1074feSSatish Balay   if (flg) {
45457622a8eSBarry 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);
455fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
4560f1074feSSatish Balay   }
4570f1074feSSatish Balay 
4580f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
4590f1074feSSatish Balay   if (flg) {
46057622a8eSBarry 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);
4610f1074feSSatish Balay 
462fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
4630f1074feSSatish Balay   }
4640f1074feSSatish Balay 
4650f1074feSSatish Balay 
4660f1074feSSatish 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);
4670f1074feSSatish Balay   if (flg) {
46857622a8eSBarry 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);
4690f1074feSSatish Balay 
470fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
4710f1074feSSatish Balay   }
4720f1074feSSatish Balay 
4730f1074feSSatish Balay 
47416d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
47516d9e3a6SLisandro Dalcin   if (flg) {
47657622a8eSBarry 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);
477fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
47816d9e3a6SLisandro Dalcin   }
47916d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
48016d9e3a6SLisandro Dalcin   if (flg) {
48157622a8eSBarry 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);
48257622a8eSBarry 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);
483fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
48416d9e3a6SLisandro Dalcin   }
48516d9e3a6SLisandro Dalcin 
48616d9e3a6SLisandro Dalcin   /* Grid sweeps */
4870f1074feSSatish 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);
48816d9e3a6SLisandro Dalcin   if (flg) {
489fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
49016d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
49116d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
4920f1074feSSatish Balay     jac->gridsweeps[1] = indx;
4930f1074feSSatish Balay     /*defaults coarse to 1 */
4940f1074feSSatish Balay     jac->gridsweeps[2] = 1;
49516d9e3a6SLisandro Dalcin   }
4960f1074feSSatish Balay 
4975272c319SBarry 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);
4985272c319SBarry Smith   if (flg) {
4995272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,jac->nodal_coarsening));
5005272c319SBarry Smith   }
5015272c319SBarry Smith 
502*cbc39033SBarry 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);
5035272c319SBarry Smith   if (flg) {
5045272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,(jac->hsolver,jac->vec_interp_variant));
5055272c319SBarry Smith   }
5065272c319SBarry Smith 
5070f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
50816d9e3a6SLisandro Dalcin   if (flg) {
509fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
5100f1074feSSatish Balay     jac->gridsweeps[0] = indx;
51116d9e3a6SLisandro Dalcin   }
51216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
51316d9e3a6SLisandro Dalcin   if (flg) {
514fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
5150f1074feSSatish Balay     jac->gridsweeps[1] = indx;
51616d9e3a6SLisandro Dalcin   }
5170f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
51816d9e3a6SLisandro Dalcin   if (flg) {
519fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
5200f1074feSSatish Balay     jac->gridsweeps[2] = indx;
52116d9e3a6SLisandro Dalcin   }
52216d9e3a6SLisandro Dalcin 
5236a251517SEike Mueller   /* Smooth type */
5246a251517SEike Mueller   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);
5256a251517SEike Mueller   if (flg) {
5266a251517SEike Mueller     jac->smoothtype = indx;
5276a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
5288131ecf7SEike Mueller     jac->smoothnumlevels = 25;
5298131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
5308131ecf7SEike Mueller   }
5318131ecf7SEike Mueller 
5328131ecf7SEike Mueller   /* Number of smoothing levels */
5338131ecf7SEike 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);
5348131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
5358131ecf7SEike Mueller     jac->smoothnumlevels = indx;
5368131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
5376a251517SEike Mueller   }
5386a251517SEike Mueller 
5391810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
5401810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
5411810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
5421810e44eSEike Mueller     jac->eu_level = indx;
5431810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
5441810e44eSEike Mueller   }
5451810e44eSEike Mueller 
5461810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
5471810e44eSEike Mueller   double droptolerance;
5481810e44eSEike Mueller   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
5491810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
5501810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
5511810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
5521810e44eSEike Mueller   }
5531810e44eSEike Mueller 
5541810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
5551810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5561810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
5571810e44eSEike Mueller     jac->eu_bj = tmp_truth;
558493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
5591810e44eSEike Mueller   }
5601810e44eSEike Mueller 
56116d9e3a6SLisandro Dalcin   /* Relax type */
562a669f990SJed 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);
56316d9e3a6SLisandro Dalcin   if (flg) {
5640f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
565fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
5660f1074feSSatish Balay     /* by default, coarse type set to 9 */
5670f1074feSSatish Balay     jac->relaxtype[2] = 9;
5680f1074feSSatish Balay 
56916d9e3a6SLisandro Dalcin   }
570a669f990SJed 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);
57116d9e3a6SLisandro Dalcin   if (flg) {
57216d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
573fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
57416d9e3a6SLisandro Dalcin   }
575a669f990SJed 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);
57616d9e3a6SLisandro Dalcin   if (flg) {
5770f1074feSSatish Balay     jac->relaxtype[1] = indx;
578fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
57916d9e3a6SLisandro Dalcin   }
580a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
58116d9e3a6SLisandro Dalcin   if (flg) {
5820f1074feSSatish Balay     jac->relaxtype[2] = indx;
583fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
58416d9e3a6SLisandro Dalcin   }
58516d9e3a6SLisandro Dalcin 
58616d9e3a6SLisandro Dalcin   /* Relaxation Weight */
58716d9e3a6SLisandro 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);
58816d9e3a6SLisandro Dalcin   if (flg) {
589fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
59016d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
59116d9e3a6SLisandro Dalcin   }
59216d9e3a6SLisandro Dalcin 
59316d9e3a6SLisandro Dalcin   n         = 2;
59416d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
59516d9e3a6SLisandro 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);
59616d9e3a6SLisandro Dalcin   if (flg) {
59716d9e3a6SLisandro Dalcin     if (n == 2) {
59816d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
599fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
600ce94432eSBarry 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);
60116d9e3a6SLisandro Dalcin   }
60216d9e3a6SLisandro Dalcin 
60316d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
60416d9e3a6SLisandro 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);
60516d9e3a6SLisandro Dalcin   if (flg) {
606fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
60716d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
60816d9e3a6SLisandro Dalcin   }
60916d9e3a6SLisandro Dalcin 
61016d9e3a6SLisandro Dalcin   n         = 2;
61116d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
61216d9e3a6SLisandro 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);
61316d9e3a6SLisandro Dalcin   if (flg) {
61416d9e3a6SLisandro Dalcin     if (n == 2) {
61516d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
616fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
617ce94432eSBarry 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);
61816d9e3a6SLisandro Dalcin   }
61916d9e3a6SLisandro Dalcin 
62016d9e3a6SLisandro Dalcin   /* the Relax Order */
621acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
62216d9e3a6SLisandro Dalcin 
6238afaa268SBarry Smith   if (flg && tmp_truth) {
62416d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
625fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
62616d9e3a6SLisandro Dalcin   }
627a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
62816d9e3a6SLisandro Dalcin   if (flg) {
62916d9e3a6SLisandro Dalcin     jac->measuretype = indx;
630fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
63116d9e3a6SLisandro Dalcin   }
6320f1074feSSatish Balay   /* update list length 3/07 */
633a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
63416d9e3a6SLisandro Dalcin   if (flg) {
63516d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
636fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
63716d9e3a6SLisandro Dalcin   }
6380f1074feSSatish Balay 
6390f1074feSSatish Balay   /* new 3/07 */
640a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
6410f1074feSSatish Balay   if (flg) {
6420f1074feSSatish Balay     jac->interptype = indx;
643fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
6440f1074feSSatish Balay   }
6450f1074feSSatish Balay 
646b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
64716d9e3a6SLisandro Dalcin   if (flg) {
648b96a4a96SBarry Smith     level = 3;
6490298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
6502fa5cd67SKarl Rupp 
651b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
652fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
6532ae77aedSBarry Smith   }
6542ae77aedSBarry Smith 
655b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
6562ae77aedSBarry Smith   if (flg) {
657b96a4a96SBarry Smith     level = 3;
6580298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
6592fa5cd67SKarl Rupp 
660b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
661fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
66216d9e3a6SLisandro Dalcin   }
6638f87f92bSBarry Smith 
664acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
6658f87f92bSBarry Smith   if (flg && tmp_truth) {
6668f87f92bSBarry Smith     PetscInt tmp_int;
6678f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
6688f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
669fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
670fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
671fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
672fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
6738f87f92bSBarry Smith   }
6748f87f92bSBarry Smith 
67516d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
67616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
67716d9e3a6SLisandro Dalcin }
67816d9e3a6SLisandro Dalcin 
67916d9e3a6SLisandro Dalcin #undef __FUNCT__
68016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG"
681ace3abfcSBarry 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)
68216d9e3a6SLisandro Dalcin {
68316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
68416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
6854ddd07fcSJed Brown   PetscInt       oits;
68616d9e3a6SLisandro Dalcin 
68716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
688dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
689fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
690fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
69116d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
69216d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
69316d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
6948b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
6954d0a8057SBarry Smith   *outits = oits;
6964d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
6974d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
698fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
699fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
70016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
70116d9e3a6SLisandro Dalcin }
70216d9e3a6SLisandro Dalcin 
70316d9e3a6SLisandro Dalcin 
70416d9e3a6SLisandro Dalcin #undef __FUNCT__
70516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG"
70616d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
70716d9e3a6SLisandro Dalcin {
70816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
70916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
710ace3abfcSBarry Smith   PetscBool      iascii;
71116d9e3a6SLisandro Dalcin 
71216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
713251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
71416d9e3a6SLisandro Dalcin   if (iascii) {
71516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
71616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
71716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
71816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
71957622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
72057622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
72157622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
7220f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
7230f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
7240f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
7250f1074feSSatish Balay 
72657622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
72716d9e3a6SLisandro Dalcin 
7280f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
7290f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
7300f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
73116d9e3a6SLisandro Dalcin 
7320f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
7330f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
7340f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
73516d9e3a6SLisandro Dalcin 
73657622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
73757622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
73816d9e3a6SLisandro Dalcin 
73916d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
74016d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr);
74116d9e3a6SLisandro Dalcin     } else {
74216d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr);
74316d9e3a6SLisandro Dalcin     }
7446a251517SEike Mueller     if (jac->smoothtype!=-1) {
7456a251517SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
7468131ecf7SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Smooth num levels    %d\n",jac->smoothnumlevels);CHKERRQ(ierr);
7477e352d70SEike Mueller     } else {
7487e352d70SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using more complex smoothers.\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
7491810e44eSEike Mueller     }
7501810e44eSEike Mueller     if (jac->smoothtype==3) {
7511810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU(k) levels %d\n",jac->eu_level);CHKERRQ(ierr);
7521810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU(k) drop tolerance %g\n",jac->eu_droptolerance);CHKERRQ(ierr);
7531810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU use Block-Jacobi? %d\n",jac->eu_bj);CHKERRQ(ierr);
7546a251517SEike Mueller     }
75516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
75616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
7570f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
7585272c319SBarry Smith     if (jac->nodal_coarsening) {
7595272c319SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
7605272c319SBarry Smith     }
7615272c319SBarry Smith     if (jac->vec_interp_variant) {
7625272c319SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
7638f87f92bSBarry Smith     }
7648f87f92bSBarry Smith     if (jac->nodal_relax) {
7658f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
7668f87f92bSBarry Smith     }
76716d9e3a6SLisandro Dalcin   }
76816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
76916d9e3a6SLisandro Dalcin }
77016d9e3a6SLisandro Dalcin 
77116d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
77216d9e3a6SLisandro Dalcin #undef __FUNCT__
77316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails"
7748c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptions *PetscOptionsObject,PC pc)
77516d9e3a6SLisandro Dalcin {
77616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
77716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
7784ddd07fcSJed Brown   PetscInt       indx;
779ace3abfcSBarry Smith   PetscBool      flag;
78016d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
78116d9e3a6SLisandro Dalcin 
78216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
783e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
78416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
78516d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
7862fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
78716d9e3a6SLisandro Dalcin 
78816d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
7892fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
79016d9e3a6SLisandro Dalcin 
79116d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
7922fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
79316d9e3a6SLisandro Dalcin 
794acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
7952fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
79616d9e3a6SLisandro Dalcin 
797acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
7982fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
79916d9e3a6SLisandro Dalcin 
800a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
80116d9e3a6SLisandro Dalcin   if (flag) {
80216d9e3a6SLisandro Dalcin     jac->symt = indx;
803fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
80416d9e3a6SLisandro Dalcin   }
80516d9e3a6SLisandro Dalcin 
80616d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
80716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
80816d9e3a6SLisandro Dalcin }
80916d9e3a6SLisandro Dalcin 
81016d9e3a6SLisandro Dalcin #undef __FUNCT__
81116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails"
81216d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
81316d9e3a6SLisandro Dalcin {
81416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
81516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
816ace3abfcSBarry Smith   PetscBool      iascii;
81716d9e3a6SLisandro Dalcin   const char     *symt = 0;;
81816d9e3a6SLisandro Dalcin 
81916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
820251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
82116d9e3a6SLisandro Dalcin   if (iascii) {
82216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
82316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
82457622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
82557622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: filter %g\n",(double)jac->filter);CHKERRQ(ierr);
82657622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
827ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
828ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
8292fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
8302fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
8312fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
832ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
83316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr);
83416d9e3a6SLisandro Dalcin   }
83516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
83616d9e3a6SLisandro Dalcin }
8374cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
8384cb006feSStefano Zampini #undef __FUNCT__
8394cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS"
8409fa463a7SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptions *PetscOptionsObject,PC pc)
8414cb006feSStefano Zampini {
8424cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
8434cb006feSStefano Zampini   PetscErrorCode ierr;
8444cb006feSStefano Zampini   PetscInt       n;
8454cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
8464cb006feSStefano Zampini 
8474cb006feSStefano Zampini   PetscFunctionBegin;
8489fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
849863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
850863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
851863406b8SStefano 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);
852863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
8534cb006feSStefano 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);
8544cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
855863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
856863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
857863406b8SStefano 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);
858863406b8SStefano 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);
859863406b8SStefano 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);
860863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
8614cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
862863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
863863406b8SStefano Zampini                                                                       jac->as_relax_times,
864863406b8SStefano Zampini                                                                       jac->as_relax_weight,
865863406b8SStefano Zampini                                                                       jac->as_omega));
8664cb006feSStefano Zampini   }
867863406b8SStefano 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);
8684cb006feSStefano Zampini   n = 5;
869863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
8704cb006feSStefano Zampini   if (flag || flag2) {
871863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
872863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
873863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
874863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
875863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
876863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
8774cb006feSStefano Zampini   }
878863406b8SStefano 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);
8794cb006feSStefano Zampini   n = 5;
880863406b8SStefano 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);
8814cb006feSStefano Zampini   if (flag || flag2) {
882863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
883863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
884863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
885863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
886863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
887863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
8884cb006feSStefano Zampini   }
8894cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
8904cb006feSStefano Zampini   PetscFunctionReturn(0);
8914cb006feSStefano Zampini }
8924cb006feSStefano Zampini 
8934cb006feSStefano Zampini #undef __FUNCT__
8944cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS"
8954cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
8964cb006feSStefano Zampini {
8974cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
8984cb006feSStefano Zampini   PetscErrorCode ierr;
8994cb006feSStefano Zampini   PetscBool      iascii;
9004cb006feSStefano Zampini 
9014cb006feSStefano Zampini   PetscFunctionBegin;
9024cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
9034cb006feSStefano Zampini   if (iascii) {
9044cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
905863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
9064cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
907863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
908863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
909863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
910863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
911863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
9124cb006feSStefano Zampini     if (jac->alpha_Poisson) {
9134cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
9144cb006feSStefano Zampini     } else {
9154cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr);
9164cb006feSStefano Zampini     }
917863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
918863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
919863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
920863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
921863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
922863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
9234cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
9244cb006feSStefano Zampini       if (jac->beta_Poisson) {
9254cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
9264cb006feSStefano Zampini       } else {
9274cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr);
9284cb006feSStefano Zampini       }
929863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
930863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
931863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
932863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
933863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
934863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
9354cb006feSStefano Zampini     }
9364cb006feSStefano Zampini   }
9374cb006feSStefano Zampini   PetscFunctionReturn(0);
9384cb006feSStefano Zampini }
9394cb006feSStefano Zampini 
9404cb006feSStefano Zampini #undef __FUNCT__
941863406b8SStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_ADS"
942863406b8SStefano Zampini static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptions *PetscOptionsObject,PC pc)
943863406b8SStefano Zampini {
944863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
945863406b8SStefano Zampini   PetscErrorCode ierr;
946863406b8SStefano Zampini   PetscInt       n;
947863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
948863406b8SStefano Zampini 
949863406b8SStefano Zampini   PetscFunctionBegin;
950863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
951863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
952863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
953863406b8SStefano 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);
954863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
955863406b8SStefano 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);
956863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
957863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
958863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
959863406b8SStefano 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);
960863406b8SStefano 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);
961863406b8SStefano 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);
962863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
963863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
964863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
965863406b8SStefano Zampini                                                                       jac->as_relax_times,
966863406b8SStefano Zampini                                                                       jac->as_relax_weight,
967863406b8SStefano Zampini                                                                       jac->as_omega));
968863406b8SStefano Zampini   }
969863406b8SStefano 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);
970863406b8SStefano Zampini   n = 5;
971863406b8SStefano 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);
972863406b8SStefano 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);
973863406b8SStefano Zampini   if (flag || flag2 || flag3) {
974863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
975863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
976863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
977863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
978863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
979863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
980863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
981863406b8SStefano Zampini   }
982863406b8SStefano 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);
983863406b8SStefano Zampini   n = 5;
984863406b8SStefano 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);
985863406b8SStefano Zampini   if (flag || flag2) {
986863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
987863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
988863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
989863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
990863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
991863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
992863406b8SStefano Zampini   }
993863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
994863406b8SStefano Zampini   PetscFunctionReturn(0);
995863406b8SStefano Zampini }
996863406b8SStefano Zampini 
997863406b8SStefano Zampini #undef __FUNCT__
998863406b8SStefano Zampini #define __FUNCT__ "PCView_HYPRE_ADS"
999863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1000863406b8SStefano Zampini {
1001863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1002863406b8SStefano Zampini   PetscErrorCode ierr;
1003863406b8SStefano Zampini   PetscBool      iascii;
1004863406b8SStefano Zampini 
1005863406b8SStefano Zampini   PetscFunctionBegin;
1006863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1007863406b8SStefano Zampini   if (iascii) {
1008863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
1009863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1010863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
1011863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1012863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1013863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1014863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1015863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
1016863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: AMS solver\n");CHKERRQ(ierr);
1017863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1018863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1019863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1020863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1021863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1022863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1023863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
1024863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: vector Poisson solver\n");CHKERRQ(ierr);
1025863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1026863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1027863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1028863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1029863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1030863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
1031863406b8SStefano Zampini   }
1032863406b8SStefano Zampini   PetscFunctionReturn(0);
1033863406b8SStefano Zampini }
1034863406b8SStefano Zampini 
1035863406b8SStefano Zampini #undef __FUNCT__
1036863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE"
1037863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
10384cb006feSStefano Zampini {
10394cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
10404cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_G;
10414cb006feSStefano Zampini   PetscErrorCode     ierr;
10424cb006feSStefano Zampini 
10434cb006feSStefano Zampini   PetscFunctionBegin;
10444cb006feSStefano Zampini   /* throw away any discrete gradient if already set */
10454cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
10464cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(G,&jac->G);CHKERRQ(ierr);
10474cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(G,jac->G);CHKERRQ(ierr);
10484cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->G,(void**)(&parcsr_G)));
1049863406b8SStefano Zampini   PetscStackCall("Hypre set gradient",ierr = (*jac->setdgrad)(jac->hsolver,parcsr_G);CHKERRQ(ierr););
10504cb006feSStefano Zampini   PetscFunctionReturn(0);
10514cb006feSStefano Zampini }
10524cb006feSStefano Zampini 
10534cb006feSStefano Zampini #undef __FUNCT__
10544cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient"
10554cb006feSStefano Zampini /*@
10564cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
10574cb006feSStefano Zampini 
10584cb006feSStefano Zampini    Collective on PC
10594cb006feSStefano Zampini 
10604cb006feSStefano Zampini    Input Parameters:
10614cb006feSStefano Zampini +  pc - the preconditioning context
10624cb006feSStefano Zampini -  G - the discrete gradient
10634cb006feSStefano Zampini 
10644cb006feSStefano Zampini    Level: intermediate
10654cb006feSStefano Zampini 
10664cb006feSStefano 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
1067863406b8SStefano 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
10684cb006feSStefano Zampini 
10694cb006feSStefano Zampini .seealso:
10704cb006feSStefano Zampini @*/
10714cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
10724cb006feSStefano Zampini {
10734cb006feSStefano Zampini   PetscErrorCode ierr;
10744cb006feSStefano Zampini 
10754cb006feSStefano Zampini   PetscFunctionBegin;
10764cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
10774cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
10784cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
10794cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
10804cb006feSStefano Zampini   PetscFunctionReturn(0);
10814cb006feSStefano Zampini }
10824cb006feSStefano Zampini 
10834cb006feSStefano Zampini #undef __FUNCT__
1084863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl_HYPRE"
1085863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1086863406b8SStefano Zampini {
1087863406b8SStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
1088863406b8SStefano Zampini   HYPRE_ParCSRMatrix parcsr_C;
1089863406b8SStefano Zampini   PetscErrorCode     ierr;
1090863406b8SStefano Zampini 
1091863406b8SStefano Zampini   PetscFunctionBegin;
1092863406b8SStefano Zampini   /* throw away any discrete curl if already set */
1093863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
1094863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(C,&jac->C);CHKERRQ(ierr);
1095863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(C,jac->C);CHKERRQ(ierr);
1096863406b8SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->C,(void**)(&parcsr_C)));
1097863406b8SStefano Zampini   PetscStackCall("Hypre set curl",ierr = (*jac->setdcurl)(jac->hsolver,parcsr_C);CHKERRQ(ierr););
1098863406b8SStefano Zampini   PetscFunctionReturn(0);
1099863406b8SStefano Zampini }
1100863406b8SStefano Zampini 
1101863406b8SStefano Zampini #undef __FUNCT__
1102863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl"
1103863406b8SStefano Zampini /*@
1104863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1105863406b8SStefano Zampini 
1106863406b8SStefano Zampini    Collective on PC
1107863406b8SStefano Zampini 
1108863406b8SStefano Zampini    Input Parameters:
1109863406b8SStefano Zampini +  pc - the preconditioning context
1110863406b8SStefano Zampini -  C - the discrete curl
1111863406b8SStefano Zampini 
1112863406b8SStefano Zampini    Level: intermediate
1113863406b8SStefano Zampini 
1114863406b8SStefano 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
1115863406b8SStefano 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
1116863406b8SStefano Zampini 
1117863406b8SStefano Zampini .seealso:
1118863406b8SStefano Zampini @*/
1119863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1120863406b8SStefano Zampini {
1121863406b8SStefano Zampini   PetscErrorCode ierr;
1122863406b8SStefano Zampini 
1123863406b8SStefano Zampini   PetscFunctionBegin;
1124863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1125863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1126863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1127863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1128863406b8SStefano Zampini   PetscFunctionReturn(0);
1129863406b8SStefano Zampini }
1130863406b8SStefano Zampini 
1131863406b8SStefano Zampini #undef __FUNCT__
11324cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS"
11334cb006feSStefano Zampini static PetscErrorCode PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
11344cb006feSStefano Zampini {
11354cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11364cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_alpha_Poisson;
11374cb006feSStefano Zampini   PetscErrorCode     ierr;
11384cb006feSStefano Zampini 
11394cb006feSStefano Zampini   PetscFunctionBegin;
11404cb006feSStefano Zampini   /* throw away any matrix if already set */
11414cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
11424cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->alpha_Poisson);CHKERRQ(ierr);
11434cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->alpha_Poisson);CHKERRQ(ierr);
11444cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->alpha_Poisson,(void**)(&parcsr_alpha_Poisson)));
11454cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr_alpha_Poisson));
11464cb006feSStefano Zampini   PetscFunctionReturn(0);
11474cb006feSStefano Zampini }
11484cb006feSStefano Zampini 
11494cb006feSStefano Zampini #undef __FUNCT__
11504cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix"
11514cb006feSStefano Zampini /*@
11524cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
11534cb006feSStefano Zampini 
11544cb006feSStefano Zampini    Collective on PC
11554cb006feSStefano Zampini 
11564cb006feSStefano Zampini    Input Parameters:
11574cb006feSStefano Zampini +  pc - the preconditioning context
11584cb006feSStefano Zampini -  A - the matrix
11594cb006feSStefano Zampini 
11604cb006feSStefano Zampini    Level: intermediate
11614cb006feSStefano Zampini 
11624cb006feSStefano Zampini    Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
11634cb006feSStefano Zampini 
11644cb006feSStefano Zampini .seealso:
11654cb006feSStefano Zampini @*/
11664cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
11674cb006feSStefano Zampini {
11684cb006feSStefano Zampini   PetscErrorCode ierr;
11694cb006feSStefano Zampini 
11704cb006feSStefano Zampini   PetscFunctionBegin;
11714cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11724cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
11734cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
11744cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetAlphaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
11754cb006feSStefano Zampini   PetscFunctionReturn(0);
11764cb006feSStefano Zampini }
11774cb006feSStefano Zampini 
11784cb006feSStefano Zampini #undef __FUNCT__
11794cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix_HYPRE_AMS"
11804cb006feSStefano Zampini static PetscErrorCode PCHYPRESetBetaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
11814cb006feSStefano Zampini {
11824cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11834cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_beta_Poisson;
11844cb006feSStefano Zampini   PetscErrorCode     ierr;
11854cb006feSStefano Zampini 
11864cb006feSStefano Zampini   PetscFunctionBegin;
11874cb006feSStefano Zampini   if (!A) {
1188484796dcSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
11894cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_TRUE;
11904cb006feSStefano Zampini     PetscFunctionReturn(0);
11914cb006feSStefano Zampini   }
11924cb006feSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
11934cb006feSStefano Zampini   /* throw away any matrix if already set */
11944cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
11954cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->beta_Poisson);CHKERRQ(ierr);
11964cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->beta_Poisson);CHKERRQ(ierr);
11974cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->beta_Poisson,(void**)(&parcsr_beta_Poisson)));
11984cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr_beta_Poisson));
11994cb006feSStefano Zampini   PetscFunctionReturn(0);
12004cb006feSStefano Zampini }
12014cb006feSStefano Zampini 
12024cb006feSStefano Zampini #undef __FUNCT__
12034cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix"
12044cb006feSStefano Zampini /*@
12054cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
12064cb006feSStefano Zampini 
12074cb006feSStefano Zampini    Collective on PC
12084cb006feSStefano Zampini 
12094cb006feSStefano Zampini    Input Parameters:
12104cb006feSStefano Zampini +  pc - the preconditioning context
12114cb006feSStefano Zampini -  A - the matrix
12124cb006feSStefano Zampini 
12134cb006feSStefano Zampini    Level: intermediate
12144cb006feSStefano Zampini 
12154cb006feSStefano Zampini    Notes: A should be obtained by discretizing the Poisson problem with linear finite elements.
12164cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
12174cb006feSStefano Zampini 
12184cb006feSStefano Zampini .seealso:
12194cb006feSStefano Zampini @*/
12204cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
12214cb006feSStefano Zampini {
12224cb006feSStefano Zampini   PetscErrorCode ierr;
12234cb006feSStefano Zampini 
12244cb006feSStefano Zampini   PetscFunctionBegin;
12254cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12264cb006feSStefano Zampini   if (A) {
12274cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
12284cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
12294cb006feSStefano Zampini   }
12304cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetBetaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
12314cb006feSStefano Zampini   PetscFunctionReturn(0);
12324cb006feSStefano Zampini }
12334cb006feSStefano Zampini 
12344cb006feSStefano Zampini #undef __FUNCT__
12354cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE_AMS"
12364cb006feSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE_AMS(PC pc,Vec ozz, Vec zoz, Vec zzo)
12374cb006feSStefano Zampini {
12384cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
12394cb006feSStefano Zampini   HYPRE_ParVector    par_ozz,par_zoz,par_zzo;
124012ddd1b6SStefano Zampini   PetscInt           dim;
12414cb006feSStefano Zampini   PetscErrorCode     ierr;
12424cb006feSStefano Zampini 
12434cb006feSStefano Zampini   PetscFunctionBegin;
12444cb006feSStefano Zampini   /* throw away any vector if already set */
12454cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
12464cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
12474cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
12484cb006feSStefano Zampini   jac->constants[0] = NULL;
12494cb006feSStefano Zampini   jac->constants[1] = NULL;
12504cb006feSStefano Zampini   jac->constants[2] = NULL;
12514cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
12524cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
12534cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&par_ozz)));
12544cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
12554cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
12564cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&par_zoz)));
125712ddd1b6SStefano Zampini   dim = 2;
12584cb006feSStefano Zampini   if (zzo) {
12594cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
12604cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
12614cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&par_zzo)));
126212ddd1b6SStefano Zampini     dim++;
12634cb006feSStefano Zampini   }
12644cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,par_ozz,par_zoz,par_zzo));
126512ddd1b6SStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim));
12664cb006feSStefano Zampini   PetscFunctionReturn(0);
12674cb006feSStefano Zampini }
12684cb006feSStefano Zampini 
12694cb006feSStefano Zampini #undef __FUNCT__
12704cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors"
12714cb006feSStefano Zampini /*@
12724cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
12734cb006feSStefano Zampini 
12744cb006feSStefano Zampini    Collective on PC
12754cb006feSStefano Zampini 
12764cb006feSStefano Zampini    Input Parameters:
12774cb006feSStefano Zampini +  pc - the preconditioning context
12784cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
12794cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
12804cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
12814cb006feSStefano Zampini 
12824cb006feSStefano Zampini    Level: intermediate
12834cb006feSStefano Zampini 
12844cb006feSStefano Zampini    Notes:
12854cb006feSStefano Zampini 
12864cb006feSStefano Zampini .seealso:
12874cb006feSStefano Zampini @*/
12884cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
12894cb006feSStefano Zampini {
12904cb006feSStefano Zampini   PetscErrorCode ierr;
12914cb006feSStefano Zampini 
12924cb006feSStefano Zampini   PetscFunctionBegin;
12934cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12944cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
12954cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
12964cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
12974cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
12984cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
12994cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
13004cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
13014cb006feSStefano Zampini   PetscFunctionReturn(0);
13024cb006feSStefano Zampini }
13034cb006feSStefano Zampini 
13044cb006feSStefano Zampini #undef __FUNCT__
1305863406b8SStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE"
1306863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
13074cb006feSStefano Zampini {
13084cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
13094cb006feSStefano Zampini   Vec             tv;
13104cb006feSStefano Zampini   HYPRE_ParVector par_coords[3];
13114cb006feSStefano Zampini   PetscInt        i;
13124cb006feSStefano Zampini   PetscErrorCode  ierr;
13134cb006feSStefano Zampini 
13144cb006feSStefano Zampini   PetscFunctionBegin;
13154cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
13164cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
13174cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
13184cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
13194cb006feSStefano Zampini   /* set problem's dimension */
1320863406b8SStefano Zampini   if (jac->setdim) {
1321863406b8SStefano Zampini     PetscStackCall("Hypre set dim",ierr = (*jac->setdim)(jac->hsolver,dim);CHKERRQ(ierr););
1322863406b8SStefano Zampini   }
13234cb006feSStefano Zampini   /* compute IJ vector for coordinates */
13244cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
13254cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
13264cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
13274cb006feSStefano Zampini   for (i=0;i<dim;i++) {
13284cb006feSStefano Zampini     PetscScalar *array;
13294cb006feSStefano Zampini     PetscInt    j;
13304cb006feSStefano Zampini 
13314cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
13324cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
13334cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
13344cb006feSStefano Zampini       array[j] = coords[j*dim+i];
13354cb006feSStefano Zampini     }
13364cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
13374cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
13384cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
13394cb006feSStefano Zampini   }
13404cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
13414cb006feSStefano Zampini   /* pass parCSR vectors to AMS solver */
13424cb006feSStefano Zampini   par_coords[0] = NULL;
13434cb006feSStefano Zampini   par_coords[1] = NULL;
13444cb006feSStefano Zampini   par_coords[2] = NULL;
13454cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&par_coords[0])));
13464cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&par_coords[1])));
13474cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&par_coords[2])));
1348863406b8SStefano Zampini   PetscStackCall("Hypre set coords",ierr = (*jac->setcoord)(jac->hsolver,par_coords[0],par_coords[1],par_coords[2]);CHKERRQ(ierr););
13494cb006feSStefano Zampini   PetscFunctionReturn(0);
13504cb006feSStefano Zampini }
13514cb006feSStefano Zampini 
135216d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
135316d9e3a6SLisandro Dalcin 
135416d9e3a6SLisandro Dalcin #undef __FUNCT__
135516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
1356f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
135716d9e3a6SLisandro Dalcin {
135816d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
135916d9e3a6SLisandro Dalcin 
136016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
136116d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
136216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
136316d9e3a6SLisandro Dalcin }
136416d9e3a6SLisandro Dalcin 
136516d9e3a6SLisandro Dalcin #undef __FUNCT__
136616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
1367f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
136816d9e3a6SLisandro Dalcin {
136916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
137016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1371ace3abfcSBarry Smith   PetscBool      flag;
137216d9e3a6SLisandro Dalcin 
137316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
137416d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
137516d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1376ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
137716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
137816d9e3a6SLisandro Dalcin   } else {
137916d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
138016d9e3a6SLisandro Dalcin   }
138116d9e3a6SLisandro Dalcin 
138216d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
138316d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
138416d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
138516d9e3a6SLisandro Dalcin 
138616d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
138716d9e3a6SLisandro Dalcin   if (flag) {
1388fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
138916d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
139016d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
139116d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
139216d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
139316d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
139416d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
139516d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
139616d9e3a6SLisandro Dalcin   }
139716d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
139816d9e3a6SLisandro Dalcin   if (flag) {
1399fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
140016d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
140116d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
140216d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
140316d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
140416d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
140516d9e3a6SLisandro Dalcin     /* initialize */
140616d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
140716d9e3a6SLisandro Dalcin     jac->threshhold = .1;
140816d9e3a6SLisandro Dalcin     jac->filter     = .1;
140916d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
14102fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
14112fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
14122fa5cd67SKarl Rupp 
141316d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
141416d9e3a6SLisandro Dalcin     jac->symt = 0;
1415fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1416fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1417fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1418fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1419fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1420fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
142116d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
142216d9e3a6SLisandro Dalcin   }
142316d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
142416d9e3a6SLisandro Dalcin   if (flag) {
142516d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
142616d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
142716d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
142816d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
142916d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
143016d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
143116d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
143216d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
143316d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
143416d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
143516d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
143616d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
143716d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
14388f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
143916d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
144016d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
144116d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
144216d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
144316d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
14440f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
14456a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1446b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
14471810e44eSEike Mueller     jac->eu_level         = 0;
14481810e44eSEike Mueller     jac->eu_droptolerance = 0;
14491810e44eSEike Mueller     jac->eu_bj            = 0;
14508f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
14510f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
145216d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
145316d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
145416d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
14550f1074feSSatish Balay     jac->interptype       = 0;
14560f1074feSSatish Balay     jac->agg_nl           = 0;
14570f1074feSSatish Balay     jac->pmax             = 0;
14580f1074feSSatish Balay     jac->truncfactor      = 0.0;
14590f1074feSSatish Balay     jac->agg_num_paths    = 1;
14608f87f92bSBarry Smith 
14618f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
14628f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
14638f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1464fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1465fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1466fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1467fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1468fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1469fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1470fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1471fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1472fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1473fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1474fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1475fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1476fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1477fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1478fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1479fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
148016d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
148116d9e3a6SLisandro Dalcin   }
14824cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
14834cb006feSStefano Zampini   if (flag) {
14844cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
14854cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
14864cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
14874cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
14884cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
14894cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
1490863406b8SStefano Zampini     jac->setdgrad            = HYPRE_AMSSetDiscreteGradient;
1491863406b8SStefano Zampini     jac->setcoord            = HYPRE_AMSSetCoordinateVectors;
1492863406b8SStefano Zampini     jac->setdim              = HYPRE_AMSSetDimension;
14934cb006feSStefano Zampini     jac->coords[0]           = NULL;
14944cb006feSStefano Zampini     jac->coords[1]           = NULL;
14954cb006feSStefano Zampini     jac->coords[2]           = NULL;
14964cb006feSStefano Zampini     jac->G                   = NULL;
14974cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1498863406b8SStefano Zampini     jac->as_print           = 0;
1499863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1500863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
15014cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
15024cb006feSStefano Zampini     /* Smoothing options */
1503863406b8SStefano Zampini     jac->as_relax_type      = 2;
1504863406b8SStefano Zampini     jac->as_relax_times     = 1;
1505863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1506863406b8SStefano Zampini     jac->as_omega           = 1.0;
15074cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1508863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1509863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
15100bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1511863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1512863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1513863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
15144cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
15154cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_FALSE;
1516863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1517863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
15180bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1519863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1520863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1521863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1522863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1523863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
15244cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1525863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1526863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1527863406b8SStefano Zampini                                                                       jac->as_relax_times,
1528863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1529863406b8SStefano Zampini                                                                       jac->as_omega));
1530863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1531863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1532863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1533863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1534863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1535863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1536863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1537863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1538863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1539863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1540863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1541863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1542863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1543863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
15444cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE_AMS);CHKERRQ(ierr);
15454cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
15464cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",PCHYPRESetBetaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
15474cb006feSStefano Zampini     PetscFunctionReturn(0);
15484cb006feSStefano Zampini   }
1549863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1550863406b8SStefano Zampini   if (flag) {
1551863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1552863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1553863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1554863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1555863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1556863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1557863406b8SStefano Zampini     jac->setdgrad            = HYPRE_ADSSetDiscreteGradient;
1558863406b8SStefano Zampini     jac->setdcurl            = HYPRE_ADSSetDiscreteCurl;
1559863406b8SStefano Zampini     jac->setcoord            = HYPRE_ADSSetCoordinateVectors;
1560863406b8SStefano Zampini     jac->coords[0]           = NULL;
1561863406b8SStefano Zampini     jac->coords[1]           = NULL;
1562863406b8SStefano Zampini     jac->coords[2]           = NULL;
1563863406b8SStefano Zampini     jac->G                   = NULL;
1564863406b8SStefano Zampini     jac->C                   = NULL;
1565863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1566863406b8SStefano Zampini     jac->as_print           = 0;
1567863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1568863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1569863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1570863406b8SStefano Zampini     /* Smoothing options */
1571863406b8SStefano Zampini     jac->as_relax_type      = 2;
1572863406b8SStefano Zampini     jac->as_relax_times     = 1;
1573863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1574863406b8SStefano Zampini     jac->as_omega           = 1.0;
1575863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1576863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1577863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1578863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1579863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1580863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1581863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1582863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1583863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1584863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1585863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1586863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1587863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1588863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1589863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1590863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1591863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1592863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1593863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1594863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1595863406b8SStefano Zampini                                                                       jac->as_relax_times,
1596863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1597863406b8SStefano Zampini                                                                       jac->as_omega));
1598863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1599863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1600863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1601863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1602863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1603863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1604863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1605863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1606863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1607863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1608863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1609863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1610863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1611863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1612863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
1613863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
1614863406b8SStefano Zampini     PetscFunctionReturn(0);
1615863406b8SStefano Zampini   }
1616503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
16172fa5cd67SKarl Rupp 
16180298fd71SBarry Smith   jac->hypre_type = NULL;
161933263987SBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, boomeramg, ams",name);
162016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
162116d9e3a6SLisandro Dalcin }
162216d9e3a6SLisandro Dalcin 
162316d9e3a6SLisandro Dalcin /*
162416d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
162516d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
162616d9e3a6SLisandro Dalcin */
162716d9e3a6SLisandro Dalcin #undef __FUNCT__
162816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
16298c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptions *PetscOptionsObject,PC pc)
163016d9e3a6SLisandro Dalcin {
163116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
16324ddd07fcSJed Brown   PetscInt       indx;
1633863406b8SStefano Zampini   const char     *type[] = {"pilut","parasails","boomeramg","ams","ads"};
1634ace3abfcSBarry Smith   PetscBool      flg;
163516d9e3a6SLisandro Dalcin 
163616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16379fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
16389c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
163916d9e3a6SLisandro Dalcin   if (flg) {
164016d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
164102a17cd4SBarry Smith   } else {
164202a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
164316d9e3a6SLisandro Dalcin   }
164416d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
16453931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
164616d9e3a6SLisandro Dalcin   }
164716d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
164816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
164916d9e3a6SLisandro Dalcin }
165016d9e3a6SLisandro Dalcin 
165116d9e3a6SLisandro Dalcin #undef __FUNCT__
165216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
165316d9e3a6SLisandro Dalcin /*@C
165416d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
165516d9e3a6SLisandro Dalcin 
165616d9e3a6SLisandro Dalcin    Input Parameters:
165716d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1658863406b8SStefano Zampini -     name - either  pilut, parasails, boomeramg, ams, ads
165916d9e3a6SLisandro Dalcin 
166016d9e3a6SLisandro Dalcin    Options Database Keys:
1661863406b8SStefano Zampini    -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
166216d9e3a6SLisandro Dalcin 
166316d9e3a6SLisandro Dalcin    Level: intermediate
166416d9e3a6SLisandro Dalcin 
166516d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
166616d9e3a6SLisandro Dalcin            PCHYPRE
166716d9e3a6SLisandro Dalcin 
166816d9e3a6SLisandro Dalcin @*/
16697087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
167016d9e3a6SLisandro Dalcin {
16714ac538c5SBarry Smith   PetscErrorCode ierr;
167216d9e3a6SLisandro Dalcin 
167316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16740700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
167516d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
16764ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
167716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
167816d9e3a6SLisandro Dalcin }
167916d9e3a6SLisandro Dalcin 
168016d9e3a6SLisandro Dalcin #undef __FUNCT__
168116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
168216d9e3a6SLisandro Dalcin /*@C
168316d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
168416d9e3a6SLisandro Dalcin 
168516d9e3a6SLisandro Dalcin    Input Parameter:
168616d9e3a6SLisandro Dalcin .     pc - the preconditioner context
168716d9e3a6SLisandro Dalcin 
168816d9e3a6SLisandro Dalcin    Output Parameter:
1689863406b8SStefano Zampini .     name - either  pilut, parasails, boomeramg, ams, ads
169016d9e3a6SLisandro Dalcin 
169116d9e3a6SLisandro Dalcin    Level: intermediate
169216d9e3a6SLisandro Dalcin 
169316d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
169416d9e3a6SLisandro Dalcin            PCHYPRE
169516d9e3a6SLisandro Dalcin 
169616d9e3a6SLisandro Dalcin @*/
16977087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
169816d9e3a6SLisandro Dalcin {
16994ac538c5SBarry Smith   PetscErrorCode ierr;
170016d9e3a6SLisandro Dalcin 
170116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
17020700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
170316d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
17044ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
170516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
170616d9e3a6SLisandro Dalcin }
170716d9e3a6SLisandro Dalcin 
170816d9e3a6SLisandro Dalcin /*MC
170916d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
171016d9e3a6SLisandro Dalcin 
171116d9e3a6SLisandro Dalcin    Options Database Keys:
1712863406b8SStefano Zampini +   -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
171316d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
171416d9e3a6SLisandro Dalcin           preconditioner
171516d9e3a6SLisandro Dalcin 
171616d9e3a6SLisandro Dalcin    Level: intermediate
171716d9e3a6SLisandro Dalcin 
171816d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
171916d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
172016d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
172116d9e3a6SLisandro Dalcin 
172216d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
17230f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
17240f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
17250f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
17268f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
17270f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
17280f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
172916d9e3a6SLisandro Dalcin 
17300f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
17310f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
17320f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
173316d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
173416d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
173516d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
173616d9e3a6SLisandro Dalcin 
173716d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
173816d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
173916d9e3a6SLisandro Dalcin 
17405272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
17415272c319SBarry Smith           the two options:
17425272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
1743*cbc39033SBarry Smith -   -pc_hypre_boomeramg_vec_interp_variant <v> where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
17445272c319SBarry Smith 
17455272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
17465272c319SBarry Smith 
17479e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
17489e5bc791SBarry Smith 
174916d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
17509e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
175116d9e3a6SLisandro Dalcin 
175216d9e3a6SLisandro Dalcin M*/
175316d9e3a6SLisandro Dalcin 
175416d9e3a6SLisandro Dalcin #undef __FUNCT__
175516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
17568cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
175716d9e3a6SLisandro Dalcin {
175816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
175916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
176016d9e3a6SLisandro Dalcin 
176116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1762b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
17632fa5cd67SKarl Rupp 
176416d9e3a6SLisandro Dalcin   pc->data                = jac;
176516d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
176616d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
176716d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
176816d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
176916d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
17700298fd71SBarry Smith   jac->hypre_type         = NULL;
17714cb006feSStefano Zampini   jac->coords[0]          = NULL;
17724cb006feSStefano Zampini   jac->coords[1]          = NULL;
17734cb006feSStefano Zampini   jac->coords[2]          = NULL;
17744cb006feSStefano Zampini   jac->constants[0]       = NULL;
17754cb006feSStefano Zampini   jac->constants[1]       = NULL;
17764cb006feSStefano Zampini   jac->constants[2]       = NULL;
1777863406b8SStefano Zampini   jac->G                  = NULL;
1778863406b8SStefano Zampini   jac->C                  = NULL;
1779863406b8SStefano Zampini   jac->alpha_Poisson      = NULL;
1780863406b8SStefano Zampini   jac->beta_Poisson       = NULL;
1781fd444223SStefano Zampini   jac->setdim             = NULL;
17825272c319SBarry Smith   jac->hmnull             = NULL;
17835272c319SBarry Smith   jac->n_hmnull           = 0;
178416d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1785ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1786bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1787bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
178816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
178916d9e3a6SLisandro Dalcin }
1790ebc551c0SBarry Smith 
1791f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1792f91d8e95SBarry Smith 
1793b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1794af0996ceSBarry Smith #include <petsc/private/matimpl.h>
1795ebc551c0SBarry Smith 
1796ebc551c0SBarry Smith typedef struct {
179768326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1798f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
17999e5bc791SBarry Smith 
18009e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
18014ddd07fcSJed Brown   PetscInt its;
18029e5bc791SBarry Smith   double   tol;
18034ddd07fcSJed Brown   PetscInt relax_type;
18044ddd07fcSJed Brown   PetscInt rap_type;
18054ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
18064ddd07fcSJed Brown   PetscInt max_levels;
1807ebc551c0SBarry Smith } PC_PFMG;
1808ebc551c0SBarry Smith 
1809ebc551c0SBarry Smith #undef __FUNCT__
1810ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1811ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1812ebc551c0SBarry Smith {
1813ebc551c0SBarry Smith   PetscErrorCode ierr;
1814f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1815ebc551c0SBarry Smith 
1816ebc551c0SBarry Smith   PetscFunctionBegin;
18172fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1818f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1819c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1820ebc551c0SBarry Smith   PetscFunctionReturn(0);
1821ebc551c0SBarry Smith }
1822ebc551c0SBarry Smith 
18239e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
18249e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
18259e5bc791SBarry Smith 
1826ebc551c0SBarry Smith #undef __FUNCT__
1827ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1828ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1829ebc551c0SBarry Smith {
1830ebc551c0SBarry Smith   PetscErrorCode ierr;
1831ace3abfcSBarry Smith   PetscBool      iascii;
1832f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1833ebc551c0SBarry Smith 
1834ebc551c0SBarry Smith   PetscFunctionBegin;
1835251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
18369e5bc791SBarry Smith   if (iascii) {
18379e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
18389e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
18399e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
18409e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
18419e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
18429e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
18433b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
18449e5bc791SBarry Smith   }
1845ebc551c0SBarry Smith   PetscFunctionReturn(0);
1846ebc551c0SBarry Smith }
1847ebc551c0SBarry Smith 
18489e5bc791SBarry Smith 
1849ebc551c0SBarry Smith #undef __FUNCT__
1850ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
18518c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptions *PetscOptionsObject,PC pc)
1852ebc551c0SBarry Smith {
1853ebc551c0SBarry Smith   PetscErrorCode ierr;
1854f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1855ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1856ebc551c0SBarry Smith 
1857ebc551c0SBarry Smith   PetscFunctionBegin;
1858e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
18590298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
186068326731SBarry Smith   if (flg) {
1861a0324ebeSBarry Smith     int level=3;
1862fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
186368326731SBarry Smith   }
18640298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1865fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
18660298fd71SBarry 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);
1867fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
18680298fd71SBarry 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);
1869fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
18709e5bc791SBarry Smith 
18710298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
1872fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
18733b46a515SGlenn Hammond 
18740298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1875fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
18760298fd71SBarry 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);
1877fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
18780298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
1879fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1880ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1881ebc551c0SBarry Smith   PetscFunctionReturn(0);
1882ebc551c0SBarry Smith }
1883ebc551c0SBarry Smith 
1884f91d8e95SBarry Smith #undef __FUNCT__
1885f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1886f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1887f91d8e95SBarry Smith {
1888f91d8e95SBarry Smith   PetscErrorCode    ierr;
1889f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
1890d9ca1df4SBarry Smith   PetscScalar       *yy;
1891d9ca1df4SBarry Smith   const PetscScalar *xx;
18924ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
189368326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1894f91d8e95SBarry Smith 
1895f91d8e95SBarry Smith   PetscFunctionBegin;
1896dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1897aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1898f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1899f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1900f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1901f91d8e95SBarry Smith 
1902f91d8e95SBarry Smith   /* copy x values over to hypre */
1903fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1904d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1905d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
1906d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1907fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
1908fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1909f91d8e95SBarry Smith 
1910f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1911f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
19128b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
1913f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1914f91d8e95SBarry Smith   PetscFunctionReturn(0);
1915f91d8e95SBarry Smith }
1916f91d8e95SBarry Smith 
19179e5bc791SBarry Smith #undef __FUNCT__
19189e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1919ace3abfcSBarry 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)
19209e5bc791SBarry Smith {
19219e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
19229e5bc791SBarry Smith   PetscErrorCode ierr;
19234ddd07fcSJed Brown   PetscInt       oits;
19249e5bc791SBarry Smith 
19259e5bc791SBarry Smith   PetscFunctionBegin;
1926dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1927fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1928fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
19299e5bc791SBarry Smith 
19309e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
19318b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
19329e5bc791SBarry Smith   *outits = oits;
19339e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
19349e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1935fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1936fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
19379e5bc791SBarry Smith   PetscFunctionReturn(0);
19389e5bc791SBarry Smith }
19399e5bc791SBarry Smith 
19409e5bc791SBarry Smith 
19413a32d3dbSGlenn Hammond #undef __FUNCT__
19423a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
19433a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
19443a32d3dbSGlenn Hammond {
19453a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
19463a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
19473a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1948ace3abfcSBarry Smith   PetscBool       flg;
19493a32d3dbSGlenn Hammond 
19503a32d3dbSGlenn Hammond   PetscFunctionBegin;
1951251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1952ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
19533a32d3dbSGlenn Hammond 
19543a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
19552fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1956fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1957fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1958fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
19593a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
19603a32d3dbSGlenn Hammond }
19613a32d3dbSGlenn Hammond 
1962ebc551c0SBarry Smith 
1963ebc551c0SBarry Smith /*MC
1964ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1965ebc551c0SBarry Smith 
1966ebc551c0SBarry Smith    Level: advanced
1967ebc551c0SBarry Smith 
19689e5bc791SBarry Smith    Options Database:
19699e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
19709e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
19719e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
19729e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
19739e5bc791SBarry 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
19749e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
1975f91d8e95SBarry Smith 
19769e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
19779e5bc791SBarry Smith 
19788e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
1979aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
19809e5bc791SBarry Smith 
19819e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
1982ebc551c0SBarry Smith M*/
1983ebc551c0SBarry Smith 
1984ebc551c0SBarry Smith #undef __FUNCT__
1985ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
19868cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
1987ebc551c0SBarry Smith {
1988ebc551c0SBarry Smith   PetscErrorCode ierr;
1989ebc551c0SBarry Smith   PC_PFMG        *ex;
1990ebc551c0SBarry Smith 
1991ebc551c0SBarry Smith   PetscFunctionBegin;
1992b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
199368326731SBarry Smith   pc->data = ex;
1994ebc551c0SBarry Smith 
19959e5bc791SBarry Smith   ex->its            = 1;
19969e5bc791SBarry Smith   ex->tol            = 1.e-8;
19979e5bc791SBarry Smith   ex->relax_type     = 1;
19989e5bc791SBarry Smith   ex->rap_type       = 0;
19999e5bc791SBarry Smith   ex->num_pre_relax  = 1;
20009e5bc791SBarry Smith   ex->num_post_relax = 1;
20013b46a515SGlenn Hammond   ex->max_levels     = 0;
20029e5bc791SBarry Smith 
2003ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2004ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2005ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2006f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
20079e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
200868326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
20092fa5cd67SKarl Rupp 
2010ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2011fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2012ebc551c0SBarry Smith   PetscFunctionReturn(0);
2013ebc551c0SBarry Smith }
2014d851a50bSGlenn Hammond 
2015325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2016325fc9f4SBarry Smith 
2017d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2018d851a50bSGlenn Hammond typedef struct {
2019d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2020d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2021d851a50bSGlenn Hammond 
2022d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
20234ddd07fcSJed Brown   PetscInt its;
2024d851a50bSGlenn Hammond   double   tol;
20254ddd07fcSJed Brown   PetscInt relax_type;
20264ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2027d851a50bSGlenn Hammond } PC_SysPFMG;
2028d851a50bSGlenn Hammond 
2029d851a50bSGlenn Hammond #undef __FUNCT__
2030d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
2031d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2032d851a50bSGlenn Hammond {
2033d851a50bSGlenn Hammond   PetscErrorCode ierr;
2034d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2035d851a50bSGlenn Hammond 
2036d851a50bSGlenn Hammond   PetscFunctionBegin;
20372fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2038d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2039c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2040d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2041d851a50bSGlenn Hammond }
2042d851a50bSGlenn Hammond 
2043d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2044d851a50bSGlenn Hammond 
2045d851a50bSGlenn Hammond #undef __FUNCT__
2046d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
2047d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2048d851a50bSGlenn Hammond {
2049d851a50bSGlenn Hammond   PetscErrorCode ierr;
2050ace3abfcSBarry Smith   PetscBool      iascii;
2051d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2052d851a50bSGlenn Hammond 
2053d851a50bSGlenn Hammond   PetscFunctionBegin;
2054251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2055d851a50bSGlenn Hammond   if (iascii) {
2056d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2057d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
2058d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
2059d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2060d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2061d851a50bSGlenn Hammond   }
2062d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2063d851a50bSGlenn Hammond }
2064d851a50bSGlenn Hammond 
2065d851a50bSGlenn Hammond 
2066d851a50bSGlenn Hammond #undef __FUNCT__
2067d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
20688c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptions *PetscOptionsObject,PC pc)
2069d851a50bSGlenn Hammond {
2070d851a50bSGlenn Hammond   PetscErrorCode ierr;
2071d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2072ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2073d851a50bSGlenn Hammond 
2074d851a50bSGlenn Hammond   PetscFunctionBegin;
2075e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
20760298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2077d851a50bSGlenn Hammond   if (flg) {
2078d851a50bSGlenn Hammond     int level=3;
2079fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
2080d851a50bSGlenn Hammond   }
20810298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2082fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
20830298fd71SBarry 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);
2084fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
20850298fd71SBarry 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);
2086fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2087d851a50bSGlenn Hammond 
20880298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2089fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
20900298fd71SBarry 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);
2091fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2092d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2093d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2094d851a50bSGlenn Hammond }
2095d851a50bSGlenn Hammond 
2096d851a50bSGlenn Hammond #undef __FUNCT__
2097d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
2098d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2099d851a50bSGlenn Hammond {
2100d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2101d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2102d9ca1df4SBarry Smith   PetscScalar       *yy;
2103d9ca1df4SBarry Smith   const PetscScalar *xx;
21044ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
2105d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
21064ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
21074ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
21084ddd07fcSJed Brown   PetscInt          part    = 0;
21094ddd07fcSJed Brown   PetscInt          size;
21104ddd07fcSJed Brown   PetscInt          i;
2111d851a50bSGlenn Hammond 
2112d851a50bSGlenn Hammond   PetscFunctionBegin;
2113dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2114aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2115d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2116d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2117d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2118d851a50bSGlenn Hammond 
2119d851a50bSGlenn Hammond   size = 1;
21202fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
21212fa5cd67SKarl Rupp 
2122d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2123d851a50bSGlenn Hammond   if (ordering) {
2124fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2125d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2126d9ca1df4SBarry 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)));
2127d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2128fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2129fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2130fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2131d851a50bSGlenn Hammond 
2132d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2133d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
21348b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2135d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2136a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2137d851a50bSGlenn Hammond     PetscScalar *z;
21384ddd07fcSJed Brown     PetscInt    j, k;
2139d851a50bSGlenn Hammond 
2140785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2141fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2142d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2143d851a50bSGlenn Hammond 
2144d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2145d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2146d851a50bSGlenn Hammond       k= i*nvars;
21472fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2148d851a50bSGlenn Hammond     }
21498b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2150d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2151fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2152fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2153d851a50bSGlenn Hammond 
2154d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2155d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
21568b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2157d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2158d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2159d851a50bSGlenn Hammond       k= i*nvars;
21602fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2161d851a50bSGlenn Hammond     }
2162d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2163d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2164d851a50bSGlenn Hammond   }
2165d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2166d851a50bSGlenn Hammond }
2167d851a50bSGlenn Hammond 
2168d851a50bSGlenn Hammond #undef __FUNCT__
2169d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
2170ace3abfcSBarry 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)
2171d851a50bSGlenn Hammond {
2172d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2173d851a50bSGlenn Hammond   PetscErrorCode ierr;
21744ddd07fcSJed Brown   PetscInt       oits;
2175d851a50bSGlenn Hammond 
2176d851a50bSGlenn Hammond   PetscFunctionBegin;
2177dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2178fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2179fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2180d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
21818b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2182d851a50bSGlenn Hammond   *outits = oits;
2183d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2184d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2185fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2186fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2187d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2188d851a50bSGlenn Hammond }
2189d851a50bSGlenn Hammond 
2190d851a50bSGlenn Hammond 
2191d851a50bSGlenn Hammond #undef __FUNCT__
2192d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
2193d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2194d851a50bSGlenn Hammond {
2195d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2196d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2197d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2198ace3abfcSBarry Smith   PetscBool        flg;
2199d851a50bSGlenn Hammond 
2200d851a50bSGlenn Hammond   PetscFunctionBegin;
2201251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2202ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2203d851a50bSGlenn Hammond 
2204d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
22052fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2206fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2207fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2208fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2209d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2210d851a50bSGlenn Hammond }
2211d851a50bSGlenn Hammond 
2212d851a50bSGlenn Hammond 
2213d851a50bSGlenn Hammond /*MC
2214d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2215d851a50bSGlenn Hammond 
2216d851a50bSGlenn Hammond    Level: advanced
2217d851a50bSGlenn Hammond 
2218d851a50bSGlenn Hammond    Options Database:
2219d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2220d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2221d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2222d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2223d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2224d851a50bSGlenn Hammond 
2225d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
2226d851a50bSGlenn Hammond 
2227f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2228aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2229d851a50bSGlenn Hammond            Also, only cell-centered variables.
2230d851a50bSGlenn Hammond 
2231d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2232d851a50bSGlenn Hammond M*/
2233d851a50bSGlenn Hammond 
2234d851a50bSGlenn Hammond #undef __FUNCT__
2235d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
22368cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2237d851a50bSGlenn Hammond {
2238d851a50bSGlenn Hammond   PetscErrorCode ierr;
2239d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2240d851a50bSGlenn Hammond 
2241d851a50bSGlenn Hammond   PetscFunctionBegin;
2242b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2243d851a50bSGlenn Hammond   pc->data = ex;
2244d851a50bSGlenn Hammond 
2245d851a50bSGlenn Hammond   ex->its            = 1;
2246d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2247d851a50bSGlenn Hammond   ex->relax_type     = 1;
2248d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2249d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2250d851a50bSGlenn Hammond 
2251d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2252d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2253d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2254d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2255d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2256d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
22572fa5cd67SKarl Rupp 
2258ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2259fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2260d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2261d851a50bSGlenn Hammond }
2262