xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision d9ca1df42eda25bc875149d6d493aad6e204c9ff)
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 
8b45d2f2cSJed Brown #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);
2616d9e3a6SLisandro Dalcin 
2716d9e3a6SLisandro Dalcin   MPI_Comm comm_hypre;
2816d9e3a6SLisandro Dalcin   char     *hypre_type;
2916d9e3a6SLisandro Dalcin 
3016d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
314ddd07fcSJed Brown   PetscInt maxiter;
3216d9e3a6SLisandro Dalcin   double   tol;
3316d9e3a6SLisandro Dalcin 
3416d9e3a6SLisandro Dalcin   /* options for Pilut */
354ddd07fcSJed Brown   PetscInt factorrowsize;
3616d9e3a6SLisandro Dalcin 
3716d9e3a6SLisandro Dalcin   /* options for ParaSails */
384ddd07fcSJed Brown   PetscInt nlevels;
3916d9e3a6SLisandro Dalcin   double   threshhold;
4016d9e3a6SLisandro Dalcin   double   filter;
414ddd07fcSJed Brown   PetscInt sym;
4216d9e3a6SLisandro Dalcin   double   loadbal;
434ddd07fcSJed Brown   PetscInt logging;
444ddd07fcSJed Brown   PetscInt ruse;
454ddd07fcSJed Brown   PetscInt symt;
4616d9e3a6SLisandro Dalcin 
4722b6d1caSBarry Smith   /* options for BoomerAMG */
48ace3abfcSBarry Smith   PetscBool printstatistics;
4916d9e3a6SLisandro Dalcin 
5016d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
514ddd07fcSJed Brown   PetscInt  cycletype;
524ddd07fcSJed Brown   PetscInt  maxlevels;
5316d9e3a6SLisandro Dalcin   double    strongthreshold;
5416d9e3a6SLisandro Dalcin   double    maxrowsum;
554ddd07fcSJed Brown   PetscInt  gridsweeps[3];
564ddd07fcSJed Brown   PetscInt  coarsentype;
574ddd07fcSJed Brown   PetscInt  measuretype;
584ddd07fcSJed Brown   PetscInt  relaxtype[3];
5916d9e3a6SLisandro Dalcin   double    relaxweight;
6016d9e3a6SLisandro Dalcin   double    outerrelaxweight;
614ddd07fcSJed Brown   PetscInt  relaxorder;
6216d9e3a6SLisandro Dalcin   double    truncfactor;
63ace3abfcSBarry Smith   PetscBool applyrichardson;
644ddd07fcSJed Brown   PetscInt  pmax;
654ddd07fcSJed Brown   PetscInt  interptype;
664ddd07fcSJed Brown   PetscInt  agg_nl;
674ddd07fcSJed Brown   PetscInt  agg_num_paths;
684ddd07fcSJed Brown   PetscInt  nodal_coarsen;
69ace3abfcSBarry Smith   PetscBool nodal_relax;
704ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
714cb006feSStefano Zampini 
724cb006feSStefano Zampini   /* options for AMS */
734cb006feSStefano Zampini   PetscInt  ams_print;
744cb006feSStefano Zampini   PetscInt  ams_max_iter;
754cb006feSStefano Zampini   PetscInt  ams_cycle_type;
764cb006feSStefano Zampini   PetscReal ams_tol;
774cb006feSStefano Zampini   PetscInt  ams_relax_type;
784cb006feSStefano Zampini   PetscInt  ams_relax_times;
794cb006feSStefano Zampini   PetscReal ams_relax_weight;
804cb006feSStefano Zampini   PetscReal ams_omega;
814cb006feSStefano Zampini   PetscInt  ams_amg_alpha_opts[5]; /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for vector Poisson */
824cb006feSStefano Zampini   PetscReal ams_amg_alpha_theta;   /* AMG strength for vector Poisson */
834cb006feSStefano Zampini   PetscInt  ams_amg_beta_opts[5];  /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for scalar Poisson */
844cb006feSStefano Zampini   PetscReal ams_amg_beta_theta;    /* AMG strength for scalar Poisson */
854cb006feSStefano Zampini 
864cb006feSStefano Zampini   /* additional data */
874cb006feSStefano Zampini   HYPRE_IJVector coords[3];
884cb006feSStefano Zampini   HYPRE_IJVector constants[3];
894cb006feSStefano Zampini   HYPRE_IJMatrix G;
904cb006feSStefano Zampini   HYPRE_IJMatrix alpha_Poisson;
914cb006feSStefano Zampini   HYPRE_IJMatrix beta_Poisson;
924cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
9316d9e3a6SLisandro Dalcin } PC_HYPRE;
9416d9e3a6SLisandro Dalcin 
95d2128fa2SBarry Smith #undef __FUNCT__
96d2128fa2SBarry Smith #define __FUNCT__ "PCHYPREGetSolver"
97d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
98d2128fa2SBarry Smith {
99d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
100d2128fa2SBarry Smith 
101d2128fa2SBarry Smith   PetscFunctionBegin;
102d2128fa2SBarry Smith   *hsolver = jac->hsolver;
103d2128fa2SBarry Smith   PetscFunctionReturn(0);
104d2128fa2SBarry Smith }
10516d9e3a6SLisandro Dalcin 
10616d9e3a6SLisandro Dalcin #undef __FUNCT__
10716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE"
10816d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
10916d9e3a6SLisandro Dalcin {
11016d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11116d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
11216d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
11316d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
11416d9e3a6SLisandro Dalcin   PetscInt           bs;
11516d9e3a6SLisandro Dalcin 
11616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
11716d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
11802a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
11916d9e3a6SLisandro Dalcin   }
1205f5c5b43SBarry Smith 
1215f5c5b43SBarry Smith   if (pc->setupcalled) {
1225f5c5b43SBarry Smith     /* always destroy the old matrix and create a new memory;
1235f5c5b43SBarry Smith        hope this does not churn the memory too much. The problem
1245f5c5b43SBarry Smith        is I do not know if it is possible to put the matrix back to
1255f5c5b43SBarry Smith        its initial state so that we can directly copy the values
1265f5c5b43SBarry Smith        the second time through. */
127fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
1285f5c5b43SBarry Smith     jac->ij = 0;
12916d9e3a6SLisandro Dalcin   }
1305f5c5b43SBarry Smith 
13116d9e3a6SLisandro Dalcin   if (!jac->ij) { /* create the matrix the first time through */
13216d9e3a6SLisandro Dalcin     ierr = MatHYPRE_IJMatrixCreate(pc->pmat,&jac->ij);CHKERRQ(ierr);
13316d9e3a6SLisandro Dalcin   }
13416d9e3a6SLisandro Dalcin   if (!jac->b) { /* create the vectors the first time through */
13516d9e3a6SLisandro Dalcin     Vec x,b;
1362a7a6963SBarry Smith     ierr = MatCreateVecs(pc->pmat,&x,&b);CHKERRQ(ierr);
13716d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(x,&jac->x);CHKERRQ(ierr);
13816d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(b,&jac->b);CHKERRQ(ierr);
1396bf464f9SBarry Smith     ierr = VecDestroy(&x);CHKERRQ(ierr);
1406bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
14116d9e3a6SLisandro Dalcin   }
1425f5c5b43SBarry Smith 
14316d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
14416d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
14516d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1462fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
1474cb006feSStefano Zampini   }
1484cb006feSStefano Zampini   /* special case for AMS */
1494cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
1504cb006feSStefano 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()");
1514cb006feSStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
1524cb006feSStefano Zampini   }
15316d9e3a6SLisandro Dalcin   ierr = MatHYPRE_IJMatrixCopy(pc->pmat,jac->ij);CHKERRQ(ierr);
154fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
155fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&bv));
156fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&xv));
157fd3f9acdSBarry Smith   PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr););
15816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
15916d9e3a6SLisandro Dalcin }
16016d9e3a6SLisandro Dalcin 
16116d9e3a6SLisandro Dalcin /*
16216d9e3a6SLisandro Dalcin     Replaces the address where the HYPRE vector points to its data with the address of
16316d9e3a6SLisandro Dalcin   PETSc's data. Saves the old address so it can be reset when we are finished with it.
16416d9e3a6SLisandro Dalcin   Allows use to get the data into a HYPRE vector without the cost of memcopies
16516d9e3a6SLisandro Dalcin */
16616d9e3a6SLisandro Dalcin #define HYPREReplacePointer(b,newvalue,savedvalue) { \
16716d9e3a6SLisandro Dalcin     hypre_ParVector *par_vector   = (hypre_ParVector*)hypre_IJVectorObject(((hypre_IJVector*)b)); \
16816d9e3a6SLisandro Dalcin     hypre_Vector    *local_vector = hypre_ParVectorLocalVector(par_vector); \
16916d9e3a6SLisandro Dalcin     savedvalue         = local_vector->data; \
1700ad7597dSKarl Rupp     local_vector->data = newvalue;          \
1710ad7597dSKarl Rupp }
17216d9e3a6SLisandro Dalcin 
17316d9e3a6SLisandro Dalcin #undef __FUNCT__
17416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE"
17516d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
17616d9e3a6SLisandro Dalcin {
17716d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
17816d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
17916d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
180*d9ca1df4SBarry Smith   PetscScalar        *xv;
181*d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
18216d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
183*d9ca1df4SBarry Smith   PetscScalar        *sxv;
1844ddd07fcSJed Brown   PetscInt           hierr;
18516d9e3a6SLisandro Dalcin 
18616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
187dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
18816d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
189*d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
19016d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
191*d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
19216d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
19316d9e3a6SLisandro Dalcin 
194fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
195fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
196fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
197fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
19865e19b50SBarry Smith                                if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
199fd3f9acdSBarry Smith                                if (hierr) hypre__global_error = 0;);
20016d9e3a6SLisandro Dalcin 
201*d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)sbv,bv);
20216d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
20316d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
204*d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
20516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
20616d9e3a6SLisandro Dalcin }
20716d9e3a6SLisandro Dalcin 
20816d9e3a6SLisandro Dalcin #undef __FUNCT__
20916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE"
21016d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
21116d9e3a6SLisandro Dalcin {
21216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
21316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
21416d9e3a6SLisandro Dalcin 
21516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
216fd3f9acdSBarry Smith   if (jac->ij) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
217fd3f9acdSBarry Smith   if (jac->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->b));
218fd3f9acdSBarry Smith   if (jac->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->x));
2194cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
2204cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
2214cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
2224cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
2234cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
2244cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
2254cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
2264cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
2274cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
228226b0620SJed Brown   if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr););
229503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
23016d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
231c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
23216d9e3a6SLisandro Dalcin 
23316d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
234bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
235bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
2364cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
2374cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
2384cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
2394cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",NULL);CHKERRQ(ierr);
2404cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",NULL);CHKERRQ(ierr);
24116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
24216d9e3a6SLisandro Dalcin }
24316d9e3a6SLisandro Dalcin 
24416d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
24516d9e3a6SLisandro Dalcin #undef __FUNCT__
24616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut"
2478c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptions *PetscOptionsObject,PC pc)
24816d9e3a6SLisandro Dalcin {
24916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
25016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
251ace3abfcSBarry Smith   PetscBool      flag;
25216d9e3a6SLisandro Dalcin 
25316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
254e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
25516d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
256fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
25716d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
258fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
25916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
260fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
26116d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
26216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
26316d9e3a6SLisandro Dalcin }
26416d9e3a6SLisandro Dalcin 
26516d9e3a6SLisandro Dalcin #undef __FUNCT__
26616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut"
26716d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
26816d9e3a6SLisandro Dalcin {
26916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
27016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
271ace3abfcSBarry Smith   PetscBool      iascii;
27216d9e3a6SLisandro Dalcin 
27316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
274251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
27516d9e3a6SLisandro Dalcin   if (iascii) {
27616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
27716d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
27816d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
27916d9e3a6SLisandro Dalcin     } else {
28016d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr);
28116d9e3a6SLisandro Dalcin     }
28216d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
28357622a8eSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
28416d9e3a6SLisandro Dalcin     } else {
28516d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr);
28616d9e3a6SLisandro Dalcin     }
28716d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
28816d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
28916d9e3a6SLisandro Dalcin     } else {
29016d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default factor row size \n");CHKERRQ(ierr);
29116d9e3a6SLisandro Dalcin     }
29216d9e3a6SLisandro Dalcin   }
29316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
29416d9e3a6SLisandro Dalcin }
29516d9e3a6SLisandro Dalcin 
29616d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
29716d9e3a6SLisandro Dalcin 
29816d9e3a6SLisandro Dalcin #undef __FUNCT__
29916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG"
30016d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
30116d9e3a6SLisandro Dalcin {
30216d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
30316d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
30416d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
305*d9ca1df4SBarry Smith   PetscScalar        *xv;
306*d9ca1df4SBarry Smith   const PetscScalar  *bv;
30716d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
30816d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
3094ddd07fcSJed Brown   PetscInt           hierr;
31016d9e3a6SLisandro Dalcin 
31116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
312dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
31316d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
314*d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
31516d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
316*d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
31716d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
31816d9e3a6SLisandro Dalcin 
319fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
320fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
321fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
32216d9e3a6SLisandro Dalcin 
32316d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
32416d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
325e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
32616d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
32716d9e3a6SLisandro Dalcin 
32816d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
32916d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
33016d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
331*d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
33216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
33316d9e3a6SLisandro Dalcin }
33416d9e3a6SLisandro Dalcin 
335a669f990SJed Brown /* static array length */
336a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
337a669f990SJed Brown 
33816d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
3390f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
34016d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
34165de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
34265de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
34365de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
34465de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
34565de4495SJed Brown                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */,
34665de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
3470f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
3480f1074feSSatish Balay                                                   "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"};
34916d9e3a6SLisandro Dalcin #undef __FUNCT__
35016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG"
3518c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptions *PetscOptionsObject,PC pc)
35216d9e3a6SLisandro Dalcin {
35316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
35416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
3554ddd07fcSJed Brown   PetscInt       n,indx,level;
356ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
35716d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
35816d9e3a6SLisandro Dalcin 
35916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
360e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
3614336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
36216d9e3a6SLisandro Dalcin   if (flg) {
3634336a9eeSBarry Smith     jac->cycletype = indx+1;
364fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
36516d9e3a6SLisandro Dalcin   }
36616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
36716d9e3a6SLisandro Dalcin   if (flg) {
368ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
369fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
37016d9e3a6SLisandro Dalcin   }
37116d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
37216d9e3a6SLisandro Dalcin   if (flg) {
373ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
374fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
37516d9e3a6SLisandro Dalcin   }
3760f1074feSSatish 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);
37716d9e3a6SLisandro Dalcin   if (flg) {
37857622a8eSBarry 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);
379fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
38016d9e3a6SLisandro Dalcin   }
38116d9e3a6SLisandro Dalcin 
3820f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
38316d9e3a6SLisandro Dalcin   if (flg) {
38457622a8eSBarry 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);
385fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
38616d9e3a6SLisandro Dalcin   }
38716d9e3a6SLisandro Dalcin 
3880f1074feSSatish 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);
3890f1074feSSatish Balay   if (flg) {
39057622a8eSBarry 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);
391fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
3920f1074feSSatish Balay   }
3930f1074feSSatish Balay 
3940f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
3950f1074feSSatish Balay   if (flg) {
39657622a8eSBarry 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);
3970f1074feSSatish Balay 
398fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
3990f1074feSSatish Balay   }
4000f1074feSSatish Balay 
4010f1074feSSatish Balay 
4020f1074feSSatish 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);
4030f1074feSSatish Balay   if (flg) {
40457622a8eSBarry 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);
4050f1074feSSatish Balay 
406fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
4070f1074feSSatish Balay   }
4080f1074feSSatish Balay 
4090f1074feSSatish Balay 
41016d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
41116d9e3a6SLisandro Dalcin   if (flg) {
41257622a8eSBarry 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);
413fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
41416d9e3a6SLisandro Dalcin   }
41516d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
41616d9e3a6SLisandro Dalcin   if (flg) {
41757622a8eSBarry 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);
41857622a8eSBarry 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);
419fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
42016d9e3a6SLisandro Dalcin   }
42116d9e3a6SLisandro Dalcin 
42216d9e3a6SLisandro Dalcin   /* Grid sweeps */
4230f1074feSSatish 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);
42416d9e3a6SLisandro Dalcin   if (flg) {
425fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
42616d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
42716d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
4280f1074feSSatish Balay     jac->gridsweeps[1] = indx;
4290f1074feSSatish Balay     /*defaults coarse to 1 */
4300f1074feSSatish Balay     jac->gridsweeps[2] = 1;
43116d9e3a6SLisandro Dalcin   }
4320f1074feSSatish Balay 
4330f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
43416d9e3a6SLisandro Dalcin   if (flg) {
435fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
4360f1074feSSatish Balay     jac->gridsweeps[0] = indx;
43716d9e3a6SLisandro Dalcin   }
43816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
43916d9e3a6SLisandro Dalcin   if (flg) {
440fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
4410f1074feSSatish Balay     jac->gridsweeps[1] = indx;
44216d9e3a6SLisandro Dalcin   }
4430f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
44416d9e3a6SLisandro Dalcin   if (flg) {
445fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
4460f1074feSSatish Balay     jac->gridsweeps[2] = indx;
44716d9e3a6SLisandro Dalcin   }
44816d9e3a6SLisandro Dalcin 
44916d9e3a6SLisandro Dalcin   /* Relax type */
450a669f990SJed 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);
45116d9e3a6SLisandro Dalcin   if (flg) {
4520f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
453fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
4540f1074feSSatish Balay     /* by default, coarse type set to 9 */
4550f1074feSSatish Balay     jac->relaxtype[2] = 9;
4560f1074feSSatish Balay 
45716d9e3a6SLisandro Dalcin   }
458a669f990SJed 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);
45916d9e3a6SLisandro Dalcin   if (flg) {
46016d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
461fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
46216d9e3a6SLisandro Dalcin   }
463a669f990SJed 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);
46416d9e3a6SLisandro Dalcin   if (flg) {
4650f1074feSSatish Balay     jac->relaxtype[1] = indx;
466fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
46716d9e3a6SLisandro Dalcin   }
468a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
46916d9e3a6SLisandro Dalcin   if (flg) {
4700f1074feSSatish Balay     jac->relaxtype[2] = indx;
471fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
47216d9e3a6SLisandro Dalcin   }
47316d9e3a6SLisandro Dalcin 
47416d9e3a6SLisandro Dalcin   /* Relaxation Weight */
47516d9e3a6SLisandro 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);
47616d9e3a6SLisandro Dalcin   if (flg) {
477fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
47816d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
47916d9e3a6SLisandro Dalcin   }
48016d9e3a6SLisandro Dalcin 
48116d9e3a6SLisandro Dalcin   n         = 2;
48216d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
48316d9e3a6SLisandro 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);
48416d9e3a6SLisandro Dalcin   if (flg) {
48516d9e3a6SLisandro Dalcin     if (n == 2) {
48616d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
487fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
488ce94432eSBarry 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);
48916d9e3a6SLisandro Dalcin   }
49016d9e3a6SLisandro Dalcin 
49116d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
49216d9e3a6SLisandro 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);
49316d9e3a6SLisandro Dalcin   if (flg) {
494fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
49516d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
49616d9e3a6SLisandro Dalcin   }
49716d9e3a6SLisandro Dalcin 
49816d9e3a6SLisandro Dalcin   n         = 2;
49916d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
50016d9e3a6SLisandro 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);
50116d9e3a6SLisandro Dalcin   if (flg) {
50216d9e3a6SLisandro Dalcin     if (n == 2) {
50316d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
504fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
505ce94432eSBarry 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);
50616d9e3a6SLisandro Dalcin   }
50716d9e3a6SLisandro Dalcin 
50816d9e3a6SLisandro Dalcin   /* the Relax Order */
509acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
51016d9e3a6SLisandro Dalcin 
5118afaa268SBarry Smith   if (flg && tmp_truth) {
51216d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
513fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
51416d9e3a6SLisandro Dalcin   }
515a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
51616d9e3a6SLisandro Dalcin   if (flg) {
51716d9e3a6SLisandro Dalcin     jac->measuretype = indx;
518fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
51916d9e3a6SLisandro Dalcin   }
5200f1074feSSatish Balay   /* update list length 3/07 */
521a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
52216d9e3a6SLisandro Dalcin   if (flg) {
52316d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
524fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
52516d9e3a6SLisandro Dalcin   }
5260f1074feSSatish Balay 
5270f1074feSSatish Balay   /* new 3/07 */
528a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
5290f1074feSSatish Balay   if (flg) {
5300f1074feSSatish Balay     jac->interptype = indx;
531fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
5320f1074feSSatish Balay   }
5330f1074feSSatish Balay 
534b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
53516d9e3a6SLisandro Dalcin   if (flg) {
536b96a4a96SBarry Smith     level = 3;
5370298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
5382fa5cd67SKarl Rupp 
539b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
540fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
5412ae77aedSBarry Smith   }
5422ae77aedSBarry Smith 
543b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
5442ae77aedSBarry Smith   if (flg) {
545b96a4a96SBarry Smith     level = 3;
5460298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
5472fa5cd67SKarl Rupp 
548b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
549fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
55016d9e3a6SLisandro Dalcin   }
5518f87f92bSBarry Smith 
5528afaa268SBarry Smith   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_coarsen", "HYPRE_BoomerAMGSetNodal()", "None", jac->nodal_coarsen ? PETSC_TRUE : PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5538f87f92bSBarry Smith   if (flg && tmp_truth) {
5548f87f92bSBarry Smith     jac->nodal_coarsen = 1;
555fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,1));
5568f87f92bSBarry Smith   }
5578f87f92bSBarry Smith 
558acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5598f87f92bSBarry Smith   if (flg && tmp_truth) {
5608f87f92bSBarry Smith     PetscInt tmp_int;
5618f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
5628f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
563fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
564fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
565fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
566fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
5678f87f92bSBarry Smith   }
5688f87f92bSBarry Smith 
56916d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
57016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
57116d9e3a6SLisandro Dalcin }
57216d9e3a6SLisandro Dalcin 
57316d9e3a6SLisandro Dalcin #undef __FUNCT__
57416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG"
575ace3abfcSBarry 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)
57616d9e3a6SLisandro Dalcin {
57716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
57816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
5794ddd07fcSJed Brown   PetscInt       oits;
58016d9e3a6SLisandro Dalcin 
58116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
582dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
583fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
584fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
58516d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
58616d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
58716d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
5888b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
5894d0a8057SBarry Smith   *outits = oits;
5904d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
5914d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
592fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
593fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
59416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
59516d9e3a6SLisandro Dalcin }
59616d9e3a6SLisandro Dalcin 
59716d9e3a6SLisandro Dalcin 
59816d9e3a6SLisandro Dalcin #undef __FUNCT__
59916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG"
60016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
60116d9e3a6SLisandro Dalcin {
60216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
60316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
604ace3abfcSBarry Smith   PetscBool      iascii;
60516d9e3a6SLisandro Dalcin 
60616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
607251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
60816d9e3a6SLisandro Dalcin   if (iascii) {
60916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
61016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
61116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
61216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
61357622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
61457622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
61557622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
6160f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
6170f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
6180f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
6190f1074feSSatish Balay 
62057622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
62116d9e3a6SLisandro Dalcin 
6220f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
6230f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
6240f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
62516d9e3a6SLisandro Dalcin 
6260f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
6270f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
6280f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
62916d9e3a6SLisandro Dalcin 
63057622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
63157622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
63216d9e3a6SLisandro Dalcin 
63316d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
63416d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr);
63516d9e3a6SLisandro Dalcin     } else {
63616d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr);
63716d9e3a6SLisandro Dalcin     }
63816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
63916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
6400f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
6418f87f92bSBarry Smith     if (jac->nodal_coarsen) {
6428f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal())\n");CHKERRQ(ierr);
6438f87f92bSBarry Smith     }
6448f87f92bSBarry Smith     if (jac->nodal_relax) {
6458f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
6468f87f92bSBarry Smith     }
64716d9e3a6SLisandro Dalcin   }
64816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
64916d9e3a6SLisandro Dalcin }
65016d9e3a6SLisandro Dalcin 
65116d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
65216d9e3a6SLisandro Dalcin #undef __FUNCT__
65316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails"
6548c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptions *PetscOptionsObject,PC pc)
65516d9e3a6SLisandro Dalcin {
65616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
65716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
6584ddd07fcSJed Brown   PetscInt       indx;
659ace3abfcSBarry Smith   PetscBool      flag;
66016d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
66116d9e3a6SLisandro Dalcin 
66216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
663e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
66416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
66516d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
6662fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
66716d9e3a6SLisandro Dalcin 
66816d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
6692fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
67016d9e3a6SLisandro Dalcin 
67116d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
6722fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
67316d9e3a6SLisandro Dalcin 
674acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
6752fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
67616d9e3a6SLisandro Dalcin 
677acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
6782fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
67916d9e3a6SLisandro Dalcin 
680a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
68116d9e3a6SLisandro Dalcin   if (flag) {
68216d9e3a6SLisandro Dalcin     jac->symt = indx;
683fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
68416d9e3a6SLisandro Dalcin   }
68516d9e3a6SLisandro Dalcin 
68616d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
68716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
68816d9e3a6SLisandro Dalcin }
68916d9e3a6SLisandro Dalcin 
69016d9e3a6SLisandro Dalcin #undef __FUNCT__
69116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails"
69216d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
69316d9e3a6SLisandro Dalcin {
69416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
69516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
696ace3abfcSBarry Smith   PetscBool      iascii;
69716d9e3a6SLisandro Dalcin   const char     *symt = 0;;
69816d9e3a6SLisandro Dalcin 
69916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
700251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
70116d9e3a6SLisandro Dalcin   if (iascii) {
70216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
70316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
70457622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
70557622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: filter %g\n",(double)jac->filter);CHKERRQ(ierr);
70657622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
707ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
708ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
7092fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
7102fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
7112fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
712ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
71316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr);
71416d9e3a6SLisandro Dalcin   }
71516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
71616d9e3a6SLisandro Dalcin }
7174cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
7184cb006feSStefano Zampini #undef __FUNCT__
7194cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS"
7209fa463a7SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptions *PetscOptionsObject,PC pc)
7214cb006feSStefano Zampini {
7224cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
7234cb006feSStefano Zampini   PetscErrorCode ierr;
7244cb006feSStefano Zampini   PetscInt       n;
7254cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
7264cb006feSStefano Zampini 
7274cb006feSStefano Zampini   PetscFunctionBegin;
7289fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
7294cb006feSStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->ams_print,&jac->ams_print,&flag);CHKERRQ(ierr);
7304cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->ams_print));
7314cb006feSStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_max_iter","Maximum number of AMS multigrid iterations within PCApply","None",jac->ams_max_iter,&jac->ams_max_iter,&flag);CHKERRQ(ierr);
7324cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->ams_max_iter));
7334cb006feSStefano 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);
7344cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
7354cb006feSStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->ams_tol,&jac->ams_tol,&flag);CHKERRQ(ierr);
7364cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->ams_tol));
7374cb006feSStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_relax_type","Relaxation type for AMS smoother","None",jac->ams_relax_type,&jac->ams_relax_type,&flag);CHKERRQ(ierr);
7384cb006feSStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_relax_times","Number of relaxation steps for AMS smoother","None",jac->ams_relax_times,&jac->ams_relax_times,&flag2);CHKERRQ(ierr);
7394cb006feSStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_relax_weight","Relaxation weight for AMS smoother","None",jac->ams_relax_weight,&jac->ams_relax_weight,&flag3);CHKERRQ(ierr);
7404cb006feSStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->ams_omega,&jac->ams_omega,&flag4);CHKERRQ(ierr);
7414cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
7424cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->ams_relax_type,
7434cb006feSStefano Zampini                                                                       jac->ams_relax_times,
7444cb006feSStefano Zampini                                                                       jac->ams_relax_weight,
7454cb006feSStefano Zampini                                                                       jac->ams_omega));
7464cb006feSStefano Zampini   }
7474cb006feSStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_amg_alpha_theta","Threshold for strong coupling of vector Poisson AMG solver","None",jac->ams_amg_alpha_theta,&jac->ams_amg_alpha_theta,&flag);CHKERRQ(ierr);
7484cb006feSStefano Zampini   n = 5;
7494cb006feSStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->ams_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
7504cb006feSStefano Zampini   if (flag || flag2) {
7514cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->ams_amg_alpha_opts[0],       /* AMG coarsen type */
7524cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[1],       /* AMG agg_levels */
7534cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[2],       /* AMG relax_type */
7544cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_theta,
7554cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[3],       /* AMG interp_type */
7564cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[4]));     /* AMG Pmax */
7574cb006feSStefano Zampini   }
7584cb006feSStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_amg_beta_theta","Threshold for strong coupling of scalar Poisson AMG solver","None",jac->ams_amg_beta_theta,&jac->ams_amg_beta_theta,&flag);CHKERRQ(ierr);
7594cb006feSStefano Zampini   n = 5;
7604cb006feSStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_beta_options","AMG options for scalar Poisson solver","None",jac->ams_amg_beta_opts,&n,&flag2);CHKERRQ(ierr);
7614cb006feSStefano Zampini   if (flag || flag2) {
7624cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->ams_amg_beta_opts[0],       /* AMG coarsen type */
7634cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[1],       /* AMG agg_levels */
7644cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[2],       /* AMG relax_type */
7654cb006feSStefano Zampini                                                                     jac->ams_amg_beta_theta,
7664cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[3],       /* AMG interp_type */
7674cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[4]));     /* AMG Pmax */
7684cb006feSStefano Zampini   }
7694cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
7704cb006feSStefano Zampini   PetscFunctionReturn(0);
7714cb006feSStefano Zampini }
7724cb006feSStefano Zampini 
7734cb006feSStefano Zampini #undef __FUNCT__
7744cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS"
7754cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
7764cb006feSStefano Zampini {
7774cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
7784cb006feSStefano Zampini   PetscErrorCode ierr;
7794cb006feSStefano Zampini   PetscBool      iascii;
7804cb006feSStefano Zampini 
7814cb006feSStefano Zampini   PetscFunctionBegin;
7824cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
7834cb006feSStefano Zampini   if (iascii) {
7844cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
7854cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iterations per application %d\n",jac->ams_max_iter);CHKERRQ(ierr);
7864cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
7874cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iteration tolerance %g\n",jac->ams_tol);CHKERRQ(ierr);
7884cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother type %d\n",jac->ams_relax_type);CHKERRQ(ierr);
7894cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: number of smoothing steps %d\n",jac->ams_relax_times);CHKERRQ(ierr);
7904cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother weight %g\n",jac->ams_relax_weight);CHKERRQ(ierr);
7914cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother omega %g\n",jac->ams_omega);CHKERRQ(ierr);
7924cb006feSStefano Zampini     if (jac->alpha_Poisson) {
7934cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
7944cb006feSStefano Zampini     } else {
7954cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr);
7964cb006feSStefano Zampini     }
7974cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->ams_amg_alpha_opts[0]);CHKERRQ(ierr);
7984cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->ams_amg_alpha_opts[1]);CHKERRQ(ierr);
7994cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->ams_amg_alpha_opts[2]);CHKERRQ(ierr);
8004cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->ams_amg_alpha_opts[3]);CHKERRQ(ierr);
8014cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->ams_amg_alpha_opts[4]);CHKERRQ(ierr);
8024cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->ams_amg_alpha_theta);CHKERRQ(ierr);
8034cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
8044cb006feSStefano Zampini       if (jac->beta_Poisson) {
8054cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8064cb006feSStefano Zampini       } else {
8074cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr);
8084cb006feSStefano Zampini       }
8094cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->ams_amg_beta_opts[0]);CHKERRQ(ierr);
8104cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->ams_amg_beta_opts[1]);CHKERRQ(ierr);
8114cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->ams_amg_beta_opts[2]);CHKERRQ(ierr);
8124cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->ams_amg_beta_opts[3]);CHKERRQ(ierr);
8134cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->ams_amg_beta_opts[4]);CHKERRQ(ierr);
8144cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->ams_amg_beta_theta);CHKERRQ(ierr);
8154cb006feSStefano Zampini     }
8164cb006feSStefano Zampini   }
8174cb006feSStefano Zampini   PetscFunctionReturn(0);
8184cb006feSStefano Zampini }
8194cb006feSStefano Zampini 
8204cb006feSStefano Zampini #undef __FUNCT__
8214cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE_AMS"
8224cb006feSStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE_AMS(PC pc, Mat G)
8234cb006feSStefano Zampini {
8244cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
8254cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_G;
8264cb006feSStefano Zampini   PetscErrorCode     ierr;
8274cb006feSStefano Zampini 
8284cb006feSStefano Zampini   PetscFunctionBegin;
8294cb006feSStefano Zampini   /* throw away any discrete gradient if already set */
8304cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
8314cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(G,&jac->G);CHKERRQ(ierr);
8324cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(G,jac->G);CHKERRQ(ierr);
8334cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->G,(void**)(&parcsr_G)));
8344cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr_G));
8354cb006feSStefano Zampini   PetscFunctionReturn(0);
8364cb006feSStefano Zampini }
8374cb006feSStefano Zampini 
8384cb006feSStefano Zampini #undef __FUNCT__
8394cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient"
8404cb006feSStefano Zampini /*@
8414cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
8424cb006feSStefano Zampini 
8434cb006feSStefano Zampini    Collective on PC
8444cb006feSStefano Zampini 
8454cb006feSStefano Zampini    Input Parameters:
8464cb006feSStefano Zampini +  pc - the preconditioning context
8474cb006feSStefano Zampini -  G - the discrete gradient
8484cb006feSStefano Zampini 
8494cb006feSStefano Zampini    Level: intermediate
8504cb006feSStefano Zampini 
8514cb006feSStefano 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
8524cb006feSStefano Zampini           Each row of G has 2 nonzeros, with column indexes being the global indexes of edge's endpoints: matrix values are +1 and -1 depending on edge orientation
8534cb006feSStefano Zampini 
8544cb006feSStefano Zampini .seealso:
8554cb006feSStefano Zampini @*/
8564cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
8574cb006feSStefano Zampini {
8584cb006feSStefano Zampini   PetscErrorCode ierr;
8594cb006feSStefano Zampini 
8604cb006feSStefano Zampini   PetscFunctionBegin;
8614cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
8624cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
8634cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
8644cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
8654cb006feSStefano Zampini   PetscFunctionReturn(0);
8664cb006feSStefano Zampini }
8674cb006feSStefano Zampini 
8684cb006feSStefano Zampini #undef __FUNCT__
8694cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS"
8704cb006feSStefano Zampini static PetscErrorCode PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
8714cb006feSStefano Zampini {
8724cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
8734cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_alpha_Poisson;
8744cb006feSStefano Zampini   PetscErrorCode     ierr;
8754cb006feSStefano Zampini 
8764cb006feSStefano Zampini   PetscFunctionBegin;
8774cb006feSStefano Zampini   /* throw away any matrix if already set */
8784cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
8794cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->alpha_Poisson);CHKERRQ(ierr);
8804cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->alpha_Poisson);CHKERRQ(ierr);
8814cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->alpha_Poisson,(void**)(&parcsr_alpha_Poisson)));
8824cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr_alpha_Poisson));
8834cb006feSStefano Zampini   PetscFunctionReturn(0);
8844cb006feSStefano Zampini }
8854cb006feSStefano Zampini 
8864cb006feSStefano Zampini #undef __FUNCT__
8874cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix"
8884cb006feSStefano Zampini /*@
8894cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
8904cb006feSStefano Zampini 
8914cb006feSStefano Zampini    Collective on PC
8924cb006feSStefano Zampini 
8934cb006feSStefano Zampini    Input Parameters:
8944cb006feSStefano Zampini +  pc - the preconditioning context
8954cb006feSStefano Zampini -  A - the matrix
8964cb006feSStefano Zampini 
8974cb006feSStefano Zampini    Level: intermediate
8984cb006feSStefano Zampini 
8994cb006feSStefano Zampini    Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
9004cb006feSStefano Zampini 
9014cb006feSStefano Zampini .seealso:
9024cb006feSStefano Zampini @*/
9034cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
9044cb006feSStefano Zampini {
9054cb006feSStefano Zampini   PetscErrorCode ierr;
9064cb006feSStefano Zampini 
9074cb006feSStefano Zampini   PetscFunctionBegin;
9084cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
9094cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
9104cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
9114cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetAlphaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
9124cb006feSStefano Zampini   PetscFunctionReturn(0);
9134cb006feSStefano Zampini }
9144cb006feSStefano Zampini 
9154cb006feSStefano Zampini #undef __FUNCT__
9164cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix_HYPRE_AMS"
9174cb006feSStefano Zampini static PetscErrorCode PCHYPRESetBetaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
9184cb006feSStefano Zampini {
9194cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
9204cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_beta_Poisson;
9214cb006feSStefano Zampini   PetscErrorCode     ierr;
9224cb006feSStefano Zampini 
9234cb006feSStefano Zampini   PetscFunctionBegin;
9244cb006feSStefano Zampini   if (!A) {
9254cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_TRUE;
9264cb006feSStefano Zampini     PetscFunctionReturn(0);
9274cb006feSStefano Zampini   }
9284cb006feSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
9294cb006feSStefano Zampini   /* throw away any matrix if already set */
9304cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
9314cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->beta_Poisson);CHKERRQ(ierr);
9324cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->beta_Poisson);CHKERRQ(ierr);
9334cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->beta_Poisson,(void**)(&parcsr_beta_Poisson)));
9344cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr_beta_Poisson));
9354cb006feSStefano Zampini   PetscFunctionReturn(0);
9364cb006feSStefano Zampini }
9374cb006feSStefano Zampini 
9384cb006feSStefano Zampini #undef __FUNCT__
9394cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix"
9404cb006feSStefano Zampini /*@
9414cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
9424cb006feSStefano Zampini 
9434cb006feSStefano Zampini    Collective on PC
9444cb006feSStefano Zampini 
9454cb006feSStefano Zampini    Input Parameters:
9464cb006feSStefano Zampini +  pc - the preconditioning context
9474cb006feSStefano Zampini -  A - the matrix
9484cb006feSStefano Zampini 
9494cb006feSStefano Zampini    Level: intermediate
9504cb006feSStefano Zampini 
9514cb006feSStefano Zampini    Notes: A should be obtained by discretizing the Poisson problem with linear finite elements.
9524cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
9534cb006feSStefano Zampini 
9544cb006feSStefano Zampini .seealso:
9554cb006feSStefano Zampini @*/
9564cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
9574cb006feSStefano Zampini {
9584cb006feSStefano Zampini   PetscErrorCode ierr;
9594cb006feSStefano Zampini 
9604cb006feSStefano Zampini   PetscFunctionBegin;
9614cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
9624cb006feSStefano Zampini   if (A) {
9634cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
9644cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
9654cb006feSStefano Zampini   }
9664cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetBetaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
9674cb006feSStefano Zampini   PetscFunctionReturn(0);
9684cb006feSStefano Zampini }
9694cb006feSStefano Zampini 
9704cb006feSStefano Zampini #undef __FUNCT__
9714cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE_AMS"
9724cb006feSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE_AMS(PC pc,Vec ozz, Vec zoz, Vec zzo)
9734cb006feSStefano Zampini {
9744cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
9754cb006feSStefano Zampini   HYPRE_ParVector    par_ozz,par_zoz,par_zzo;
97612ddd1b6SStefano Zampini   PetscInt           dim;
9774cb006feSStefano Zampini   PetscErrorCode     ierr;
9784cb006feSStefano Zampini 
9794cb006feSStefano Zampini   PetscFunctionBegin;
9804cb006feSStefano Zampini   /* throw away any vector if already set */
9814cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
9824cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
9834cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
9844cb006feSStefano Zampini   jac->constants[0] = NULL;
9854cb006feSStefano Zampini   jac->constants[1] = NULL;
9864cb006feSStefano Zampini   jac->constants[2] = NULL;
9874cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
9884cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
9894cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&par_ozz)));
9904cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
9914cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
9924cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&par_zoz)));
99312ddd1b6SStefano Zampini   dim = 2;
9944cb006feSStefano Zampini   if (zzo) {
9954cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
9964cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
9974cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&par_zzo)));
99812ddd1b6SStefano Zampini     dim++;
9994cb006feSStefano Zampini   }
10004cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,par_ozz,par_zoz,par_zzo));
100112ddd1b6SStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim));
10024cb006feSStefano Zampini   PetscFunctionReturn(0);
10034cb006feSStefano Zampini }
10044cb006feSStefano Zampini 
10054cb006feSStefano Zampini #undef __FUNCT__
10064cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors"
10074cb006feSStefano Zampini /*@
10084cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
10094cb006feSStefano Zampini 
10104cb006feSStefano Zampini    Collective on PC
10114cb006feSStefano Zampini 
10124cb006feSStefano Zampini    Input Parameters:
10134cb006feSStefano Zampini +  pc - the preconditioning context
10144cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
10154cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
10164cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
10174cb006feSStefano Zampini 
10184cb006feSStefano Zampini    Level: intermediate
10194cb006feSStefano Zampini 
10204cb006feSStefano Zampini    Notes:
10214cb006feSStefano Zampini 
10224cb006feSStefano Zampini .seealso:
10234cb006feSStefano Zampini @*/
10244cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
10254cb006feSStefano Zampini {
10264cb006feSStefano Zampini   PetscErrorCode ierr;
10274cb006feSStefano Zampini 
10284cb006feSStefano Zampini   PetscFunctionBegin;
10294cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
10304cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
10314cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
10324cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
10334cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
10344cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
10354cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
10364cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
10374cb006feSStefano Zampini   PetscFunctionReturn(0);
10384cb006feSStefano Zampini }
10394cb006feSStefano Zampini 
10404cb006feSStefano Zampini #undef __FUNCT__
10414cb006feSStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE_AMS"
10424cb006feSStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE_AMS(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
10434cb006feSStefano Zampini {
10444cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
10454cb006feSStefano Zampini   Vec             tv;
10464cb006feSStefano Zampini   HYPRE_ParVector par_coords[3];
10474cb006feSStefano Zampini   PetscInt        i;
10484cb006feSStefano Zampini   PetscErrorCode  ierr;
10494cb006feSStefano Zampini 
10504cb006feSStefano Zampini   PetscFunctionBegin;
10514cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
10524cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
10534cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
10544cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
10554cb006feSStefano Zampini   /* set problem's dimension */
10564cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim));
10574cb006feSStefano Zampini   /* compute IJ vector for coordinates */
10584cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
10594cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
10604cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
10614cb006feSStefano Zampini   for (i=0;i<dim;i++) {
10624cb006feSStefano Zampini     PetscScalar *array;
10634cb006feSStefano Zampini     PetscInt    j;
10644cb006feSStefano Zampini 
10654cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
10664cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
10674cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
10684cb006feSStefano Zampini       array[j] = coords[j*dim+i];
10694cb006feSStefano Zampini     }
10704cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
10714cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
10724cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
10734cb006feSStefano Zampini   }
10744cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
10754cb006feSStefano Zampini   /* pass parCSR vectors to AMS solver */
10764cb006feSStefano Zampini   par_coords[0] = NULL;
10774cb006feSStefano Zampini   par_coords[1] = NULL;
10784cb006feSStefano Zampini   par_coords[2] = NULL;
10794cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&par_coords[0])));
10804cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&par_coords[1])));
10814cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&par_coords[2])));
10824cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,par_coords[0],par_coords[1],par_coords[2]));
10834cb006feSStefano Zampini   PetscFunctionReturn(0);
10844cb006feSStefano Zampini }
10854cb006feSStefano Zampini 
108616d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
108716d9e3a6SLisandro Dalcin 
108816d9e3a6SLisandro Dalcin #undef __FUNCT__
108916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
1090f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
109116d9e3a6SLisandro Dalcin {
109216d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
109316d9e3a6SLisandro Dalcin 
109416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
109516d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
109616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
109716d9e3a6SLisandro Dalcin }
109816d9e3a6SLisandro Dalcin 
109916d9e3a6SLisandro Dalcin #undef __FUNCT__
110016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
1101f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
110216d9e3a6SLisandro Dalcin {
110316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
110416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1105ace3abfcSBarry Smith   PetscBool      flag;
110616d9e3a6SLisandro Dalcin 
110716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
110816d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
110916d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1110ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
111116d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
111216d9e3a6SLisandro Dalcin   } else {
111316d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
111416d9e3a6SLisandro Dalcin   }
111516d9e3a6SLisandro Dalcin 
111616d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
111716d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
111816d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
111916d9e3a6SLisandro Dalcin 
112016d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
112116d9e3a6SLisandro Dalcin   if (flag) {
1122fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
112316d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
112416d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
112516d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
112616d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
112716d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
112816d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
112916d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
113016d9e3a6SLisandro Dalcin   }
113116d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
113216d9e3a6SLisandro Dalcin   if (flag) {
1133fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
113416d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
113516d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
113616d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
113716d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
113816d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
113916d9e3a6SLisandro Dalcin     /* initialize */
114016d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
114116d9e3a6SLisandro Dalcin     jac->threshhold = .1;
114216d9e3a6SLisandro Dalcin     jac->filter     = .1;
114316d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
11442fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
11452fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
11462fa5cd67SKarl Rupp 
114716d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
114816d9e3a6SLisandro Dalcin     jac->symt = 0;
1149fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1150fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1151fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1152fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1153fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1154fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
115516d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
115616d9e3a6SLisandro Dalcin   }
115716d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
115816d9e3a6SLisandro Dalcin   if (flag) {
115916d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
116016d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
116116d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
116216d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
116316d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
116416d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
116516d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
116616d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
116716d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
116816d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
116916d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
117016d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
117116d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
11728f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
117316d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
117416d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
117516d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
117616d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
117716d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
11780f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
11798f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
11800f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
118116d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
118216d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
118316d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
11840f1074feSSatish Balay     jac->interptype       = 0;
11850f1074feSSatish Balay     jac->agg_nl           = 0;
11860f1074feSSatish Balay     jac->pmax             = 0;
11870f1074feSSatish Balay     jac->truncfactor      = 0.0;
11880f1074feSSatish Balay     jac->agg_num_paths    = 1;
11898f87f92bSBarry Smith 
11908f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
11918f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
11928f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1193fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1194fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1195fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1196fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1197fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1198fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1199fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1200fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1201fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1202fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1203fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1204fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1205fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1206fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1207fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1208fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
120916d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
121016d9e3a6SLisandro Dalcin   }
12114cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
12124cb006feSStefano Zampini   if (flag) {
12134cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
12144cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
12154cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
12164cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
12174cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
12184cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
12194cb006feSStefano Zampini     jac->coords[0]           = NULL;
12204cb006feSStefano Zampini     jac->coords[1]           = NULL;
12214cb006feSStefano Zampini     jac->coords[2]           = NULL;
12224cb006feSStefano Zampini     jac->G                   = NULL;
12234cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
12244cb006feSStefano Zampini     jac->ams_print           = 0;
12254cb006feSStefano Zampini     jac->ams_max_iter        = 1; /* used as a preconditioner */
12264cb006feSStefano Zampini     jac->ams_cycle_type      = 13;
12274cb006feSStefano Zampini     jac->ams_tol             = 0.; /* used as a preconditioner */
12284cb006feSStefano Zampini     /* Smoothing options */
12294cb006feSStefano Zampini     jac->ams_relax_type      = 2;
12304cb006feSStefano Zampini     jac->ams_relax_times     = 1;
12314cb006feSStefano Zampini     jac->ams_relax_weight    = 1.0;
12324cb006feSStefano Zampini     jac->ams_omega           = 1.0;
12334cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
12344cb006feSStefano Zampini     jac->ams_amg_alpha_opts[0] = 10;
12354cb006feSStefano Zampini     jac->ams_amg_alpha_opts[1] = 1;
12364cb006feSStefano Zampini     jac->ams_amg_alpha_opts[2] = 8;
12374cb006feSStefano Zampini     jac->ams_amg_alpha_opts[3] = 6;
12384cb006feSStefano Zampini     jac->ams_amg_alpha_opts[4] = 4;
12394cb006feSStefano Zampini     jac->ams_amg_alpha_theta   = 0.25;
12404cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
12414cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_FALSE;
12424cb006feSStefano Zampini     jac->ams_amg_beta_opts[0] = 10;
12434cb006feSStefano Zampini     jac->ams_amg_beta_opts[1] = 1;
12444cb006feSStefano Zampini     jac->ams_amg_beta_opts[2] = 8;
12454cb006feSStefano Zampini     jac->ams_amg_beta_opts[3] = 6;
12464cb006feSStefano Zampini     jac->ams_amg_beta_opts[4] = 4;
12474cb006feSStefano Zampini     jac->ams_amg_beta_theta   = 0.25;
12484cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->ams_print));
12494cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->ams_max_iter));
12504cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
12514cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->ams_tol));
12524cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->ams_relax_type,
12534cb006feSStefano Zampini                                                                       jac->ams_relax_times,
12544cb006feSStefano Zampini                                                                       jac->ams_relax_weight,
12554cb006feSStefano Zampini                                                                       jac->ams_omega));
12564cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->ams_amg_alpha_opts[0],       /* AMG coarsen type */
12574cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[1],       /* AMG agg_levels */
12584cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[2],       /* AMG relax_type */
12594cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_theta,
12604cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[3],       /* AMG interp_type */
12614cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[4]));     /* AMG Pmax */
12624cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->ams_amg_beta_opts[0],       /* AMG coarsen type */
12634cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[1],       /* AMG agg_levels */
12644cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[2],       /* AMG relax_type */
12654cb006feSStefano Zampini                                                                     jac->ams_amg_beta_theta,
12664cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[3],       /* AMG interp_type */
12674cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[4]));     /* AMG Pmax */
12684cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE_AMS);CHKERRQ(ierr);
12694cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE_AMS);CHKERRQ(ierr);
12704cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE_AMS);CHKERRQ(ierr);
12714cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
12724cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",PCHYPRESetBetaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
12734cb006feSStefano Zampini     PetscFunctionReturn(0);
12744cb006feSStefano Zampini   }
1275503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
12762fa5cd67SKarl Rupp 
12770298fd71SBarry Smith   jac->hypre_type = NULL;
127833263987SBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, boomeramg, ams",name);
127916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
128016d9e3a6SLisandro Dalcin }
128116d9e3a6SLisandro Dalcin 
128216d9e3a6SLisandro Dalcin /*
128316d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
128416d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
128516d9e3a6SLisandro Dalcin */
128616d9e3a6SLisandro Dalcin #undef __FUNCT__
128716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
12888c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptions *PetscOptionsObject,PC pc)
128916d9e3a6SLisandro Dalcin {
129016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
12914ddd07fcSJed Brown   PetscInt       indx;
129233263987SBarry Smith   const char     *type[] = {"pilut","parasails","boomeramg","ams"};
1293ace3abfcSBarry Smith   PetscBool      flg;
129416d9e3a6SLisandro Dalcin 
129516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
12969fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
12979c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
129816d9e3a6SLisandro Dalcin   if (flg) {
129916d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
130002a17cd4SBarry Smith   } else {
130102a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
130216d9e3a6SLisandro Dalcin   }
130316d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
13043931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
130516d9e3a6SLisandro Dalcin   }
130616d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
130716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
130816d9e3a6SLisandro Dalcin }
130916d9e3a6SLisandro Dalcin 
131016d9e3a6SLisandro Dalcin #undef __FUNCT__
131116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
131216d9e3a6SLisandro Dalcin /*@C
131316d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
131416d9e3a6SLisandro Dalcin 
131516d9e3a6SLisandro Dalcin    Input Parameters:
131616d9e3a6SLisandro Dalcin +     pc - the preconditioner context
131733263987SBarry Smith -     name - either  pilut, parasails, boomeramg, ams
131816d9e3a6SLisandro Dalcin 
131916d9e3a6SLisandro Dalcin    Options Database Keys:
132033263987SBarry Smith    -pc_hypre_type - One of pilut, parasails, boomeramg, ams
132116d9e3a6SLisandro Dalcin 
132216d9e3a6SLisandro Dalcin    Level: intermediate
132316d9e3a6SLisandro Dalcin 
132416d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
132516d9e3a6SLisandro Dalcin            PCHYPRE
132616d9e3a6SLisandro Dalcin 
132716d9e3a6SLisandro Dalcin @*/
13287087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
132916d9e3a6SLisandro Dalcin {
13304ac538c5SBarry Smith   PetscErrorCode ierr;
133116d9e3a6SLisandro Dalcin 
133216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
13330700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
133416d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
13354ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
133616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
133716d9e3a6SLisandro Dalcin }
133816d9e3a6SLisandro Dalcin 
133916d9e3a6SLisandro Dalcin #undef __FUNCT__
134016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
134116d9e3a6SLisandro Dalcin /*@C
134216d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
134316d9e3a6SLisandro Dalcin 
134416d9e3a6SLisandro Dalcin    Input Parameter:
134516d9e3a6SLisandro Dalcin .     pc - the preconditioner context
134616d9e3a6SLisandro Dalcin 
134716d9e3a6SLisandro Dalcin    Output Parameter:
134833263987SBarry Smith .     name - either  pilut, parasails, boomeramg, ams
134916d9e3a6SLisandro Dalcin 
135016d9e3a6SLisandro Dalcin    Level: intermediate
135116d9e3a6SLisandro Dalcin 
135216d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
135316d9e3a6SLisandro Dalcin            PCHYPRE
135416d9e3a6SLisandro Dalcin 
135516d9e3a6SLisandro Dalcin @*/
13567087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
135716d9e3a6SLisandro Dalcin {
13584ac538c5SBarry Smith   PetscErrorCode ierr;
135916d9e3a6SLisandro Dalcin 
136016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
13610700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
136216d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
13634ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
136416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
136516d9e3a6SLisandro Dalcin }
136616d9e3a6SLisandro Dalcin 
136716d9e3a6SLisandro Dalcin /*MC
136816d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
136916d9e3a6SLisandro Dalcin 
137016d9e3a6SLisandro Dalcin    Options Database Keys:
137133263987SBarry Smith +   -pc_hypre_type - One of pilut, parasails, boomeramg, ams
137216d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
137316d9e3a6SLisandro Dalcin           preconditioner
137416d9e3a6SLisandro Dalcin 
137516d9e3a6SLisandro Dalcin    Level: intermediate
137616d9e3a6SLisandro Dalcin 
137716d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
137816d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
137916d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
138016d9e3a6SLisandro Dalcin 
138116d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
13820f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
13830f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
13840f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
13858f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
13860f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
13870f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
138816d9e3a6SLisandro Dalcin 
13890f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
13900f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
13910f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
139216d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
139316d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
139416d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
139516d9e3a6SLisandro Dalcin 
139616d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
139716d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
139816d9e3a6SLisandro Dalcin 
13999e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
14009e5bc791SBarry Smith 
140116d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
14029e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
140316d9e3a6SLisandro Dalcin 
140416d9e3a6SLisandro Dalcin M*/
140516d9e3a6SLisandro Dalcin 
140616d9e3a6SLisandro Dalcin #undef __FUNCT__
140716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
14088cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
140916d9e3a6SLisandro Dalcin {
141016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
141116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
141216d9e3a6SLisandro Dalcin 
141316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1414b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
14152fa5cd67SKarl Rupp 
141616d9e3a6SLisandro Dalcin   pc->data                = jac;
141716d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
141816d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
141916d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
142016d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
142116d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
14220298fd71SBarry Smith   jac->hypre_type         = NULL;
14234cb006feSStefano Zampini   jac->coords[0]          = NULL;
14244cb006feSStefano Zampini   jac->coords[1]          = NULL;
14254cb006feSStefano Zampini   jac->coords[2]          = NULL;
14264cb006feSStefano Zampini   jac->constants[0]       = NULL;
14274cb006feSStefano Zampini   jac->constants[1]       = NULL;
14284cb006feSStefano Zampini   jac->constants[2]       = NULL;
142916d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1430ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1431bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1432bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
143316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
143416d9e3a6SLisandro Dalcin }
1435ebc551c0SBarry Smith 
1436f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1437f91d8e95SBarry Smith 
1438b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1439b45d2f2cSJed Brown #include <petsc-private/matimpl.h>
1440ebc551c0SBarry Smith 
1441ebc551c0SBarry Smith typedef struct {
144268326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1443f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
14449e5bc791SBarry Smith 
14459e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
14464ddd07fcSJed Brown   PetscInt its;
14479e5bc791SBarry Smith   double   tol;
14484ddd07fcSJed Brown   PetscInt relax_type;
14494ddd07fcSJed Brown   PetscInt rap_type;
14504ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
14514ddd07fcSJed Brown   PetscInt max_levels;
1452ebc551c0SBarry Smith } PC_PFMG;
1453ebc551c0SBarry Smith 
1454ebc551c0SBarry Smith #undef __FUNCT__
1455ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1456ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1457ebc551c0SBarry Smith {
1458ebc551c0SBarry Smith   PetscErrorCode ierr;
1459f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1460ebc551c0SBarry Smith 
1461ebc551c0SBarry Smith   PetscFunctionBegin;
14622fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1463f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1464c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1465ebc551c0SBarry Smith   PetscFunctionReturn(0);
1466ebc551c0SBarry Smith }
1467ebc551c0SBarry Smith 
14689e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
14699e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
14709e5bc791SBarry Smith 
1471ebc551c0SBarry Smith #undef __FUNCT__
1472ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1473ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1474ebc551c0SBarry Smith {
1475ebc551c0SBarry Smith   PetscErrorCode ierr;
1476ace3abfcSBarry Smith   PetscBool      iascii;
1477f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1478ebc551c0SBarry Smith 
1479ebc551c0SBarry Smith   PetscFunctionBegin;
1480251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
14819e5bc791SBarry Smith   if (iascii) {
14829e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
14839e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
14849e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
14859e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
14869e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
14879e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
14883b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
14899e5bc791SBarry Smith   }
1490ebc551c0SBarry Smith   PetscFunctionReturn(0);
1491ebc551c0SBarry Smith }
1492ebc551c0SBarry Smith 
14939e5bc791SBarry Smith 
1494ebc551c0SBarry Smith #undef __FUNCT__
1495ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
14968c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptions *PetscOptionsObject,PC pc)
1497ebc551c0SBarry Smith {
1498ebc551c0SBarry Smith   PetscErrorCode ierr;
1499f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1500ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1501ebc551c0SBarry Smith 
1502ebc551c0SBarry Smith   PetscFunctionBegin;
1503e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
15040298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
150568326731SBarry Smith   if (flg) {
1506a0324ebeSBarry Smith     int level=3;
1507fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
150868326731SBarry Smith   }
15090298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1510fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
15110298fd71SBarry 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);
1512fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
15130298fd71SBarry 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);
1514fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
15159e5bc791SBarry Smith 
15160298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
1517fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
15183b46a515SGlenn Hammond 
15190298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1520fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
15210298fd71SBarry 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);
1522fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
15230298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
1524fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1525ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1526ebc551c0SBarry Smith   PetscFunctionReturn(0);
1527ebc551c0SBarry Smith }
1528ebc551c0SBarry Smith 
1529f91d8e95SBarry Smith #undef __FUNCT__
1530f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1531f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1532f91d8e95SBarry Smith {
1533f91d8e95SBarry Smith   PetscErrorCode    ierr;
1534f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
1535*d9ca1df4SBarry Smith   PetscScalar       *yy;
1536*d9ca1df4SBarry Smith   const PetscScalar *xx;
15374ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
153868326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1539f91d8e95SBarry Smith 
1540f91d8e95SBarry Smith   PetscFunctionBegin;
1541dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1542aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1543f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1544f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1545f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1546f91d8e95SBarry Smith 
1547f91d8e95SBarry Smith   /* copy x values over to hypre */
1548fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1549*d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1550*d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
1551*d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1552fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
1553fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1554f91d8e95SBarry Smith 
1555f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1556f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
15578b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
1558f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1559f91d8e95SBarry Smith   PetscFunctionReturn(0);
1560f91d8e95SBarry Smith }
1561f91d8e95SBarry Smith 
15629e5bc791SBarry Smith #undef __FUNCT__
15639e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1564ace3abfcSBarry 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)
15659e5bc791SBarry Smith {
15669e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
15679e5bc791SBarry Smith   PetscErrorCode ierr;
15684ddd07fcSJed Brown   PetscInt       oits;
15699e5bc791SBarry Smith 
15709e5bc791SBarry Smith   PetscFunctionBegin;
1571dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1572fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1573fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
15749e5bc791SBarry Smith 
15759e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
15768b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
15779e5bc791SBarry Smith   *outits = oits;
15789e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
15799e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1580fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1581fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
15829e5bc791SBarry Smith   PetscFunctionReturn(0);
15839e5bc791SBarry Smith }
15849e5bc791SBarry Smith 
15859e5bc791SBarry Smith 
15863a32d3dbSGlenn Hammond #undef __FUNCT__
15873a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
15883a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
15893a32d3dbSGlenn Hammond {
15903a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
15913a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
15923a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1593ace3abfcSBarry Smith   PetscBool       flg;
15943a32d3dbSGlenn Hammond 
15953a32d3dbSGlenn Hammond   PetscFunctionBegin;
1596251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1597ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
15983a32d3dbSGlenn Hammond 
15993a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
16002fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1601fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1602fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1603fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
16043a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
16053a32d3dbSGlenn Hammond }
16063a32d3dbSGlenn Hammond 
1607ebc551c0SBarry Smith 
1608ebc551c0SBarry Smith /*MC
1609ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1610ebc551c0SBarry Smith 
1611ebc551c0SBarry Smith    Level: advanced
1612ebc551c0SBarry Smith 
16139e5bc791SBarry Smith    Options Database:
16149e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
16159e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
16169e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
16179e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
16189e5bc791SBarry 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
16199e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
1620f91d8e95SBarry Smith 
16219e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
16229e5bc791SBarry Smith 
16238e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
1624aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
16259e5bc791SBarry Smith 
16269e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
1627ebc551c0SBarry Smith M*/
1628ebc551c0SBarry Smith 
1629ebc551c0SBarry Smith #undef __FUNCT__
1630ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
16318cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
1632ebc551c0SBarry Smith {
1633ebc551c0SBarry Smith   PetscErrorCode ierr;
1634ebc551c0SBarry Smith   PC_PFMG        *ex;
1635ebc551c0SBarry Smith 
1636ebc551c0SBarry Smith   PetscFunctionBegin;
1637b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
163868326731SBarry Smith   pc->data = ex;
1639ebc551c0SBarry Smith 
16409e5bc791SBarry Smith   ex->its            = 1;
16419e5bc791SBarry Smith   ex->tol            = 1.e-8;
16429e5bc791SBarry Smith   ex->relax_type     = 1;
16439e5bc791SBarry Smith   ex->rap_type       = 0;
16449e5bc791SBarry Smith   ex->num_pre_relax  = 1;
16459e5bc791SBarry Smith   ex->num_post_relax = 1;
16463b46a515SGlenn Hammond   ex->max_levels     = 0;
16479e5bc791SBarry Smith 
1648ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
1649ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
1650ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
1651f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
16529e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
165368326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
16542fa5cd67SKarl Rupp 
1655ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
1656fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1657ebc551c0SBarry Smith   PetscFunctionReturn(0);
1658ebc551c0SBarry Smith }
1659d851a50bSGlenn Hammond 
1660325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
1661325fc9f4SBarry Smith 
1662d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
1663d851a50bSGlenn Hammond typedef struct {
1664d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
1665d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
1666d851a50bSGlenn Hammond 
1667d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
16684ddd07fcSJed Brown   PetscInt its;
1669d851a50bSGlenn Hammond   double   tol;
16704ddd07fcSJed Brown   PetscInt relax_type;
16714ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
1672d851a50bSGlenn Hammond } PC_SysPFMG;
1673d851a50bSGlenn Hammond 
1674d851a50bSGlenn Hammond #undef __FUNCT__
1675d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
1676d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
1677d851a50bSGlenn Hammond {
1678d851a50bSGlenn Hammond   PetscErrorCode ierr;
1679d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1680d851a50bSGlenn Hammond 
1681d851a50bSGlenn Hammond   PetscFunctionBegin;
16822fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1683d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1684c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1685d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1686d851a50bSGlenn Hammond }
1687d851a50bSGlenn Hammond 
1688d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
1689d851a50bSGlenn Hammond 
1690d851a50bSGlenn Hammond #undef __FUNCT__
1691d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
1692d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
1693d851a50bSGlenn Hammond {
1694d851a50bSGlenn Hammond   PetscErrorCode ierr;
1695ace3abfcSBarry Smith   PetscBool      iascii;
1696d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1697d851a50bSGlenn Hammond 
1698d851a50bSGlenn Hammond   PetscFunctionBegin;
1699251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1700d851a50bSGlenn Hammond   if (iascii) {
1701d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
1702d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
1703d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
1704d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
1705d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
1706d851a50bSGlenn Hammond   }
1707d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1708d851a50bSGlenn Hammond }
1709d851a50bSGlenn Hammond 
1710d851a50bSGlenn Hammond 
1711d851a50bSGlenn Hammond #undef __FUNCT__
1712d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
17138c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptions *PetscOptionsObject,PC pc)
1714d851a50bSGlenn Hammond {
1715d851a50bSGlenn Hammond   PetscErrorCode ierr;
1716d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1717ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1718d851a50bSGlenn Hammond 
1719d851a50bSGlenn Hammond   PetscFunctionBegin;
1720e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
17210298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
1722d851a50bSGlenn Hammond   if (flg) {
1723d851a50bSGlenn Hammond     int level=3;
1724fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
1725d851a50bSGlenn Hammond   }
17260298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1727fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
17280298fd71SBarry 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);
1729fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
17300298fd71SBarry 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);
1731fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
1732d851a50bSGlenn Hammond 
17330298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1734fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
17350298fd71SBarry 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);
1736fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
1737d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
1738d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1739d851a50bSGlenn Hammond }
1740d851a50bSGlenn Hammond 
1741d851a50bSGlenn Hammond #undef __FUNCT__
1742d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
1743d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
1744d851a50bSGlenn Hammond {
1745d851a50bSGlenn Hammond   PetscErrorCode    ierr;
1746d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
1747*d9ca1df4SBarry Smith   PetscScalar       *yy;
1748*d9ca1df4SBarry Smith   const PetscScalar *xx;
17494ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
1750d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
17514ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
17524ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
17534ddd07fcSJed Brown   PetscInt          part    = 0;
17544ddd07fcSJed Brown   PetscInt          size;
17554ddd07fcSJed Brown   PetscInt          i;
1756d851a50bSGlenn Hammond 
1757d851a50bSGlenn Hammond   PetscFunctionBegin;
1758dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1759aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1760d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
1761d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
1762d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
1763d851a50bSGlenn Hammond 
1764d851a50bSGlenn Hammond   size = 1;
17652fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
17662fa5cd67SKarl Rupp 
1767d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
1768d851a50bSGlenn Hammond   if (ordering) {
1769fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
1770*d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1771*d9ca1df4SBarry 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)));
1772*d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1773fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
1774fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
1775fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1776d851a50bSGlenn Hammond 
1777d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
1778d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
17798b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
1780d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1781a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
1782d851a50bSGlenn Hammond     PetscScalar *z;
17834ddd07fcSJed Brown     PetscInt    j, k;
1784d851a50bSGlenn Hammond 
1785785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
1786fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
1787*d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1788d851a50bSGlenn Hammond 
1789d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
1790d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
1791d851a50bSGlenn Hammond       k= i*nvars;
17922fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
1793d851a50bSGlenn Hammond     }
17948b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
1795*d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1796fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
1797fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1798d851a50bSGlenn Hammond 
1799d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
1800d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
18018b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
1802d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
1803d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
1804d851a50bSGlenn Hammond       k= i*nvars;
18052fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
1806d851a50bSGlenn Hammond     }
1807d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1808d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
1809d851a50bSGlenn Hammond   }
1810d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1811d851a50bSGlenn Hammond }
1812d851a50bSGlenn Hammond 
1813d851a50bSGlenn Hammond #undef __FUNCT__
1814d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
1815ace3abfcSBarry 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)
1816d851a50bSGlenn Hammond {
1817d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
1818d851a50bSGlenn Hammond   PetscErrorCode ierr;
18194ddd07fcSJed Brown   PetscInt       oits;
1820d851a50bSGlenn Hammond 
1821d851a50bSGlenn Hammond   PetscFunctionBegin;
1822dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1823fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
1824fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
1825d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
18268b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
1827d851a50bSGlenn Hammond   *outits = oits;
1828d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
1829d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1830fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
1831fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
1832d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1833d851a50bSGlenn Hammond }
1834d851a50bSGlenn Hammond 
1835d851a50bSGlenn Hammond 
1836d851a50bSGlenn Hammond #undef __FUNCT__
1837d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
1838d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
1839d851a50bSGlenn Hammond {
1840d851a50bSGlenn Hammond   PetscErrorCode   ierr;
1841d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
1842d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
1843ace3abfcSBarry Smith   PetscBool        flg;
1844d851a50bSGlenn Hammond 
1845d851a50bSGlenn Hammond   PetscFunctionBegin;
1846251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
1847ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
1848d851a50bSGlenn Hammond 
1849d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
18502fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1851fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
1852fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
1853fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1854d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1855d851a50bSGlenn Hammond }
1856d851a50bSGlenn Hammond 
1857d851a50bSGlenn Hammond 
1858d851a50bSGlenn Hammond /*MC
1859d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
1860d851a50bSGlenn Hammond 
1861d851a50bSGlenn Hammond    Level: advanced
1862d851a50bSGlenn Hammond 
1863d851a50bSGlenn Hammond    Options Database:
1864d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
1865d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
1866d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
1867d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
1868d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
1869d851a50bSGlenn Hammond 
1870d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
1871d851a50bSGlenn Hammond 
1872f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
1873aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
1874d851a50bSGlenn Hammond            Also, only cell-centered variables.
1875d851a50bSGlenn Hammond 
1876d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
1877d851a50bSGlenn Hammond M*/
1878d851a50bSGlenn Hammond 
1879d851a50bSGlenn Hammond #undef __FUNCT__
1880d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
18818cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
1882d851a50bSGlenn Hammond {
1883d851a50bSGlenn Hammond   PetscErrorCode ierr;
1884d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
1885d851a50bSGlenn Hammond 
1886d851a50bSGlenn Hammond   PetscFunctionBegin;
1887b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
1888d851a50bSGlenn Hammond   pc->data = ex;
1889d851a50bSGlenn Hammond 
1890d851a50bSGlenn Hammond   ex->its            = 1;
1891d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
1892d851a50bSGlenn Hammond   ex->relax_type     = 1;
1893d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
1894d851a50bSGlenn Hammond   ex->num_post_relax = 1;
1895d851a50bSGlenn Hammond 
1896d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
1897d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
1898d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
1899d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
1900d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
1901d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
19022fa5cd67SKarl Rupp 
1903ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
1904fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
1905d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1906d851a50bSGlenn Hammond }
1907