xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 9fa463a794a71f9b3cd4db07ec8d63fd87f6bbc5)
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;
18016d9e3a6SLisandro Dalcin   PetscScalar        *bv,*xv;
18116d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
18216d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
1834ddd07fcSJed Brown   PetscInt           hierr;
18416d9e3a6SLisandro Dalcin 
18516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
186dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
18716d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
18816d9e3a6SLisandro Dalcin   ierr = VecGetArray(b,&bv);CHKERRQ(ierr);
18916d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
19016d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,bv,sbv);
19116d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
19216d9e3a6SLisandro Dalcin 
193fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
194fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
195fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
196fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
19765e19b50SBarry Smith                                if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
198fd3f9acdSBarry Smith                                if (hierr) hypre__global_error = 0;);
19916d9e3a6SLisandro Dalcin 
20016d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
20116d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
20216d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
20316d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(b,&bv);CHKERRQ(ierr);
20416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
20516d9e3a6SLisandro Dalcin }
20616d9e3a6SLisandro Dalcin 
20716d9e3a6SLisandro Dalcin #undef __FUNCT__
20816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE"
20916d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
21016d9e3a6SLisandro Dalcin {
21116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
21216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
21316d9e3a6SLisandro Dalcin 
21416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
215fd3f9acdSBarry Smith   if (jac->ij) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
216fd3f9acdSBarry Smith   if (jac->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->b));
217fd3f9acdSBarry Smith   if (jac->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->x));
2184cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
2194cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
2204cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
2214cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
2224cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
2234cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
2244cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
2254cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
2264cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
227226b0620SJed Brown   if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr););
228503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
22916d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
230c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
23116d9e3a6SLisandro Dalcin 
23216d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
233bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
234bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
2354cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
2364cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
2374cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
2384cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",NULL);CHKERRQ(ierr);
2394cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",NULL);CHKERRQ(ierr);
24016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
24116d9e3a6SLisandro Dalcin }
24216d9e3a6SLisandro Dalcin 
24316d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
24416d9e3a6SLisandro Dalcin #undef __FUNCT__
24516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut"
2468c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptions *PetscOptionsObject,PC pc)
24716d9e3a6SLisandro Dalcin {
24816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
24916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
250ace3abfcSBarry Smith   PetscBool      flag;
25116d9e3a6SLisandro Dalcin 
25216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
253e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
25416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
255fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
25616d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
257fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
25816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
259fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
26016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
26116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
26216d9e3a6SLisandro Dalcin }
26316d9e3a6SLisandro Dalcin 
26416d9e3a6SLisandro Dalcin #undef __FUNCT__
26516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut"
26616d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
26716d9e3a6SLisandro Dalcin {
26816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
26916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
270ace3abfcSBarry Smith   PetscBool      iascii;
27116d9e3a6SLisandro Dalcin 
27216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
273251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
27416d9e3a6SLisandro Dalcin   if (iascii) {
27516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
27616d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
27716d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
27816d9e3a6SLisandro Dalcin     } else {
27916d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr);
28016d9e3a6SLisandro Dalcin     }
28116d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
28257622a8eSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
28316d9e3a6SLisandro Dalcin     } else {
28416d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr);
28516d9e3a6SLisandro Dalcin     }
28616d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
28716d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
28816d9e3a6SLisandro Dalcin     } else {
28916d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default factor row size \n");CHKERRQ(ierr);
29016d9e3a6SLisandro Dalcin     }
29116d9e3a6SLisandro Dalcin   }
29216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
29316d9e3a6SLisandro Dalcin }
29416d9e3a6SLisandro Dalcin 
29516d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
29616d9e3a6SLisandro Dalcin 
29716d9e3a6SLisandro Dalcin #undef __FUNCT__
29816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG"
29916d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
30016d9e3a6SLisandro Dalcin {
30116d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
30216d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
30316d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
30416d9e3a6SLisandro Dalcin   PetscScalar        *bv,*xv;
30516d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
30616d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
3074ddd07fcSJed Brown   PetscInt           hierr;
30816d9e3a6SLisandro Dalcin 
30916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
310dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
31116d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
31216d9e3a6SLisandro Dalcin   ierr = VecGetArray(b,&bv);CHKERRQ(ierr);
31316d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
31416d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,bv,sbv);
31516d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
31616d9e3a6SLisandro Dalcin 
317fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
318fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
319fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
32016d9e3a6SLisandro Dalcin 
32116d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
32216d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
323e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
32416d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
32516d9e3a6SLisandro Dalcin 
32616d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
32716d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
32816d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
32916d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(b,&bv);CHKERRQ(ierr);
33016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
33116d9e3a6SLisandro Dalcin }
33216d9e3a6SLisandro Dalcin 
333a669f990SJed Brown /* static array length */
334a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
335a669f990SJed Brown 
33616d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
3370f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
33816d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
33965de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
34065de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
34165de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
34265de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
34365de4495SJed Brown                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */,
34465de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
3450f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
3460f1074feSSatish Balay                                                   "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"};
34716d9e3a6SLisandro Dalcin #undef __FUNCT__
34816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG"
3498c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptions *PetscOptionsObject,PC pc)
35016d9e3a6SLisandro Dalcin {
35116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
35216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
3534ddd07fcSJed Brown   PetscInt       n,indx,level;
354ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
35516d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
35616d9e3a6SLisandro Dalcin 
35716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
358e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
3594336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
36016d9e3a6SLisandro Dalcin   if (flg) {
3614336a9eeSBarry Smith     jac->cycletype = indx+1;
362fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
36316d9e3a6SLisandro Dalcin   }
36416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
36516d9e3a6SLisandro Dalcin   if (flg) {
366ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
367fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
36816d9e3a6SLisandro Dalcin   }
36916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
37016d9e3a6SLisandro Dalcin   if (flg) {
371ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
372fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
37316d9e3a6SLisandro Dalcin   }
3740f1074feSSatish 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);
37516d9e3a6SLisandro Dalcin   if (flg) {
37657622a8eSBarry 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);
377fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
37816d9e3a6SLisandro Dalcin   }
37916d9e3a6SLisandro Dalcin 
3800f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
38116d9e3a6SLisandro Dalcin   if (flg) {
38257622a8eSBarry 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);
383fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
38416d9e3a6SLisandro Dalcin   }
38516d9e3a6SLisandro Dalcin 
3860f1074feSSatish 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);
3870f1074feSSatish Balay   if (flg) {
38857622a8eSBarry 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);
389fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
3900f1074feSSatish Balay   }
3910f1074feSSatish Balay 
3920f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
3930f1074feSSatish Balay   if (flg) {
39457622a8eSBarry 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);
3950f1074feSSatish Balay 
396fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
3970f1074feSSatish Balay   }
3980f1074feSSatish Balay 
3990f1074feSSatish Balay 
4000f1074feSSatish 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);
4010f1074feSSatish Balay   if (flg) {
40257622a8eSBarry 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);
4030f1074feSSatish Balay 
404fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
4050f1074feSSatish Balay   }
4060f1074feSSatish Balay 
4070f1074feSSatish Balay 
40816d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
40916d9e3a6SLisandro Dalcin   if (flg) {
41057622a8eSBarry 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);
411fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
41216d9e3a6SLisandro Dalcin   }
41316d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
41416d9e3a6SLisandro Dalcin   if (flg) {
41557622a8eSBarry 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);
41657622a8eSBarry 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);
417fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
41816d9e3a6SLisandro Dalcin   }
41916d9e3a6SLisandro Dalcin 
42016d9e3a6SLisandro Dalcin   /* Grid sweeps */
4210f1074feSSatish 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);
42216d9e3a6SLisandro Dalcin   if (flg) {
423fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
42416d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
42516d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
4260f1074feSSatish Balay     jac->gridsweeps[1] = indx;
4270f1074feSSatish Balay     /*defaults coarse to 1 */
4280f1074feSSatish Balay     jac->gridsweeps[2] = 1;
42916d9e3a6SLisandro Dalcin   }
4300f1074feSSatish Balay 
4310f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
43216d9e3a6SLisandro Dalcin   if (flg) {
433fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
4340f1074feSSatish Balay     jac->gridsweeps[0] = indx;
43516d9e3a6SLisandro Dalcin   }
43616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
43716d9e3a6SLisandro Dalcin   if (flg) {
438fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
4390f1074feSSatish Balay     jac->gridsweeps[1] = indx;
44016d9e3a6SLisandro Dalcin   }
4410f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
44216d9e3a6SLisandro Dalcin   if (flg) {
443fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
4440f1074feSSatish Balay     jac->gridsweeps[2] = indx;
44516d9e3a6SLisandro Dalcin   }
44616d9e3a6SLisandro Dalcin 
44716d9e3a6SLisandro Dalcin   /* Relax type */
448a669f990SJed 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);
44916d9e3a6SLisandro Dalcin   if (flg) {
4500f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
451fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
4520f1074feSSatish Balay     /* by default, coarse type set to 9 */
4530f1074feSSatish Balay     jac->relaxtype[2] = 9;
4540f1074feSSatish Balay 
45516d9e3a6SLisandro Dalcin   }
456a669f990SJed 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);
45716d9e3a6SLisandro Dalcin   if (flg) {
45816d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
459fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
46016d9e3a6SLisandro Dalcin   }
461a669f990SJed 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);
46216d9e3a6SLisandro Dalcin   if (flg) {
4630f1074feSSatish Balay     jac->relaxtype[1] = indx;
464fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
46516d9e3a6SLisandro Dalcin   }
466a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
46716d9e3a6SLisandro Dalcin   if (flg) {
4680f1074feSSatish Balay     jac->relaxtype[2] = indx;
469fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
47016d9e3a6SLisandro Dalcin   }
47116d9e3a6SLisandro Dalcin 
47216d9e3a6SLisandro Dalcin   /* Relaxation Weight */
47316d9e3a6SLisandro 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);
47416d9e3a6SLisandro Dalcin   if (flg) {
475fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
47616d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
47716d9e3a6SLisandro Dalcin   }
47816d9e3a6SLisandro Dalcin 
47916d9e3a6SLisandro Dalcin   n         = 2;
48016d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
48116d9e3a6SLisandro 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);
48216d9e3a6SLisandro Dalcin   if (flg) {
48316d9e3a6SLisandro Dalcin     if (n == 2) {
48416d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
485fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
486ce94432eSBarry 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);
48716d9e3a6SLisandro Dalcin   }
48816d9e3a6SLisandro Dalcin 
48916d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
49016d9e3a6SLisandro 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);
49116d9e3a6SLisandro Dalcin   if (flg) {
492fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
49316d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
49416d9e3a6SLisandro Dalcin   }
49516d9e3a6SLisandro Dalcin 
49616d9e3a6SLisandro Dalcin   n         = 2;
49716d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
49816d9e3a6SLisandro 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);
49916d9e3a6SLisandro Dalcin   if (flg) {
50016d9e3a6SLisandro Dalcin     if (n == 2) {
50116d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
502fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
503ce94432eSBarry 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);
50416d9e3a6SLisandro Dalcin   }
50516d9e3a6SLisandro Dalcin 
50616d9e3a6SLisandro Dalcin   /* the Relax Order */
507acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
50816d9e3a6SLisandro Dalcin 
5098afaa268SBarry Smith   if (flg && tmp_truth) {
51016d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
511fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
51216d9e3a6SLisandro Dalcin   }
513a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
51416d9e3a6SLisandro Dalcin   if (flg) {
51516d9e3a6SLisandro Dalcin     jac->measuretype = indx;
516fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
51716d9e3a6SLisandro Dalcin   }
5180f1074feSSatish Balay   /* update list length 3/07 */
519a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
52016d9e3a6SLisandro Dalcin   if (flg) {
52116d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
522fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
52316d9e3a6SLisandro Dalcin   }
5240f1074feSSatish Balay 
5250f1074feSSatish Balay   /* new 3/07 */
526a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
5270f1074feSSatish Balay   if (flg) {
5280f1074feSSatish Balay     jac->interptype = indx;
529fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
5300f1074feSSatish Balay   }
5310f1074feSSatish Balay 
532b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
53316d9e3a6SLisandro Dalcin   if (flg) {
534b96a4a96SBarry Smith     level = 3;
5350298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
5362fa5cd67SKarl Rupp 
537b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
538fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
5392ae77aedSBarry Smith   }
5402ae77aedSBarry Smith 
541b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
5422ae77aedSBarry Smith   if (flg) {
543b96a4a96SBarry Smith     level = 3;
5440298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
5452fa5cd67SKarl Rupp 
546b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
547fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
54816d9e3a6SLisandro Dalcin   }
5498f87f92bSBarry Smith 
5508afaa268SBarry Smith   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_coarsen", "HYPRE_BoomerAMGSetNodal()", "None", jac->nodal_coarsen ? PETSC_TRUE : PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5518f87f92bSBarry Smith   if (flg && tmp_truth) {
5528f87f92bSBarry Smith     jac->nodal_coarsen = 1;
553fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,1));
5548f87f92bSBarry Smith   }
5558f87f92bSBarry Smith 
556acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5578f87f92bSBarry Smith   if (flg && tmp_truth) {
5588f87f92bSBarry Smith     PetscInt tmp_int;
5598f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
5608f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
561fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
562fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
563fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
564fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
5658f87f92bSBarry Smith   }
5668f87f92bSBarry Smith 
56716d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
56816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
56916d9e3a6SLisandro Dalcin }
57016d9e3a6SLisandro Dalcin 
57116d9e3a6SLisandro Dalcin #undef __FUNCT__
57216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG"
573ace3abfcSBarry 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)
57416d9e3a6SLisandro Dalcin {
57516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
57616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
5774ddd07fcSJed Brown   PetscInt       oits;
57816d9e3a6SLisandro Dalcin 
57916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
580dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
581fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
582fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
58316d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
58416d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
58516d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
5868b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
5874d0a8057SBarry Smith   *outits = oits;
5884d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
5894d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
590fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
591fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
59216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
59316d9e3a6SLisandro Dalcin }
59416d9e3a6SLisandro Dalcin 
59516d9e3a6SLisandro Dalcin 
59616d9e3a6SLisandro Dalcin #undef __FUNCT__
59716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG"
59816d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
59916d9e3a6SLisandro Dalcin {
60016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
60116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
602ace3abfcSBarry Smith   PetscBool      iascii;
60316d9e3a6SLisandro Dalcin 
60416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
605251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
60616d9e3a6SLisandro Dalcin   if (iascii) {
60716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
60816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
60916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
61016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
61157622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
61257622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
61357622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
6140f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
6150f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
6160f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
6170f1074feSSatish Balay 
61857622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
61916d9e3a6SLisandro Dalcin 
6200f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
6210f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
6220f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
62316d9e3a6SLisandro Dalcin 
6240f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
6250f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
6260f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
62716d9e3a6SLisandro Dalcin 
62857622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
62957622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
63016d9e3a6SLisandro Dalcin 
63116d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
63216d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr);
63316d9e3a6SLisandro Dalcin     } else {
63416d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr);
63516d9e3a6SLisandro Dalcin     }
63616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
63716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
6380f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
6398f87f92bSBarry Smith     if (jac->nodal_coarsen) {
6408f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal())\n");CHKERRQ(ierr);
6418f87f92bSBarry Smith     }
6428f87f92bSBarry Smith     if (jac->nodal_relax) {
6438f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
6448f87f92bSBarry Smith     }
64516d9e3a6SLisandro Dalcin   }
64616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
64716d9e3a6SLisandro Dalcin }
64816d9e3a6SLisandro Dalcin 
64916d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
65016d9e3a6SLisandro Dalcin #undef __FUNCT__
65116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails"
6528c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptions *PetscOptionsObject,PC pc)
65316d9e3a6SLisandro Dalcin {
65416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
65516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
6564ddd07fcSJed Brown   PetscInt       indx;
657ace3abfcSBarry Smith   PetscBool      flag;
65816d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
65916d9e3a6SLisandro Dalcin 
66016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
661e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
66216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
66316d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
6642fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
66516d9e3a6SLisandro Dalcin 
66616d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
6672fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
66816d9e3a6SLisandro Dalcin 
66916d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
6702fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
67116d9e3a6SLisandro Dalcin 
672acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
6732fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
67416d9e3a6SLisandro Dalcin 
675acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
6762fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
67716d9e3a6SLisandro Dalcin 
678a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
67916d9e3a6SLisandro Dalcin   if (flag) {
68016d9e3a6SLisandro Dalcin     jac->symt = indx;
681fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
68216d9e3a6SLisandro Dalcin   }
68316d9e3a6SLisandro Dalcin 
68416d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
68516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
68616d9e3a6SLisandro Dalcin }
68716d9e3a6SLisandro Dalcin 
68816d9e3a6SLisandro Dalcin #undef __FUNCT__
68916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails"
69016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
69116d9e3a6SLisandro Dalcin {
69216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
69316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
694ace3abfcSBarry Smith   PetscBool      iascii;
69516d9e3a6SLisandro Dalcin   const char     *symt = 0;;
69616d9e3a6SLisandro Dalcin 
69716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
698251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
69916d9e3a6SLisandro Dalcin   if (iascii) {
70016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
70116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
70257622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
70357622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: filter %g\n",(double)jac->filter);CHKERRQ(ierr);
70457622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
705ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
706ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
7072fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
7082fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
7092fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
710ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
71116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr);
71216d9e3a6SLisandro Dalcin   }
71316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
71416d9e3a6SLisandro Dalcin }
7154cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
7164cb006feSStefano Zampini #undef __FUNCT__
7174cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS"
718*9fa463a7SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptions *PetscOptionsObject,PC pc)
7194cb006feSStefano Zampini {
7204cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
7214cb006feSStefano Zampini   PetscErrorCode ierr;
7224cb006feSStefano Zampini   PetscInt       n;
7234cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
7244cb006feSStefano Zampini 
7254cb006feSStefano Zampini   PetscFunctionBegin;
726*9fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
7274cb006feSStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->ams_print,&jac->ams_print,&flag);CHKERRQ(ierr);
7284cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->ams_print));
7294cb006feSStefano 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);
7304cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->ams_max_iter));
7314cb006feSStefano 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);
7324cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
7334cb006feSStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->ams_tol,&jac->ams_tol,&flag);CHKERRQ(ierr);
7344cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->ams_tol));
7354cb006feSStefano 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);
7364cb006feSStefano 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);
7374cb006feSStefano 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);
7384cb006feSStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->ams_omega,&jac->ams_omega,&flag4);CHKERRQ(ierr);
7394cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
7404cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->ams_relax_type,
7414cb006feSStefano Zampini                                                                       jac->ams_relax_times,
7424cb006feSStefano Zampini                                                                       jac->ams_relax_weight,
7434cb006feSStefano Zampini                                                                       jac->ams_omega));
7444cb006feSStefano Zampini   }
7454cb006feSStefano 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);
7464cb006feSStefano Zampini   n = 5;
7474cb006feSStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->ams_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
7484cb006feSStefano Zampini   if (flag || flag2) {
7494cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->ams_amg_alpha_opts[0],       /* AMG coarsen type */
7504cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[1],       /* AMG agg_levels */
7514cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[2],       /* AMG relax_type */
7524cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_theta,
7534cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[3],       /* AMG interp_type */
7544cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[4]));     /* AMG Pmax */
7554cb006feSStefano Zampini   }
7564cb006feSStefano 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);
7574cb006feSStefano Zampini   n = 5;
7584cb006feSStefano 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);
7594cb006feSStefano Zampini   if (flag || flag2) {
7604cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->ams_amg_beta_opts[0],       /* AMG coarsen type */
7614cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[1],       /* AMG agg_levels */
7624cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[2],       /* AMG relax_type */
7634cb006feSStefano Zampini                                                                     jac->ams_amg_beta_theta,
7644cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[3],       /* AMG interp_type */
7654cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[4]));     /* AMG Pmax */
7664cb006feSStefano Zampini   }
7674cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
7684cb006feSStefano Zampini   PetscFunctionReturn(0);
7694cb006feSStefano Zampini }
7704cb006feSStefano Zampini 
7714cb006feSStefano Zampini #undef __FUNCT__
7724cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS"
7734cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
7744cb006feSStefano Zampini {
7754cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
7764cb006feSStefano Zampini   PetscErrorCode ierr;
7774cb006feSStefano Zampini   PetscBool      iascii;
7784cb006feSStefano Zampini 
7794cb006feSStefano Zampini   PetscFunctionBegin;
7804cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
7814cb006feSStefano Zampini   if (iascii) {
7824cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
7834cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iterations per application %d\n",jac->ams_max_iter);CHKERRQ(ierr);
7844cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
7854cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iteration tolerance %g\n",jac->ams_tol);CHKERRQ(ierr);
7864cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother type %d\n",jac->ams_relax_type);CHKERRQ(ierr);
7874cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: number of smoothing steps %d\n",jac->ams_relax_times);CHKERRQ(ierr);
7884cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother weight %g\n",jac->ams_relax_weight);CHKERRQ(ierr);
7894cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother omega %g\n",jac->ams_omega);CHKERRQ(ierr);
7904cb006feSStefano Zampini     if (jac->alpha_Poisson) {
7914cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
7924cb006feSStefano Zampini     } else {
7934cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr);
7944cb006feSStefano Zampini     }
7954cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->ams_amg_alpha_opts[0]);CHKERRQ(ierr);
7964cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->ams_amg_alpha_opts[1]);CHKERRQ(ierr);
7974cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->ams_amg_alpha_opts[2]);CHKERRQ(ierr);
7984cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->ams_amg_alpha_opts[3]);CHKERRQ(ierr);
7994cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->ams_amg_alpha_opts[4]);CHKERRQ(ierr);
8004cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->ams_amg_alpha_theta);CHKERRQ(ierr);
8014cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
8024cb006feSStefano Zampini       if (jac->beta_Poisson) {
8034cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8044cb006feSStefano Zampini       } else {
8054cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr);
8064cb006feSStefano Zampini       }
8074cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->ams_amg_beta_opts[0]);CHKERRQ(ierr);
8084cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->ams_amg_beta_opts[1]);CHKERRQ(ierr);
8094cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->ams_amg_beta_opts[2]);CHKERRQ(ierr);
8104cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->ams_amg_beta_opts[3]);CHKERRQ(ierr);
8114cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->ams_amg_beta_opts[4]);CHKERRQ(ierr);
8124cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->ams_amg_beta_theta);CHKERRQ(ierr);
8134cb006feSStefano Zampini     }
8144cb006feSStefano Zampini   }
8154cb006feSStefano Zampini   PetscFunctionReturn(0);
8164cb006feSStefano Zampini }
8174cb006feSStefano Zampini 
8184cb006feSStefano Zampini #undef __FUNCT__
8194cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE_AMS"
8204cb006feSStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE_AMS(PC pc, Mat G)
8214cb006feSStefano Zampini {
8224cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
8234cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_G;
8244cb006feSStefano Zampini   PetscErrorCode     ierr;
8254cb006feSStefano Zampini 
8264cb006feSStefano Zampini   PetscFunctionBegin;
8274cb006feSStefano Zampini   /* throw away any discrete gradient if already set */
8284cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
8294cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(G,&jac->G);CHKERRQ(ierr);
8304cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(G,jac->G);CHKERRQ(ierr);
8314cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->G,(void**)(&parcsr_G)));
8324cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr_G));
8334cb006feSStefano Zampini   PetscFunctionReturn(0);
8344cb006feSStefano Zampini }
8354cb006feSStefano Zampini 
8364cb006feSStefano Zampini #undef __FUNCT__
8374cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient"
8384cb006feSStefano Zampini /*@
8394cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
8404cb006feSStefano Zampini 
8414cb006feSStefano Zampini    Collective on PC
8424cb006feSStefano Zampini 
8434cb006feSStefano Zampini    Input Parameters:
8444cb006feSStefano Zampini +  pc - the preconditioning context
8454cb006feSStefano Zampini -  G - the discrete gradient
8464cb006feSStefano Zampini 
8474cb006feSStefano Zampini    Level: intermediate
8484cb006feSStefano Zampini 
8494cb006feSStefano 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
8504cb006feSStefano 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
8514cb006feSStefano Zampini 
8524cb006feSStefano Zampini .seealso:
8534cb006feSStefano Zampini @*/
8544cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
8554cb006feSStefano Zampini {
8564cb006feSStefano Zampini   PetscErrorCode ierr;
8574cb006feSStefano Zampini 
8584cb006feSStefano Zampini   PetscFunctionBegin;
8594cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
8604cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
8614cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
8624cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
8634cb006feSStefano Zampini   PetscFunctionReturn(0);
8644cb006feSStefano Zampini }
8654cb006feSStefano Zampini 
8664cb006feSStefano Zampini #undef __FUNCT__
8674cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS"
8684cb006feSStefano Zampini static PetscErrorCode PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
8694cb006feSStefano Zampini {
8704cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
8714cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_alpha_Poisson;
8724cb006feSStefano Zampini   PetscErrorCode     ierr;
8734cb006feSStefano Zampini 
8744cb006feSStefano Zampini   PetscFunctionBegin;
8754cb006feSStefano Zampini   /* throw away any matrix if already set */
8764cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
8774cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->alpha_Poisson);CHKERRQ(ierr);
8784cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->alpha_Poisson);CHKERRQ(ierr);
8794cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->alpha_Poisson,(void**)(&parcsr_alpha_Poisson)));
8804cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr_alpha_Poisson));
8814cb006feSStefano Zampini   PetscFunctionReturn(0);
8824cb006feSStefano Zampini }
8834cb006feSStefano Zampini 
8844cb006feSStefano Zampini #undef __FUNCT__
8854cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix"
8864cb006feSStefano Zampini /*@
8874cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
8884cb006feSStefano Zampini 
8894cb006feSStefano Zampini    Collective on PC
8904cb006feSStefano Zampini 
8914cb006feSStefano Zampini    Input Parameters:
8924cb006feSStefano Zampini +  pc - the preconditioning context
8934cb006feSStefano Zampini -  A - the matrix
8944cb006feSStefano Zampini 
8954cb006feSStefano Zampini    Level: intermediate
8964cb006feSStefano Zampini 
8974cb006feSStefano Zampini    Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
8984cb006feSStefano Zampini 
8994cb006feSStefano Zampini .seealso:
9004cb006feSStefano Zampini @*/
9014cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
9024cb006feSStefano Zampini {
9034cb006feSStefano Zampini   PetscErrorCode ierr;
9044cb006feSStefano Zampini 
9054cb006feSStefano Zampini   PetscFunctionBegin;
9064cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
9074cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
9084cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
9094cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetAlphaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
9104cb006feSStefano Zampini   PetscFunctionReturn(0);
9114cb006feSStefano Zampini }
9124cb006feSStefano Zampini 
9134cb006feSStefano Zampini #undef __FUNCT__
9144cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix_HYPRE_AMS"
9154cb006feSStefano Zampini static PetscErrorCode PCHYPRESetBetaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
9164cb006feSStefano Zampini {
9174cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
9184cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_beta_Poisson;
9194cb006feSStefano Zampini   PetscErrorCode     ierr;
9204cb006feSStefano Zampini 
9214cb006feSStefano Zampini   PetscFunctionBegin;
9224cb006feSStefano Zampini   if (!A) {
9234cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_TRUE;
9244cb006feSStefano Zampini     PetscFunctionReturn(0);
9254cb006feSStefano Zampini   }
9264cb006feSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
9274cb006feSStefano Zampini   /* throw away any matrix if already set */
9284cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
9294cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->beta_Poisson);CHKERRQ(ierr);
9304cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->beta_Poisson);CHKERRQ(ierr);
9314cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->beta_Poisson,(void**)(&parcsr_beta_Poisson)));
9324cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr_beta_Poisson));
9334cb006feSStefano Zampini   PetscFunctionReturn(0);
9344cb006feSStefano Zampini }
9354cb006feSStefano Zampini 
9364cb006feSStefano Zampini #undef __FUNCT__
9374cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix"
9384cb006feSStefano Zampini /*@
9394cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
9404cb006feSStefano Zampini 
9414cb006feSStefano Zampini    Collective on PC
9424cb006feSStefano Zampini 
9434cb006feSStefano Zampini    Input Parameters:
9444cb006feSStefano Zampini +  pc - the preconditioning context
9454cb006feSStefano Zampini -  A - the matrix
9464cb006feSStefano Zampini 
9474cb006feSStefano Zampini    Level: intermediate
9484cb006feSStefano Zampini 
9494cb006feSStefano Zampini    Notes: A should be obtained by discretizing the Poisson problem with linear finite elements.
9504cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
9514cb006feSStefano Zampini 
9524cb006feSStefano Zampini .seealso:
9534cb006feSStefano Zampini @*/
9544cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
9554cb006feSStefano Zampini {
9564cb006feSStefano Zampini   PetscErrorCode ierr;
9574cb006feSStefano Zampini 
9584cb006feSStefano Zampini   PetscFunctionBegin;
9594cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
9604cb006feSStefano Zampini   if (A) {
9614cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
9624cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
9634cb006feSStefano Zampini   }
9644cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetBetaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
9654cb006feSStefano Zampini   PetscFunctionReturn(0);
9664cb006feSStefano Zampini }
9674cb006feSStefano Zampini 
9684cb006feSStefano Zampini #undef __FUNCT__
9694cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE_AMS"
9704cb006feSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE_AMS(PC pc,Vec ozz, Vec zoz, Vec zzo)
9714cb006feSStefano Zampini {
9724cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
9734cb006feSStefano Zampini   HYPRE_ParVector    par_ozz,par_zoz,par_zzo;
97412ddd1b6SStefano Zampini   PetscInt           dim;
9754cb006feSStefano Zampini   PetscErrorCode     ierr;
9764cb006feSStefano Zampini 
9774cb006feSStefano Zampini   PetscFunctionBegin;
9784cb006feSStefano Zampini   /* throw away any vector if already set */
9794cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
9804cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
9814cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
9824cb006feSStefano Zampini   jac->constants[0] = NULL;
9834cb006feSStefano Zampini   jac->constants[1] = NULL;
9844cb006feSStefano Zampini   jac->constants[2] = NULL;
9854cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
9864cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
9874cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&par_ozz)));
9884cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
9894cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
9904cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&par_zoz)));
99112ddd1b6SStefano Zampini   dim = 2;
9924cb006feSStefano Zampini   if (zzo) {
9934cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
9944cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
9954cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&par_zzo)));
99612ddd1b6SStefano Zampini     dim++;
9974cb006feSStefano Zampini   }
9984cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,par_ozz,par_zoz,par_zzo));
99912ddd1b6SStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim));
10004cb006feSStefano Zampini   PetscFunctionReturn(0);
10014cb006feSStefano Zampini }
10024cb006feSStefano Zampini 
10034cb006feSStefano Zampini #undef __FUNCT__
10044cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors"
10054cb006feSStefano Zampini /*@
10064cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
10074cb006feSStefano Zampini 
10084cb006feSStefano Zampini    Collective on PC
10094cb006feSStefano Zampini 
10104cb006feSStefano Zampini    Input Parameters:
10114cb006feSStefano Zampini +  pc - the preconditioning context
10124cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
10134cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
10144cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
10154cb006feSStefano Zampini 
10164cb006feSStefano Zampini    Level: intermediate
10174cb006feSStefano Zampini 
10184cb006feSStefano Zampini    Notes:
10194cb006feSStefano Zampini 
10204cb006feSStefano Zampini .seealso:
10214cb006feSStefano Zampini @*/
10224cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
10234cb006feSStefano Zampini {
10244cb006feSStefano Zampini   PetscErrorCode ierr;
10254cb006feSStefano Zampini 
10264cb006feSStefano Zampini   PetscFunctionBegin;
10274cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
10284cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
10294cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
10304cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
10314cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
10324cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
10334cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
10344cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
10354cb006feSStefano Zampini   PetscFunctionReturn(0);
10364cb006feSStefano Zampini }
10374cb006feSStefano Zampini 
10384cb006feSStefano Zampini #undef __FUNCT__
10394cb006feSStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE_AMS"
10404cb006feSStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE_AMS(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
10414cb006feSStefano Zampini {
10424cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
10434cb006feSStefano Zampini   Vec             tv;
10444cb006feSStefano Zampini   HYPRE_ParVector par_coords[3];
10454cb006feSStefano Zampini   PetscInt        i;
10464cb006feSStefano Zampini   PetscErrorCode  ierr;
10474cb006feSStefano Zampini 
10484cb006feSStefano Zampini   PetscFunctionBegin;
10494cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
10504cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
10514cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
10524cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
10534cb006feSStefano Zampini   /* set problem's dimension */
10544cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim));
10554cb006feSStefano Zampini   /* compute IJ vector for coordinates */
10564cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
10574cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
10584cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
10594cb006feSStefano Zampini   for (i=0;i<dim;i++) {
10604cb006feSStefano Zampini     PetscScalar *array;
10614cb006feSStefano Zampini     PetscInt    j;
10624cb006feSStefano Zampini 
10634cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
10644cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
10654cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
10664cb006feSStefano Zampini       array[j] = coords[j*dim+i];
10674cb006feSStefano Zampini     }
10684cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
10694cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
10704cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
10714cb006feSStefano Zampini   }
10724cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
10734cb006feSStefano Zampini   /* pass parCSR vectors to AMS solver */
10744cb006feSStefano Zampini   par_coords[0] = NULL;
10754cb006feSStefano Zampini   par_coords[1] = NULL;
10764cb006feSStefano Zampini   par_coords[2] = NULL;
10774cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&par_coords[0])));
10784cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&par_coords[1])));
10794cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&par_coords[2])));
10804cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,par_coords[0],par_coords[1],par_coords[2]));
10814cb006feSStefano Zampini   PetscFunctionReturn(0);
10824cb006feSStefano Zampini }
10834cb006feSStefano Zampini 
108416d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
108516d9e3a6SLisandro Dalcin 
108616d9e3a6SLisandro Dalcin #undef __FUNCT__
108716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
1088f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
108916d9e3a6SLisandro Dalcin {
109016d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
109116d9e3a6SLisandro Dalcin 
109216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
109316d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
109416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
109516d9e3a6SLisandro Dalcin }
109616d9e3a6SLisandro Dalcin 
109716d9e3a6SLisandro Dalcin #undef __FUNCT__
109816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
1099f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
110016d9e3a6SLisandro Dalcin {
110116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
110216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1103ace3abfcSBarry Smith   PetscBool      flag;
110416d9e3a6SLisandro Dalcin 
110516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
110616d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
110716d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1108ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
110916d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
111016d9e3a6SLisandro Dalcin   } else {
111116d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
111216d9e3a6SLisandro Dalcin   }
111316d9e3a6SLisandro Dalcin 
111416d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
111516d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
111616d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
111716d9e3a6SLisandro Dalcin 
111816d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
111916d9e3a6SLisandro Dalcin   if (flag) {
1120fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
112116d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
112216d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
112316d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
112416d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
112516d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
112616d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
112716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
112816d9e3a6SLisandro Dalcin   }
112916d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
113016d9e3a6SLisandro Dalcin   if (flag) {
1131fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
113216d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
113316d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
113416d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
113516d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
113616d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
113716d9e3a6SLisandro Dalcin     /* initialize */
113816d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
113916d9e3a6SLisandro Dalcin     jac->threshhold = .1;
114016d9e3a6SLisandro Dalcin     jac->filter     = .1;
114116d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
11422fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
11432fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
11442fa5cd67SKarl Rupp 
114516d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
114616d9e3a6SLisandro Dalcin     jac->symt = 0;
1147fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1148fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1149fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1150fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1151fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1152fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
115316d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
115416d9e3a6SLisandro Dalcin   }
115516d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
115616d9e3a6SLisandro Dalcin   if (flag) {
115716d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
115816d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
115916d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
116016d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
116116d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
116216d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
116316d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
116416d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
116516d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
116616d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
116716d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
116816d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
116916d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
11708f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
117116d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
117216d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
117316d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
117416d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
117516d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
11760f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
11778f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
11780f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
117916d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
118016d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
118116d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
11820f1074feSSatish Balay     jac->interptype       = 0;
11830f1074feSSatish Balay     jac->agg_nl           = 0;
11840f1074feSSatish Balay     jac->pmax             = 0;
11850f1074feSSatish Balay     jac->truncfactor      = 0.0;
11860f1074feSSatish Balay     jac->agg_num_paths    = 1;
11878f87f92bSBarry Smith 
11888f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
11898f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
11908f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1191fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1192fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1193fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1194fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1195fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1196fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1197fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1198fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1199fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1200fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1201fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1202fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1203fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1204fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1205fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1206fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
120716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
120816d9e3a6SLisandro Dalcin   }
12094cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
12104cb006feSStefano Zampini   if (flag) {
12114cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
12124cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
12134cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
12144cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
12154cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
12164cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
12174cb006feSStefano Zampini     jac->coords[0]           = NULL;
12184cb006feSStefano Zampini     jac->coords[1]           = NULL;
12194cb006feSStefano Zampini     jac->coords[2]           = NULL;
12204cb006feSStefano Zampini     jac->G                   = NULL;
12214cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
12224cb006feSStefano Zampini     jac->ams_print           = 0;
12234cb006feSStefano Zampini     jac->ams_max_iter        = 1; /* used as a preconditioner */
12244cb006feSStefano Zampini     jac->ams_cycle_type      = 13;
12254cb006feSStefano Zampini     jac->ams_tol             = 0.; /* used as a preconditioner */
12264cb006feSStefano Zampini     /* Smoothing options */
12274cb006feSStefano Zampini     jac->ams_relax_type      = 2;
12284cb006feSStefano Zampini     jac->ams_relax_times     = 1;
12294cb006feSStefano Zampini     jac->ams_relax_weight    = 1.0;
12304cb006feSStefano Zampini     jac->ams_omega           = 1.0;
12314cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
12324cb006feSStefano Zampini     jac->ams_amg_alpha_opts[0] = 10;
12334cb006feSStefano Zampini     jac->ams_amg_alpha_opts[1] = 1;
12344cb006feSStefano Zampini     jac->ams_amg_alpha_opts[2] = 8;
12354cb006feSStefano Zampini     jac->ams_amg_alpha_opts[3] = 6;
12364cb006feSStefano Zampini     jac->ams_amg_alpha_opts[4] = 4;
12374cb006feSStefano Zampini     jac->ams_amg_alpha_theta   = 0.25;
12384cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
12394cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_FALSE;
12404cb006feSStefano Zampini     jac->ams_amg_beta_opts[0] = 10;
12414cb006feSStefano Zampini     jac->ams_amg_beta_opts[1] = 1;
12424cb006feSStefano Zampini     jac->ams_amg_beta_opts[2] = 8;
12434cb006feSStefano Zampini     jac->ams_amg_beta_opts[3] = 6;
12444cb006feSStefano Zampini     jac->ams_amg_beta_opts[4] = 4;
12454cb006feSStefano Zampini     jac->ams_amg_beta_theta   = 0.25;
12464cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->ams_print));
12474cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->ams_max_iter));
12484cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
12494cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->ams_tol));
12504cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->ams_relax_type,
12514cb006feSStefano Zampini                                                                       jac->ams_relax_times,
12524cb006feSStefano Zampini                                                                       jac->ams_relax_weight,
12534cb006feSStefano Zampini                                                                       jac->ams_omega));
12544cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->ams_amg_alpha_opts[0],       /* AMG coarsen type */
12554cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[1],       /* AMG agg_levels */
12564cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[2],       /* AMG relax_type */
12574cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_theta,
12584cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[3],       /* AMG interp_type */
12594cb006feSStefano Zampini                                                                      jac->ams_amg_alpha_opts[4]));     /* AMG Pmax */
12604cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->ams_amg_beta_opts[0],       /* AMG coarsen type */
12614cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[1],       /* AMG agg_levels */
12624cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[2],       /* AMG relax_type */
12634cb006feSStefano Zampini                                                                     jac->ams_amg_beta_theta,
12644cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[3],       /* AMG interp_type */
12654cb006feSStefano Zampini                                                                     jac->ams_amg_beta_opts[4]));     /* AMG Pmax */
12664cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE_AMS);CHKERRQ(ierr);
12674cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE_AMS);CHKERRQ(ierr);
12684cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE_AMS);CHKERRQ(ierr);
12694cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
12704cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",PCHYPRESetBetaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
12714cb006feSStefano Zampini     PetscFunctionReturn(0);
12724cb006feSStefano Zampini   }
1273503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
12742fa5cd67SKarl Rupp 
12750298fd71SBarry Smith   jac->hypre_type = NULL;
127633263987SBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, boomeramg, ams",name);
127716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
127816d9e3a6SLisandro Dalcin }
127916d9e3a6SLisandro Dalcin 
128016d9e3a6SLisandro Dalcin /*
128116d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
128216d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
128316d9e3a6SLisandro Dalcin */
128416d9e3a6SLisandro Dalcin #undef __FUNCT__
128516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
12868c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptions *PetscOptionsObject,PC pc)
128716d9e3a6SLisandro Dalcin {
128816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
12894ddd07fcSJed Brown   PetscInt       indx;
129033263987SBarry Smith   const char     *type[] = {"pilut","parasails","boomeramg","ams"};
1291ace3abfcSBarry Smith   PetscBool      flg;
129216d9e3a6SLisandro Dalcin 
129316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1294*9fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
12954cb006feSStefano Zampini   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,5,"boomeramg",&indx,&flg);CHKERRQ(ierr);
129616d9e3a6SLisandro Dalcin   if (flg) {
129716d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
129802a17cd4SBarry Smith   } else {
129902a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
130016d9e3a6SLisandro Dalcin   }
130116d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
13023931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
130316d9e3a6SLisandro Dalcin   }
130416d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
130516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
130616d9e3a6SLisandro Dalcin }
130716d9e3a6SLisandro Dalcin 
130816d9e3a6SLisandro Dalcin #undef __FUNCT__
130916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
131016d9e3a6SLisandro Dalcin /*@C
131116d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
131216d9e3a6SLisandro Dalcin 
131316d9e3a6SLisandro Dalcin    Input Parameters:
131416d9e3a6SLisandro Dalcin +     pc - the preconditioner context
131533263987SBarry Smith -     name - either  pilut, parasails, boomeramg, ams
131616d9e3a6SLisandro Dalcin 
131716d9e3a6SLisandro Dalcin    Options Database Keys:
131833263987SBarry Smith    -pc_hypre_type - One of pilut, parasails, boomeramg, ams
131916d9e3a6SLisandro Dalcin 
132016d9e3a6SLisandro Dalcin    Level: intermediate
132116d9e3a6SLisandro Dalcin 
132216d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
132316d9e3a6SLisandro Dalcin            PCHYPRE
132416d9e3a6SLisandro Dalcin 
132516d9e3a6SLisandro Dalcin @*/
13267087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
132716d9e3a6SLisandro Dalcin {
13284ac538c5SBarry Smith   PetscErrorCode ierr;
132916d9e3a6SLisandro Dalcin 
133016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
13310700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
133216d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
13334ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
133416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
133516d9e3a6SLisandro Dalcin }
133616d9e3a6SLisandro Dalcin 
133716d9e3a6SLisandro Dalcin #undef __FUNCT__
133816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
133916d9e3a6SLisandro Dalcin /*@C
134016d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
134116d9e3a6SLisandro Dalcin 
134216d9e3a6SLisandro Dalcin    Input Parameter:
134316d9e3a6SLisandro Dalcin .     pc - the preconditioner context
134416d9e3a6SLisandro Dalcin 
134516d9e3a6SLisandro Dalcin    Output Parameter:
134633263987SBarry Smith .     name - either  pilut, parasails, boomeramg, ams
134716d9e3a6SLisandro Dalcin 
134816d9e3a6SLisandro Dalcin    Level: intermediate
134916d9e3a6SLisandro Dalcin 
135016d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
135116d9e3a6SLisandro Dalcin            PCHYPRE
135216d9e3a6SLisandro Dalcin 
135316d9e3a6SLisandro Dalcin @*/
13547087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
135516d9e3a6SLisandro Dalcin {
13564ac538c5SBarry Smith   PetscErrorCode ierr;
135716d9e3a6SLisandro Dalcin 
135816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
13590700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
136016d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
13614ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
136216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
136316d9e3a6SLisandro Dalcin }
136416d9e3a6SLisandro Dalcin 
136516d9e3a6SLisandro Dalcin /*MC
136616d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
136716d9e3a6SLisandro Dalcin 
136816d9e3a6SLisandro Dalcin    Options Database Keys:
136933263987SBarry Smith +   -pc_hypre_type - One of pilut, parasails, boomeramg, ams
137016d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
137116d9e3a6SLisandro Dalcin           preconditioner
137216d9e3a6SLisandro Dalcin 
137316d9e3a6SLisandro Dalcin    Level: intermediate
137416d9e3a6SLisandro Dalcin 
137516d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
137616d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
137716d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
137816d9e3a6SLisandro Dalcin 
137916d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
13800f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
13810f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
13820f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
13838f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
13840f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
13850f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
138616d9e3a6SLisandro Dalcin 
13870f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
13880f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
13890f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
139016d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
139116d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
139216d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
139316d9e3a6SLisandro Dalcin 
139416d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
139516d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
139616d9e3a6SLisandro Dalcin 
13979e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
13989e5bc791SBarry Smith 
139916d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
14009e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
140116d9e3a6SLisandro Dalcin 
140216d9e3a6SLisandro Dalcin M*/
140316d9e3a6SLisandro Dalcin 
140416d9e3a6SLisandro Dalcin #undef __FUNCT__
140516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
14068cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
140716d9e3a6SLisandro Dalcin {
140816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
140916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
141016d9e3a6SLisandro Dalcin 
141116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1412b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
14132fa5cd67SKarl Rupp 
141416d9e3a6SLisandro Dalcin   pc->data                = jac;
141516d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
141616d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
141716d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
141816d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
141916d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
14200298fd71SBarry Smith   jac->hypre_type         = NULL;
14214cb006feSStefano Zampini   jac->coords[0]          = NULL;
14224cb006feSStefano Zampini   jac->coords[1]          = NULL;
14234cb006feSStefano Zampini   jac->coords[2]          = NULL;
14244cb006feSStefano Zampini   jac->constants[0]       = NULL;
14254cb006feSStefano Zampini   jac->constants[1]       = NULL;
14264cb006feSStefano Zampini   jac->constants[2]       = NULL;
142716d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1428ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1429bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1430bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
143116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
143216d9e3a6SLisandro Dalcin }
1433ebc551c0SBarry Smith 
1434f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1435f91d8e95SBarry Smith 
1436b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1437b45d2f2cSJed Brown #include <petsc-private/matimpl.h>
1438ebc551c0SBarry Smith 
1439ebc551c0SBarry Smith typedef struct {
144068326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1441f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
14429e5bc791SBarry Smith 
14439e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
14444ddd07fcSJed Brown   PetscInt its;
14459e5bc791SBarry Smith   double   tol;
14464ddd07fcSJed Brown   PetscInt relax_type;
14474ddd07fcSJed Brown   PetscInt rap_type;
14484ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
14494ddd07fcSJed Brown   PetscInt max_levels;
1450ebc551c0SBarry Smith } PC_PFMG;
1451ebc551c0SBarry Smith 
1452ebc551c0SBarry Smith #undef __FUNCT__
1453ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1454ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1455ebc551c0SBarry Smith {
1456ebc551c0SBarry Smith   PetscErrorCode ierr;
1457f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1458ebc551c0SBarry Smith 
1459ebc551c0SBarry Smith   PetscFunctionBegin;
14602fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1461f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1462c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1463ebc551c0SBarry Smith   PetscFunctionReturn(0);
1464ebc551c0SBarry Smith }
1465ebc551c0SBarry Smith 
14669e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
14679e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
14689e5bc791SBarry Smith 
1469ebc551c0SBarry Smith #undef __FUNCT__
1470ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1471ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1472ebc551c0SBarry Smith {
1473ebc551c0SBarry Smith   PetscErrorCode ierr;
1474ace3abfcSBarry Smith   PetscBool      iascii;
1475f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1476ebc551c0SBarry Smith 
1477ebc551c0SBarry Smith   PetscFunctionBegin;
1478251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
14799e5bc791SBarry Smith   if (iascii) {
14809e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
14819e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
14829e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
14839e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
14849e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
14859e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
14863b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
14879e5bc791SBarry Smith   }
1488ebc551c0SBarry Smith   PetscFunctionReturn(0);
1489ebc551c0SBarry Smith }
1490ebc551c0SBarry Smith 
14919e5bc791SBarry Smith 
1492ebc551c0SBarry Smith #undef __FUNCT__
1493ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
14948c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptions *PetscOptionsObject,PC pc)
1495ebc551c0SBarry Smith {
1496ebc551c0SBarry Smith   PetscErrorCode ierr;
1497f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1498ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1499ebc551c0SBarry Smith 
1500ebc551c0SBarry Smith   PetscFunctionBegin;
1501e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
15020298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
150368326731SBarry Smith   if (flg) {
1504a0324ebeSBarry Smith     int level=3;
1505fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
150668326731SBarry Smith   }
15070298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1508fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
15090298fd71SBarry 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);
1510fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
15110298fd71SBarry 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);
1512fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
15139e5bc791SBarry Smith 
15140298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
1515fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
15163b46a515SGlenn Hammond 
15170298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1518fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
15190298fd71SBarry 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);
1520fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
15210298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
1522fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1523ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1524ebc551c0SBarry Smith   PetscFunctionReturn(0);
1525ebc551c0SBarry Smith }
1526ebc551c0SBarry Smith 
1527f91d8e95SBarry Smith #undef __FUNCT__
1528f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1529f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1530f91d8e95SBarry Smith {
1531f91d8e95SBarry Smith   PetscErrorCode  ierr;
1532f91d8e95SBarry Smith   PC_PFMG         *ex = (PC_PFMG*) pc->data;
1533f91d8e95SBarry Smith   PetscScalar     *xx,*yy;
15344ddd07fcSJed Brown   PetscInt        ilower[3],iupper[3];
153568326731SBarry Smith   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1536f91d8e95SBarry Smith 
1537f91d8e95SBarry Smith   PetscFunctionBegin;
1538dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1539aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1540f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1541f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1542f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1543f91d8e95SBarry Smith 
1544f91d8e95SBarry Smith   /* copy x values over to hypre */
1545fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1546f91d8e95SBarry Smith   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
15478b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,xx));
1548f91d8e95SBarry Smith   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
1549fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
1550fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1551f91d8e95SBarry Smith 
1552f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1553f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
15548b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
1555f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1556f91d8e95SBarry Smith   PetscFunctionReturn(0);
1557f91d8e95SBarry Smith }
1558f91d8e95SBarry Smith 
15599e5bc791SBarry Smith #undef __FUNCT__
15609e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1561ace3abfcSBarry 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)
15629e5bc791SBarry Smith {
15639e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
15649e5bc791SBarry Smith   PetscErrorCode ierr;
15654ddd07fcSJed Brown   PetscInt       oits;
15669e5bc791SBarry Smith 
15679e5bc791SBarry Smith   PetscFunctionBegin;
1568dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1569fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1570fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
15719e5bc791SBarry Smith 
15729e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
15738b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
15749e5bc791SBarry Smith   *outits = oits;
15759e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
15769e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1577fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1578fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
15799e5bc791SBarry Smith   PetscFunctionReturn(0);
15809e5bc791SBarry Smith }
15819e5bc791SBarry Smith 
15829e5bc791SBarry Smith 
15833a32d3dbSGlenn Hammond #undef __FUNCT__
15843a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
15853a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
15863a32d3dbSGlenn Hammond {
15873a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
15883a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
15893a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1590ace3abfcSBarry Smith   PetscBool       flg;
15913a32d3dbSGlenn Hammond 
15923a32d3dbSGlenn Hammond   PetscFunctionBegin;
1593251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1594ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
15953a32d3dbSGlenn Hammond 
15963a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
15972fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1598fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1599fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1600fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
16013a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
16023a32d3dbSGlenn Hammond }
16033a32d3dbSGlenn Hammond 
1604ebc551c0SBarry Smith 
1605ebc551c0SBarry Smith /*MC
1606ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1607ebc551c0SBarry Smith 
1608ebc551c0SBarry Smith    Level: advanced
1609ebc551c0SBarry Smith 
16109e5bc791SBarry Smith    Options Database:
16119e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
16129e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
16139e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
16149e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
16159e5bc791SBarry 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
16169e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
1617f91d8e95SBarry Smith 
16189e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
16199e5bc791SBarry Smith 
16208e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
1621aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
16229e5bc791SBarry Smith 
16239e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
1624ebc551c0SBarry Smith M*/
1625ebc551c0SBarry Smith 
1626ebc551c0SBarry Smith #undef __FUNCT__
1627ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
16288cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
1629ebc551c0SBarry Smith {
1630ebc551c0SBarry Smith   PetscErrorCode ierr;
1631ebc551c0SBarry Smith   PC_PFMG        *ex;
1632ebc551c0SBarry Smith 
1633ebc551c0SBarry Smith   PetscFunctionBegin;
1634b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
163568326731SBarry Smith   pc->data = ex;
1636ebc551c0SBarry Smith 
16379e5bc791SBarry Smith   ex->its            = 1;
16389e5bc791SBarry Smith   ex->tol            = 1.e-8;
16399e5bc791SBarry Smith   ex->relax_type     = 1;
16409e5bc791SBarry Smith   ex->rap_type       = 0;
16419e5bc791SBarry Smith   ex->num_pre_relax  = 1;
16429e5bc791SBarry Smith   ex->num_post_relax = 1;
16433b46a515SGlenn Hammond   ex->max_levels     = 0;
16449e5bc791SBarry Smith 
1645ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
1646ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
1647ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
1648f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
16499e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
165068326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
16512fa5cd67SKarl Rupp 
1652ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
1653fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1654ebc551c0SBarry Smith   PetscFunctionReturn(0);
1655ebc551c0SBarry Smith }
1656d851a50bSGlenn Hammond 
1657325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
1658325fc9f4SBarry Smith 
1659d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
1660d851a50bSGlenn Hammond typedef struct {
1661d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
1662d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
1663d851a50bSGlenn Hammond 
1664d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
16654ddd07fcSJed Brown   PetscInt its;
1666d851a50bSGlenn Hammond   double   tol;
16674ddd07fcSJed Brown   PetscInt relax_type;
16684ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
1669d851a50bSGlenn Hammond } PC_SysPFMG;
1670d851a50bSGlenn Hammond 
1671d851a50bSGlenn Hammond #undef __FUNCT__
1672d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
1673d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
1674d851a50bSGlenn Hammond {
1675d851a50bSGlenn Hammond   PetscErrorCode ierr;
1676d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1677d851a50bSGlenn Hammond 
1678d851a50bSGlenn Hammond   PetscFunctionBegin;
16792fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1680d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1681c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1682d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1683d851a50bSGlenn Hammond }
1684d851a50bSGlenn Hammond 
1685d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
1686d851a50bSGlenn Hammond 
1687d851a50bSGlenn Hammond #undef __FUNCT__
1688d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
1689d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
1690d851a50bSGlenn Hammond {
1691d851a50bSGlenn Hammond   PetscErrorCode ierr;
1692ace3abfcSBarry Smith   PetscBool      iascii;
1693d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1694d851a50bSGlenn Hammond 
1695d851a50bSGlenn Hammond   PetscFunctionBegin;
1696251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1697d851a50bSGlenn Hammond   if (iascii) {
1698d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
1699d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
1700d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
1701d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
1702d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
1703d851a50bSGlenn Hammond   }
1704d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1705d851a50bSGlenn Hammond }
1706d851a50bSGlenn Hammond 
1707d851a50bSGlenn Hammond 
1708d851a50bSGlenn Hammond #undef __FUNCT__
1709d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
17108c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptions *PetscOptionsObject,PC pc)
1711d851a50bSGlenn Hammond {
1712d851a50bSGlenn Hammond   PetscErrorCode ierr;
1713d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1714ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1715d851a50bSGlenn Hammond 
1716d851a50bSGlenn Hammond   PetscFunctionBegin;
1717e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
17180298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
1719d851a50bSGlenn Hammond   if (flg) {
1720d851a50bSGlenn Hammond     int level=3;
1721fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
1722d851a50bSGlenn Hammond   }
17230298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1724fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
17250298fd71SBarry 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);
1726fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
17270298fd71SBarry 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);
1728fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
1729d851a50bSGlenn Hammond 
17300298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1731fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
17320298fd71SBarry 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);
1733fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
1734d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
1735d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1736d851a50bSGlenn Hammond }
1737d851a50bSGlenn Hammond 
1738d851a50bSGlenn Hammond #undef __FUNCT__
1739d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
1740d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
1741d851a50bSGlenn Hammond {
1742d851a50bSGlenn Hammond   PetscErrorCode   ierr;
1743d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
1744d851a50bSGlenn Hammond   PetscScalar      *xx,*yy;
17454ddd07fcSJed Brown   PetscInt         ilower[3],iupper[3];
1746d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
17474ddd07fcSJed Brown   PetscInt         ordering= mx->dofs_order;
17484ddd07fcSJed Brown   PetscInt         nvars   = mx->nvars;
17494ddd07fcSJed Brown   PetscInt         part    = 0;
17504ddd07fcSJed Brown   PetscInt         size;
17514ddd07fcSJed Brown   PetscInt         i;
1752d851a50bSGlenn Hammond 
1753d851a50bSGlenn Hammond   PetscFunctionBegin;
1754dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1755aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1756d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
1757d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
1758d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
1759d851a50bSGlenn Hammond 
1760d851a50bSGlenn Hammond   size = 1;
17612fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
17622fa5cd67SKarl Rupp 
1763d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
1764d851a50bSGlenn Hammond   if (ordering) {
1765fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
1766d851a50bSGlenn Hammond     ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
17678b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,xx+(size*i)));
1768d851a50bSGlenn Hammond     ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
1769fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
1770fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
1771fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1772d851a50bSGlenn Hammond 
1773d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
1774d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
17758b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
1776d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1777a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
1778d851a50bSGlenn Hammond     PetscScalar *z;
17794ddd07fcSJed Brown     PetscInt    j, k;
1780d851a50bSGlenn Hammond 
1781785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
1782fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
1783d851a50bSGlenn Hammond     ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
1784d851a50bSGlenn Hammond 
1785d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
1786d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
1787d851a50bSGlenn Hammond       k= i*nvars;
17882fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
1789d851a50bSGlenn Hammond     }
17908b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
1791d851a50bSGlenn Hammond     ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
1792fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
1793fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1794d851a50bSGlenn Hammond 
1795d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
1796d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
17978b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
1798d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
1799d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
1800d851a50bSGlenn Hammond       k= i*nvars;
18012fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
1802d851a50bSGlenn Hammond     }
1803d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1804d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
1805d851a50bSGlenn Hammond   }
1806d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1807d851a50bSGlenn Hammond }
1808d851a50bSGlenn Hammond 
1809d851a50bSGlenn Hammond #undef __FUNCT__
1810d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
1811ace3abfcSBarry 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)
1812d851a50bSGlenn Hammond {
1813d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
1814d851a50bSGlenn Hammond   PetscErrorCode ierr;
18154ddd07fcSJed Brown   PetscInt       oits;
1816d851a50bSGlenn Hammond 
1817d851a50bSGlenn Hammond   PetscFunctionBegin;
1818dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1819fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
1820fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
1821d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
18228b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
1823d851a50bSGlenn Hammond   *outits = oits;
1824d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
1825d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1826fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
1827fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
1828d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1829d851a50bSGlenn Hammond }
1830d851a50bSGlenn Hammond 
1831d851a50bSGlenn Hammond 
1832d851a50bSGlenn Hammond #undef __FUNCT__
1833d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
1834d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
1835d851a50bSGlenn Hammond {
1836d851a50bSGlenn Hammond   PetscErrorCode   ierr;
1837d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
1838d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
1839ace3abfcSBarry Smith   PetscBool        flg;
1840d851a50bSGlenn Hammond 
1841d851a50bSGlenn Hammond   PetscFunctionBegin;
1842251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
1843ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
1844d851a50bSGlenn Hammond 
1845d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
18462fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1847fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
1848fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
1849fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
1850d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1851d851a50bSGlenn Hammond }
1852d851a50bSGlenn Hammond 
1853d851a50bSGlenn Hammond 
1854d851a50bSGlenn Hammond /*MC
1855d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
1856d851a50bSGlenn Hammond 
1857d851a50bSGlenn Hammond    Level: advanced
1858d851a50bSGlenn Hammond 
1859d851a50bSGlenn Hammond    Options Database:
1860d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
1861d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
1862d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
1863d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
1864d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
1865d851a50bSGlenn Hammond 
1866d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
1867d851a50bSGlenn Hammond 
1868f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
1869aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
1870d851a50bSGlenn Hammond            Also, only cell-centered variables.
1871d851a50bSGlenn Hammond 
1872d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
1873d851a50bSGlenn Hammond M*/
1874d851a50bSGlenn Hammond 
1875d851a50bSGlenn Hammond #undef __FUNCT__
1876d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
18778cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
1878d851a50bSGlenn Hammond {
1879d851a50bSGlenn Hammond   PetscErrorCode ierr;
1880d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
1881d851a50bSGlenn Hammond 
1882d851a50bSGlenn Hammond   PetscFunctionBegin;
1883b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
1884d851a50bSGlenn Hammond   pc->data = ex;
1885d851a50bSGlenn Hammond 
1886d851a50bSGlenn Hammond   ex->its            = 1;
1887d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
1888d851a50bSGlenn Hammond   ex->relax_type     = 1;
1889d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
1890d851a50bSGlenn Hammond   ex->num_post_relax = 1;
1891d851a50bSGlenn Hammond 
1892d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
1893d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
1894d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
1895d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
1896d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
1897d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
18982fa5cd67SKarl Rupp 
1899ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
1900fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
1901d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1902d851a50bSGlenn Hammond }
1903