xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 23df4f25d27b6bf7629e610a0845c2293a974714)
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;
99*23df4f25SStefano Zampini   PetscBool      ams_beta_is_zero_part;
100*23df4f25SStefano Zampini   PetscInt       ams_proj_freq;
10116d9e3a6SLisandro Dalcin } PC_HYPRE;
10216d9e3a6SLisandro Dalcin 
103d2128fa2SBarry Smith #undef __FUNCT__
104d2128fa2SBarry Smith #define __FUNCT__ "PCHYPREGetSolver"
105d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
106d2128fa2SBarry Smith {
107d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
108d2128fa2SBarry Smith 
109d2128fa2SBarry Smith   PetscFunctionBegin;
110d2128fa2SBarry Smith   *hsolver = jac->hsolver;
111d2128fa2SBarry Smith   PetscFunctionReturn(0);
112d2128fa2SBarry Smith }
11316d9e3a6SLisandro Dalcin 
11416d9e3a6SLisandro Dalcin #undef __FUNCT__
11516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE"
11616d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
11716d9e3a6SLisandro Dalcin {
11816d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11916d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
12016d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
12116d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
12216d9e3a6SLisandro Dalcin   PetscInt           bs;
12316d9e3a6SLisandro Dalcin 
12416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
12516d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
12602a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
12716d9e3a6SLisandro Dalcin   }
1285f5c5b43SBarry Smith 
1295f5c5b43SBarry Smith   if (pc->setupcalled) {
1305f5c5b43SBarry Smith     /* always destroy the old matrix and create a new memory;
1315f5c5b43SBarry Smith        hope this does not churn the memory too much. The problem
1325f5c5b43SBarry Smith        is I do not know if it is possible to put the matrix back to
1335f5c5b43SBarry Smith        its initial state so that we can directly copy the values
1345f5c5b43SBarry Smith        the second time through. */
135fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
1365f5c5b43SBarry Smith     jac->ij = 0;
13716d9e3a6SLisandro Dalcin   }
1385f5c5b43SBarry Smith 
13916d9e3a6SLisandro Dalcin   if (!jac->ij) { /* create the matrix the first time through */
14016d9e3a6SLisandro Dalcin     ierr = MatHYPRE_IJMatrixCreate(pc->pmat,&jac->ij);CHKERRQ(ierr);
14116d9e3a6SLisandro Dalcin   }
14216d9e3a6SLisandro Dalcin   if (!jac->b) { /* create the vectors the first time through */
14316d9e3a6SLisandro Dalcin     Vec x,b;
1442a7a6963SBarry Smith     ierr = MatCreateVecs(pc->pmat,&x,&b);CHKERRQ(ierr);
14516d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(x,&jac->x);CHKERRQ(ierr);
14616d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(b,&jac->b);CHKERRQ(ierr);
1476bf464f9SBarry Smith     ierr = VecDestroy(&x);CHKERRQ(ierr);
1486bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
14916d9e3a6SLisandro Dalcin   }
1505f5c5b43SBarry Smith 
15116d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
15216d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
15316d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1542fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
1554cb006feSStefano Zampini   }
156863406b8SStefano Zampini 
1574cb006feSStefano Zampini   /* special case for AMS */
1584cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
1594cb006feSStefano 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()");
1604cb006feSStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
1614cb006feSStefano Zampini   }
162863406b8SStefano Zampini   /* special case for ADS */
163863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
164863406b8SStefano Zampini     if (!jac->coords[0]) {
165863406b8SStefano Zampini       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs coordinate vectors via PCSetCoordinates()");
166fd444223SStefano Zampini     } else if (!jac->coords[1] || !jac->coords[2]) {
167fd444223SStefano 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");
168863406b8SStefano Zampini     }
169863406b8SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
170863406b8SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete curl operator via PCHYPRESetDiscreteGradient");
171863406b8SStefano Zampini   }
17216d9e3a6SLisandro Dalcin   ierr = MatHYPRE_IJMatrixCopy(pc->pmat,jac->ij);CHKERRQ(ierr);
173fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
174fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&bv));
175fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&xv));
176fd3f9acdSBarry Smith   PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr););
17716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
17816d9e3a6SLisandro Dalcin }
17916d9e3a6SLisandro Dalcin 
18016d9e3a6SLisandro Dalcin /*
18116d9e3a6SLisandro Dalcin     Replaces the address where the HYPRE vector points to its data with the address of
18216d9e3a6SLisandro Dalcin   PETSc's data. Saves the old address so it can be reset when we are finished with it.
18316d9e3a6SLisandro Dalcin   Allows use to get the data into a HYPRE vector without the cost of memcopies
18416d9e3a6SLisandro Dalcin */
18516d9e3a6SLisandro Dalcin #define HYPREReplacePointer(b,newvalue,savedvalue) { \
18616d9e3a6SLisandro Dalcin     hypre_ParVector *par_vector   = (hypre_ParVector*)hypre_IJVectorObject(((hypre_IJVector*)b)); \
18716d9e3a6SLisandro Dalcin     hypre_Vector    *local_vector = hypre_ParVectorLocalVector(par_vector); \
18816d9e3a6SLisandro Dalcin     savedvalue         = local_vector->data; \
1890ad7597dSKarl Rupp     local_vector->data = newvalue;          \
1900ad7597dSKarl Rupp }
19116d9e3a6SLisandro Dalcin 
19216d9e3a6SLisandro Dalcin #undef __FUNCT__
19316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE"
19416d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
19516d9e3a6SLisandro Dalcin {
19616d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
19716d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
19816d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
199d9ca1df4SBarry Smith   PetscScalar        *xv;
200d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
20116d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
202d9ca1df4SBarry Smith   PetscScalar        *sxv;
2034ddd07fcSJed Brown   PetscInt           hierr;
20416d9e3a6SLisandro Dalcin 
20516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
206dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
20716d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
208d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
20916d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
210d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
21116d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
21216d9e3a6SLisandro Dalcin 
213fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
214fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
215fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
216fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
21765e19b50SBarry Smith                                if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
218fd3f9acdSBarry Smith                                if (hierr) hypre__global_error = 0;);
21916d9e3a6SLisandro Dalcin 
220*23df4f25SStefano Zampini   if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) {
22121df291bSStefano Zampini     PetscStackCall("HYPRE_AMSProjectOutGradients",ierr = HYPRE_AMSProjectOutGradients(jac->hsolver,jxv);CHKERRQ(ierr););
22221df291bSStefano Zampini   }
223d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)sbv,bv);
22416d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
22516d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
226d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
22716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
22816d9e3a6SLisandro Dalcin }
22916d9e3a6SLisandro Dalcin 
23016d9e3a6SLisandro Dalcin #undef __FUNCT__
23116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE"
23216d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
23316d9e3a6SLisandro Dalcin {
23416d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
23516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
23616d9e3a6SLisandro Dalcin 
23716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
238fd3f9acdSBarry Smith   if (jac->ij) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
239fd3f9acdSBarry Smith   if (jac->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->b));
240fd3f9acdSBarry Smith   if (jac->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->x));
2414cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
2424cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
2434cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
2444cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
2454cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
2464cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
2474cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
248863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
2494cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
2504cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
251226b0620SJed Brown   if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr););
252503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
25316d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
254c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
25516d9e3a6SLisandro Dalcin 
25616d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
257bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
258bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
2594cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
2604cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
261863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
2624cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
2634cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",NULL);CHKERRQ(ierr);
2644cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",NULL);CHKERRQ(ierr);
26516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
26616d9e3a6SLisandro Dalcin }
26716d9e3a6SLisandro Dalcin 
26816d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
26916d9e3a6SLisandro Dalcin #undef __FUNCT__
27016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut"
2718c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptions *PetscOptionsObject,PC pc)
27216d9e3a6SLisandro Dalcin {
27316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
27416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
275ace3abfcSBarry Smith   PetscBool      flag;
27616d9e3a6SLisandro Dalcin 
27716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
278e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
27916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
280fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
28116d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
282fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
28316d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
284fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
28516d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
28616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
28716d9e3a6SLisandro Dalcin }
28816d9e3a6SLisandro Dalcin 
28916d9e3a6SLisandro Dalcin #undef __FUNCT__
29016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut"
29116d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
29216d9e3a6SLisandro Dalcin {
29316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
29416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
295ace3abfcSBarry Smith   PetscBool      iascii;
29616d9e3a6SLisandro Dalcin 
29716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
298251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
29916d9e3a6SLisandro Dalcin   if (iascii) {
30016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
30116d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
30216d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
30316d9e3a6SLisandro Dalcin     } else {
30416d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr);
30516d9e3a6SLisandro Dalcin     }
30616d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
30757622a8eSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
30816d9e3a6SLisandro Dalcin     } else {
30916d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr);
31016d9e3a6SLisandro Dalcin     }
31116d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
31216d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
31316d9e3a6SLisandro Dalcin     } else {
31416d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default factor row size \n");CHKERRQ(ierr);
31516d9e3a6SLisandro Dalcin     }
31616d9e3a6SLisandro Dalcin   }
31716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
31816d9e3a6SLisandro Dalcin }
31916d9e3a6SLisandro Dalcin 
32016d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
32116d9e3a6SLisandro Dalcin 
32216d9e3a6SLisandro Dalcin #undef __FUNCT__
32316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG"
32416d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
32516d9e3a6SLisandro Dalcin {
32616d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
32716d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
32816d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
329d9ca1df4SBarry Smith   PetscScalar        *xv;
330d9ca1df4SBarry Smith   const PetscScalar  *bv;
33116d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
33216d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
3334ddd07fcSJed Brown   PetscInt           hierr;
33416d9e3a6SLisandro Dalcin 
33516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
336dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
33716d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
338d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
33916d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
340d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
34116d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
34216d9e3a6SLisandro Dalcin 
343fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
344fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
345fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
34616d9e3a6SLisandro Dalcin 
34716d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
34816d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
349e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
35016d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
35116d9e3a6SLisandro Dalcin 
35216d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
35316d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
35416d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
355d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
35616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
35716d9e3a6SLisandro Dalcin }
35816d9e3a6SLisandro Dalcin 
359a669f990SJed Brown /* static array length */
360a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
361a669f990SJed Brown 
36216d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
3630f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
36416d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
36565de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
36665de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
36765de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
36865de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
36965de4495SJed Brown                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */,
37065de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
3710f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
3720f1074feSSatish Balay                                                   "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"};
37316d9e3a6SLisandro Dalcin #undef __FUNCT__
37416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG"
3758c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptions *PetscOptionsObject,PC pc)
37616d9e3a6SLisandro Dalcin {
37716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
37816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
3794ddd07fcSJed Brown   PetscInt       n,indx,level;
380ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
38116d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
38216d9e3a6SLisandro Dalcin 
38316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
384e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
3854336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
38616d9e3a6SLisandro Dalcin   if (flg) {
3874336a9eeSBarry Smith     jac->cycletype = indx+1;
388fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
38916d9e3a6SLisandro Dalcin   }
39016d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
39116d9e3a6SLisandro Dalcin   if (flg) {
392ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
393fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
39416d9e3a6SLisandro Dalcin   }
39516d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
39616d9e3a6SLisandro Dalcin   if (flg) {
397ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
398fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
39916d9e3a6SLisandro Dalcin   }
4000f1074feSSatish 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);
40116d9e3a6SLisandro Dalcin   if (flg) {
40257622a8eSBarry 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);
403fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
40416d9e3a6SLisandro Dalcin   }
40516d9e3a6SLisandro Dalcin 
4060f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
40716d9e3a6SLisandro Dalcin   if (flg) {
40857622a8eSBarry 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);
409fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
41016d9e3a6SLisandro Dalcin   }
41116d9e3a6SLisandro Dalcin 
4120f1074feSSatish 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);
4130f1074feSSatish Balay   if (flg) {
41457622a8eSBarry 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);
415fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
4160f1074feSSatish Balay   }
4170f1074feSSatish Balay 
4180f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
4190f1074feSSatish Balay   if (flg) {
42057622a8eSBarry 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);
4210f1074feSSatish Balay 
422fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
4230f1074feSSatish Balay   }
4240f1074feSSatish Balay 
4250f1074feSSatish Balay 
4260f1074feSSatish 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);
4270f1074feSSatish Balay   if (flg) {
42857622a8eSBarry 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);
4290f1074feSSatish Balay 
430fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
4310f1074feSSatish Balay   }
4320f1074feSSatish Balay 
4330f1074feSSatish Balay 
43416d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
43516d9e3a6SLisandro Dalcin   if (flg) {
43657622a8eSBarry 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);
437fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
43816d9e3a6SLisandro Dalcin   }
43916d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
44016d9e3a6SLisandro Dalcin   if (flg) {
44157622a8eSBarry 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);
44257622a8eSBarry 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);
443fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
44416d9e3a6SLisandro Dalcin   }
44516d9e3a6SLisandro Dalcin 
44616d9e3a6SLisandro Dalcin   /* Grid sweeps */
4470f1074feSSatish 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);
44816d9e3a6SLisandro Dalcin   if (flg) {
449fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
45016d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
45116d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
4520f1074feSSatish Balay     jac->gridsweeps[1] = indx;
4530f1074feSSatish Balay     /*defaults coarse to 1 */
4540f1074feSSatish Balay     jac->gridsweeps[2] = 1;
45516d9e3a6SLisandro Dalcin   }
4560f1074feSSatish Balay 
4570f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
45816d9e3a6SLisandro Dalcin   if (flg) {
459fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
4600f1074feSSatish Balay     jac->gridsweeps[0] = indx;
46116d9e3a6SLisandro Dalcin   }
46216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
46316d9e3a6SLisandro Dalcin   if (flg) {
464fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
4650f1074feSSatish Balay     jac->gridsweeps[1] = indx;
46616d9e3a6SLisandro Dalcin   }
4670f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
46816d9e3a6SLisandro Dalcin   if (flg) {
469fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
4700f1074feSSatish Balay     jac->gridsweeps[2] = indx;
47116d9e3a6SLisandro Dalcin   }
47216d9e3a6SLisandro Dalcin 
47316d9e3a6SLisandro Dalcin   /* Relax type */
474a669f990SJed 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);
47516d9e3a6SLisandro Dalcin   if (flg) {
4760f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
477fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
4780f1074feSSatish Balay     /* by default, coarse type set to 9 */
4790f1074feSSatish Balay     jac->relaxtype[2] = 9;
4800f1074feSSatish Balay 
48116d9e3a6SLisandro Dalcin   }
482a669f990SJed 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);
48316d9e3a6SLisandro Dalcin   if (flg) {
48416d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
485fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
48616d9e3a6SLisandro Dalcin   }
487a669f990SJed 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);
48816d9e3a6SLisandro Dalcin   if (flg) {
4890f1074feSSatish Balay     jac->relaxtype[1] = indx;
490fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
49116d9e3a6SLisandro Dalcin   }
492a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
49316d9e3a6SLisandro Dalcin   if (flg) {
4940f1074feSSatish Balay     jac->relaxtype[2] = indx;
495fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
49616d9e3a6SLisandro Dalcin   }
49716d9e3a6SLisandro Dalcin 
49816d9e3a6SLisandro Dalcin   /* Relaxation Weight */
49916d9e3a6SLisandro 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);
50016d9e3a6SLisandro Dalcin   if (flg) {
501fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
50216d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
50316d9e3a6SLisandro Dalcin   }
50416d9e3a6SLisandro Dalcin 
50516d9e3a6SLisandro Dalcin   n         = 2;
50616d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
50716d9e3a6SLisandro 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);
50816d9e3a6SLisandro Dalcin   if (flg) {
50916d9e3a6SLisandro Dalcin     if (n == 2) {
51016d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
511fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
512ce94432eSBarry 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);
51316d9e3a6SLisandro Dalcin   }
51416d9e3a6SLisandro Dalcin 
51516d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
51616d9e3a6SLisandro 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);
51716d9e3a6SLisandro Dalcin   if (flg) {
518fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
51916d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
52016d9e3a6SLisandro Dalcin   }
52116d9e3a6SLisandro Dalcin 
52216d9e3a6SLisandro Dalcin   n         = 2;
52316d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
52416d9e3a6SLisandro 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);
52516d9e3a6SLisandro Dalcin   if (flg) {
52616d9e3a6SLisandro Dalcin     if (n == 2) {
52716d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
528fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
529ce94432eSBarry 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);
53016d9e3a6SLisandro Dalcin   }
53116d9e3a6SLisandro Dalcin 
53216d9e3a6SLisandro Dalcin   /* the Relax Order */
533acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
53416d9e3a6SLisandro Dalcin 
5358afaa268SBarry Smith   if (flg && tmp_truth) {
53616d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
537fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
53816d9e3a6SLisandro Dalcin   }
539a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
54016d9e3a6SLisandro Dalcin   if (flg) {
54116d9e3a6SLisandro Dalcin     jac->measuretype = indx;
542fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
54316d9e3a6SLisandro Dalcin   }
5440f1074feSSatish Balay   /* update list length 3/07 */
545a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
54616d9e3a6SLisandro Dalcin   if (flg) {
54716d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
548fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
54916d9e3a6SLisandro Dalcin   }
5500f1074feSSatish Balay 
5510f1074feSSatish Balay   /* new 3/07 */
552a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
5530f1074feSSatish Balay   if (flg) {
5540f1074feSSatish Balay     jac->interptype = indx;
555fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
5560f1074feSSatish Balay   }
5570f1074feSSatish Balay 
558b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
55916d9e3a6SLisandro Dalcin   if (flg) {
560b96a4a96SBarry Smith     level = 3;
5610298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
5622fa5cd67SKarl Rupp 
563b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
564fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
5652ae77aedSBarry Smith   }
5662ae77aedSBarry Smith 
567b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
5682ae77aedSBarry Smith   if (flg) {
569b96a4a96SBarry Smith     level = 3;
5700298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
5712fa5cd67SKarl Rupp 
572b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
573fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
57416d9e3a6SLisandro Dalcin   }
5758f87f92bSBarry Smith 
5768afaa268SBarry Smith   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_coarsen", "HYPRE_BoomerAMGSetNodal()", "None", jac->nodal_coarsen ? PETSC_TRUE : PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5778f87f92bSBarry Smith   if (flg && tmp_truth) {
5788f87f92bSBarry Smith     jac->nodal_coarsen = 1;
579fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,1));
5808f87f92bSBarry Smith   }
5818f87f92bSBarry Smith 
582acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5838f87f92bSBarry Smith   if (flg && tmp_truth) {
5848f87f92bSBarry Smith     PetscInt tmp_int;
5858f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
5868f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
587fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
588fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
589fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
590fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
5918f87f92bSBarry Smith   }
5928f87f92bSBarry Smith 
59316d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
59416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
59516d9e3a6SLisandro Dalcin }
59616d9e3a6SLisandro Dalcin 
59716d9e3a6SLisandro Dalcin #undef __FUNCT__
59816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG"
599ace3abfcSBarry 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)
60016d9e3a6SLisandro Dalcin {
60116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
60216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
6034ddd07fcSJed Brown   PetscInt       oits;
60416d9e3a6SLisandro Dalcin 
60516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
606dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
607fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
608fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
60916d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
61016d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
61116d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
6128b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
6134d0a8057SBarry Smith   *outits = oits;
6144d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
6154d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
616fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
617fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
61816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
61916d9e3a6SLisandro Dalcin }
62016d9e3a6SLisandro Dalcin 
62116d9e3a6SLisandro Dalcin 
62216d9e3a6SLisandro Dalcin #undef __FUNCT__
62316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG"
62416d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
62516d9e3a6SLisandro Dalcin {
62616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
62716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
628ace3abfcSBarry Smith   PetscBool      iascii;
62916d9e3a6SLisandro Dalcin 
63016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
631251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
63216d9e3a6SLisandro Dalcin   if (iascii) {
63316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
63416d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
63516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
63616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
63757622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
63857622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
63957622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
6400f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
6410f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
6420f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
6430f1074feSSatish Balay 
64457622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
64516d9e3a6SLisandro Dalcin 
6460f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
6470f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
6480f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
64916d9e3a6SLisandro Dalcin 
6500f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
6510f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
6520f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
65316d9e3a6SLisandro Dalcin 
65457622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
65557622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
65616d9e3a6SLisandro Dalcin 
65716d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
65816d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr);
65916d9e3a6SLisandro Dalcin     } else {
66016d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr);
66116d9e3a6SLisandro Dalcin     }
66216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
66316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
6640f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
6658f87f92bSBarry Smith     if (jac->nodal_coarsen) {
6668f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal())\n");CHKERRQ(ierr);
6678f87f92bSBarry Smith     }
6688f87f92bSBarry Smith     if (jac->nodal_relax) {
6698f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer," HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
6708f87f92bSBarry Smith     }
67116d9e3a6SLisandro Dalcin   }
67216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
67316d9e3a6SLisandro Dalcin }
67416d9e3a6SLisandro Dalcin 
67516d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
67616d9e3a6SLisandro Dalcin #undef __FUNCT__
67716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails"
6788c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptions *PetscOptionsObject,PC pc)
67916d9e3a6SLisandro Dalcin {
68016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
68116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
6824ddd07fcSJed Brown   PetscInt       indx;
683ace3abfcSBarry Smith   PetscBool      flag;
68416d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
68516d9e3a6SLisandro Dalcin 
68616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
687e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
68816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
68916d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
6902fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
69116d9e3a6SLisandro Dalcin 
69216d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
6932fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
69416d9e3a6SLisandro Dalcin 
69516d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
6962fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
69716d9e3a6SLisandro Dalcin 
698acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
6992fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
70016d9e3a6SLisandro Dalcin 
701acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
7022fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
70316d9e3a6SLisandro Dalcin 
704a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
70516d9e3a6SLisandro Dalcin   if (flag) {
70616d9e3a6SLisandro Dalcin     jac->symt = indx;
707fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
70816d9e3a6SLisandro Dalcin   }
70916d9e3a6SLisandro Dalcin 
71016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
71116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
71216d9e3a6SLisandro Dalcin }
71316d9e3a6SLisandro Dalcin 
71416d9e3a6SLisandro Dalcin #undef __FUNCT__
71516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails"
71616d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
71716d9e3a6SLisandro Dalcin {
71816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
71916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
720ace3abfcSBarry Smith   PetscBool      iascii;
72116d9e3a6SLisandro Dalcin   const char     *symt = 0;;
72216d9e3a6SLisandro Dalcin 
72316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
724251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
72516d9e3a6SLisandro Dalcin   if (iascii) {
72616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
72716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
72857622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
72957622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: filter %g\n",(double)jac->filter);CHKERRQ(ierr);
73057622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
731ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
732ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
7332fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
7342fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
7352fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
736ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
73716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr);
73816d9e3a6SLisandro Dalcin   }
73916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
74016d9e3a6SLisandro Dalcin }
7414cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
7424cb006feSStefano Zampini #undef __FUNCT__
7434cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS"
7449fa463a7SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptions *PetscOptionsObject,PC pc)
7454cb006feSStefano Zampini {
7464cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
7474cb006feSStefano Zampini   PetscErrorCode ierr;
7484cb006feSStefano Zampini   PetscInt       n;
7494cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
7504cb006feSStefano Zampini 
7514cb006feSStefano Zampini   PetscFunctionBegin;
7529fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
753863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
754863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
755863406b8SStefano 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);
756863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
7574cb006feSStefano 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);
7584cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
759863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
760863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
761863406b8SStefano 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);
762863406b8SStefano 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);
763863406b8SStefano 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);
764863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
7654cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
766863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
767863406b8SStefano Zampini                                                                       jac->as_relax_times,
768863406b8SStefano Zampini                                                                       jac->as_relax_weight,
769863406b8SStefano Zampini                                                                       jac->as_omega));
7704cb006feSStefano Zampini   }
771863406b8SStefano 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);
7724cb006feSStefano Zampini   n = 5;
773863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
7744cb006feSStefano Zampini   if (flag || flag2) {
775863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
776863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
777863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
778863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
779863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
780863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
7814cb006feSStefano Zampini   }
782863406b8SStefano 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);
7834cb006feSStefano Zampini   n = 5;
784863406b8SStefano 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);
7854cb006feSStefano Zampini   if (flag || flag2) {
786863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
787863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
788863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
789863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
790863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
791863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
7924cb006feSStefano Zampini   }
793*23df4f25SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_projection_frequency","Frequency at which a projection onto the compatible subspace for problems with zero conductivity regions is performed","None",jac->ams_proj_freq,&jac->ams_proj_freq,&flag);CHKERRQ(ierr);
794*23df4f25SStefano Zampini   if (flag) { /* override HYPRE's default only if the options is used */
795*23df4f25SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetProjectionFrequency,(jac->hsolver,jac->ams_proj_freq));
796*23df4f25SStefano Zampini   }
7974cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
7984cb006feSStefano Zampini   PetscFunctionReturn(0);
7994cb006feSStefano Zampini }
8004cb006feSStefano Zampini 
8014cb006feSStefano Zampini #undef __FUNCT__
8024cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS"
8034cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
8044cb006feSStefano Zampini {
8054cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
8064cb006feSStefano Zampini   PetscErrorCode ierr;
8074cb006feSStefano Zampini   PetscBool      iascii;
8084cb006feSStefano Zampini 
8094cb006feSStefano Zampini   PetscFunctionBegin;
8104cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
8114cb006feSStefano Zampini   if (iascii) {
8124cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
813863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
8144cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
815863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
816863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
817863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
818863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
819863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
8204cb006feSStefano Zampini     if (jac->alpha_Poisson) {
8214cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8224cb006feSStefano Zampini     } else {
8234cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr);
8244cb006feSStefano Zampini     }
825863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
826863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
827863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
828863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
829863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
830863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
8314cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
8324cb006feSStefano Zampini       if (jac->beta_Poisson) {
8334cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
8344cb006feSStefano Zampini       } else {
8354cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr);
8364cb006feSStefano Zampini       }
837863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
838863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
839863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
840863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
841863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
842863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
843*23df4f25SStefano Zampini       if (jac->ams_beta_is_zero_part) {
844*23df4f25SStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     compatible subspace projection frequency %d (-1 HYPRE uses default)\n",jac->ams_proj_freq);CHKERRQ(ierr);
845*23df4f25SStefano Zampini       }
846*23df4f25SStefano Zampini     } else {
847*23df4f25SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver not used (zero-conductivity everywhere) \n");CHKERRQ(ierr);
8484cb006feSStefano Zampini     }
8494cb006feSStefano Zampini   }
8504cb006feSStefano Zampini   PetscFunctionReturn(0);
8514cb006feSStefano Zampini }
8524cb006feSStefano Zampini 
8534cb006feSStefano Zampini #undef __FUNCT__
854863406b8SStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_ADS"
855863406b8SStefano Zampini static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptions *PetscOptionsObject,PC pc)
856863406b8SStefano Zampini {
857863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
858863406b8SStefano Zampini   PetscErrorCode ierr;
859863406b8SStefano Zampini   PetscInt       n;
860863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
861863406b8SStefano Zampini 
862863406b8SStefano Zampini   PetscFunctionBegin;
863863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
864863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
865863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
866863406b8SStefano 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);
867863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
868863406b8SStefano 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);
869863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
870863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
871863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
872863406b8SStefano 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);
873863406b8SStefano 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);
874863406b8SStefano 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);
875863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
876863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
877863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
878863406b8SStefano Zampini                                                                       jac->as_relax_times,
879863406b8SStefano Zampini                                                                       jac->as_relax_weight,
880863406b8SStefano Zampini                                                                       jac->as_omega));
881863406b8SStefano Zampini   }
882863406b8SStefano 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);
883863406b8SStefano Zampini   n = 5;
884863406b8SStefano 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);
885863406b8SStefano 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);
886863406b8SStefano Zampini   if (flag || flag2 || flag3) {
887863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
888863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
889863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
890863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
891863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
892863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
893863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
894863406b8SStefano Zampini   }
895863406b8SStefano 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);
896863406b8SStefano Zampini   n = 5;
897863406b8SStefano 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);
898863406b8SStefano Zampini   if (flag || flag2) {
899863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
900863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
901863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
902863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
903863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
904863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
905863406b8SStefano Zampini   }
906863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
907863406b8SStefano Zampini   PetscFunctionReturn(0);
908863406b8SStefano Zampini }
909863406b8SStefano Zampini 
910863406b8SStefano Zampini #undef __FUNCT__
911863406b8SStefano Zampini #define __FUNCT__ "PCView_HYPRE_ADS"
912863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
913863406b8SStefano Zampini {
914863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
915863406b8SStefano Zampini   PetscErrorCode ierr;
916863406b8SStefano Zampini   PetscBool      iascii;
917863406b8SStefano Zampini 
918863406b8SStefano Zampini   PetscFunctionBegin;
919863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
920863406b8SStefano Zampini   if (iascii) {
921863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
922863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
923863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
924863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
925863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
926863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
927863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
928863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
929863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: AMS solver\n");CHKERRQ(ierr);
930863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
931863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
932863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
933863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
934863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
935863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
936863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
937863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: vector Poisson solver\n");CHKERRQ(ierr);
938863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
939863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
940863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
941863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
942863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
943863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
944863406b8SStefano Zampini   }
945863406b8SStefano Zampini   PetscFunctionReturn(0);
946863406b8SStefano Zampini }
947863406b8SStefano Zampini 
948863406b8SStefano Zampini #undef __FUNCT__
949863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE"
950863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
9514cb006feSStefano Zampini {
9524cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
9534cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_G;
9544cb006feSStefano Zampini   PetscErrorCode     ierr;
9554cb006feSStefano Zampini 
9564cb006feSStefano Zampini   PetscFunctionBegin;
9574cb006feSStefano Zampini   /* throw away any discrete gradient if already set */
9584cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
9594cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(G,&jac->G);CHKERRQ(ierr);
9604cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(G,jac->G);CHKERRQ(ierr);
9614cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->G,(void**)(&parcsr_G)));
962863406b8SStefano Zampini   PetscStackCall("Hypre set gradient",ierr = (*jac->setdgrad)(jac->hsolver,parcsr_G);CHKERRQ(ierr););
9634cb006feSStefano Zampini   PetscFunctionReturn(0);
9644cb006feSStefano Zampini }
9654cb006feSStefano Zampini 
9664cb006feSStefano Zampini #undef __FUNCT__
9674cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient"
9684cb006feSStefano Zampini /*@
9694cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
9704cb006feSStefano Zampini 
9714cb006feSStefano Zampini    Collective on PC
9724cb006feSStefano Zampini 
9734cb006feSStefano Zampini    Input Parameters:
9744cb006feSStefano Zampini +  pc - the preconditioning context
9754cb006feSStefano Zampini -  G - the discrete gradient
9764cb006feSStefano Zampini 
9774cb006feSStefano Zampini    Level: intermediate
9784cb006feSStefano Zampini 
9794cb006feSStefano 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
980863406b8SStefano 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
9814cb006feSStefano Zampini 
9824cb006feSStefano Zampini .seealso:
9834cb006feSStefano Zampini @*/
9844cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
9854cb006feSStefano Zampini {
9864cb006feSStefano Zampini   PetscErrorCode ierr;
9874cb006feSStefano Zampini 
9884cb006feSStefano Zampini   PetscFunctionBegin;
9894cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
9904cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
9914cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
9924cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
9934cb006feSStefano Zampini   PetscFunctionReturn(0);
9944cb006feSStefano Zampini }
9954cb006feSStefano Zampini 
9964cb006feSStefano Zampini #undef __FUNCT__
997863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl_HYPRE"
998863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
999863406b8SStefano Zampini {
1000863406b8SStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
1001863406b8SStefano Zampini   HYPRE_ParCSRMatrix parcsr_C;
1002863406b8SStefano Zampini   PetscErrorCode     ierr;
1003863406b8SStefano Zampini 
1004863406b8SStefano Zampini   PetscFunctionBegin;
1005863406b8SStefano Zampini   /* throw away any discrete curl if already set */
1006863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
1007863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(C,&jac->C);CHKERRQ(ierr);
1008863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(C,jac->C);CHKERRQ(ierr);
1009863406b8SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->C,(void**)(&parcsr_C)));
1010863406b8SStefano Zampini   PetscStackCall("Hypre set curl",ierr = (*jac->setdcurl)(jac->hsolver,parcsr_C);CHKERRQ(ierr););
1011863406b8SStefano Zampini   PetscFunctionReturn(0);
1012863406b8SStefano Zampini }
1013863406b8SStefano Zampini 
1014863406b8SStefano Zampini #undef __FUNCT__
1015863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl"
1016863406b8SStefano Zampini /*@
1017863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1018863406b8SStefano Zampini 
1019863406b8SStefano Zampini    Collective on PC
1020863406b8SStefano Zampini 
1021863406b8SStefano Zampini    Input Parameters:
1022863406b8SStefano Zampini +  pc - the preconditioning context
1023863406b8SStefano Zampini -  C - the discrete curl
1024863406b8SStefano Zampini 
1025863406b8SStefano Zampini    Level: intermediate
1026863406b8SStefano Zampini 
1027863406b8SStefano 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
1028863406b8SStefano 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
1029863406b8SStefano Zampini 
1030863406b8SStefano Zampini .seealso:
1031863406b8SStefano Zampini @*/
1032863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1033863406b8SStefano Zampini {
1034863406b8SStefano Zampini   PetscErrorCode ierr;
1035863406b8SStefano Zampini 
1036863406b8SStefano Zampini   PetscFunctionBegin;
1037863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1038863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1039863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1040863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1041863406b8SStefano Zampini   PetscFunctionReturn(0);
1042863406b8SStefano Zampini }
1043863406b8SStefano Zampini 
1044863406b8SStefano Zampini #undef __FUNCT__
10454cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS"
10464cb006feSStefano Zampini static PetscErrorCode PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
10474cb006feSStefano Zampini {
10484cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
10494cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_alpha_Poisson;
10504cb006feSStefano Zampini   PetscErrorCode     ierr;
10514cb006feSStefano Zampini 
10524cb006feSStefano Zampini   PetscFunctionBegin;
10534cb006feSStefano Zampini   /* throw away any matrix if already set */
10544cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
10554cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->alpha_Poisson);CHKERRQ(ierr);
10564cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->alpha_Poisson);CHKERRQ(ierr);
10574cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->alpha_Poisson,(void**)(&parcsr_alpha_Poisson)));
10584cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr_alpha_Poisson));
10594cb006feSStefano Zampini   PetscFunctionReturn(0);
10604cb006feSStefano Zampini }
10614cb006feSStefano Zampini 
10624cb006feSStefano Zampini #undef __FUNCT__
10634cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix"
10644cb006feSStefano Zampini /*@
10654cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
10664cb006feSStefano Zampini 
10674cb006feSStefano Zampini    Collective on PC
10684cb006feSStefano Zampini 
10694cb006feSStefano Zampini    Input Parameters:
10704cb006feSStefano Zampini +  pc - the preconditioning context
10714cb006feSStefano Zampini -  A - the matrix
10724cb006feSStefano Zampini 
10734cb006feSStefano Zampini    Level: intermediate
10744cb006feSStefano Zampini 
10754cb006feSStefano Zampini    Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
10764cb006feSStefano Zampini 
10774cb006feSStefano Zampini .seealso:
10784cb006feSStefano Zampini @*/
10794cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
10804cb006feSStefano Zampini {
10814cb006feSStefano Zampini   PetscErrorCode ierr;
10824cb006feSStefano Zampini 
10834cb006feSStefano Zampini   PetscFunctionBegin;
10844cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
10854cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
10864cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
10874cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetAlphaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
10884cb006feSStefano Zampini   PetscFunctionReturn(0);
10894cb006feSStefano Zampini }
10904cb006feSStefano Zampini 
10914cb006feSStefano Zampini #undef __FUNCT__
10924cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix_HYPRE_AMS"
10934cb006feSStefano Zampini static PetscErrorCode PCHYPRESetBetaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
10944cb006feSStefano Zampini {
10954cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
10964cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_beta_Poisson;
10974cb006feSStefano Zampini   PetscErrorCode     ierr;
10984cb006feSStefano Zampini 
10994cb006feSStefano Zampini   PetscFunctionBegin;
11004cb006feSStefano Zampini   if (!A) {
1101484796dcSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
11024cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_TRUE;
11034cb006feSStefano Zampini     PetscFunctionReturn(0);
11044cb006feSStefano Zampini   }
11054cb006feSStefano Zampini   /* throw away any matrix if already set */
11064cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
11074cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->beta_Poisson);CHKERRQ(ierr);
11084cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->beta_Poisson);CHKERRQ(ierr);
11094cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->beta_Poisson,(void**)(&parcsr_beta_Poisson)));
11104cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr_beta_Poisson));
11114cb006feSStefano Zampini   PetscFunctionReturn(0);
11124cb006feSStefano Zampini }
11134cb006feSStefano Zampini 
11144cb006feSStefano Zampini #undef __FUNCT__
11154cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix"
11164cb006feSStefano Zampini /*@
11174cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
11184cb006feSStefano Zampini 
11194cb006feSStefano Zampini    Collective on PC
11204cb006feSStefano Zampini 
11214cb006feSStefano Zampini    Input Parameters:
11224cb006feSStefano Zampini +  pc - the preconditioning context
11234cb006feSStefano Zampini -  A - the matrix
11244cb006feSStefano Zampini 
11254cb006feSStefano Zampini    Level: intermediate
11264cb006feSStefano Zampini 
11274cb006feSStefano Zampini    Notes: A should be obtained by discretizing the Poisson problem with linear finite elements.
11284cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
11294cb006feSStefano Zampini 
11304cb006feSStefano Zampini .seealso:
11314cb006feSStefano Zampini @*/
11324cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
11334cb006feSStefano Zampini {
11344cb006feSStefano Zampini   PetscErrorCode ierr;
11354cb006feSStefano Zampini 
11364cb006feSStefano Zampini   PetscFunctionBegin;
11374cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11384cb006feSStefano Zampini   if (A) {
11394cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
11404cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
11414cb006feSStefano Zampini   }
11424cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetBetaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
11434cb006feSStefano Zampini   PetscFunctionReturn(0);
11444cb006feSStefano Zampini }
11454cb006feSStefano Zampini 
11464cb006feSStefano Zampini #undef __FUNCT__
11474cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE_AMS"
11484cb006feSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE_AMS(PC pc,Vec ozz, Vec zoz, Vec zzo)
11494cb006feSStefano Zampini {
11504cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11514cb006feSStefano Zampini   HYPRE_ParVector    par_ozz,par_zoz,par_zzo;
115212ddd1b6SStefano Zampini   PetscInt           dim;
11534cb006feSStefano Zampini   PetscErrorCode     ierr;
11544cb006feSStefano Zampini 
11554cb006feSStefano Zampini   PetscFunctionBegin;
11564cb006feSStefano Zampini   /* throw away any vector if already set */
11574cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
11584cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
11594cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
11604cb006feSStefano Zampini   jac->constants[0] = NULL;
11614cb006feSStefano Zampini   jac->constants[1] = NULL;
11624cb006feSStefano Zampini   jac->constants[2] = NULL;
11634cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
11644cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
11654cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&par_ozz)));
11664cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
11674cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
11684cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&par_zoz)));
116912ddd1b6SStefano Zampini   dim = 2;
11704cb006feSStefano Zampini   if (zzo) {
11714cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
11724cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
11734cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&par_zzo)));
117412ddd1b6SStefano Zampini     dim++;
11754cb006feSStefano Zampini   }
11764cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,par_ozz,par_zoz,par_zzo));
117712ddd1b6SStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim));
11784cb006feSStefano Zampini   PetscFunctionReturn(0);
11794cb006feSStefano Zampini }
11804cb006feSStefano Zampini 
11814cb006feSStefano Zampini #undef __FUNCT__
11824cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors"
11834cb006feSStefano Zampini /*@
11844cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
11854cb006feSStefano Zampini 
11864cb006feSStefano Zampini    Collective on PC
11874cb006feSStefano Zampini 
11884cb006feSStefano Zampini    Input Parameters:
11894cb006feSStefano Zampini +  pc - the preconditioning context
11904cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
11914cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
11924cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
11934cb006feSStefano Zampini 
11944cb006feSStefano Zampini    Level: intermediate
11954cb006feSStefano Zampini 
11964cb006feSStefano Zampini    Notes:
11974cb006feSStefano Zampini 
11984cb006feSStefano Zampini .seealso:
11994cb006feSStefano Zampini @*/
12004cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
12014cb006feSStefano Zampini {
12024cb006feSStefano Zampini   PetscErrorCode ierr;
12034cb006feSStefano Zampini 
12044cb006feSStefano Zampini   PetscFunctionBegin;
12054cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12064cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
12074cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
12084cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
12094cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
12104cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
12114cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
12124cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
12134cb006feSStefano Zampini   PetscFunctionReturn(0);
12144cb006feSStefano Zampini }
12154cb006feSStefano Zampini 
12164cb006feSStefano Zampini #undef __FUNCT__
1217863406b8SStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE"
1218863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
12194cb006feSStefano Zampini {
12204cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
12214cb006feSStefano Zampini   Vec             tv;
12224cb006feSStefano Zampini   HYPRE_ParVector par_coords[3];
12234cb006feSStefano Zampini   PetscInt        i;
12244cb006feSStefano Zampini   PetscErrorCode  ierr;
12254cb006feSStefano Zampini 
12264cb006feSStefano Zampini   PetscFunctionBegin;
12274cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
12284cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
12294cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
12304cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
12314cb006feSStefano Zampini   /* set problem's dimension */
1232863406b8SStefano Zampini   if (jac->setdim) {
1233863406b8SStefano Zampini     PetscStackCall("Hypre set dim",ierr = (*jac->setdim)(jac->hsolver,dim);CHKERRQ(ierr););
1234863406b8SStefano Zampini   }
12354cb006feSStefano Zampini   /* compute IJ vector for coordinates */
12364cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
12374cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
12384cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
12394cb006feSStefano Zampini   for (i=0;i<dim;i++) {
12404cb006feSStefano Zampini     PetscScalar *array;
12414cb006feSStefano Zampini     PetscInt    j;
12424cb006feSStefano Zampini 
12434cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
12444cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
12454cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
12464cb006feSStefano Zampini       array[j] = coords[j*dim+i];
12474cb006feSStefano Zampini     }
12484cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
12494cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
12504cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
12514cb006feSStefano Zampini   }
12524cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
12534cb006feSStefano Zampini   /* pass parCSR vectors to AMS solver */
12544cb006feSStefano Zampini   par_coords[0] = NULL;
12554cb006feSStefano Zampini   par_coords[1] = NULL;
12564cb006feSStefano Zampini   par_coords[2] = NULL;
12574cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&par_coords[0])));
12584cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&par_coords[1])));
12594cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&par_coords[2])));
1260863406b8SStefano Zampini   PetscStackCall("Hypre set coords",ierr = (*jac->setcoord)(jac->hsolver,par_coords[0],par_coords[1],par_coords[2]);CHKERRQ(ierr););
12614cb006feSStefano Zampini   PetscFunctionReturn(0);
12624cb006feSStefano Zampini }
12634cb006feSStefano Zampini 
126416d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
126516d9e3a6SLisandro Dalcin 
126616d9e3a6SLisandro Dalcin #undef __FUNCT__
126716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
1268f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
126916d9e3a6SLisandro Dalcin {
127016d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
127116d9e3a6SLisandro Dalcin 
127216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
127316d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
127416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
127516d9e3a6SLisandro Dalcin }
127616d9e3a6SLisandro Dalcin 
127716d9e3a6SLisandro Dalcin #undef __FUNCT__
127816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
1279f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
128016d9e3a6SLisandro Dalcin {
128116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
128216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1283ace3abfcSBarry Smith   PetscBool      flag;
128416d9e3a6SLisandro Dalcin 
128516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
128616d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
128716d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1288ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
128916d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
129016d9e3a6SLisandro Dalcin   } else {
129116d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
129216d9e3a6SLisandro Dalcin   }
129316d9e3a6SLisandro Dalcin 
129416d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
129516d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
129616d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
129716d9e3a6SLisandro Dalcin 
129816d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
129916d9e3a6SLisandro Dalcin   if (flag) {
1300fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
130116d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
130216d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
130316d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
130416d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
130516d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
130616d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
130716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
130816d9e3a6SLisandro Dalcin   }
130916d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
131016d9e3a6SLisandro Dalcin   if (flag) {
1311fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
131216d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
131316d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
131416d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
131516d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
131616d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
131716d9e3a6SLisandro Dalcin     /* initialize */
131816d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
131916d9e3a6SLisandro Dalcin     jac->threshhold = .1;
132016d9e3a6SLisandro Dalcin     jac->filter     = .1;
132116d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
13222fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
13232fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
13242fa5cd67SKarl Rupp 
132516d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
132616d9e3a6SLisandro Dalcin     jac->symt = 0;
1327fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1328fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1329fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1330fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1331fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1332fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
133316d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
133416d9e3a6SLisandro Dalcin   }
133516d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
133616d9e3a6SLisandro Dalcin   if (flag) {
133716d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
133816d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
133916d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
134016d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
134116d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
134216d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
134316d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
134416d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
134516d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
134616d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
134716d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
134816d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
134916d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
13508f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
135116d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
135216d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
135316d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
135416d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
135516d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
13560f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
13578f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
13580f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
135916d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
136016d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
136116d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
13620f1074feSSatish Balay     jac->interptype       = 0;
13630f1074feSSatish Balay     jac->agg_nl           = 0;
13640f1074feSSatish Balay     jac->pmax             = 0;
13650f1074feSSatish Balay     jac->truncfactor      = 0.0;
13660f1074feSSatish Balay     jac->agg_num_paths    = 1;
13678f87f92bSBarry Smith 
13688f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
13698f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
13708f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1371fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1372fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1373fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1374fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1375fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1376fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1377fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1378fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1379fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1380fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1381fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1382fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1383fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1384fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1385fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1386fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
138716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
138816d9e3a6SLisandro Dalcin   }
13894cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
13904cb006feSStefano Zampini   if (flag) {
13914cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
13924cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
13934cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
13944cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
13954cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
13964cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
1397863406b8SStefano Zampini     jac->setdgrad            = HYPRE_AMSSetDiscreteGradient;
1398863406b8SStefano Zampini     jac->setcoord            = HYPRE_AMSSetCoordinateVectors;
1399863406b8SStefano Zampini     jac->setdim              = HYPRE_AMSSetDimension;
14004cb006feSStefano Zampini     jac->coords[0]           = NULL;
14014cb006feSStefano Zampini     jac->coords[1]           = NULL;
14024cb006feSStefano Zampini     jac->coords[2]           = NULL;
14034cb006feSStefano Zampini     jac->G                   = NULL;
14044cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1405863406b8SStefano Zampini     jac->as_print           = 0;
1406863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1407863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
14084cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
14094cb006feSStefano Zampini     /* Smoothing options */
1410863406b8SStefano Zampini     jac->as_relax_type      = 2;
1411863406b8SStefano Zampini     jac->as_relax_times     = 1;
1412863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1413863406b8SStefano Zampini     jac->as_omega           = 1.0;
14144cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1415863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1416863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1417863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 8;
1418863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1419863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1420863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
14214cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1422863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1423863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1424863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 8;
1425863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1426863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1427863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1428863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1429863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
14304cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1431863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1432863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1433863406b8SStefano Zampini                                                                       jac->as_relax_times,
1434863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1435863406b8SStefano Zampini                                                                       jac->as_omega));
1436863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1437863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1438863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1439863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1440863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1441863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1442863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1443863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1444863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1445863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1446863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1447863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1448*23df4f25SStefano Zampini     /* Zero conductivity */
1449*23df4f25SStefano Zampini     jac->ams_beta_is_zero      = PETSC_FALSE;
1450*23df4f25SStefano Zampini     jac->ams_beta_is_zero_part = PETSC_FALSE;
1451863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1452863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
14534cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE_AMS);CHKERRQ(ierr);
14544cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
14554cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",PCHYPRESetBetaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
14564cb006feSStefano Zampini     PetscFunctionReturn(0);
14574cb006feSStefano Zampini   }
1458863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1459863406b8SStefano Zampini   if (flag) {
1460863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1461863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1462863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1463863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1464863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1465863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1466863406b8SStefano Zampini     jac->setdgrad            = HYPRE_ADSSetDiscreteGradient;
1467863406b8SStefano Zampini     jac->setdcurl            = HYPRE_ADSSetDiscreteCurl;
1468863406b8SStefano Zampini     jac->setcoord            = HYPRE_ADSSetCoordinateVectors;
1469863406b8SStefano Zampini     jac->coords[0]           = NULL;
1470863406b8SStefano Zampini     jac->coords[1]           = NULL;
1471863406b8SStefano Zampini     jac->coords[2]           = NULL;
1472863406b8SStefano Zampini     jac->G                   = NULL;
1473863406b8SStefano Zampini     jac->C                   = NULL;
1474863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1475863406b8SStefano Zampini     jac->as_print           = 0;
1476863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1477863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1478863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1479863406b8SStefano Zampini     /* Smoothing options */
1480863406b8SStefano Zampini     jac->as_relax_type      = 2;
1481863406b8SStefano Zampini     jac->as_relax_times     = 1;
1482863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1483863406b8SStefano Zampini     jac->as_omega           = 1.0;
1484863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1485863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1486863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1487863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1488863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1489863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1490863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1491863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1492863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1493863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1494863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1495863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1496863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1497863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1498863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1499863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1500863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1501863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1502863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1503863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1504863406b8SStefano Zampini                                                                       jac->as_relax_times,
1505863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1506863406b8SStefano Zampini                                                                       jac->as_omega));
1507863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1508863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1509863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1510863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1511863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1512863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1513863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1514863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1515863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1516863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1517863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1518863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1519863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1520863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1521863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
1522863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
1523863406b8SStefano Zampini     PetscFunctionReturn(0);
1524863406b8SStefano Zampini   }
1525503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
15262fa5cd67SKarl Rupp 
15270298fd71SBarry Smith   jac->hypre_type = NULL;
152833263987SBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, boomeramg, ams",name);
152916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
153016d9e3a6SLisandro Dalcin }
153116d9e3a6SLisandro Dalcin 
153216d9e3a6SLisandro Dalcin /*
153316d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
153416d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
153516d9e3a6SLisandro Dalcin */
153616d9e3a6SLisandro Dalcin #undef __FUNCT__
153716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
15388c34d3f5SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptions *PetscOptionsObject,PC pc)
153916d9e3a6SLisandro Dalcin {
154016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
15414ddd07fcSJed Brown   PetscInt       indx;
1542863406b8SStefano Zampini   const char     *type[] = {"pilut","parasails","boomeramg","ams","ads"};
1543ace3abfcSBarry Smith   PetscBool      flg;
154416d9e3a6SLisandro Dalcin 
154516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
15469fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
15479c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
154816d9e3a6SLisandro Dalcin   if (flg) {
154916d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
155002a17cd4SBarry Smith   } else {
155102a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
155216d9e3a6SLisandro Dalcin   }
155316d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
15543931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
155516d9e3a6SLisandro Dalcin   }
155616d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
155716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
155816d9e3a6SLisandro Dalcin }
155916d9e3a6SLisandro Dalcin 
156016d9e3a6SLisandro Dalcin #undef __FUNCT__
156116d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
156216d9e3a6SLisandro Dalcin /*@C
156316d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
156416d9e3a6SLisandro Dalcin 
156516d9e3a6SLisandro Dalcin    Input Parameters:
156616d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1567863406b8SStefano Zampini -     name - either  pilut, parasails, boomeramg, ams, ads
156816d9e3a6SLisandro Dalcin 
156916d9e3a6SLisandro Dalcin    Options Database Keys:
1570863406b8SStefano Zampini    -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
157116d9e3a6SLisandro Dalcin 
157216d9e3a6SLisandro Dalcin    Level: intermediate
157316d9e3a6SLisandro Dalcin 
157416d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
157516d9e3a6SLisandro Dalcin            PCHYPRE
157616d9e3a6SLisandro Dalcin 
157716d9e3a6SLisandro Dalcin @*/
15787087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
157916d9e3a6SLisandro Dalcin {
15804ac538c5SBarry Smith   PetscErrorCode ierr;
158116d9e3a6SLisandro Dalcin 
158216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
15830700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
158416d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
15854ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
158616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
158716d9e3a6SLisandro Dalcin }
158816d9e3a6SLisandro Dalcin 
158916d9e3a6SLisandro Dalcin #undef __FUNCT__
159016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
159116d9e3a6SLisandro Dalcin /*@C
159216d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
159316d9e3a6SLisandro Dalcin 
159416d9e3a6SLisandro Dalcin    Input Parameter:
159516d9e3a6SLisandro Dalcin .     pc - the preconditioner context
159616d9e3a6SLisandro Dalcin 
159716d9e3a6SLisandro Dalcin    Output Parameter:
1598863406b8SStefano Zampini .     name - either  pilut, parasails, boomeramg, ams, ads
159916d9e3a6SLisandro Dalcin 
160016d9e3a6SLisandro Dalcin    Level: intermediate
160116d9e3a6SLisandro Dalcin 
160216d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
160316d9e3a6SLisandro Dalcin            PCHYPRE
160416d9e3a6SLisandro Dalcin 
160516d9e3a6SLisandro Dalcin @*/
16067087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
160716d9e3a6SLisandro Dalcin {
16084ac538c5SBarry Smith   PetscErrorCode ierr;
160916d9e3a6SLisandro Dalcin 
161016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16110700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
161216d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
16134ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
161416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
161516d9e3a6SLisandro Dalcin }
161616d9e3a6SLisandro Dalcin 
161716d9e3a6SLisandro Dalcin /*MC
161816d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
161916d9e3a6SLisandro Dalcin 
162016d9e3a6SLisandro Dalcin    Options Database Keys:
1621863406b8SStefano Zampini +   -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
162216d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
162316d9e3a6SLisandro Dalcin           preconditioner
162416d9e3a6SLisandro Dalcin 
162516d9e3a6SLisandro Dalcin    Level: intermediate
162616d9e3a6SLisandro Dalcin 
162716d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
162816d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
162916d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
163016d9e3a6SLisandro Dalcin 
163116d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
16320f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
16330f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
16340f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
16358f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
16360f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
16370f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
163816d9e3a6SLisandro Dalcin 
16390f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
16400f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
16410f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
164216d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
164316d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
164416d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
164516d9e3a6SLisandro Dalcin 
164616d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
164716d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
164816d9e3a6SLisandro Dalcin 
16499e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
16509e5bc791SBarry Smith 
165116d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
16529e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
165316d9e3a6SLisandro Dalcin 
165416d9e3a6SLisandro Dalcin M*/
165516d9e3a6SLisandro Dalcin 
165616d9e3a6SLisandro Dalcin #undef __FUNCT__
165716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
16588cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
165916d9e3a6SLisandro Dalcin {
166016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
166116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
166216d9e3a6SLisandro Dalcin 
166316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1664b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
16652fa5cd67SKarl Rupp 
166616d9e3a6SLisandro Dalcin   pc->data                = jac;
166716d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
166816d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
166916d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
167016d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
167116d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
16720298fd71SBarry Smith   jac->hypre_type         = NULL;
16734cb006feSStefano Zampini   jac->coords[0]          = NULL;
16744cb006feSStefano Zampini   jac->coords[1]          = NULL;
16754cb006feSStefano Zampini   jac->coords[2]          = NULL;
16764cb006feSStefano Zampini   jac->constants[0]       = NULL;
16774cb006feSStefano Zampini   jac->constants[1]       = NULL;
16784cb006feSStefano Zampini   jac->constants[2]       = NULL;
1679863406b8SStefano Zampini   jac->G                  = NULL;
1680863406b8SStefano Zampini   jac->C                  = NULL;
1681863406b8SStefano Zampini   jac->alpha_Poisson      = NULL;
1682863406b8SStefano Zampini   jac->beta_Poisson       = NULL;
1683fd444223SStefano Zampini   jac->setdim             = NULL;
168416d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1685ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1686bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1687bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
168816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
168916d9e3a6SLisandro Dalcin }
1690ebc551c0SBarry Smith 
1691f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1692f91d8e95SBarry Smith 
1693b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1694af0996ceSBarry Smith #include <petsc/private/matimpl.h>
1695ebc551c0SBarry Smith 
1696ebc551c0SBarry Smith typedef struct {
169768326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1698f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
16999e5bc791SBarry Smith 
17009e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
17014ddd07fcSJed Brown   PetscInt its;
17029e5bc791SBarry Smith   double   tol;
17034ddd07fcSJed Brown   PetscInt relax_type;
17044ddd07fcSJed Brown   PetscInt rap_type;
17054ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
17064ddd07fcSJed Brown   PetscInt max_levels;
1707ebc551c0SBarry Smith } PC_PFMG;
1708ebc551c0SBarry Smith 
1709ebc551c0SBarry Smith #undef __FUNCT__
1710ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1711ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1712ebc551c0SBarry Smith {
1713ebc551c0SBarry Smith   PetscErrorCode ierr;
1714f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1715ebc551c0SBarry Smith 
1716ebc551c0SBarry Smith   PetscFunctionBegin;
17172fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1718f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1719c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1720ebc551c0SBarry Smith   PetscFunctionReturn(0);
1721ebc551c0SBarry Smith }
1722ebc551c0SBarry Smith 
17239e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
17249e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
17259e5bc791SBarry Smith 
1726ebc551c0SBarry Smith #undef __FUNCT__
1727ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1728ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1729ebc551c0SBarry Smith {
1730ebc551c0SBarry Smith   PetscErrorCode ierr;
1731ace3abfcSBarry Smith   PetscBool      iascii;
1732f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1733ebc551c0SBarry Smith 
1734ebc551c0SBarry Smith   PetscFunctionBegin;
1735251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
17369e5bc791SBarry Smith   if (iascii) {
17379e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
17389e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
17399e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
17409e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
17419e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
17429e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
17433b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
17449e5bc791SBarry Smith   }
1745ebc551c0SBarry Smith   PetscFunctionReturn(0);
1746ebc551c0SBarry Smith }
1747ebc551c0SBarry Smith 
17489e5bc791SBarry Smith 
1749ebc551c0SBarry Smith #undef __FUNCT__
1750ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
17518c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptions *PetscOptionsObject,PC pc)
1752ebc551c0SBarry Smith {
1753ebc551c0SBarry Smith   PetscErrorCode ierr;
1754f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1755ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1756ebc551c0SBarry Smith 
1757ebc551c0SBarry Smith   PetscFunctionBegin;
1758e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
17590298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
176068326731SBarry Smith   if (flg) {
1761a0324ebeSBarry Smith     int level=3;
1762fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
176368326731SBarry Smith   }
17640298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1765fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
17660298fd71SBarry 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);
1767fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
17680298fd71SBarry 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);
1769fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
17709e5bc791SBarry Smith 
17710298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
1772fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
17733b46a515SGlenn Hammond 
17740298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1775fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
17760298fd71SBarry 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);
1777fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
17780298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
1779fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1780ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1781ebc551c0SBarry Smith   PetscFunctionReturn(0);
1782ebc551c0SBarry Smith }
1783ebc551c0SBarry Smith 
1784f91d8e95SBarry Smith #undef __FUNCT__
1785f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1786f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1787f91d8e95SBarry Smith {
1788f91d8e95SBarry Smith   PetscErrorCode    ierr;
1789f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
1790d9ca1df4SBarry Smith   PetscScalar       *yy;
1791d9ca1df4SBarry Smith   const PetscScalar *xx;
17924ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
179368326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1794f91d8e95SBarry Smith 
1795f91d8e95SBarry Smith   PetscFunctionBegin;
1796dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1797aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1798f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1799f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1800f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1801f91d8e95SBarry Smith 
1802f91d8e95SBarry Smith   /* copy x values over to hypre */
1803fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1804d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1805d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
1806d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1807fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
1808fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1809f91d8e95SBarry Smith 
1810f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1811f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
18128b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
1813f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1814f91d8e95SBarry Smith   PetscFunctionReturn(0);
1815f91d8e95SBarry Smith }
1816f91d8e95SBarry Smith 
18179e5bc791SBarry Smith #undef __FUNCT__
18189e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1819ace3abfcSBarry 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)
18209e5bc791SBarry Smith {
18219e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
18229e5bc791SBarry Smith   PetscErrorCode ierr;
18234ddd07fcSJed Brown   PetscInt       oits;
18249e5bc791SBarry Smith 
18259e5bc791SBarry Smith   PetscFunctionBegin;
1826dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1827fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1828fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
18299e5bc791SBarry Smith 
18309e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
18318b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
18329e5bc791SBarry Smith   *outits = oits;
18339e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
18349e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1835fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1836fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
18379e5bc791SBarry Smith   PetscFunctionReturn(0);
18389e5bc791SBarry Smith }
18399e5bc791SBarry Smith 
18409e5bc791SBarry Smith 
18413a32d3dbSGlenn Hammond #undef __FUNCT__
18423a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
18433a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
18443a32d3dbSGlenn Hammond {
18453a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
18463a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
18473a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1848ace3abfcSBarry Smith   PetscBool       flg;
18493a32d3dbSGlenn Hammond 
18503a32d3dbSGlenn Hammond   PetscFunctionBegin;
1851251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1852ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
18533a32d3dbSGlenn Hammond 
18543a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
18552fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1856fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1857fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1858fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
18593a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
18603a32d3dbSGlenn Hammond }
18613a32d3dbSGlenn Hammond 
1862ebc551c0SBarry Smith 
1863ebc551c0SBarry Smith /*MC
1864ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1865ebc551c0SBarry Smith 
1866ebc551c0SBarry Smith    Level: advanced
1867ebc551c0SBarry Smith 
18689e5bc791SBarry Smith    Options Database:
18699e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
18709e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
18719e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
18729e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
18739e5bc791SBarry 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
18749e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
1875f91d8e95SBarry Smith 
18769e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
18779e5bc791SBarry Smith 
18788e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
1879aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
18809e5bc791SBarry Smith 
18819e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
1882ebc551c0SBarry Smith M*/
1883ebc551c0SBarry Smith 
1884ebc551c0SBarry Smith #undef __FUNCT__
1885ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
18868cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
1887ebc551c0SBarry Smith {
1888ebc551c0SBarry Smith   PetscErrorCode ierr;
1889ebc551c0SBarry Smith   PC_PFMG        *ex;
1890ebc551c0SBarry Smith 
1891ebc551c0SBarry Smith   PetscFunctionBegin;
1892b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
189368326731SBarry Smith   pc->data = ex;
1894ebc551c0SBarry Smith 
18959e5bc791SBarry Smith   ex->its            = 1;
18969e5bc791SBarry Smith   ex->tol            = 1.e-8;
18979e5bc791SBarry Smith   ex->relax_type     = 1;
18989e5bc791SBarry Smith   ex->rap_type       = 0;
18999e5bc791SBarry Smith   ex->num_pre_relax  = 1;
19009e5bc791SBarry Smith   ex->num_post_relax = 1;
19013b46a515SGlenn Hammond   ex->max_levels     = 0;
19029e5bc791SBarry Smith 
1903ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
1904ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
1905ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
1906f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
19079e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
190868326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
19092fa5cd67SKarl Rupp 
1910ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
1911fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1912ebc551c0SBarry Smith   PetscFunctionReturn(0);
1913ebc551c0SBarry Smith }
1914d851a50bSGlenn Hammond 
1915325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
1916325fc9f4SBarry Smith 
1917d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
1918d851a50bSGlenn Hammond typedef struct {
1919d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
1920d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
1921d851a50bSGlenn Hammond 
1922d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
19234ddd07fcSJed Brown   PetscInt its;
1924d851a50bSGlenn Hammond   double   tol;
19254ddd07fcSJed Brown   PetscInt relax_type;
19264ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
1927d851a50bSGlenn Hammond } PC_SysPFMG;
1928d851a50bSGlenn Hammond 
1929d851a50bSGlenn Hammond #undef __FUNCT__
1930d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
1931d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
1932d851a50bSGlenn Hammond {
1933d851a50bSGlenn Hammond   PetscErrorCode ierr;
1934d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1935d851a50bSGlenn Hammond 
1936d851a50bSGlenn Hammond   PetscFunctionBegin;
19372fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
1938d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1939c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1940d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1941d851a50bSGlenn Hammond }
1942d851a50bSGlenn Hammond 
1943d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
1944d851a50bSGlenn Hammond 
1945d851a50bSGlenn Hammond #undef __FUNCT__
1946d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
1947d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
1948d851a50bSGlenn Hammond {
1949d851a50bSGlenn Hammond   PetscErrorCode ierr;
1950ace3abfcSBarry Smith   PetscBool      iascii;
1951d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1952d851a50bSGlenn Hammond 
1953d851a50bSGlenn Hammond   PetscFunctionBegin;
1954251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1955d851a50bSGlenn Hammond   if (iascii) {
1956d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
1957d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
1958d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
1959d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
1960d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
1961d851a50bSGlenn Hammond   }
1962d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1963d851a50bSGlenn Hammond }
1964d851a50bSGlenn Hammond 
1965d851a50bSGlenn Hammond 
1966d851a50bSGlenn Hammond #undef __FUNCT__
1967d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
19688c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptions *PetscOptionsObject,PC pc)
1969d851a50bSGlenn Hammond {
1970d851a50bSGlenn Hammond   PetscErrorCode ierr;
1971d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
1972ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1973d851a50bSGlenn Hammond 
1974d851a50bSGlenn Hammond   PetscFunctionBegin;
1975e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
19760298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
1977d851a50bSGlenn Hammond   if (flg) {
1978d851a50bSGlenn Hammond     int level=3;
1979fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
1980d851a50bSGlenn Hammond   }
19810298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1982fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
19830298fd71SBarry 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);
1984fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
19850298fd71SBarry 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);
1986fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
1987d851a50bSGlenn Hammond 
19880298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1989fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
19900298fd71SBarry 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);
1991fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
1992d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
1993d851a50bSGlenn Hammond   PetscFunctionReturn(0);
1994d851a50bSGlenn Hammond }
1995d851a50bSGlenn Hammond 
1996d851a50bSGlenn Hammond #undef __FUNCT__
1997d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
1998d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
1999d851a50bSGlenn Hammond {
2000d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2001d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2002d9ca1df4SBarry Smith   PetscScalar       *yy;
2003d9ca1df4SBarry Smith   const PetscScalar *xx;
20044ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
2005d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
20064ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
20074ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
20084ddd07fcSJed Brown   PetscInt          part    = 0;
20094ddd07fcSJed Brown   PetscInt          size;
20104ddd07fcSJed Brown   PetscInt          i;
2011d851a50bSGlenn Hammond 
2012d851a50bSGlenn Hammond   PetscFunctionBegin;
2013dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2014aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2015d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2016d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2017d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2018d851a50bSGlenn Hammond 
2019d851a50bSGlenn Hammond   size = 1;
20202fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
20212fa5cd67SKarl Rupp 
2022d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2023d851a50bSGlenn Hammond   if (ordering) {
2024fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2025d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2026d9ca1df4SBarry 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)));
2027d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2028fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2029fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2030fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2031d851a50bSGlenn Hammond 
2032d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2033d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
20348b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2035d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2036a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2037d851a50bSGlenn Hammond     PetscScalar *z;
20384ddd07fcSJed Brown     PetscInt    j, k;
2039d851a50bSGlenn Hammond 
2040785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2041fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2042d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2043d851a50bSGlenn Hammond 
2044d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2045d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2046d851a50bSGlenn Hammond       k= i*nvars;
20472fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2048d851a50bSGlenn Hammond     }
20498b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2050d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2051fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2052fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2053d851a50bSGlenn Hammond 
2054d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2055d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
20568b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2057d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2058d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2059d851a50bSGlenn Hammond       k= i*nvars;
20602fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2061d851a50bSGlenn Hammond     }
2062d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2063d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2064d851a50bSGlenn Hammond   }
2065d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2066d851a50bSGlenn Hammond }
2067d851a50bSGlenn Hammond 
2068d851a50bSGlenn Hammond #undef __FUNCT__
2069d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
2070ace3abfcSBarry 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)
2071d851a50bSGlenn Hammond {
2072d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2073d851a50bSGlenn Hammond   PetscErrorCode ierr;
20744ddd07fcSJed Brown   PetscInt       oits;
2075d851a50bSGlenn Hammond 
2076d851a50bSGlenn Hammond   PetscFunctionBegin;
2077dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2078fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2079fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2080d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
20818b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2082d851a50bSGlenn Hammond   *outits = oits;
2083d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2084d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2085fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2086fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2087d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2088d851a50bSGlenn Hammond }
2089d851a50bSGlenn Hammond 
2090d851a50bSGlenn Hammond 
2091d851a50bSGlenn Hammond #undef __FUNCT__
2092d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
2093d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2094d851a50bSGlenn Hammond {
2095d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2096d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2097d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2098ace3abfcSBarry Smith   PetscBool        flg;
2099d851a50bSGlenn Hammond 
2100d851a50bSGlenn Hammond   PetscFunctionBegin;
2101251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2102ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2103d851a50bSGlenn Hammond 
2104d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
21052fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2106fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2107fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2108fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2109d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2110d851a50bSGlenn Hammond }
2111d851a50bSGlenn Hammond 
2112d851a50bSGlenn Hammond 
2113d851a50bSGlenn Hammond /*MC
2114d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2115d851a50bSGlenn Hammond 
2116d851a50bSGlenn Hammond    Level: advanced
2117d851a50bSGlenn Hammond 
2118d851a50bSGlenn Hammond    Options Database:
2119d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2120d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2121d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2122d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2123d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2124d851a50bSGlenn Hammond 
2125d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
2126d851a50bSGlenn Hammond 
2127f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2128aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2129d851a50bSGlenn Hammond            Also, only cell-centered variables.
2130d851a50bSGlenn Hammond 
2131d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2132d851a50bSGlenn Hammond M*/
2133d851a50bSGlenn Hammond 
2134d851a50bSGlenn Hammond #undef __FUNCT__
2135d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
21368cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2137d851a50bSGlenn Hammond {
2138d851a50bSGlenn Hammond   PetscErrorCode ierr;
2139d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2140d851a50bSGlenn Hammond 
2141d851a50bSGlenn Hammond   PetscFunctionBegin;
2142b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2143d851a50bSGlenn Hammond   pc->data = ex;
2144d851a50bSGlenn Hammond 
2145d851a50bSGlenn Hammond   ex->its            = 1;
2146d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2147d851a50bSGlenn Hammond   ex->relax_type     = 1;
2148d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2149d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2150d851a50bSGlenn Hammond 
2151d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2152d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2153d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2154d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2155d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2156d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
21572fa5cd67SKarl Rupp 
2158ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2159fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2160d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2161d851a50bSGlenn Hammond }
2162