xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 21df291b450e4ebf27ac0fc2b4dbb8de3f025202)
116d9e3a6SLisandro Dalcin 
216d9e3a6SLisandro Dalcin /*
316d9e3a6SLisandro Dalcin    Provides an interface to the LLNL package hypre
416d9e3a6SLisandro Dalcin */
50f1074feSSatish Balay 
60f1074feSSatish Balay /* Must use hypre 2.0.0 or more recent. */
70f1074feSSatish Balay 
8af0996ceSBarry Smith #include <petsc/private/pcimpl.h>          /*I "petscpc.h" I*/
9c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h>
104cb006feSStefano Zampini #include <_hypre_parcsr_ls.h>
1116d9e3a6SLisandro Dalcin 
12dff31646SBarry Smith static PetscBool cite = PETSC_FALSE;
131f817a21SBarry Smith static const char hypreCitation[] = "@manual{hypre-web-page,\n  title  = {{\\sl hypre}: High Performance Preconditioners},\n  organization = {Lawrence Livermore National Laboratory},\n  note  = {\\url{http://www.llnl.gov/CASC/hypre/}}\n}\n";
141f817a21SBarry Smith 
1516d9e3a6SLisandro Dalcin /*
1616d9e3a6SLisandro Dalcin    Private context (data structure) for the  preconditioner.
1716d9e3a6SLisandro Dalcin */
1816d9e3a6SLisandro Dalcin typedef struct {
1916d9e3a6SLisandro Dalcin   HYPRE_Solver   hsolver;
2016d9e3a6SLisandro Dalcin   HYPRE_IJMatrix ij;
2116d9e3a6SLisandro Dalcin   HYPRE_IJVector b,x;
2216d9e3a6SLisandro Dalcin 
234ddd07fcSJed Brown   HYPRE_Int (*destroy)(HYPRE_Solver);
244ddd07fcSJed Brown   HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
254ddd07fcSJed Brown   HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
26863406b8SStefano Zampini   HYPRE_Int (*setdgrad)(HYPRE_Solver,HYPRE_ParCSRMatrix);
27863406b8SStefano Zampini   HYPRE_Int (*setdcurl)(HYPRE_Solver,HYPRE_ParCSRMatrix);
28863406b8SStefano Zampini   HYPRE_Int (*setcoord)(HYPRE_Solver,HYPRE_ParVector,HYPRE_ParVector,HYPRE_ParVector);
29863406b8SStefano Zampini   HYPRE_Int (*setdim)(HYPRE_Solver,HYPRE_Int);
3016d9e3a6SLisandro Dalcin 
3116d9e3a6SLisandro Dalcin   MPI_Comm comm_hypre;
3216d9e3a6SLisandro Dalcin   char     *hypre_type;
3316d9e3a6SLisandro Dalcin 
3416d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
354ddd07fcSJed Brown   PetscInt maxiter;
3616d9e3a6SLisandro Dalcin   double   tol;
3716d9e3a6SLisandro Dalcin 
3816d9e3a6SLisandro Dalcin   /* options for Pilut */
394ddd07fcSJed Brown   PetscInt factorrowsize;
4016d9e3a6SLisandro Dalcin 
4116d9e3a6SLisandro Dalcin   /* options for ParaSails */
424ddd07fcSJed Brown   PetscInt nlevels;
4316d9e3a6SLisandro Dalcin   double   threshhold;
4416d9e3a6SLisandro Dalcin   double   filter;
454ddd07fcSJed Brown   PetscInt sym;
4616d9e3a6SLisandro Dalcin   double   loadbal;
474ddd07fcSJed Brown   PetscInt logging;
484ddd07fcSJed Brown   PetscInt ruse;
494ddd07fcSJed Brown   PetscInt symt;
5016d9e3a6SLisandro Dalcin 
5122b6d1caSBarry Smith   /* options for BoomerAMG */
52ace3abfcSBarry Smith   PetscBool printstatistics;
5316d9e3a6SLisandro Dalcin 
5416d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
554ddd07fcSJed Brown   PetscInt  cycletype;
564ddd07fcSJed Brown   PetscInt  maxlevels;
5716d9e3a6SLisandro Dalcin   double    strongthreshold;
5816d9e3a6SLisandro Dalcin   double    maxrowsum;
594ddd07fcSJed Brown   PetscInt  gridsweeps[3];
604ddd07fcSJed Brown   PetscInt  coarsentype;
614ddd07fcSJed Brown   PetscInt  measuretype;
624ddd07fcSJed Brown   PetscInt  relaxtype[3];
6316d9e3a6SLisandro Dalcin   double    relaxweight;
6416d9e3a6SLisandro Dalcin   double    outerrelaxweight;
654ddd07fcSJed Brown   PetscInt  relaxorder;
6616d9e3a6SLisandro Dalcin   double    truncfactor;
67ace3abfcSBarry Smith   PetscBool applyrichardson;
684ddd07fcSJed Brown   PetscInt  pmax;
694ddd07fcSJed Brown   PetscInt  interptype;
704ddd07fcSJed Brown   PetscInt  agg_nl;
714ddd07fcSJed Brown   PetscInt  agg_num_paths;
724ddd07fcSJed Brown   PetscInt  nodal_coarsen;
73ace3abfcSBarry Smith   PetscBool nodal_relax;
744ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
754cb006feSStefano Zampini 
76863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
77863406b8SStefano Zampini   PetscInt  as_print;
78863406b8SStefano Zampini   PetscInt  as_max_iter;
79863406b8SStefano Zampini   PetscReal as_tol;
80863406b8SStefano Zampini   PetscInt  as_relax_type;
81863406b8SStefano Zampini   PetscInt  as_relax_times;
82863406b8SStefano Zampini   PetscReal as_relax_weight;
83863406b8SStefano Zampini   PetscReal as_omega;
84863406b8SStefano Zampini   PetscInt  as_amg_alpha_opts[5]; /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for vector Poisson (AMS) or Curl problem (ADS) */
85863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
86863406b8SStefano Zampini   PetscInt  as_amg_beta_opts[5];  /* AMG coarsen type, agg_levels, relax_type, interp_type, Pmax for scalar Poisson (AMS) or vector Poisson (ADS) */
87863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
884cb006feSStefano Zampini   PetscInt  ams_cycle_type;
89863406b8SStefano Zampini   PetscInt  ads_cycle_type;
904cb006feSStefano Zampini 
914cb006feSStefano Zampini   /* additional data */
924cb006feSStefano Zampini   HYPRE_IJVector coords[3];
934cb006feSStefano Zampini   HYPRE_IJVector constants[3];
944cb006feSStefano Zampini   HYPRE_IJMatrix G;
95863406b8SStefano Zampini   HYPRE_IJMatrix C;
964cb006feSStefano Zampini   HYPRE_IJMatrix alpha_Poisson;
974cb006feSStefano Zampini   HYPRE_IJMatrix beta_Poisson;
984cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
9916d9e3a6SLisandro Dalcin } PC_HYPRE;
10016d9e3a6SLisandro Dalcin 
101d2128fa2SBarry Smith #undef __FUNCT__
102d2128fa2SBarry Smith #define __FUNCT__ "PCHYPREGetSolver"
103d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
104d2128fa2SBarry Smith {
105d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
106d2128fa2SBarry Smith 
107d2128fa2SBarry Smith   PetscFunctionBegin;
108d2128fa2SBarry Smith   *hsolver = jac->hsolver;
109d2128fa2SBarry Smith   PetscFunctionReturn(0);
110d2128fa2SBarry Smith }
11116d9e3a6SLisandro Dalcin 
11216d9e3a6SLisandro Dalcin #undef __FUNCT__
11316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE"
11416d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
11516d9e3a6SLisandro Dalcin {
11616d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11716d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
11816d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
11916d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
12016d9e3a6SLisandro Dalcin   PetscInt           bs;
12116d9e3a6SLisandro Dalcin 
12216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
12316d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
12402a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
12516d9e3a6SLisandro Dalcin   }
1265f5c5b43SBarry Smith 
1275f5c5b43SBarry Smith   if (pc->setupcalled) {
1285f5c5b43SBarry Smith     /* always destroy the old matrix and create a new memory;
1295f5c5b43SBarry Smith        hope this does not churn the memory too much. The problem
1305f5c5b43SBarry Smith        is I do not know if it is possible to put the matrix back to
1315f5c5b43SBarry Smith        its initial state so that we can directly copy the values
1325f5c5b43SBarry Smith        the second time through. */
133fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
1345f5c5b43SBarry Smith     jac->ij = 0;
13516d9e3a6SLisandro Dalcin   }
1365f5c5b43SBarry Smith 
13716d9e3a6SLisandro Dalcin   if (!jac->ij) { /* create the matrix the first time through */
13816d9e3a6SLisandro Dalcin     ierr = MatHYPRE_IJMatrixCreate(pc->pmat,&jac->ij);CHKERRQ(ierr);
13916d9e3a6SLisandro Dalcin   }
14016d9e3a6SLisandro Dalcin   if (!jac->b) { /* create the vectors the first time through */
14116d9e3a6SLisandro Dalcin     Vec x,b;
1422a7a6963SBarry Smith     ierr = MatCreateVecs(pc->pmat,&x,&b);CHKERRQ(ierr);
14316d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(x,&jac->x);CHKERRQ(ierr);
14416d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(b,&jac->b);CHKERRQ(ierr);
1456bf464f9SBarry Smith     ierr = VecDestroy(&x);CHKERRQ(ierr);
1466bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
14716d9e3a6SLisandro Dalcin   }
1485f5c5b43SBarry Smith 
14916d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
15016d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
15116d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1522fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
1534cb006feSStefano Zampini   }
154863406b8SStefano Zampini 
1554cb006feSStefano Zampini   /* special case for AMS */
1564cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
1574cb006feSStefano 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()");
1584cb006feSStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
1594cb006feSStefano Zampini   }
160863406b8SStefano Zampini   /* special case for ADS */
161863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
162863406b8SStefano Zampini     if (!jac->coords[0]) {
163863406b8SStefano Zampini       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs coordinate vectors via PCSetCoordinates()");
164fd444223SStefano Zampini     } else if (!jac->coords[1] || !jac->coords[2]) {
165fd444223SStefano Zampini       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner has been designed for three dimensional problems! For two dimensional problems, use HYPRE AMS instead");
166863406b8SStefano Zampini     }
167863406b8SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
168863406b8SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete curl operator via PCHYPRESetDiscreteGradient");
169863406b8SStefano Zampini   }
17016d9e3a6SLisandro Dalcin   ierr = MatHYPRE_IJMatrixCopy(pc->pmat,jac->ij);CHKERRQ(ierr);
171fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
172fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&bv));
173fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&xv));
174fd3f9acdSBarry Smith   PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr););
17516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
17616d9e3a6SLisandro Dalcin }
17716d9e3a6SLisandro Dalcin 
17816d9e3a6SLisandro Dalcin /*
17916d9e3a6SLisandro Dalcin     Replaces the address where the HYPRE vector points to its data with the address of
18016d9e3a6SLisandro Dalcin   PETSc's data. Saves the old address so it can be reset when we are finished with it.
18116d9e3a6SLisandro Dalcin   Allows use to get the data into a HYPRE vector without the cost of memcopies
18216d9e3a6SLisandro Dalcin */
18316d9e3a6SLisandro Dalcin #define HYPREReplacePointer(b,newvalue,savedvalue) { \
18416d9e3a6SLisandro Dalcin     hypre_ParVector *par_vector   = (hypre_ParVector*)hypre_IJVectorObject(((hypre_IJVector*)b)); \
18516d9e3a6SLisandro Dalcin     hypre_Vector    *local_vector = hypre_ParVectorLocalVector(par_vector); \
18616d9e3a6SLisandro Dalcin     savedvalue         = local_vector->data; \
1870ad7597dSKarl Rupp     local_vector->data = newvalue;          \
1880ad7597dSKarl Rupp }
18916d9e3a6SLisandro Dalcin 
19016d9e3a6SLisandro Dalcin #undef __FUNCT__
19116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE"
19216d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
19316d9e3a6SLisandro Dalcin {
19416d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
19516d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
19616d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
197d9ca1df4SBarry Smith   PetscScalar        *xv;
198d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
19916d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
200d9ca1df4SBarry Smith   PetscScalar        *sxv;
2014ddd07fcSJed Brown   PetscInt           hierr;
20216d9e3a6SLisandro Dalcin 
20316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
204dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
20516d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
206d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
20716d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
208d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
20916d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
21016d9e3a6SLisandro Dalcin 
211fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
212fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
213fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
214fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
21565e19b50SBarry Smith                                if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
216fd3f9acdSBarry Smith                                if (hierr) hypre__global_error = 0;);
21716d9e3a6SLisandro Dalcin 
218*21df291bSStefano Zampini   if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero) {
219*21df291bSStefano Zampini     PetscStackCall("HYPRE_AMSProjectOutGradients",ierr = HYPRE_AMSProjectOutGradients(jac->hsolver,jxv);CHKERRQ(ierr););
220*21df291bSStefano Zampini   }
221d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)sbv,bv);
22216d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
22316d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
224d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
22516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
22616d9e3a6SLisandro Dalcin }
22716d9e3a6SLisandro Dalcin 
22816d9e3a6SLisandro Dalcin #undef __FUNCT__
22916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE"
23016d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
23116d9e3a6SLisandro Dalcin {
23216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
23316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
23416d9e3a6SLisandro Dalcin 
23516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
236fd3f9acdSBarry Smith   if (jac->ij) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
237fd3f9acdSBarry Smith   if (jac->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->b));
238fd3f9acdSBarry Smith   if (jac->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->x));
2394cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
2404cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
2414cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
2424cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
2434cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
2444cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
2454cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
246863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
2474cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
2484cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
249226b0620SJed Brown   if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr););
250503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
25116d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
252c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
25316d9e3a6SLisandro Dalcin 
25416d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
255bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
256bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
2574cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
2584cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
259863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
2604cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
2614cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",NULL);CHKERRQ(ierr);
2624cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",NULL);CHKERRQ(ierr);
26316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
26416d9e3a6SLisandro Dalcin }
26516d9e3a6SLisandro Dalcin 
26616d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
26716d9e3a6SLisandro Dalcin #undef __FUNCT__
26816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut"
2698c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptions *PetscOptionsObject,PC pc)
27016d9e3a6SLisandro Dalcin {
27116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
27216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
273ace3abfcSBarry Smith   PetscBool      flag;
27416d9e3a6SLisandro Dalcin 
27516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
276e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
27716d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
278fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
27916d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
280fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
28116d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
282fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
28316d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
28416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
28516d9e3a6SLisandro Dalcin }
28616d9e3a6SLisandro Dalcin 
28716d9e3a6SLisandro Dalcin #undef __FUNCT__
28816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut"
28916d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
29016d9e3a6SLisandro Dalcin {
29116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
29216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
293ace3abfcSBarry Smith   PetscBool      iascii;
29416d9e3a6SLisandro Dalcin 
29516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
296251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
29716d9e3a6SLisandro Dalcin   if (iascii) {
29816d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
29916d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
30016d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
30116d9e3a6SLisandro Dalcin     } else {
30216d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr);
30316d9e3a6SLisandro Dalcin     }
30416d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
30557622a8eSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
30616d9e3a6SLisandro Dalcin     } else {
30716d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr);
30816d9e3a6SLisandro Dalcin     }
30916d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
31016d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
31116d9e3a6SLisandro Dalcin     } else {
31216d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default factor row size \n");CHKERRQ(ierr);
31316d9e3a6SLisandro Dalcin     }
31416d9e3a6SLisandro Dalcin   }
31516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
31616d9e3a6SLisandro Dalcin }
31716d9e3a6SLisandro Dalcin 
31816d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
31916d9e3a6SLisandro Dalcin 
32016d9e3a6SLisandro Dalcin #undef __FUNCT__
32116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG"
32216d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
32316d9e3a6SLisandro Dalcin {
32416d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
32516d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
32616d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
327d9ca1df4SBarry Smith   PetscScalar        *xv;
328d9ca1df4SBarry Smith   const PetscScalar  *bv;
32916d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
33016d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
3314ddd07fcSJed Brown   PetscInt           hierr;
33216d9e3a6SLisandro Dalcin 
33316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
334dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
33516d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
336d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
33716d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
338d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
33916d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
34016d9e3a6SLisandro Dalcin 
341fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
342fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
343fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
34416d9e3a6SLisandro Dalcin 
34516d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
34616d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
347e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
34816d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
34916d9e3a6SLisandro Dalcin 
35016d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
35116d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
35216d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
353d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
35416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
35516d9e3a6SLisandro Dalcin }
35616d9e3a6SLisandro Dalcin 
357a669f990SJed Brown /* static array length */
358a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
359a669f990SJed Brown 
36016d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
3610f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
36216d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
36365de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
36465de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
36565de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
36665de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
36765de4495SJed Brown                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */,
36865de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
3690f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
3700f1074feSSatish Balay                                                   "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"};
37116d9e3a6SLisandro Dalcin #undef __FUNCT__
37216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG"
3738c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptions *PetscOptionsObject,PC pc)
37416d9e3a6SLisandro Dalcin {
37516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
37616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
3774ddd07fcSJed Brown   PetscInt       n,indx,level;
378ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
37916d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
38016d9e3a6SLisandro Dalcin 
38116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
382e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
3834336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
38416d9e3a6SLisandro Dalcin   if (flg) {
3854336a9eeSBarry Smith     jac->cycletype = indx+1;
386fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
38716d9e3a6SLisandro Dalcin   }
38816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
38916d9e3a6SLisandro Dalcin   if (flg) {
390ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
391fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
39216d9e3a6SLisandro Dalcin   }
39316d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
39416d9e3a6SLisandro Dalcin   if (flg) {
395ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
396fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
39716d9e3a6SLisandro Dalcin   }
3980f1074feSSatish 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);
39916d9e3a6SLisandro Dalcin   if (flg) {
40057622a8eSBarry 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);
401fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
40216d9e3a6SLisandro Dalcin   }
40316d9e3a6SLisandro Dalcin 
4040f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
40516d9e3a6SLisandro Dalcin   if (flg) {
40657622a8eSBarry 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);
407fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
40816d9e3a6SLisandro Dalcin   }
40916d9e3a6SLisandro Dalcin 
4100f1074feSSatish 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);
4110f1074feSSatish Balay   if (flg) {
41257622a8eSBarry 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);
413fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
4140f1074feSSatish Balay   }
4150f1074feSSatish Balay 
4160f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
4170f1074feSSatish Balay   if (flg) {
41857622a8eSBarry 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);
4190f1074feSSatish Balay 
420fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
4210f1074feSSatish Balay   }
4220f1074feSSatish Balay 
4230f1074feSSatish Balay 
4240f1074feSSatish 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);
4250f1074feSSatish Balay   if (flg) {
42657622a8eSBarry 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);
4270f1074feSSatish Balay 
428fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
4290f1074feSSatish Balay   }
4300f1074feSSatish Balay 
4310f1074feSSatish Balay 
43216d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
43316d9e3a6SLisandro Dalcin   if (flg) {
43457622a8eSBarry 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);
435fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
43616d9e3a6SLisandro Dalcin   }
43716d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
43816d9e3a6SLisandro Dalcin   if (flg) {
43957622a8eSBarry 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);
44057622a8eSBarry 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);
441fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
44216d9e3a6SLisandro Dalcin   }
44316d9e3a6SLisandro Dalcin 
44416d9e3a6SLisandro Dalcin   /* Grid sweeps */
4450f1074feSSatish 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);
44616d9e3a6SLisandro Dalcin   if (flg) {
447fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
44816d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
44916d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
4500f1074feSSatish Balay     jac->gridsweeps[1] = indx;
4510f1074feSSatish Balay     /*defaults coarse to 1 */
4520f1074feSSatish Balay     jac->gridsweeps[2] = 1;
45316d9e3a6SLisandro Dalcin   }
4540f1074feSSatish Balay 
4550f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
45616d9e3a6SLisandro Dalcin   if (flg) {
457fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
4580f1074feSSatish Balay     jac->gridsweeps[0] = indx;
45916d9e3a6SLisandro Dalcin   }
46016d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
46116d9e3a6SLisandro Dalcin   if (flg) {
462fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
4630f1074feSSatish Balay     jac->gridsweeps[1] = indx;
46416d9e3a6SLisandro Dalcin   }
4650f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
46616d9e3a6SLisandro Dalcin   if (flg) {
467fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
4680f1074feSSatish Balay     jac->gridsweeps[2] = indx;
46916d9e3a6SLisandro Dalcin   }
47016d9e3a6SLisandro Dalcin 
47116d9e3a6SLisandro Dalcin   /* Relax type */
472a669f990SJed 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);
47316d9e3a6SLisandro Dalcin   if (flg) {
4740f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
475fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
4760f1074feSSatish Balay     /* by default, coarse type set to 9 */
4770f1074feSSatish Balay     jac->relaxtype[2] = 9;
4780f1074feSSatish Balay 
47916d9e3a6SLisandro Dalcin   }
480a669f990SJed 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);
48116d9e3a6SLisandro Dalcin   if (flg) {
48216d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
483fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
48416d9e3a6SLisandro Dalcin   }
485a669f990SJed 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);
48616d9e3a6SLisandro Dalcin   if (flg) {
4870f1074feSSatish Balay     jac->relaxtype[1] = indx;
488fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
48916d9e3a6SLisandro Dalcin   }
490a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
49116d9e3a6SLisandro Dalcin   if (flg) {
4920f1074feSSatish Balay     jac->relaxtype[2] = indx;
493fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
49416d9e3a6SLisandro Dalcin   }
49516d9e3a6SLisandro Dalcin 
49616d9e3a6SLisandro Dalcin   /* Relaxation Weight */
49716d9e3a6SLisandro 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);
49816d9e3a6SLisandro Dalcin   if (flg) {
499fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
50016d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
50116d9e3a6SLisandro Dalcin   }
50216d9e3a6SLisandro Dalcin 
50316d9e3a6SLisandro Dalcin   n         = 2;
50416d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
50516d9e3a6SLisandro 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);
50616d9e3a6SLisandro Dalcin   if (flg) {
50716d9e3a6SLisandro Dalcin     if (n == 2) {
50816d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
509fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
510ce94432eSBarry 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);
51116d9e3a6SLisandro Dalcin   }
51216d9e3a6SLisandro Dalcin 
51316d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
51416d9e3a6SLisandro 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);
51516d9e3a6SLisandro Dalcin   if (flg) {
516fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
51716d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
51816d9e3a6SLisandro Dalcin   }
51916d9e3a6SLisandro Dalcin 
52016d9e3a6SLisandro Dalcin   n         = 2;
52116d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
52216d9e3a6SLisandro 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);
52316d9e3a6SLisandro Dalcin   if (flg) {
52416d9e3a6SLisandro Dalcin     if (n == 2) {
52516d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
526fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
527ce94432eSBarry 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);
52816d9e3a6SLisandro Dalcin   }
52916d9e3a6SLisandro Dalcin 
53016d9e3a6SLisandro Dalcin   /* the Relax Order */
531acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
53216d9e3a6SLisandro Dalcin 
5338afaa268SBarry Smith   if (flg && tmp_truth) {
53416d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
535fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
53616d9e3a6SLisandro Dalcin   }
537a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
53816d9e3a6SLisandro Dalcin   if (flg) {
53916d9e3a6SLisandro Dalcin     jac->measuretype = indx;
540fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
54116d9e3a6SLisandro Dalcin   }
5420f1074feSSatish Balay   /* update list length 3/07 */
543a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
54416d9e3a6SLisandro Dalcin   if (flg) {
54516d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
546fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
54716d9e3a6SLisandro Dalcin   }
5480f1074feSSatish Balay 
5490f1074feSSatish Balay   /* new 3/07 */
550a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
5510f1074feSSatish Balay   if (flg) {
5520f1074feSSatish Balay     jac->interptype = indx;
553fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
5540f1074feSSatish Balay   }
5550f1074feSSatish Balay 
556b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
55716d9e3a6SLisandro Dalcin   if (flg) {
558b96a4a96SBarry Smith     level = 3;
5590298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
5602fa5cd67SKarl Rupp 
561b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
562fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
5632ae77aedSBarry Smith   }
5642ae77aedSBarry Smith 
565b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
5662ae77aedSBarry Smith   if (flg) {
567b96a4a96SBarry Smith     level = 3;
5680298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
5692fa5cd67SKarl Rupp 
570b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
571fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
57216d9e3a6SLisandro Dalcin   }
5738f87f92bSBarry Smith 
5748afaa268SBarry Smith   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_coarsen", "HYPRE_BoomerAMGSetNodal()", "None", jac->nodal_coarsen ? PETSC_TRUE : PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5758f87f92bSBarry Smith   if (flg && tmp_truth) {
5768f87f92bSBarry Smith     jac->nodal_coarsen = 1;
577fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,1));
5788f87f92bSBarry Smith   }
5798f87f92bSBarry Smith 
580acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5818f87f92bSBarry Smith   if (flg && tmp_truth) {
5828f87f92bSBarry Smith     PetscInt tmp_int;
5838f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
5848f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
585fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
586fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
587fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
588fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
5898f87f92bSBarry Smith   }
5908f87f92bSBarry Smith 
59116d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
59216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
59316d9e3a6SLisandro Dalcin }
59416d9e3a6SLisandro Dalcin 
59516d9e3a6SLisandro Dalcin #undef __FUNCT__
59616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG"
597ace3abfcSBarry 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)
59816d9e3a6SLisandro Dalcin {
59916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
60016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
6014ddd07fcSJed Brown   PetscInt       oits;
60216d9e3a6SLisandro Dalcin 
60316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
604dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
605fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
606fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
60716d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
60816d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
60916d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
6108b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
6114d0a8057SBarry Smith   *outits = oits;
6124d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
6134d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
614fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
615fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
61616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
61716d9e3a6SLisandro Dalcin }
61816d9e3a6SLisandro Dalcin 
61916d9e3a6SLisandro Dalcin 
62016d9e3a6SLisandro Dalcin #undef __FUNCT__
62116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG"
62216d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
62316d9e3a6SLisandro Dalcin {
62416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
62516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
626ace3abfcSBarry Smith   PetscBool      iascii;
62716d9e3a6SLisandro Dalcin 
62816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
629251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
63016d9e3a6SLisandro Dalcin   if (iascii) {
63116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
63216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
63316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
63416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
63557622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
63657622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
63757622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
6380f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
6390f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
6400f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
6410f1074feSSatish Balay 
64257622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
64316d9e3a6SLisandro Dalcin 
6440f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
6450f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
6460f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
64716d9e3a6SLisandro Dalcin 
6480f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
6490f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
6500f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
65116d9e3a6SLisandro Dalcin 
65257622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
65357622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
65416d9e3a6SLisandro Dalcin 
65516d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
65616d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr);
65716d9e3a6SLisandro Dalcin     } else {
65816d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr);
65916d9e3a6SLisandro Dalcin     }
66016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
66116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
6620f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
6638f87f92bSBarry Smith     if (jac->nodal_coarsen) {
6648f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal())\n");CHKERRQ(ierr);
6658f87f92bSBarry Smith     }
6668f87f92bSBarry Smith     if (jac->nodal_relax) {
6678f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
6688f87f92bSBarry Smith     }
66916d9e3a6SLisandro Dalcin   }
67016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
67116d9e3a6SLisandro Dalcin }
67216d9e3a6SLisandro Dalcin 
67316d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
67416d9e3a6SLisandro Dalcin #undef __FUNCT__
67516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails"
6768c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptions *PetscOptionsObject,PC pc)
67716d9e3a6SLisandro Dalcin {
67816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
67916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
6804ddd07fcSJed Brown   PetscInt       indx;
681ace3abfcSBarry Smith   PetscBool      flag;
68216d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
68316d9e3a6SLisandro Dalcin 
68416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
685e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
68616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
68716d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
6882fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
68916d9e3a6SLisandro Dalcin 
69016d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
6912fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
69216d9e3a6SLisandro Dalcin 
69316d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
6942fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
69516d9e3a6SLisandro Dalcin 
696acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
6972fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
69816d9e3a6SLisandro Dalcin 
699acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
7002fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
70116d9e3a6SLisandro Dalcin 
702a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
70316d9e3a6SLisandro Dalcin   if (flag) {
70416d9e3a6SLisandro Dalcin     jac->symt = indx;
705fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
70616d9e3a6SLisandro Dalcin   }
70716d9e3a6SLisandro Dalcin 
70816d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
70916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
71016d9e3a6SLisandro Dalcin }
71116d9e3a6SLisandro Dalcin 
71216d9e3a6SLisandro Dalcin #undef __FUNCT__
71316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails"
71416d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
71516d9e3a6SLisandro Dalcin {
71616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
71716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
718ace3abfcSBarry Smith   PetscBool      iascii;
71916d9e3a6SLisandro Dalcin   const char     *symt = 0;;
72016d9e3a6SLisandro Dalcin 
72116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
722251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
72316d9e3a6SLisandro Dalcin   if (iascii) {
72416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
72516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
72657622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
72757622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: filter %g\n",(double)jac->filter);CHKERRQ(ierr);
72857622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
729ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
730ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
7312fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
7322fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
7332fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
734ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
73516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr);
73616d9e3a6SLisandro Dalcin   }
73716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
73816d9e3a6SLisandro Dalcin }
7394cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
7404cb006feSStefano Zampini #undef __FUNCT__
7414cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS"
7429fa463a7SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptions *PetscOptionsObject,PC pc)
7434cb006feSStefano Zampini {
7444cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
7454cb006feSStefano Zampini   PetscErrorCode ierr;
7464cb006feSStefano Zampini   PetscInt       n;
7474cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
7484cb006feSStefano Zampini 
7494cb006feSStefano Zampini   PetscFunctionBegin;
7509fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
751863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
752863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
753863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_max_iter","Maximum number of AMS multigrid iterations within PCApply","None",jac->as_max_iter,&jac->as_max_iter,&flag);CHKERRQ(ierr);
754863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
7554cb006feSStefano 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);
7564cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
757863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
758863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
759863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_relax_type","Relaxation type for AMS smoother","None",jac->as_relax_type,&jac->as_relax_type,&flag);CHKERRQ(ierr);
760863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_relax_times","Number of relaxation steps for AMS smoother","None",jac->as_relax_times,&jac->as_relax_times,&flag2);CHKERRQ(ierr);
761863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_relax_weight","Relaxation weight for AMS smoother","None",jac->as_relax_weight,&jac->as_relax_weight,&flag3);CHKERRQ(ierr);
762863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
7634cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
764863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
765863406b8SStefano Zampini                                                                       jac->as_relax_times,
766863406b8SStefano Zampini                                                                       jac->as_relax_weight,
767863406b8SStefano Zampini                                                                       jac->as_omega));
7684cb006feSStefano Zampini   }
769863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_amg_alpha_theta","Threshold for strong coupling of vector Poisson AMG solver","None",jac->as_amg_alpha_theta,&jac->as_amg_alpha_theta,&flag);CHKERRQ(ierr);
7704cb006feSStefano Zampini   n = 5;
771863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
7724cb006feSStefano Zampini   if (flag || flag2) {
773863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
774863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
775863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
776863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
777863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
778863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
7794cb006feSStefano Zampini   }
780863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_amg_beta_theta","Threshold for strong coupling of scalar Poisson AMG solver","None",jac->as_amg_beta_theta,&jac->as_amg_beta_theta,&flag);CHKERRQ(ierr);
7814cb006feSStefano Zampini   n = 5;
782863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_beta_options","AMG options for scalar Poisson solver","None",jac->as_amg_beta_opts,&n,&flag2);CHKERRQ(ierr);
7834cb006feSStefano Zampini   if (flag || flag2) {
784863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
785863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
786863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
787863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
788863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
789863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
7904cb006feSStefano Zampini   }
7914cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
7924cb006feSStefano Zampini   PetscFunctionReturn(0);
7934cb006feSStefano Zampini }
7944cb006feSStefano Zampini 
7954cb006feSStefano Zampini #undef __FUNCT__
7964cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS"
7974cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
7984cb006feSStefano Zampini {
7994cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
8004cb006feSStefano Zampini   PetscErrorCode ierr;
8014cb006feSStefano Zampini   PetscBool      iascii;
8024cb006feSStefano Zampini 
8034cb006feSStefano Zampini   PetscFunctionBegin;
8044cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
8054cb006feSStefano Zampini   if (iascii) {
8064cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
807863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
8084cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
809863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
810863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
811863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
812863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
813863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
8144cb006feSStefano Zampini     if (jac->alpha_Poisson) {
8154cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8164cb006feSStefano Zampini     } else {
8174cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr);
8184cb006feSStefano Zampini     }
819863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
820863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
821863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
822863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
823863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
824863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
8254cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
8264cb006feSStefano Zampini       if (jac->beta_Poisson) {
8274cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8284cb006feSStefano Zampini       } else {
8294cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr);
8304cb006feSStefano Zampini       }
831863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
832863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
833863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
834863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
835863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
836863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
8374cb006feSStefano Zampini     }
8384cb006feSStefano Zampini   }
8394cb006feSStefano Zampini   PetscFunctionReturn(0);
8404cb006feSStefano Zampini }
8414cb006feSStefano Zampini 
8424cb006feSStefano Zampini #undef __FUNCT__
843863406b8SStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_ADS"
844863406b8SStefano Zampini static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptions *PetscOptionsObject,PC pc)
845863406b8SStefano Zampini {
846863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
847863406b8SStefano Zampini   PetscErrorCode ierr;
848863406b8SStefano Zampini   PetscInt       n;
849863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
850863406b8SStefano Zampini 
851863406b8SStefano Zampini   PetscFunctionBegin;
852863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
853863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
854863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
855863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_max_iter","Maximum number of ADS multigrid iterations within PCApply","None",jac->as_max_iter,&jac->as_max_iter,&flag);CHKERRQ(ierr);
856863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
857863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_cycle_type","Cycle type for ADS multigrid","None",jac->ads_cycle_type,&jac->ads_cycle_type,&flag);CHKERRQ(ierr);
858863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
859863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
860863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
861863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_relax_type","Relaxation type for ADS smoother","None",jac->as_relax_type,&jac->as_relax_type,&flag);CHKERRQ(ierr);
862863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_relax_times","Number of relaxation steps for ADS smoother","None",jac->as_relax_times,&jac->as_relax_times,&flag2);CHKERRQ(ierr);
863863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_relax_weight","Relaxation weight for ADS smoother","None",jac->as_relax_weight,&jac->as_relax_weight,&flag3);CHKERRQ(ierr);
864863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
865863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
866863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
867863406b8SStefano Zampini                                                                       jac->as_relax_times,
868863406b8SStefano Zampini                                                                       jac->as_relax_weight,
869863406b8SStefano Zampini                                                                       jac->as_omega));
870863406b8SStefano Zampini   }
871863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_ams_theta","Threshold for strong coupling of AMS solver inside ADS","None",jac->as_amg_alpha_theta,&jac->as_amg_alpha_theta,&flag);CHKERRQ(ierr);
872863406b8SStefano Zampini   n = 5;
873863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ads_ams_options","AMG options for AMS solver inside ADS","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
874863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_ams_cycle_type","Cycle type for AMS solver inside ADS","None",jac->ams_cycle_type,&jac->ams_cycle_type,&flag3);CHKERRQ(ierr);
875863406b8SStefano Zampini   if (flag || flag2 || flag3) {
876863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
877863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
878863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
879863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
880863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
881863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
882863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
883863406b8SStefano Zampini   }
884863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_amg_theta","Threshold for strong coupling of vector AMG solver inside ADS","None",jac->as_amg_beta_theta,&jac->as_amg_beta_theta,&flag);CHKERRQ(ierr);
885863406b8SStefano Zampini   n = 5;
886863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ads_amg_options","AMG options for vector AMG solver inside ADS","None",jac->as_amg_beta_opts,&n,&flag2);CHKERRQ(ierr);
887863406b8SStefano Zampini   if (flag || flag2) {
888863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
889863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
890863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
891863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
892863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
893863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
894863406b8SStefano Zampini   }
895863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
896863406b8SStefano Zampini   PetscFunctionReturn(0);
897863406b8SStefano Zampini }
898863406b8SStefano Zampini 
899863406b8SStefano Zampini #undef __FUNCT__
900863406b8SStefano Zampini #define __FUNCT__ "PCView_HYPRE_ADS"
901863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
902863406b8SStefano Zampini {
903863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
904863406b8SStefano Zampini   PetscErrorCode ierr;
905863406b8SStefano Zampini   PetscBool      iascii;
906863406b8SStefano Zampini 
907863406b8SStefano Zampini   PetscFunctionBegin;
908863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
909863406b8SStefano Zampini   if (iascii) {
910863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
911863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
912863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
913863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
914863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
915863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
916863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
917863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
918863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: AMS solver\n");CHKERRQ(ierr);
919863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
920863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
921863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
922863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
923863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
924863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
925863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
926863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: vector Poisson solver\n");CHKERRQ(ierr);
927863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
928863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
929863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
930863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
931863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
932863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
933863406b8SStefano Zampini   }
934863406b8SStefano Zampini   PetscFunctionReturn(0);
935863406b8SStefano Zampini }
936863406b8SStefano Zampini 
937863406b8SStefano Zampini #undef __FUNCT__
938863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE"
939863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
9404cb006feSStefano Zampini {
9414cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
9424cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_G;
9434cb006feSStefano Zampini   PetscErrorCode     ierr;
9444cb006feSStefano Zampini 
9454cb006feSStefano Zampini   PetscFunctionBegin;
9464cb006feSStefano Zampini   /* throw away any discrete gradient if already set */
9474cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
9484cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(G,&jac->G);CHKERRQ(ierr);
9494cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(G,jac->G);CHKERRQ(ierr);
9504cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->G,(void**)(&parcsr_G)));
951863406b8SStefano Zampini   PetscStackCall("Hypre set gradient",ierr = (*jac->setdgrad)(jac->hsolver,parcsr_G);CHKERRQ(ierr););
9524cb006feSStefano Zampini   PetscFunctionReturn(0);
9534cb006feSStefano Zampini }
9544cb006feSStefano Zampini 
9554cb006feSStefano Zampini #undef __FUNCT__
9564cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient"
9574cb006feSStefano Zampini /*@
9584cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
9594cb006feSStefano Zampini 
9604cb006feSStefano Zampini    Collective on PC
9614cb006feSStefano Zampini 
9624cb006feSStefano Zampini    Input Parameters:
9634cb006feSStefano Zampini +  pc - the preconditioning context
9644cb006feSStefano Zampini -  G - the discrete gradient
9654cb006feSStefano Zampini 
9664cb006feSStefano Zampini    Level: intermediate
9674cb006feSStefano Zampini 
9684cb006feSStefano 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
969863406b8SStefano Zampini           Each row of G has 2 nonzeros, with column indexes being the global indexes of edge's endpoints: matrix entries are +1 and -1 depending on edge orientation
9704cb006feSStefano Zampini 
9714cb006feSStefano Zampini .seealso:
9724cb006feSStefano Zampini @*/
9734cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
9744cb006feSStefano Zampini {
9754cb006feSStefano Zampini   PetscErrorCode ierr;
9764cb006feSStefano Zampini 
9774cb006feSStefano Zampini   PetscFunctionBegin;
9784cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
9794cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
9804cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
9814cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
9824cb006feSStefano Zampini   PetscFunctionReturn(0);
9834cb006feSStefano Zampini }
9844cb006feSStefano Zampini 
9854cb006feSStefano Zampini #undef __FUNCT__
986863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl_HYPRE"
987863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
988863406b8SStefano Zampini {
989863406b8SStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
990863406b8SStefano Zampini   HYPRE_ParCSRMatrix parcsr_C;
991863406b8SStefano Zampini   PetscErrorCode     ierr;
992863406b8SStefano Zampini 
993863406b8SStefano Zampini   PetscFunctionBegin;
994863406b8SStefano Zampini   /* throw away any discrete curl if already set */
995863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
996863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(C,&jac->C);CHKERRQ(ierr);
997863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(C,jac->C);CHKERRQ(ierr);
998863406b8SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->C,(void**)(&parcsr_C)));
999863406b8SStefano Zampini   PetscStackCall("Hypre set curl",ierr = (*jac->setdcurl)(jac->hsolver,parcsr_C);CHKERRQ(ierr););
1000863406b8SStefano Zampini   PetscFunctionReturn(0);
1001863406b8SStefano Zampini }
1002863406b8SStefano Zampini 
1003863406b8SStefano Zampini #undef __FUNCT__
1004863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl"
1005863406b8SStefano Zampini /*@
1006863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1007863406b8SStefano Zampini 
1008863406b8SStefano Zampini    Collective on PC
1009863406b8SStefano Zampini 
1010863406b8SStefano Zampini    Input Parameters:
1011863406b8SStefano Zampini +  pc - the preconditioning context
1012863406b8SStefano Zampini -  C - the discrete curl
1013863406b8SStefano Zampini 
1014863406b8SStefano Zampini    Level: intermediate
1015863406b8SStefano Zampini 
1016863406b8SStefano Zampini    Notes: C should have as many rows as the number of faces and as many columns as the number of edges in the mesh
1017863406b8SStefano Zampini           Each row of G has as many nonzeros as the number of edges of a face, with column indexes being the global indexes of the corresponding edge: matrix entries are +1 and -1 depending on edge orientation with respect to the face orientation
1018863406b8SStefano Zampini 
1019863406b8SStefano Zampini .seealso:
1020863406b8SStefano Zampini @*/
1021863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1022863406b8SStefano Zampini {
1023863406b8SStefano Zampini   PetscErrorCode ierr;
1024863406b8SStefano Zampini 
1025863406b8SStefano Zampini   PetscFunctionBegin;
1026863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1027863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1028863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1029863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1030863406b8SStefano Zampini   PetscFunctionReturn(0);
1031863406b8SStefano Zampini }
1032863406b8SStefano Zampini 
1033863406b8SStefano Zampini #undef __FUNCT__
10344cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS"
10354cb006feSStefano Zampini static PetscErrorCode PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
10364cb006feSStefano Zampini {
10374cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
10384cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_alpha_Poisson;
10394cb006feSStefano Zampini   PetscErrorCode     ierr;
10404cb006feSStefano Zampini 
10414cb006feSStefano Zampini   PetscFunctionBegin;
10424cb006feSStefano Zampini   /* throw away any matrix if already set */
10434cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
10444cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->alpha_Poisson);CHKERRQ(ierr);
10454cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->alpha_Poisson);CHKERRQ(ierr);
10464cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->alpha_Poisson,(void**)(&parcsr_alpha_Poisson)));
10474cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr_alpha_Poisson));
10484cb006feSStefano Zampini   PetscFunctionReturn(0);
10494cb006feSStefano Zampini }
10504cb006feSStefano Zampini 
10514cb006feSStefano Zampini #undef __FUNCT__
10524cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix"
10534cb006feSStefano Zampini /*@
10544cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
10554cb006feSStefano Zampini 
10564cb006feSStefano Zampini    Collective on PC
10574cb006feSStefano Zampini 
10584cb006feSStefano Zampini    Input Parameters:
10594cb006feSStefano Zampini +  pc - the preconditioning context
10604cb006feSStefano Zampini -  A - the matrix
10614cb006feSStefano Zampini 
10624cb006feSStefano Zampini    Level: intermediate
10634cb006feSStefano Zampini 
10644cb006feSStefano Zampini    Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
10654cb006feSStefano Zampini 
10664cb006feSStefano Zampini .seealso:
10674cb006feSStefano Zampini @*/
10684cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
10694cb006feSStefano Zampini {
10704cb006feSStefano Zampini   PetscErrorCode ierr;
10714cb006feSStefano Zampini 
10724cb006feSStefano Zampini   PetscFunctionBegin;
10734cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
10744cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
10754cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
10764cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetAlphaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
10774cb006feSStefano Zampini   PetscFunctionReturn(0);
10784cb006feSStefano Zampini }
10794cb006feSStefano Zampini 
10804cb006feSStefano Zampini #undef __FUNCT__
10814cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix_HYPRE_AMS"
10824cb006feSStefano Zampini static PetscErrorCode PCHYPRESetBetaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
10834cb006feSStefano Zampini {
10844cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
10854cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_beta_Poisson;
10864cb006feSStefano Zampini   PetscErrorCode     ierr;
10874cb006feSStefano Zampini 
10884cb006feSStefano Zampini   PetscFunctionBegin;
10894cb006feSStefano Zampini   if (!A) {
1090484796dcSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
10914cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_TRUE;
10924cb006feSStefano Zampini     PetscFunctionReturn(0);
10934cb006feSStefano Zampini   }
10944cb006feSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
10954cb006feSStefano Zampini   /* throw away any matrix if already set */
10964cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
10974cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->beta_Poisson);CHKERRQ(ierr);
10984cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->beta_Poisson);CHKERRQ(ierr);
10994cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->beta_Poisson,(void**)(&parcsr_beta_Poisson)));
11004cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr_beta_Poisson));
11014cb006feSStefano Zampini   PetscFunctionReturn(0);
11024cb006feSStefano Zampini }
11034cb006feSStefano Zampini 
11044cb006feSStefano Zampini #undef __FUNCT__
11054cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix"
11064cb006feSStefano Zampini /*@
11074cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
11084cb006feSStefano Zampini 
11094cb006feSStefano Zampini    Collective on PC
11104cb006feSStefano Zampini 
11114cb006feSStefano Zampini    Input Parameters:
11124cb006feSStefano Zampini +  pc - the preconditioning context
11134cb006feSStefano Zampini -  A - the matrix
11144cb006feSStefano Zampini 
11154cb006feSStefano Zampini    Level: intermediate
11164cb006feSStefano Zampini 
11174cb006feSStefano Zampini    Notes: A should be obtained by discretizing the Poisson problem with linear finite elements.
11184cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
11194cb006feSStefano Zampini 
11204cb006feSStefano Zampini .seealso:
11214cb006feSStefano Zampini @*/
11224cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
11234cb006feSStefano Zampini {
11244cb006feSStefano Zampini   PetscErrorCode ierr;
11254cb006feSStefano Zampini 
11264cb006feSStefano Zampini   PetscFunctionBegin;
11274cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11284cb006feSStefano Zampini   if (A) {
11294cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
11304cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
11314cb006feSStefano Zampini   }
11324cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetBetaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
11334cb006feSStefano Zampini   PetscFunctionReturn(0);
11344cb006feSStefano Zampini }
11354cb006feSStefano Zampini 
11364cb006feSStefano Zampini #undef __FUNCT__
11374cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE_AMS"
11384cb006feSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE_AMS(PC pc,Vec ozz, Vec zoz, Vec zzo)
11394cb006feSStefano Zampini {
11404cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11414cb006feSStefano Zampini   HYPRE_ParVector    par_ozz,par_zoz,par_zzo;
114212ddd1b6SStefano Zampini   PetscInt           dim;
11434cb006feSStefano Zampini   PetscErrorCode     ierr;
11444cb006feSStefano Zampini 
11454cb006feSStefano Zampini   PetscFunctionBegin;
11464cb006feSStefano Zampini   /* throw away any vector if already set */
11474cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
11484cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
11494cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
11504cb006feSStefano Zampini   jac->constants[0] = NULL;
11514cb006feSStefano Zampini   jac->constants[1] = NULL;
11524cb006feSStefano Zampini   jac->constants[2] = NULL;
11534cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
11544cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
11554cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&par_ozz)));
11564cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
11574cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
11584cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&par_zoz)));
115912ddd1b6SStefano Zampini   dim = 2;
11604cb006feSStefano Zampini   if (zzo) {
11614cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
11624cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
11634cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&par_zzo)));
116412ddd1b6SStefano Zampini     dim++;
11654cb006feSStefano Zampini   }
11664cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,par_ozz,par_zoz,par_zzo));
116712ddd1b6SStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim));
11684cb006feSStefano Zampini   PetscFunctionReturn(0);
11694cb006feSStefano Zampini }
11704cb006feSStefano Zampini 
11714cb006feSStefano Zampini #undef __FUNCT__
11724cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors"
11734cb006feSStefano Zampini /*@
11744cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
11754cb006feSStefano Zampini 
11764cb006feSStefano Zampini    Collective on PC
11774cb006feSStefano Zampini 
11784cb006feSStefano Zampini    Input Parameters:
11794cb006feSStefano Zampini +  pc - the preconditioning context
11804cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
11814cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
11824cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
11834cb006feSStefano Zampini 
11844cb006feSStefano Zampini    Level: intermediate
11854cb006feSStefano Zampini 
11864cb006feSStefano Zampini    Notes:
11874cb006feSStefano Zampini 
11884cb006feSStefano Zampini .seealso:
11894cb006feSStefano Zampini @*/
11904cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
11914cb006feSStefano Zampini {
11924cb006feSStefano Zampini   PetscErrorCode ierr;
11934cb006feSStefano Zampini 
11944cb006feSStefano Zampini   PetscFunctionBegin;
11954cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11964cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
11974cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
11984cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
11994cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
12004cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
12014cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
12024cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
12034cb006feSStefano Zampini   PetscFunctionReturn(0);
12044cb006feSStefano Zampini }
12054cb006feSStefano Zampini 
12064cb006feSStefano Zampini #undef __FUNCT__
1207863406b8SStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE"
1208863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
12094cb006feSStefano Zampini {
12104cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
12114cb006feSStefano Zampini   Vec             tv;
12124cb006feSStefano Zampini   HYPRE_ParVector par_coords[3];
12134cb006feSStefano Zampini   PetscInt        i;
12144cb006feSStefano Zampini   PetscErrorCode  ierr;
12154cb006feSStefano Zampini 
12164cb006feSStefano Zampini   PetscFunctionBegin;
12174cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
12184cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
12194cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
12204cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
12214cb006feSStefano Zampini   /* set problem's dimension */
1222863406b8SStefano Zampini   if (jac->setdim) {
1223863406b8SStefano Zampini     PetscStackCall("Hypre set dim",ierr = (*jac->setdim)(jac->hsolver,dim);CHKERRQ(ierr););
1224863406b8SStefano Zampini   }
12254cb006feSStefano Zampini   /* compute IJ vector for coordinates */
12264cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
12274cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
12284cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
12294cb006feSStefano Zampini   for (i=0;i<dim;i++) {
12304cb006feSStefano Zampini     PetscScalar *array;
12314cb006feSStefano Zampini     PetscInt    j;
12324cb006feSStefano Zampini 
12334cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
12344cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
12354cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
12364cb006feSStefano Zampini       array[j] = coords[j*dim+i];
12374cb006feSStefano Zampini     }
12384cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
12394cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
12404cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
12414cb006feSStefano Zampini   }
12424cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
12434cb006feSStefano Zampini   /* pass parCSR vectors to AMS solver */
12444cb006feSStefano Zampini   par_coords[0] = NULL;
12454cb006feSStefano Zampini   par_coords[1] = NULL;
12464cb006feSStefano Zampini   par_coords[2] = NULL;
12474cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&par_coords[0])));
12484cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&par_coords[1])));
12494cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&par_coords[2])));
1250863406b8SStefano Zampini   PetscStackCall("Hypre set coords",ierr = (*jac->setcoord)(jac->hsolver,par_coords[0],par_coords[1],par_coords[2]);CHKERRQ(ierr););
12514cb006feSStefano Zampini   PetscFunctionReturn(0);
12524cb006feSStefano Zampini }
12534cb006feSStefano Zampini 
125416d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
125516d9e3a6SLisandro Dalcin 
125616d9e3a6SLisandro Dalcin #undef __FUNCT__
125716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
1258f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
125916d9e3a6SLisandro Dalcin {
126016d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
126116d9e3a6SLisandro Dalcin 
126216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
126316d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
126416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
126516d9e3a6SLisandro Dalcin }
126616d9e3a6SLisandro Dalcin 
126716d9e3a6SLisandro Dalcin #undef __FUNCT__
126816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
1269f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
127016d9e3a6SLisandro Dalcin {
127116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
127216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1273ace3abfcSBarry Smith   PetscBool      flag;
127416d9e3a6SLisandro Dalcin 
127516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
127616d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
127716d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1278ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
127916d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
128016d9e3a6SLisandro Dalcin   } else {
128116d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
128216d9e3a6SLisandro Dalcin   }
128316d9e3a6SLisandro Dalcin 
128416d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
128516d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
128616d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
128716d9e3a6SLisandro Dalcin 
128816d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
128916d9e3a6SLisandro Dalcin   if (flag) {
1290fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
129116d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
129216d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
129316d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
129416d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
129516d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
129616d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
129716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
129816d9e3a6SLisandro Dalcin   }
129916d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
130016d9e3a6SLisandro Dalcin   if (flag) {
1301fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
130216d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
130316d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
130416d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
130516d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
130616d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
130716d9e3a6SLisandro Dalcin     /* initialize */
130816d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
130916d9e3a6SLisandro Dalcin     jac->threshhold = .1;
131016d9e3a6SLisandro Dalcin     jac->filter     = .1;
131116d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
13122fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
13132fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
13142fa5cd67SKarl Rupp 
131516d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
131616d9e3a6SLisandro Dalcin     jac->symt = 0;
1317fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1318fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1319fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1320fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1321fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1322fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
132316d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
132416d9e3a6SLisandro Dalcin   }
132516d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
132616d9e3a6SLisandro Dalcin   if (flag) {
132716d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
132816d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
132916d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
133016d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
133116d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
133216d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
133316d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
133416d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
133516d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
133616d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
133716d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
133816d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
133916d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
13408f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
134116d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
134216d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
134316d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
134416d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
134516d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
13460f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
13478f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
13480f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
134916d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
135016d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
135116d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
13520f1074feSSatish Balay     jac->interptype       = 0;
13530f1074feSSatish Balay     jac->agg_nl           = 0;
13540f1074feSSatish Balay     jac->pmax             = 0;
13550f1074feSSatish Balay     jac->truncfactor      = 0.0;
13560f1074feSSatish Balay     jac->agg_num_paths    = 1;
13578f87f92bSBarry Smith 
13588f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
13598f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
13608f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1361fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1362fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1363fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1364fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1365fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1366fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1367fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1368fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1369fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1370fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1371fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1372fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1373fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1374fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1375fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1376fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
137716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
137816d9e3a6SLisandro Dalcin   }
13794cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
13804cb006feSStefano Zampini   if (flag) {
13814cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
13824cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
13834cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
13844cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
13854cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
13864cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
1387863406b8SStefano Zampini     jac->setdgrad            = HYPRE_AMSSetDiscreteGradient;
1388863406b8SStefano Zampini     jac->setcoord            = HYPRE_AMSSetCoordinateVectors;
1389863406b8SStefano Zampini     jac->setdim              = HYPRE_AMSSetDimension;
13904cb006feSStefano Zampini     jac->coords[0]           = NULL;
13914cb006feSStefano Zampini     jac->coords[1]           = NULL;
13924cb006feSStefano Zampini     jac->coords[2]           = NULL;
13934cb006feSStefano Zampini     jac->G                   = NULL;
13944cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1395863406b8SStefano Zampini     jac->as_print           = 0;
1396863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1397863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
13984cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
13994cb006feSStefano Zampini     /* Smoothing options */
1400863406b8SStefano Zampini     jac->as_relax_type      = 2;
1401863406b8SStefano Zampini     jac->as_relax_times     = 1;
1402863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1403863406b8SStefano Zampini     jac->as_omega           = 1.0;
14044cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1405863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1406863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1407863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 8;
1408863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1409863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1410863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
14114cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
14124cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_FALSE;
1413863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1414863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1415863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 8;
1416863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1417863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1418863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1419863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1420863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
14214cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1422863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1423863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1424863406b8SStefano Zampini                                                                       jac->as_relax_times,
1425863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1426863406b8SStefano Zampini                                                                       jac->as_omega));
1427863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1428863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1429863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1430863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1431863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1432863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1433863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1434863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1435863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1436863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1437863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1438863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1439863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1440863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
14414cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE_AMS);CHKERRQ(ierr);
14424cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
14434cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",PCHYPRESetBetaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
14444cb006feSStefano Zampini     PetscFunctionReturn(0);
14454cb006feSStefano Zampini   }
1446863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1447863406b8SStefano Zampini   if (flag) {
1448863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1449863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1450863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1451863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1452863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1453863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1454863406b8SStefano Zampini     jac->setdgrad            = HYPRE_ADSSetDiscreteGradient;
1455863406b8SStefano Zampini     jac->setdcurl            = HYPRE_ADSSetDiscreteCurl;
1456863406b8SStefano Zampini     jac->setcoord            = HYPRE_ADSSetCoordinateVectors;
1457863406b8SStefano Zampini     jac->coords[0]           = NULL;
1458863406b8SStefano Zampini     jac->coords[1]           = NULL;
1459863406b8SStefano Zampini     jac->coords[2]           = NULL;
1460863406b8SStefano Zampini     jac->G                   = NULL;
1461863406b8SStefano Zampini     jac->C                   = NULL;
1462863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1463863406b8SStefano Zampini     jac->as_print           = 0;
1464863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1465863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1466863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1467863406b8SStefano Zampini     /* Smoothing options */
1468863406b8SStefano Zampini     jac->as_relax_type      = 2;
1469863406b8SStefano Zampini     jac->as_relax_times     = 1;
1470863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1471863406b8SStefano Zampini     jac->as_omega           = 1.0;
1472863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1473863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1474863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1475863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1476863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1477863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1478863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1479863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1480863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1481863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1482863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1483863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1484863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1485863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1486863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1487863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1488863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1489863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1490863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1491863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1492863406b8SStefano Zampini                                                                       jac->as_relax_times,
1493863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1494863406b8SStefano Zampini                                                                       jac->as_omega));
1495863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1496863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1497863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1498863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1499863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1500863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1501863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1502863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1503863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1504863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1505863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1506863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1507863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1508863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1509863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
1510863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
1511863406b8SStefano Zampini     PetscFunctionReturn(0);
1512863406b8SStefano Zampini   }
1513503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
15142fa5cd67SKarl Rupp 
15150298fd71SBarry Smith   jac->hypre_type = NULL;
151633263987SBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, boomeramg, ams",name);
151716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
151816d9e3a6SLisandro Dalcin }
151916d9e3a6SLisandro Dalcin 
152016d9e3a6SLisandro Dalcin /*
152116d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
152216d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
152316d9e3a6SLisandro Dalcin */
152416d9e3a6SLisandro Dalcin #undef __FUNCT__
152516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
15268c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptions *PetscOptionsObject,PC pc)
152716d9e3a6SLisandro Dalcin {
152816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
15294ddd07fcSJed Brown   PetscInt       indx;
1530863406b8SStefano Zampini   const char     *type[] = {"pilut","parasails","boomeramg","ams","ads"};
1531ace3abfcSBarry Smith   PetscBool      flg;
153216d9e3a6SLisandro Dalcin 
153316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
15349fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
15359c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
153616d9e3a6SLisandro Dalcin   if (flg) {
153716d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
153802a17cd4SBarry Smith   } else {
153902a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
154016d9e3a6SLisandro Dalcin   }
154116d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
15423931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
154316d9e3a6SLisandro Dalcin   }
154416d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
154516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
154616d9e3a6SLisandro Dalcin }
154716d9e3a6SLisandro Dalcin 
154816d9e3a6SLisandro Dalcin #undef __FUNCT__
154916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
155016d9e3a6SLisandro Dalcin /*@C
155116d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
155216d9e3a6SLisandro Dalcin 
155316d9e3a6SLisandro Dalcin    Input Parameters:
155416d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1555863406b8SStefano Zampini -     name - either  pilut, parasails, boomeramg, ams, ads
155616d9e3a6SLisandro Dalcin 
155716d9e3a6SLisandro Dalcin    Options Database Keys:
1558863406b8SStefano Zampini    -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
155916d9e3a6SLisandro Dalcin 
156016d9e3a6SLisandro Dalcin    Level: intermediate
156116d9e3a6SLisandro Dalcin 
156216d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
156316d9e3a6SLisandro Dalcin            PCHYPRE
156416d9e3a6SLisandro Dalcin 
156516d9e3a6SLisandro Dalcin @*/
15667087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
156716d9e3a6SLisandro Dalcin {
15684ac538c5SBarry Smith   PetscErrorCode ierr;
156916d9e3a6SLisandro Dalcin 
157016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
15710700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
157216d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
15734ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
157416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
157516d9e3a6SLisandro Dalcin }
157616d9e3a6SLisandro Dalcin 
157716d9e3a6SLisandro Dalcin #undef __FUNCT__
157816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
157916d9e3a6SLisandro Dalcin /*@C
158016d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
158116d9e3a6SLisandro Dalcin 
158216d9e3a6SLisandro Dalcin    Input Parameter:
158316d9e3a6SLisandro Dalcin .     pc - the preconditioner context
158416d9e3a6SLisandro Dalcin 
158516d9e3a6SLisandro Dalcin    Output Parameter:
1586863406b8SStefano Zampini .     name - either  pilut, parasails, boomeramg, ams, ads
158716d9e3a6SLisandro Dalcin 
158816d9e3a6SLisandro Dalcin    Level: intermediate
158916d9e3a6SLisandro Dalcin 
159016d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
159116d9e3a6SLisandro Dalcin            PCHYPRE
159216d9e3a6SLisandro Dalcin 
159316d9e3a6SLisandro Dalcin @*/
15947087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
159516d9e3a6SLisandro Dalcin {
15964ac538c5SBarry Smith   PetscErrorCode ierr;
159716d9e3a6SLisandro Dalcin 
159816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
15990700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
160016d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
16014ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
160216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
160316d9e3a6SLisandro Dalcin }
160416d9e3a6SLisandro Dalcin 
160516d9e3a6SLisandro Dalcin /*MC
160616d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
160716d9e3a6SLisandro Dalcin 
160816d9e3a6SLisandro Dalcin    Options Database Keys:
1609863406b8SStefano Zampini +   -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
161016d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
161116d9e3a6SLisandro Dalcin           preconditioner
161216d9e3a6SLisandro Dalcin 
161316d9e3a6SLisandro Dalcin    Level: intermediate
161416d9e3a6SLisandro Dalcin 
161516d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
161616d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
161716d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
161816d9e3a6SLisandro Dalcin 
161916d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
16200f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
16210f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
16220f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
16238f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
16240f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
16250f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
162616d9e3a6SLisandro Dalcin 
16270f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
16280f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
16290f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
163016d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
163116d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
163216d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
163316d9e3a6SLisandro Dalcin 
163416d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
163516d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
163616d9e3a6SLisandro Dalcin 
16379e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
16389e5bc791SBarry Smith 
163916d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
16409e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
164116d9e3a6SLisandro Dalcin 
164216d9e3a6SLisandro Dalcin M*/
164316d9e3a6SLisandro Dalcin 
164416d9e3a6SLisandro Dalcin #undef __FUNCT__
164516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
16468cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
164716d9e3a6SLisandro Dalcin {
164816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
164916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
165016d9e3a6SLisandro Dalcin 
165116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1652b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
16532fa5cd67SKarl Rupp 
165416d9e3a6SLisandro Dalcin   pc->data                = jac;
165516d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
165616d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
165716d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
165816d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
165916d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
16600298fd71SBarry Smith   jac->hypre_type         = NULL;
16614cb006feSStefano Zampini   jac->coords[0]          = NULL;
16624cb006feSStefano Zampini   jac->coords[1]          = NULL;
16634cb006feSStefano Zampini   jac->coords[2]          = NULL;
16644cb006feSStefano Zampini   jac->constants[0]       = NULL;
16654cb006feSStefano Zampini   jac->constants[1]       = NULL;
16664cb006feSStefano Zampini   jac->constants[2]       = NULL;
1667863406b8SStefano Zampini   jac->G                  = NULL;
1668863406b8SStefano Zampini   jac->C                  = NULL;
1669863406b8SStefano Zampini   jac->alpha_Poisson      = NULL;
1670863406b8SStefano Zampini   jac->beta_Poisson       = NULL;
1671fd444223SStefano Zampini   jac->setdim             = NULL;
167216d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1673ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1674bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1675bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
167616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
167716d9e3a6SLisandro Dalcin }
1678ebc551c0SBarry Smith 
1679f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1680f91d8e95SBarry Smith 
1681b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1682af0996ceSBarry Smith #include <petsc/private/matimpl.h>
1683ebc551c0SBarry Smith 
1684ebc551c0SBarry Smith typedef struct {
168568326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1686f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
16879e5bc791SBarry Smith 
16889e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
16894ddd07fcSJed Brown   PetscInt its;
16909e5bc791SBarry Smith   double   tol;
16914ddd07fcSJed Brown   PetscInt relax_type;
16924ddd07fcSJed Brown   PetscInt rap_type;
16934ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
16944ddd07fcSJed Brown   PetscInt max_levels;
1695ebc551c0SBarry Smith } PC_PFMG;
1696ebc551c0SBarry Smith 
1697ebc551c0SBarry Smith #undef __FUNCT__
1698ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1699ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1700ebc551c0SBarry Smith {
1701ebc551c0SBarry Smith   PetscErrorCode ierr;
1702f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1703ebc551c0SBarry Smith 
1704ebc551c0SBarry Smith   PetscFunctionBegin;
17052fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1706f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1707c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1708ebc551c0SBarry Smith   PetscFunctionReturn(0);
1709ebc551c0SBarry Smith }
1710ebc551c0SBarry Smith 
17119e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
17129e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
17139e5bc791SBarry Smith 
1714ebc551c0SBarry Smith #undef __FUNCT__
1715ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1716ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1717ebc551c0SBarry Smith {
1718ebc551c0SBarry Smith   PetscErrorCode ierr;
1719ace3abfcSBarry Smith   PetscBool      iascii;
1720f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1721ebc551c0SBarry Smith 
1722ebc551c0SBarry Smith   PetscFunctionBegin;
1723251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
17249e5bc791SBarry Smith   if (iascii) {
17259e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
17269e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
17279e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
17289e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
17299e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
17309e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
17313b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
17329e5bc791SBarry Smith   }
1733ebc551c0SBarry Smith   PetscFunctionReturn(0);
1734ebc551c0SBarry Smith }
1735ebc551c0SBarry Smith 
17369e5bc791SBarry Smith 
1737ebc551c0SBarry Smith #undef __FUNCT__
1738ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
17398c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptions *PetscOptionsObject,PC pc)
1740ebc551c0SBarry Smith {
1741ebc551c0SBarry Smith   PetscErrorCode ierr;
1742f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1743ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1744ebc551c0SBarry Smith 
1745ebc551c0SBarry Smith   PetscFunctionBegin;
1746e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
17470298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
174868326731SBarry Smith   if (flg) {
1749a0324ebeSBarry Smith     int level=3;
1750fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
175168326731SBarry Smith   }
17520298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1753fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
17540298fd71SBarry 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);
1755fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
17560298fd71SBarry 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);
1757fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
17589e5bc791SBarry Smith 
17590298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
1760fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
17613b46a515SGlenn Hammond 
17620298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1763fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
17640298fd71SBarry 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);
1765fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
17660298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
1767fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1768ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1769ebc551c0SBarry Smith   PetscFunctionReturn(0);
1770ebc551c0SBarry Smith }
1771ebc551c0SBarry Smith 
1772f91d8e95SBarry Smith #undef __FUNCT__
1773f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1774f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1775f91d8e95SBarry Smith {
1776f91d8e95SBarry Smith   PetscErrorCode    ierr;
1777f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
1778d9ca1df4SBarry Smith   PetscScalar       *yy;
1779d9ca1df4SBarry Smith   const PetscScalar *xx;
17804ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
178168326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1782f91d8e95SBarry Smith 
1783f91d8e95SBarry Smith   PetscFunctionBegin;
1784dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1785aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1786f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1787f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1788f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1789f91d8e95SBarry Smith 
1790f91d8e95SBarry Smith   /* copy x values over to hypre */
1791fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1792d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1793d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
1794d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1795fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
1796fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1797f91d8e95SBarry Smith 
1798f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1799f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
18008b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
1801f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1802f91d8e95SBarry Smith   PetscFunctionReturn(0);
1803f91d8e95SBarry Smith }
1804f91d8e95SBarry Smith 
18059e5bc791SBarry Smith #undef __FUNCT__
18069e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1807ace3abfcSBarry 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)
18089e5bc791SBarry Smith {
18099e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
18109e5bc791SBarry Smith   PetscErrorCode ierr;
18114ddd07fcSJed Brown   PetscInt       oits;
18129e5bc791SBarry Smith 
18139e5bc791SBarry Smith   PetscFunctionBegin;
1814dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1815fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1816fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
18179e5bc791SBarry Smith 
18189e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
18198b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
18209e5bc791SBarry Smith   *outits = oits;
18219e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
18229e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1823fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1824fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
18259e5bc791SBarry Smith   PetscFunctionReturn(0);
18269e5bc791SBarry Smith }
18279e5bc791SBarry Smith 
18289e5bc791SBarry Smith 
18293a32d3dbSGlenn Hammond #undef __FUNCT__
18303a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
18313a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
18323a32d3dbSGlenn Hammond {
18333a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
18343a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
18353a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1836ace3abfcSBarry Smith   PetscBool       flg;
18373a32d3dbSGlenn Hammond 
18383a32d3dbSGlenn Hammond   PetscFunctionBegin;
1839251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1840ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
18413a32d3dbSGlenn Hammond 
18423a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
18432fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1844fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1845fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1846fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
18473a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
18483a32d3dbSGlenn Hammond }
18493a32d3dbSGlenn Hammond 
1850ebc551c0SBarry Smith 
1851ebc551c0SBarry Smith /*MC
1852ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1853ebc551c0SBarry Smith 
1854ebc551c0SBarry Smith    Level: advanced
1855ebc551c0SBarry Smith 
18569e5bc791SBarry Smith    Options Database:
18579e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
18589e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
18599e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
18609e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
18619e5bc791SBarry 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
18629e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
1863f91d8e95SBarry Smith 
18649e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
18659e5bc791SBarry Smith 
18668e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
1867aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
18689e5bc791SBarry Smith 
18699e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
1870ebc551c0SBarry Smith M*/
1871ebc551c0SBarry Smith 
1872ebc551c0SBarry Smith #undef __FUNCT__
1873ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
18748cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
1875ebc551c0SBarry Smith {
1876ebc551c0SBarry Smith   PetscErrorCode ierr;
1877ebc551c0SBarry Smith   PC_PFMG        *ex;
1878ebc551c0SBarry Smith 
1879ebc551c0SBarry Smith   PetscFunctionBegin;
1880b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
188168326731SBarry Smith   pc->data = ex;
1882ebc551c0SBarry Smith 
18839e5bc791SBarry Smith   ex->its            = 1;
18849e5bc791SBarry Smith   ex->tol            = 1.e-8;
18859e5bc791SBarry Smith   ex->relax_type     = 1;
18869e5bc791SBarry Smith   ex->rap_type       = 0;
18879e5bc791SBarry Smith   ex->num_pre_relax  = 1;
18889e5bc791SBarry Smith   ex->num_post_relax = 1;
18893b46a515SGlenn Hammond   ex->max_levels     = 0;
18909e5bc791SBarry Smith 
1891ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
1892ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
1893ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
1894f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
18959e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
189668326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
18972fa5cd67SKarl Rupp 
1898ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
1899fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1900ebc551c0SBarry Smith   PetscFunctionReturn(0);
1901ebc551c0SBarry Smith }
1902d851a50bSGlenn Hammond 
1903325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
1904325fc9f4SBarry Smith 
1905d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
1906d851a50bSGlenn Hammond typedef struct {
1907d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
1908d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
1909d851a50bSGlenn Hammond 
1910d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
19114ddd07fcSJed Brown   PetscInt its;
1912d851a50bSGlenn Hammond   double   tol;
19134ddd07fcSJed Brown   PetscInt relax_type;
19144ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
1915d851a50bSGlenn Hammond } PC_SysPFMG;
1916d851a50bSGlenn Hammond 
1917d851a50bSGlenn Hammond #undef __FUNCT__
1918d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
1919d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
1920d851a50bSGlenn Hammond {
1921d851a50bSGlenn Hammond   PetscErrorCode ierr;
1922d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1923d851a50bSGlenn Hammond 
1924d851a50bSGlenn Hammond   PetscFunctionBegin;
19252fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1926d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1927c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1928d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1929d851a50bSGlenn Hammond }
1930d851a50bSGlenn Hammond 
1931d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
1932d851a50bSGlenn Hammond 
1933d851a50bSGlenn Hammond #undef __FUNCT__
1934d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
1935d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
1936d851a50bSGlenn Hammond {
1937d851a50bSGlenn Hammond   PetscErrorCode ierr;
1938ace3abfcSBarry Smith   PetscBool      iascii;
1939d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1940d851a50bSGlenn Hammond 
1941d851a50bSGlenn Hammond   PetscFunctionBegin;
1942251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1943d851a50bSGlenn Hammond   if (iascii) {
1944d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
1945d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
1946d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
1947d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
1948d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
1949d851a50bSGlenn Hammond   }
1950d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1951d851a50bSGlenn Hammond }
1952d851a50bSGlenn Hammond 
1953d851a50bSGlenn Hammond 
1954d851a50bSGlenn Hammond #undef __FUNCT__
1955d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
19568c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptions *PetscOptionsObject,PC pc)
1957d851a50bSGlenn Hammond {
1958d851a50bSGlenn Hammond   PetscErrorCode ierr;
1959d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1960ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1961d851a50bSGlenn Hammond 
1962d851a50bSGlenn Hammond   PetscFunctionBegin;
1963e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
19640298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
1965d851a50bSGlenn Hammond   if (flg) {
1966d851a50bSGlenn Hammond     int level=3;
1967fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
1968d851a50bSGlenn Hammond   }
19690298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1970fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
19710298fd71SBarry 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);
1972fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
19730298fd71SBarry 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);
1974fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
1975d851a50bSGlenn Hammond 
19760298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1977fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
19780298fd71SBarry 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);
1979fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
1980d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
1981d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1982d851a50bSGlenn Hammond }
1983d851a50bSGlenn Hammond 
1984d851a50bSGlenn Hammond #undef __FUNCT__
1985d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
1986d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
1987d851a50bSGlenn Hammond {
1988d851a50bSGlenn Hammond   PetscErrorCode    ierr;
1989d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
1990d9ca1df4SBarry Smith   PetscScalar       *yy;
1991d9ca1df4SBarry Smith   const PetscScalar *xx;
19924ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
1993d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
19944ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
19954ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
19964ddd07fcSJed Brown   PetscInt          part    = 0;
19974ddd07fcSJed Brown   PetscInt          size;
19984ddd07fcSJed Brown   PetscInt          i;
1999d851a50bSGlenn Hammond 
2000d851a50bSGlenn Hammond   PetscFunctionBegin;
2001dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2002aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2003d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2004d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2005d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2006d851a50bSGlenn Hammond 
2007d851a50bSGlenn Hammond   size = 1;
20082fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
20092fa5cd67SKarl Rupp 
2010d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2011d851a50bSGlenn Hammond   if (ordering) {
2012fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2013d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2014d9ca1df4SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,(PetscScalar*)xx+(size*i)));
2015d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2016fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2017fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2018fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2019d851a50bSGlenn Hammond 
2020d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2021d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
20228b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2023d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2024a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2025d851a50bSGlenn Hammond     PetscScalar *z;
20264ddd07fcSJed Brown     PetscInt    j, k;
2027d851a50bSGlenn Hammond 
2028785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2029fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2030d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2031d851a50bSGlenn Hammond 
2032d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2033d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2034d851a50bSGlenn Hammond       k= i*nvars;
20352fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2036d851a50bSGlenn Hammond     }
20378b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2038d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2039fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2040fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2041d851a50bSGlenn Hammond 
2042d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2043d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
20448b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2045d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2046d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2047d851a50bSGlenn Hammond       k= i*nvars;
20482fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2049d851a50bSGlenn Hammond     }
2050d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2051d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2052d851a50bSGlenn Hammond   }
2053d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2054d851a50bSGlenn Hammond }
2055d851a50bSGlenn Hammond 
2056d851a50bSGlenn Hammond #undef __FUNCT__
2057d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
2058ace3abfcSBarry 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)
2059d851a50bSGlenn Hammond {
2060d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2061d851a50bSGlenn Hammond   PetscErrorCode ierr;
20624ddd07fcSJed Brown   PetscInt       oits;
2063d851a50bSGlenn Hammond 
2064d851a50bSGlenn Hammond   PetscFunctionBegin;
2065dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2066fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2067fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2068d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
20698b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2070d851a50bSGlenn Hammond   *outits = oits;
2071d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2072d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2073fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2074fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2075d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2076d851a50bSGlenn Hammond }
2077d851a50bSGlenn Hammond 
2078d851a50bSGlenn Hammond 
2079d851a50bSGlenn Hammond #undef __FUNCT__
2080d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
2081d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2082d851a50bSGlenn Hammond {
2083d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2084d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2085d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2086ace3abfcSBarry Smith   PetscBool        flg;
2087d851a50bSGlenn Hammond 
2088d851a50bSGlenn Hammond   PetscFunctionBegin;
2089251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2090ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2091d851a50bSGlenn Hammond 
2092d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
20932fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2094fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2095fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2096fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2097d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2098d851a50bSGlenn Hammond }
2099d851a50bSGlenn Hammond 
2100d851a50bSGlenn Hammond 
2101d851a50bSGlenn Hammond /*MC
2102d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2103d851a50bSGlenn Hammond 
2104d851a50bSGlenn Hammond    Level: advanced
2105d851a50bSGlenn Hammond 
2106d851a50bSGlenn Hammond    Options Database:
2107d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2108d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2109d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2110d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2111d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2112d851a50bSGlenn Hammond 
2113d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
2114d851a50bSGlenn Hammond 
2115f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2116aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2117d851a50bSGlenn Hammond            Also, only cell-centered variables.
2118d851a50bSGlenn Hammond 
2119d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2120d851a50bSGlenn Hammond M*/
2121d851a50bSGlenn Hammond 
2122d851a50bSGlenn Hammond #undef __FUNCT__
2123d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
21248cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2125d851a50bSGlenn Hammond {
2126d851a50bSGlenn Hammond   PetscErrorCode ierr;
2127d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2128d851a50bSGlenn Hammond 
2129d851a50bSGlenn Hammond   PetscFunctionBegin;
2130b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2131d851a50bSGlenn Hammond   pc->data = ex;
2132d851a50bSGlenn Hammond 
2133d851a50bSGlenn Hammond   ex->its            = 1;
2134d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2135d851a50bSGlenn Hammond   ex->relax_type     = 1;
2136d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2137d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2138d851a50bSGlenn Hammond 
2139d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2140d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2141d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2142d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2143d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2144d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
21452fa5cd67SKarl Rupp 
2146ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2147fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2148d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2149d851a50bSGlenn Hammond }
2150