xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision b1c1cd91174bd2ec81b2a031820d47f9455b5426)
116d9e3a6SLisandro Dalcin 
216d9e3a6SLisandro Dalcin /*
316d9e3a6SLisandro Dalcin    Provides an interface to the LLNL package hypre
416d9e3a6SLisandro Dalcin */
50f1074feSSatish Balay 
60f1074feSSatish Balay /* Must use hypre 2.0.0 or more recent. */
70f1074feSSatish Balay 
8af0996ceSBarry Smith #include <petsc/private/pcimpl.h>          /*I "petscpc.h" I*/
9c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h>
104cb006feSStefano Zampini #include <_hypre_parcsr_ls.h>
1116d9e3a6SLisandro Dalcin 
12dff31646SBarry Smith static PetscBool cite = PETSC_FALSE;
131f817a21SBarry Smith static const char hypreCitation[] = "@manual{hypre-web-page,\n  title  = {{\\sl hypre}: High Performance Preconditioners},\n  organization = {Lawrence Livermore National Laboratory},\n  note  = {\\url{http://www.llnl.gov/CASC/hypre/}}\n}\n";
141f817a21SBarry Smith 
1516d9e3a6SLisandro Dalcin /*
1616d9e3a6SLisandro Dalcin    Private context (data structure) for the  preconditioner.
1716d9e3a6SLisandro Dalcin */
1816d9e3a6SLisandro Dalcin typedef struct {
1916d9e3a6SLisandro Dalcin   HYPRE_Solver   hsolver;
2016d9e3a6SLisandro Dalcin   HYPRE_IJMatrix ij;
2116d9e3a6SLisandro Dalcin   HYPRE_IJVector b,x;
2216d9e3a6SLisandro Dalcin 
234ddd07fcSJed Brown   HYPRE_Int (*destroy)(HYPRE_Solver);
244ddd07fcSJed Brown   HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
254ddd07fcSJed Brown   HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
26863406b8SStefano Zampini   HYPRE_Int (*setdgrad)(HYPRE_Solver,HYPRE_ParCSRMatrix);
27863406b8SStefano Zampini   HYPRE_Int (*setdcurl)(HYPRE_Solver,HYPRE_ParCSRMatrix);
28863406b8SStefano Zampini   HYPRE_Int (*setcoord)(HYPRE_Solver,HYPRE_ParVector,HYPRE_ParVector,HYPRE_ParVector);
29863406b8SStefano Zampini   HYPRE_Int (*setdim)(HYPRE_Solver,HYPRE_Int);
3016d9e3a6SLisandro Dalcin 
3116d9e3a6SLisandro Dalcin   MPI_Comm comm_hypre;
3216d9e3a6SLisandro Dalcin   char     *hypre_type;
3316d9e3a6SLisandro Dalcin 
3416d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
354ddd07fcSJed Brown   PetscInt maxiter;
3616d9e3a6SLisandro Dalcin   double   tol;
3716d9e3a6SLisandro Dalcin 
3816d9e3a6SLisandro Dalcin   /* options for Pilut */
394ddd07fcSJed Brown   PetscInt factorrowsize;
4016d9e3a6SLisandro Dalcin 
4116d9e3a6SLisandro Dalcin   /* options for ParaSails */
424ddd07fcSJed Brown   PetscInt nlevels;
4316d9e3a6SLisandro Dalcin   double   threshhold;
4416d9e3a6SLisandro Dalcin   double   filter;
454ddd07fcSJed Brown   PetscInt sym;
4616d9e3a6SLisandro Dalcin   double   loadbal;
474ddd07fcSJed Brown   PetscInt logging;
484ddd07fcSJed Brown   PetscInt ruse;
494ddd07fcSJed Brown   PetscInt symt;
5016d9e3a6SLisandro Dalcin 
5122b6d1caSBarry Smith   /* options for BoomerAMG */
52ace3abfcSBarry Smith   PetscBool printstatistics;
5316d9e3a6SLisandro Dalcin 
5416d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
554ddd07fcSJed Brown   PetscInt  cycletype;
564ddd07fcSJed Brown   PetscInt  maxlevels;
5716d9e3a6SLisandro Dalcin   double    strongthreshold;
5816d9e3a6SLisandro Dalcin   double    maxrowsum;
594ddd07fcSJed Brown   PetscInt  gridsweeps[3];
604ddd07fcSJed Brown   PetscInt  coarsentype;
614ddd07fcSJed Brown   PetscInt  measuretype;
626a251517SEike Mueller   PetscInt  smoothtype;
638131ecf7SEike Mueller   PetscInt  smoothnumlevels;
64ec64516dSEike Mueller   PetscInt  eu_level;   /* Number of levels for ILU(k) in Euclid */
65ec64516dSEike Mueller   double    eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */
66ec64516dSEike Mueller   PetscInt  eu_bj;      /* Defines use of Block Jacobi ILU in Euclid */
674ddd07fcSJed Brown   PetscInt  relaxtype[3];
6816d9e3a6SLisandro Dalcin   double    relaxweight;
6916d9e3a6SLisandro Dalcin   double    outerrelaxweight;
704ddd07fcSJed Brown   PetscInt  relaxorder;
7116d9e3a6SLisandro Dalcin   double    truncfactor;
72ace3abfcSBarry Smith   PetscBool applyrichardson;
734ddd07fcSJed Brown   PetscInt  pmax;
744ddd07fcSJed Brown   PetscInt  interptype;
754ddd07fcSJed Brown   PetscInt  agg_nl;
764ddd07fcSJed Brown   PetscInt  agg_num_paths;
774ddd07fcSJed Brown   PetscInt  nodal_coarsen;
78ace3abfcSBarry Smith   PetscBool nodal_relax;
794ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
804cb006feSStefano Zampini 
815272c319SBarry Smith   PetscInt  nodal_coarsening;
825272c319SBarry Smith   PetscInt  vec_interp_variant;
835272c319SBarry Smith   HYPRE_IJVector  *hmnull;
845272c319SBarry Smith   HYPRE_ParVector *phmnull;  /* near null space passed to hypre */
855272c319SBarry Smith   PetscInt        n_hmnull;
865272c319SBarry Smith   Vec             hmnull_constant;
8772827435SBarry Smith   PetscScalar     **hmnull_hypre_data_array;   /* this is the space in hmnull that was allocated by hypre, it is restored to hypre just before freeing the phmnull vectors */
885272c319SBarry Smith 
89863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
90863406b8SStefano Zampini   PetscInt  as_print;
91863406b8SStefano Zampini   PetscInt  as_max_iter;
92863406b8SStefano Zampini   PetscReal as_tol;
93863406b8SStefano Zampini   PetscInt  as_relax_type;
94863406b8SStefano Zampini   PetscInt  as_relax_times;
95863406b8SStefano Zampini   PetscReal as_relax_weight;
96863406b8SStefano Zampini   PetscReal as_omega;
97863406b8SStefano 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) */
98863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
99863406b8SStefano 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) */
100863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
1014cb006feSStefano Zampini   PetscInt  ams_cycle_type;
102863406b8SStefano Zampini   PetscInt  ads_cycle_type;
1034cb006feSStefano Zampini 
1044cb006feSStefano Zampini   /* additional data */
1054cb006feSStefano Zampini   HYPRE_IJVector coords[3];
1064cb006feSStefano Zampini   HYPRE_IJVector constants[3];
1074cb006feSStefano Zampini   HYPRE_IJMatrix G;
108863406b8SStefano Zampini   HYPRE_IJMatrix C;
1094cb006feSStefano Zampini   HYPRE_IJMatrix alpha_Poisson;
1104cb006feSStefano Zampini   HYPRE_IJMatrix beta_Poisson;
1114cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
11216d9e3a6SLisandro Dalcin } PC_HYPRE;
11316d9e3a6SLisandro Dalcin 
114d2128fa2SBarry Smith #undef __FUNCT__
115d2128fa2SBarry Smith #define __FUNCT__ "PCHYPREGetSolver"
116d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
117d2128fa2SBarry Smith {
118d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
119d2128fa2SBarry Smith 
120d2128fa2SBarry Smith   PetscFunctionBegin;
121d2128fa2SBarry Smith   *hsolver = jac->hsolver;
122d2128fa2SBarry Smith   PetscFunctionReturn(0);
123d2128fa2SBarry Smith }
12416d9e3a6SLisandro Dalcin 
12572827435SBarry Smith /*
12672827435SBarry Smith     Replaces the address where the HYPRE vector points to its data with the address of
12772827435SBarry Smith   PETSc's data. Saves the old address so it can be reset when we are finished with it.
12872827435SBarry Smith   Allows use to get the data into a HYPRE vector without the cost of memcopies
12972827435SBarry Smith */
13072827435SBarry Smith #define HYPREReplacePointer(b,newvalue,savedvalue) { \
13172827435SBarry Smith     hypre_ParVector *par_vector   = (hypre_ParVector*)hypre_IJVectorObject(((hypre_IJVector*)b)); \
13272827435SBarry Smith     hypre_Vector    *local_vector = hypre_ParVectorLocalVector(par_vector); \
13372827435SBarry Smith     savedvalue         = local_vector->data; \
13472827435SBarry Smith     local_vector->data = newvalue;          \
13572827435SBarry Smith }
13672827435SBarry Smith 
13716d9e3a6SLisandro Dalcin #undef __FUNCT__
13816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetUp_HYPRE"
13916d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
14016d9e3a6SLisandro Dalcin {
14116d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
14216d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
14316d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
14416d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
14516d9e3a6SLisandro Dalcin   PetscInt           bs;
14616d9e3a6SLisandro Dalcin 
14716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
14816d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
14902a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
15016d9e3a6SLisandro Dalcin   }
1515f5c5b43SBarry Smith 
1525f5c5b43SBarry Smith   if (pc->setupcalled) {
1535f5c5b43SBarry Smith     /* always destroy the old matrix and create a new memory;
1545f5c5b43SBarry Smith        hope this does not churn the memory too much. The problem
1555f5c5b43SBarry Smith        is I do not know if it is possible to put the matrix back to
1565f5c5b43SBarry Smith        its initial state so that we can directly copy the values
1575f5c5b43SBarry Smith        the second time through. */
158fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij));
1595f5c5b43SBarry Smith     jac->ij = 0;
16016d9e3a6SLisandro Dalcin   }
1615f5c5b43SBarry Smith 
16216d9e3a6SLisandro Dalcin   if (!jac->ij) { /* create the matrix the first time through */
16316d9e3a6SLisandro Dalcin     ierr = MatHYPRE_IJMatrixCreate(pc->pmat,&jac->ij);CHKERRQ(ierr);
16416d9e3a6SLisandro Dalcin   }
16516d9e3a6SLisandro Dalcin   if (!jac->b) { /* create the vectors the first time through */
16616d9e3a6SLisandro Dalcin     Vec x,b;
1672a7a6963SBarry Smith     ierr = MatCreateVecs(pc->pmat,&x,&b);CHKERRQ(ierr);
16816d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(x,&jac->x);CHKERRQ(ierr);
16916d9e3a6SLisandro Dalcin     ierr = VecHYPRE_IJVectorCreate(b,&jac->b);CHKERRQ(ierr);
1706bf464f9SBarry Smith     ierr = VecDestroy(&x);CHKERRQ(ierr);
1716bf464f9SBarry Smith     ierr = VecDestroy(&b);CHKERRQ(ierr);
17216d9e3a6SLisandro Dalcin   }
1735f5c5b43SBarry Smith 
17416d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
17516d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
1765272c319SBarry Smith     MatNullSpace    mnull;
1775272c319SBarry Smith     PetscBool       has_const;
1785272c319SBarry Smith     PetscInt        nvec,i;
1795272c319SBarry Smith     const Vec       *vecs;
18072827435SBarry Smith     PetscScalar     *petscvecarray;
1815272c319SBarry Smith 
18216d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
1832fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
1845272c319SBarry Smith     ierr = MatGetNearNullSpace(pc->mat, &mnull);CHKERRQ(ierr);
1855272c319SBarry Smith     if (mnull) {
1865272c319SBarry Smith       ierr = MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs);CHKERRQ(ierr);
1875272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull);CHKERRQ(ierr);
18872827435SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull_hypre_data_array);CHKERRQ(ierr);
1895272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->phmnull);CHKERRQ(ierr);
1905272c319SBarry Smith       for (i=0; i<nvec; i++) {
1915272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(vecs[i],&jac->hmnull[i]);CHKERRQ(ierr);
19272827435SBarry Smith         ierr = VecGetArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
19372827435SBarry Smith         HYPREReplacePointer(jac->hmnull[i],petscvecarray,jac->hmnull_hypre_data_array[i]);
19472827435SBarry Smith         ierr = VecRestoreArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
1955272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[i],(void**)&jac->phmnull[i]));
1965272c319SBarry Smith       }
1975272c319SBarry Smith       if (has_const) {
1985272c319SBarry Smith         ierr = MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL);CHKERRQ(ierr);
1995272c319SBarry Smith         ierr = VecSet(jac->hmnull_constant,1);CHKERRQ(ierr);
2005272c319SBarry Smith         ierr = VecNormalize(jac->hmnull_constant,NULL);
2015272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(jac->hmnull_constant,&jac->hmnull[nvec]);CHKERRQ(ierr);
20272827435SBarry Smith         ierr = VecGetArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
20372827435SBarry Smith         HYPREReplacePointer(jac->hmnull[nvec],petscvecarray,jac->hmnull_hypre_data_array[nvec]);
20472827435SBarry Smith         ierr = VecRestoreArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
2055272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[nvec],(void**)&jac->phmnull[nvec]));
2065272c319SBarry Smith         nvec++;
2075272c319SBarry Smith       }
2085272c319SBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVectors,(jac->hsolver,nvec,jac->phmnull));
2095272c319SBarry Smith       jac->n_hmnull = nvec;
2105272c319SBarry Smith     }
2114cb006feSStefano Zampini   }
212863406b8SStefano Zampini 
2134cb006feSStefano Zampini   /* special case for AMS */
2144cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
2154cb006feSStefano 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()");
2164cb006feSStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
2174cb006feSStefano Zampini   }
218863406b8SStefano Zampini   /* special case for ADS */
219863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
22037096e45SBarry Smith     if (!jac->coords[0]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs coordinate vectors via PCSetCoordinates()");
22137096e45SBarry Smith     else if (!jac->coords[1] || !jac->coords[2]) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner has been designed for three dimensional problems! For two dimensional problems, use HYPRE AMS instead");
222863406b8SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete gradient operator via PCHYPRESetDiscreteGradient");
223863406b8SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs discrete curl operator via PCHYPRESetDiscreteGradient");
224863406b8SStefano Zampini   }
22516d9e3a6SLisandro Dalcin   ierr = MatHYPRE_IJMatrixCopy(pc->pmat,jac->ij);CHKERRQ(ierr);
226fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
227fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&bv));
228fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&xv));
229fd3f9acdSBarry Smith   PetscStackCall("HYPRE_SetupXXX",ierr = (*jac->setup)(jac->hsolver,hmat,bv,xv);CHKERRQ(ierr););
23016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
23116d9e3a6SLisandro Dalcin }
23216d9e3a6SLisandro Dalcin 
23316d9e3a6SLisandro Dalcin #undef __FUNCT__
23416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApply_HYPRE"
23516d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
23616d9e3a6SLisandro Dalcin {
23716d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
23816d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
23916d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
240d9ca1df4SBarry Smith   PetscScalar        *xv;
241d9ca1df4SBarry Smith   const PetscScalar  *bv,*sbv;
24216d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
243d9ca1df4SBarry Smith   PetscScalar        *sxv;
2444ddd07fcSJed Brown   PetscInt           hierr;
24516d9e3a6SLisandro Dalcin 
24616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
247dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
24816d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
249d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
25016d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
251d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
25216d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
25316d9e3a6SLisandro Dalcin 
254fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
255fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
256fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
257fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
25865e19b50SBarry Smith                                if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
259fd3f9acdSBarry Smith                                if (hierr) hypre__global_error = 0;);
26016d9e3a6SLisandro Dalcin 
261d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)sbv,bv);
26216d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
26316d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
264d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
26516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
26616d9e3a6SLisandro Dalcin }
26716d9e3a6SLisandro Dalcin 
26816d9e3a6SLisandro Dalcin #undef __FUNCT__
2698695de01SBarry Smith #define __FUNCT__ "PCReset_HYPRE"
2708695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc)
2718695de01SBarry Smith {
2728695de01SBarry Smith   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
2738695de01SBarry Smith   PetscErrorCode ierr;
2748695de01SBarry Smith 
2758695de01SBarry Smith   PetscFunctionBegin;
2768695de01SBarry Smith   if (jac->ij) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->ij)); jac->ij = NULL;
2778695de01SBarry Smith   if (jac->b) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->b)); jac->b = NULL;
2788695de01SBarry Smith   if (jac->x) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->x)); jac->x = NULL;
2798695de01SBarry Smith   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); jac->coords[0] = NULL;
2808695de01SBarry Smith   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); jac->coords[1] = NULL;
2818695de01SBarry Smith   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); jac->coords[2] = NULL;
2828695de01SBarry Smith   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); jac->constants[0] = NULL;
2838695de01SBarry Smith   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); jac->constants[1] = NULL;
2848695de01SBarry Smith   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); jac->constants[2] = NULL;
2858695de01SBarry Smith   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G)); jac->G = NULL;
2868695de01SBarry Smith   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C)); jac->C = NULL;
2878695de01SBarry Smith   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson)); jac->alpha_Poisson = NULL;
2888695de01SBarry Smith   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson)); jac->beta_Poisson = NULL;
2895272c319SBarry Smith   if (jac->n_hmnull) {
2905272c319SBarry Smith     PetscInt                 i;
291*b1c1cd91SBarry Smith     PETSC_UNUSED PetscScalar *petscvecarray;
2925272c319SBarry Smith 
2935272c319SBarry Smith     for (i=0; i<jac->n_hmnull; i++) {
29472827435SBarry Smith       HYPREReplacePointer(jac->hmnull[i],jac->hmnull_hypre_data_array[i],petscvecarray);
2955272c319SBarry Smith       PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->hmnull[i]));
2965272c319SBarry Smith     }
2975272c319SBarry Smith     ierr = PetscFree(jac->hmnull);CHKERRQ(ierr);
29872827435SBarry Smith     ierr = PetscFree(jac->hmnull_hypre_data_array);CHKERRQ(ierr);
2995272c319SBarry Smith     ierr = PetscFree(jac->phmnull);CHKERRQ(ierr);
3005272c319SBarry Smith     ierr = VecDestroy(&jac->hmnull_constant);CHKERRQ(ierr);
3015272c319SBarry Smith   }
3028695de01SBarry Smith   PetscFunctionReturn(0);
3038695de01SBarry Smith }
3048695de01SBarry Smith 
3058695de01SBarry Smith #undef __FUNCT__
30616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCDestroy_HYPRE"
30716d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
30816d9e3a6SLisandro Dalcin {
30916d9e3a6SLisandro Dalcin   PC_HYPRE                 *jac = (PC_HYPRE*)pc->data;
31016d9e3a6SLisandro Dalcin   PetscErrorCode           ierr;
31116d9e3a6SLisandro Dalcin 
31216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
3138695de01SBarry Smith   ierr = PCReset_HYPRE(pc);CHKERRQ(ierr);
314226b0620SJed Brown   if (jac->destroy) PetscStackCall("HYPRE_DestroyXXX",ierr = (*jac->destroy)(jac->hsolver);CHKERRQ(ierr););
315503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
31616d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(ierr);}
317c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
31816d9e3a6SLisandro Dalcin 
31916d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
320bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
321bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
3224cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
3234cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
324863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
3254cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
3264cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",NULL);CHKERRQ(ierr);
3274cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",NULL);CHKERRQ(ierr);
32816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
32916d9e3a6SLisandro Dalcin }
33016d9e3a6SLisandro Dalcin 
33116d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
33216d9e3a6SLisandro Dalcin #undef __FUNCT__
33316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_Pilut"
3344416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptionItems *PetscOptionsObject,PC pc)
33516d9e3a6SLisandro Dalcin {
33616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
33716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
338ace3abfcSBarry Smith   PetscBool      flag;
33916d9e3a6SLisandro Dalcin 
34016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
341e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
34216d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
343fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
34416d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
345fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
34616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
347fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
34816d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
34916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
35016d9e3a6SLisandro Dalcin }
35116d9e3a6SLisandro Dalcin 
35216d9e3a6SLisandro Dalcin #undef __FUNCT__
35316d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_Pilut"
35416d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
35516d9e3a6SLisandro Dalcin {
35616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
35716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
358ace3abfcSBarry Smith   PetscBool      iascii;
35916d9e3a6SLisandro Dalcin 
36016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
361251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
36216d9e3a6SLisandro Dalcin   if (iascii) {
36316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
36416d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
36516d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
36616d9e3a6SLisandro Dalcin     } else {
36716d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default maximum number of iterations \n");CHKERRQ(ierr);
36816d9e3a6SLisandro Dalcin     }
36916d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
37057622a8eSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
37116d9e3a6SLisandro Dalcin     } else {
37216d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default drop tolerance \n");CHKERRQ(ierr);
37316d9e3a6SLisandro Dalcin     }
37416d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
37516d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
37616d9e3a6SLisandro Dalcin     } else {
37716d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut: default factor row size \n");CHKERRQ(ierr);
37816d9e3a6SLisandro Dalcin     }
37916d9e3a6SLisandro Dalcin   }
38016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
38116d9e3a6SLisandro Dalcin }
38216d9e3a6SLisandro Dalcin 
38316d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
38416d9e3a6SLisandro Dalcin 
38516d9e3a6SLisandro Dalcin #undef __FUNCT__
38616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyTranspose_HYPRE_BoomerAMG"
38716d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
38816d9e3a6SLisandro Dalcin {
38916d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
39016d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
39116d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
392d9ca1df4SBarry Smith   PetscScalar        *xv;
393d9ca1df4SBarry Smith   const PetscScalar  *bv;
39416d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
39516d9e3a6SLisandro Dalcin   PetscScalar        *sbv,*sxv;
3964ddd07fcSJed Brown   PetscInt           hierr;
39716d9e3a6SLisandro Dalcin 
39816d9e3a6SLisandro Dalcin   PetscFunctionBegin;
399dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
40016d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
401d9ca1df4SBarry Smith   ierr = VecGetArrayRead(b,&bv);CHKERRQ(ierr);
40216d9e3a6SLisandro Dalcin   ierr = VecGetArray(x,&xv);CHKERRQ(ierr);
403d9ca1df4SBarry Smith   HYPREReplacePointer(jac->b,(PetscScalar*)bv,sbv);
40416d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,xv,sxv);
40516d9e3a6SLisandro Dalcin 
406fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->ij,(void**)&hmat));
407fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->b,(void**)&jbv));
408fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->x,(void**)&jxv));
40916d9e3a6SLisandro Dalcin 
41016d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
41116d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
412e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
41316d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
41416d9e3a6SLisandro Dalcin 
41516d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->b,sbv,bv);
41616d9e3a6SLisandro Dalcin   HYPREReplacePointer(jac->x,sxv,xv);
41716d9e3a6SLisandro Dalcin   ierr = VecRestoreArray(x,&xv);CHKERRQ(ierr);
418d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(b,&bv);CHKERRQ(ierr);
41916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
42016d9e3a6SLisandro Dalcin }
42116d9e3a6SLisandro Dalcin 
422a669f990SJed Brown /* static array length */
423a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
424a669f990SJed Brown 
42516d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
4260f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
42716d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
42865de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
4296a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]   = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
43065de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
43165de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
43265de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
43365de4495SJed Brown                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "" /* 13 */, "" /* 14 */,
43465de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
4350f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
4360f1074feSSatish Balay                                                   "ext+i-cc", "standard", "standard-wts", "", "", "FF", "FF1"};
43716d9e3a6SLisandro Dalcin #undef __FUNCT__
43816d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_BoomerAMG"
4394416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc)
44016d9e3a6SLisandro Dalcin {
44116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
44216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
4434ddd07fcSJed Brown   PetscInt       n,indx,level;
444ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
44516d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
44616d9e3a6SLisandro Dalcin 
44716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
448e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
4494336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
45016d9e3a6SLisandro Dalcin   if (flg) {
4514336a9eeSBarry Smith     jac->cycletype = indx+1;
452fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
45316d9e3a6SLisandro Dalcin   }
45416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
45516d9e3a6SLisandro Dalcin   if (flg) {
456ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
457fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
45816d9e3a6SLisandro Dalcin   }
45916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
46016d9e3a6SLisandro Dalcin   if (flg) {
461ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
462fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
46316d9e3a6SLisandro Dalcin   }
4640f1074feSSatish 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);
46516d9e3a6SLisandro Dalcin   if (flg) {
46657622a8eSBarry 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);
467fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
46816d9e3a6SLisandro Dalcin   }
46916d9e3a6SLisandro Dalcin 
4700f1074feSSatish Balay   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
47116d9e3a6SLisandro Dalcin   if (flg) {
47257622a8eSBarry 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);
473fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
47416d9e3a6SLisandro Dalcin   }
47516d9e3a6SLisandro Dalcin 
4760f1074feSSatish 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);
4770f1074feSSatish Balay   if (flg) {
47857622a8eSBarry 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);
479fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
4800f1074feSSatish Balay   }
4810f1074feSSatish Balay 
4820f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
4830f1074feSSatish Balay   if (flg) {
48457622a8eSBarry 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);
4850f1074feSSatish Balay 
486fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
4870f1074feSSatish Balay   }
4880f1074feSSatish Balay 
4890f1074feSSatish Balay 
4900f1074feSSatish 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);
4910f1074feSSatish Balay   if (flg) {
49257622a8eSBarry 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);
4930f1074feSSatish Balay 
494fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
4950f1074feSSatish Balay   }
4960f1074feSSatish Balay 
4970f1074feSSatish Balay 
49816d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
49916d9e3a6SLisandro Dalcin   if (flg) {
50057622a8eSBarry 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);
501fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
50216d9e3a6SLisandro Dalcin   }
50316d9e3a6SLisandro Dalcin   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
50416d9e3a6SLisandro Dalcin   if (flg) {
50557622a8eSBarry 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);
50657622a8eSBarry 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);
507fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
50816d9e3a6SLisandro Dalcin   }
50916d9e3a6SLisandro Dalcin 
51016d9e3a6SLisandro Dalcin   /* Grid sweeps */
5110f1074feSSatish 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);
51216d9e3a6SLisandro Dalcin   if (flg) {
513fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
51416d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
51516d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
5160f1074feSSatish Balay     jac->gridsweeps[1] = indx;
5170f1074feSSatish Balay     /*defaults coarse to 1 */
5180f1074feSSatish Balay     jac->gridsweeps[2] = 1;
51916d9e3a6SLisandro Dalcin   }
5200f1074feSSatish Balay 
5215272c319SBarry Smith   ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_coarsen","Use a nodal based coarsening 1-6","HYPRE_BoomerAMGSetNodal",jac->nodal_coarsening, &jac->nodal_coarsening,&flg);CHKERRQ(ierr);
5225272c319SBarry Smith   if (flg) {
5235272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,jac->nodal_coarsening));
5245272c319SBarry Smith   }
5255272c319SBarry Smith 
526cbc39033SBarry Smith   ierr = PetscOptionsInt("-pc_hypre_boomeramg_vec_interp_variant","Variant of algorithm 1-3","HYPRE_BoomerAMGSetInterpVecVariant",jac->vec_interp_variant, &jac->vec_interp_variant,&flg);CHKERRQ(ierr);
5275272c319SBarry Smith   if (flg) {
5285272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,(jac->hsolver,jac->vec_interp_variant));
5295272c319SBarry Smith   }
5305272c319SBarry Smith 
5310f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
53216d9e3a6SLisandro Dalcin   if (flg) {
533fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
5340f1074feSSatish Balay     jac->gridsweeps[0] = indx;
53516d9e3a6SLisandro Dalcin   }
53616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
53716d9e3a6SLisandro Dalcin   if (flg) {
538fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
5390f1074feSSatish Balay     jac->gridsweeps[1] = indx;
54016d9e3a6SLisandro Dalcin   }
5410f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
54216d9e3a6SLisandro Dalcin   if (flg) {
543fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
5440f1074feSSatish Balay     jac->gridsweeps[2] = indx;
54516d9e3a6SLisandro Dalcin   }
54616d9e3a6SLisandro Dalcin 
5476a251517SEike Mueller   /* Smooth type */
5486a251517SEike Mueller   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);
5496a251517SEike Mueller   if (flg) {
5506a251517SEike Mueller     jac->smoothtype = indx;
5516a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
5528131ecf7SEike Mueller     jac->smoothnumlevels = 25;
5538131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
5548131ecf7SEike Mueller   }
5558131ecf7SEike Mueller 
5568131ecf7SEike Mueller   /* Number of smoothing levels */
5578131ecf7SEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_smooth_num_levels","Number of levels on which more complex smoothers are used","None",25,&indx,&flg);CHKERRQ(ierr);
5588131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
5598131ecf7SEike Mueller     jac->smoothnumlevels = indx;
5608131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
5616a251517SEike Mueller   }
5626a251517SEike Mueller 
5631810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
5641810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
5651810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
5661810e44eSEike Mueller     jac->eu_level = indx;
5671810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
5681810e44eSEike Mueller   }
5691810e44eSEike Mueller 
5701810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
5711810e44eSEike Mueller   double droptolerance;
5721810e44eSEike Mueller   ierr = PetscOptionsScalar("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
5731810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
5741810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
5751810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
5761810e44eSEike Mueller   }
5771810e44eSEike Mueller 
5781810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
5791810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
5801810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
5811810e44eSEike Mueller     jac->eu_bj = tmp_truth;
582493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
5831810e44eSEike Mueller   }
5841810e44eSEike Mueller 
58516d9e3a6SLisandro Dalcin   /* Relax type */
586a669f990SJed 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);
58716d9e3a6SLisandro Dalcin   if (flg) {
5880f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
589fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
5900f1074feSSatish Balay     /* by default, coarse type set to 9 */
5910f1074feSSatish Balay     jac->relaxtype[2] = 9;
5920f1074feSSatish Balay 
59316d9e3a6SLisandro Dalcin   }
594a669f990SJed 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);
59516d9e3a6SLisandro Dalcin   if (flg) {
59616d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
597fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
59816d9e3a6SLisandro Dalcin   }
599a669f990SJed 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);
60016d9e3a6SLisandro Dalcin   if (flg) {
6010f1074feSSatish Balay     jac->relaxtype[1] = indx;
602fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
60316d9e3a6SLisandro Dalcin   }
604a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
60516d9e3a6SLisandro Dalcin   if (flg) {
6060f1074feSSatish Balay     jac->relaxtype[2] = indx;
607fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
60816d9e3a6SLisandro Dalcin   }
60916d9e3a6SLisandro Dalcin 
61016d9e3a6SLisandro Dalcin   /* Relaxation Weight */
61116d9e3a6SLisandro 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);
61216d9e3a6SLisandro Dalcin   if (flg) {
613fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
61416d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
61516d9e3a6SLisandro Dalcin   }
61616d9e3a6SLisandro Dalcin 
61716d9e3a6SLisandro Dalcin   n         = 2;
61816d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
61916d9e3a6SLisandro 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);
62016d9e3a6SLisandro Dalcin   if (flg) {
62116d9e3a6SLisandro Dalcin     if (n == 2) {
62216d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
623fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
624ce94432eSBarry 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);
62516d9e3a6SLisandro Dalcin   }
62616d9e3a6SLisandro Dalcin 
62716d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
62816d9e3a6SLisandro 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);
62916d9e3a6SLisandro Dalcin   if (flg) {
630fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
63116d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
63216d9e3a6SLisandro Dalcin   }
63316d9e3a6SLisandro Dalcin 
63416d9e3a6SLisandro Dalcin   n         = 2;
63516d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
63616d9e3a6SLisandro 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);
63716d9e3a6SLisandro Dalcin   if (flg) {
63816d9e3a6SLisandro Dalcin     if (n == 2) {
63916d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
640fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
641ce94432eSBarry 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);
64216d9e3a6SLisandro Dalcin   }
64316d9e3a6SLisandro Dalcin 
64416d9e3a6SLisandro Dalcin   /* the Relax Order */
645acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
64616d9e3a6SLisandro Dalcin 
6478afaa268SBarry Smith   if (flg && tmp_truth) {
64816d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
649fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
65016d9e3a6SLisandro Dalcin   }
651a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
65216d9e3a6SLisandro Dalcin   if (flg) {
65316d9e3a6SLisandro Dalcin     jac->measuretype = indx;
654fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
65516d9e3a6SLisandro Dalcin   }
6560f1074feSSatish Balay   /* update list length 3/07 */
657a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
65816d9e3a6SLisandro Dalcin   if (flg) {
65916d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
660fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
66116d9e3a6SLisandro Dalcin   }
6620f1074feSSatish Balay 
6630f1074feSSatish Balay   /* new 3/07 */
664a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
6650f1074feSSatish Balay   if (flg) {
6660f1074feSSatish Balay     jac->interptype = indx;
667fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
6680f1074feSSatish Balay   }
6690f1074feSSatish Balay 
670b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
67116d9e3a6SLisandro Dalcin   if (flg) {
672b96a4a96SBarry Smith     level = 3;
6730298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
6742fa5cd67SKarl Rupp 
675b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
676fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
6772ae77aedSBarry Smith   }
6782ae77aedSBarry Smith 
679b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
6802ae77aedSBarry Smith   if (flg) {
681b96a4a96SBarry Smith     level = 3;
6820298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
6832fa5cd67SKarl Rupp 
684b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
685fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
68616d9e3a6SLisandro Dalcin   }
6878f87f92bSBarry Smith 
688acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
6898f87f92bSBarry Smith   if (flg && tmp_truth) {
6908f87f92bSBarry Smith     PetscInt tmp_int;
6918f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
6928f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
693fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
694fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
695fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
696fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
6978f87f92bSBarry Smith   }
6988f87f92bSBarry Smith 
69916d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
70016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
70116d9e3a6SLisandro Dalcin }
70216d9e3a6SLisandro Dalcin 
70316d9e3a6SLisandro Dalcin #undef __FUNCT__
70416d9e3a6SLisandro Dalcin #define __FUNCT__ "PCApplyRichardson_HYPRE_BoomerAMG"
705ace3abfcSBarry 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)
70616d9e3a6SLisandro Dalcin {
70716d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
70816d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
7094ddd07fcSJed Brown   PetscInt       oits;
71016d9e3a6SLisandro Dalcin 
71116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
712dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
713fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
714fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
71516d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
71616d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
71716d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
7188b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
7194d0a8057SBarry Smith   *outits = oits;
7204d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
7214d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
722fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
723fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
72416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
72516d9e3a6SLisandro Dalcin }
72616d9e3a6SLisandro Dalcin 
72716d9e3a6SLisandro Dalcin 
72816d9e3a6SLisandro Dalcin #undef __FUNCT__
72916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_BoomerAMG"
73016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
73116d9e3a6SLisandro Dalcin {
73216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
73316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
734ace3abfcSBarry Smith   PetscBool      iascii;
73516d9e3a6SLisandro Dalcin 
73616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
737251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
73816d9e3a6SLisandro Dalcin   if (iascii) {
73916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
74016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
74116d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of levels %d\n",jac->maxlevels);CHKERRQ(ierr);
74216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum number of iterations PER hypre call %d\n",jac->maxiter);CHKERRQ(ierr);
74357622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
74457622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
74557622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
7460f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation: max elements per row %d\n",jac->pmax);CHKERRQ(ierr);
7470f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of levels of aggressive coarsening %d\n",jac->agg_nl);CHKERRQ(ierr);
7480f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Number of paths for aggressive coarsening %d\n",jac->agg_num_paths);CHKERRQ(ierr);
7490f1074feSSatish Balay 
75057622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
75116d9e3a6SLisandro Dalcin 
7520f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps down         %d\n",jac->gridsweeps[0]);CHKERRQ(ierr);
7530f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps up           %d\n",jac->gridsweeps[1]);CHKERRQ(ierr);
7540f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Sweeps on coarse    %d\n",jac->gridsweeps[2]);CHKERRQ(ierr);
75516d9e3a6SLisandro Dalcin 
7560f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
7570f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
7580f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
75916d9e3a6SLisandro Dalcin 
76057622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
76157622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
76216d9e3a6SLisandro Dalcin 
76316d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
76416d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using CF-relaxation\n");CHKERRQ(ierr);
76516d9e3a6SLisandro Dalcin     } else {
76616d9e3a6SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using CF-relaxation\n");CHKERRQ(ierr);
76716d9e3a6SLisandro Dalcin     }
7686a251517SEike Mueller     if (jac->smoothtype!=-1) {
7696a251517SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
7708131ecf7SEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Smooth num levels    %d\n",jac->smoothnumlevels);CHKERRQ(ierr);
7717e352d70SEike Mueller     } else {
772c2bc9be0SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Not using more complex smoothers.\n");CHKERRQ(ierr);
7731810e44eSEike Mueller     }
7741810e44eSEike Mueller     if (jac->smoothtype==3) {
7751810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU(k) levels %d\n",jac->eu_level);CHKERRQ(ierr);
7761810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU(k) drop tolerance %g\n",jac->eu_droptolerance);CHKERRQ(ierr);
7771810e44eSEike Mueller       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Euclid ILU use Block-Jacobi? %d\n",jac->eu_bj);CHKERRQ(ierr);
7786a251517SEike Mueller     }
77916d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
78016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
7810f1074feSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
7825272c319SBarry Smith     if (jac->nodal_coarsening) {
7835272c319SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
7845272c319SBarry Smith     }
7855272c319SBarry Smith     if (jac->vec_interp_variant) {
7865272c319SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
7878f87f92bSBarry Smith     }
7888f87f92bSBarry Smith     if (jac->nodal_relax) {
7898f87f92bSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG: Using nodal relaxation via Schwarz smoothing on levels %d\n",jac->nodal_relax_levels);CHKERRQ(ierr);
7908f87f92bSBarry Smith     }
79116d9e3a6SLisandro Dalcin   }
79216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
79316d9e3a6SLisandro Dalcin }
79416d9e3a6SLisandro Dalcin 
79516d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
79616d9e3a6SLisandro Dalcin #undef __FUNCT__
79716d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE_ParaSails"
7984416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc)
79916d9e3a6SLisandro Dalcin {
80016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
80116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
8024ddd07fcSJed Brown   PetscInt       indx;
803ace3abfcSBarry Smith   PetscBool      flag;
80416d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
80516d9e3a6SLisandro Dalcin 
80616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
807e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
80816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
80916d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshhold,&jac->threshhold,&flag);CHKERRQ(ierr);
8102fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
81116d9e3a6SLisandro Dalcin 
81216d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
8132fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
81416d9e3a6SLisandro Dalcin 
81516d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
8162fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
81716d9e3a6SLisandro Dalcin 
818acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
8192fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
82016d9e3a6SLisandro Dalcin 
821acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
8222fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
82316d9e3a6SLisandro Dalcin 
824a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
82516d9e3a6SLisandro Dalcin   if (flag) {
82616d9e3a6SLisandro Dalcin     jac->symt = indx;
827fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
82816d9e3a6SLisandro Dalcin   }
82916d9e3a6SLisandro Dalcin 
83016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
83116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
83216d9e3a6SLisandro Dalcin }
83316d9e3a6SLisandro Dalcin 
83416d9e3a6SLisandro Dalcin #undef __FUNCT__
83516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCView_HYPRE_ParaSails"
83616d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
83716d9e3a6SLisandro Dalcin {
83816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
83916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
840ace3abfcSBarry Smith   PetscBool      iascii;
84116d9e3a6SLisandro Dalcin   const char     *symt = 0;;
84216d9e3a6SLisandro Dalcin 
84316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
844251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
84516d9e3a6SLisandro Dalcin   if (iascii) {
84616d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
84716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
84857622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: threshold %g\n",(double)jac->threshhold);CHKERRQ(ierr);
84957622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: filter %g\n",(double)jac->filter);CHKERRQ(ierr);
85057622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
851ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
852ace3abfcSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
8532fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
8542fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
8552fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
856ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
85716d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails: %s\n",symt);CHKERRQ(ierr);
85816d9e3a6SLisandro Dalcin   }
85916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
86016d9e3a6SLisandro Dalcin }
8614cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
8624cb006feSStefano Zampini #undef __FUNCT__
8634cb006feSStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_AMS"
8644416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc)
8654cb006feSStefano Zampini {
8664cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
8674cb006feSStefano Zampini   PetscErrorCode ierr;
8684cb006feSStefano Zampini   PetscInt       n;
8694cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
8704cb006feSStefano Zampini 
8714cb006feSStefano Zampini   PetscFunctionBegin;
8729fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
873863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
874863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
875863406b8SStefano 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);
876863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
8774cb006feSStefano 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);
8784cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
879863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
880863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
881863406b8SStefano 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);
882863406b8SStefano 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);
883863406b8SStefano 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);
884863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
8854cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
886863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
887863406b8SStefano Zampini                                                                       jac->as_relax_times,
888863406b8SStefano Zampini                                                                       jac->as_relax_weight,
889863406b8SStefano Zampini                                                                       jac->as_omega));
8904cb006feSStefano Zampini   }
891863406b8SStefano 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);
8924cb006feSStefano Zampini   n = 5;
893863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
8944cb006feSStefano Zampini   if (flag || flag2) {
895863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
896863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
897863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
898863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
899863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
900863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
9014cb006feSStefano Zampini   }
902863406b8SStefano 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);
9034cb006feSStefano Zampini   n = 5;
904863406b8SStefano 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);
9054cb006feSStefano Zampini   if (flag || flag2) {
906863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
907863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
908863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
909863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
910863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
911863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
9124cb006feSStefano Zampini   }
9134cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
9144cb006feSStefano Zampini   PetscFunctionReturn(0);
9154cb006feSStefano Zampini }
9164cb006feSStefano Zampini 
9174cb006feSStefano Zampini #undef __FUNCT__
9184cb006feSStefano Zampini #define __FUNCT__ "PCView_HYPRE_AMS"
9194cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
9204cb006feSStefano Zampini {
9214cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
9224cb006feSStefano Zampini   PetscErrorCode ierr;
9234cb006feSStefano Zampini   PetscBool      iascii;
9244cb006feSStefano Zampini 
9254cb006feSStefano Zampini   PetscFunctionBegin;
9264cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
9274cb006feSStefano Zampini   if (iascii) {
9284cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
929863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
9304cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
931863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
932863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
933863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
934863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
935863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
9364cb006feSStefano Zampini     if (jac->alpha_Poisson) {
9374cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
9384cb006feSStefano Zampini     } else {
9394cb006feSStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: vector Poisson solver (computed) \n");CHKERRQ(ierr);
9404cb006feSStefano Zampini     }
941863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
942863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
943863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
944863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
945863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
946863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
9474cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
9484cb006feSStefano Zampini       if (jac->beta_Poisson) {
9494cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
9504cb006feSStefano Zampini       } else {
9514cb006feSStefano Zampini         ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS: scalar Poisson solver (computed) \n");CHKERRQ(ierr);
9524cb006feSStefano Zampini       }
953863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
954863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
955863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
956863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
957863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
958863406b8SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
9594cb006feSStefano Zampini     }
9604cb006feSStefano Zampini   }
9614cb006feSStefano Zampini   PetscFunctionReturn(0);
9624cb006feSStefano Zampini }
9634cb006feSStefano Zampini 
9644cb006feSStefano Zampini #undef __FUNCT__
965863406b8SStefano Zampini #define __FUNCT__ "PCSetFromOptions_HYPRE_ADS"
9664416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc)
967863406b8SStefano Zampini {
968863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
969863406b8SStefano Zampini   PetscErrorCode ierr;
970863406b8SStefano Zampini   PetscInt       n;
971863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
972863406b8SStefano Zampini 
973863406b8SStefano Zampini   PetscFunctionBegin;
974863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
975863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
976863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
977863406b8SStefano 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);
978863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
979863406b8SStefano 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);
980863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
981863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
982863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
983863406b8SStefano 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);
984863406b8SStefano 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);
985863406b8SStefano 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);
986863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
987863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
988863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
989863406b8SStefano Zampini                                                                       jac->as_relax_times,
990863406b8SStefano Zampini                                                                       jac->as_relax_weight,
991863406b8SStefano Zampini                                                                       jac->as_omega));
992863406b8SStefano Zampini   }
993863406b8SStefano 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);
994863406b8SStefano Zampini   n = 5;
995863406b8SStefano 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);
996863406b8SStefano 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);
997863406b8SStefano Zampini   if (flag || flag2 || flag3) {
998863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
999863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1000863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1001863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1002863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1003863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1004863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1005863406b8SStefano Zampini   }
1006863406b8SStefano 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);
1007863406b8SStefano Zampini   n = 5;
1008863406b8SStefano 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);
1009863406b8SStefano Zampini   if (flag || flag2) {
1010863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1011863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1012863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1013863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1014863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1015863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1016863406b8SStefano Zampini   }
1017863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
1018863406b8SStefano Zampini   PetscFunctionReturn(0);
1019863406b8SStefano Zampini }
1020863406b8SStefano Zampini 
1021863406b8SStefano Zampini #undef __FUNCT__
1022863406b8SStefano Zampini #define __FUNCT__ "PCView_HYPRE_ADS"
1023863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1024863406b8SStefano Zampini {
1025863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1026863406b8SStefano Zampini   PetscErrorCode ierr;
1027863406b8SStefano Zampini   PetscBool      iascii;
1028863406b8SStefano Zampini 
1029863406b8SStefano Zampini   PetscFunctionBegin;
1030863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1031863406b8SStefano Zampini   if (iascii) {
1032863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
1033863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1034863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
1035863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1036863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1037863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1038863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1039863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
1040863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: AMS solver\n");CHKERRQ(ierr);
1041863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1042863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1043863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1044863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1045863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1046863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1047863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
1048863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS: vector Poisson solver\n");CHKERRQ(ierr);
1049863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1050863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1051863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1052863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1053863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1054863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS:     boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
1055863406b8SStefano Zampini   }
1056863406b8SStefano Zampini   PetscFunctionReturn(0);
1057863406b8SStefano Zampini }
1058863406b8SStefano Zampini 
1059863406b8SStefano Zampini #undef __FUNCT__
1060863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient_HYPRE"
1061863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
10624cb006feSStefano Zampini {
10634cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
10644cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_G;
10654cb006feSStefano Zampini   PetscErrorCode     ierr;
10664cb006feSStefano Zampini 
10674cb006feSStefano Zampini   PetscFunctionBegin;
10684cb006feSStefano Zampini   /* throw away any discrete gradient if already set */
10694cb006feSStefano Zampini   if (jac->G) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->G));
10704cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(G,&jac->G);CHKERRQ(ierr);
10714cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(G,jac->G);CHKERRQ(ierr);
10724cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->G,(void**)(&parcsr_G)));
1073863406b8SStefano Zampini   PetscStackCall("Hypre set gradient",ierr = (*jac->setdgrad)(jac->hsolver,parcsr_G);CHKERRQ(ierr););
10744cb006feSStefano Zampini   PetscFunctionReturn(0);
10754cb006feSStefano Zampini }
10764cb006feSStefano Zampini 
10774cb006feSStefano Zampini #undef __FUNCT__
10784cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteGradient"
10794cb006feSStefano Zampini /*@
10804cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
10814cb006feSStefano Zampini 
10824cb006feSStefano Zampini    Collective on PC
10834cb006feSStefano Zampini 
10844cb006feSStefano Zampini    Input Parameters:
10854cb006feSStefano Zampini +  pc - the preconditioning context
10864cb006feSStefano Zampini -  G - the discrete gradient
10874cb006feSStefano Zampini 
10884cb006feSStefano Zampini    Level: intermediate
10894cb006feSStefano Zampini 
10904cb006feSStefano 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
1091863406b8SStefano 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
10924cb006feSStefano Zampini 
10934cb006feSStefano Zampini .seealso:
10944cb006feSStefano Zampini @*/
10954cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
10964cb006feSStefano Zampini {
10974cb006feSStefano Zampini   PetscErrorCode ierr;
10984cb006feSStefano Zampini 
10994cb006feSStefano Zampini   PetscFunctionBegin;
11004cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11014cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
11024cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
11034cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
11044cb006feSStefano Zampini   PetscFunctionReturn(0);
11054cb006feSStefano Zampini }
11064cb006feSStefano Zampini 
11074cb006feSStefano Zampini #undef __FUNCT__
1108863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl_HYPRE"
1109863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1110863406b8SStefano Zampini {
1111863406b8SStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
1112863406b8SStefano Zampini   HYPRE_ParCSRMatrix parcsr_C;
1113863406b8SStefano Zampini   PetscErrorCode     ierr;
1114863406b8SStefano Zampini 
1115863406b8SStefano Zampini   PetscFunctionBegin;
1116863406b8SStefano Zampini   /* throw away any discrete curl if already set */
1117863406b8SStefano Zampini   if (jac->C) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->C));
1118863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(C,&jac->C);CHKERRQ(ierr);
1119863406b8SStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(C,jac->C);CHKERRQ(ierr);
1120863406b8SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->C,(void**)(&parcsr_C)));
1121863406b8SStefano Zampini   PetscStackCall("Hypre set curl",ierr = (*jac->setdcurl)(jac->hsolver,parcsr_C);CHKERRQ(ierr););
1122863406b8SStefano Zampini   PetscFunctionReturn(0);
1123863406b8SStefano Zampini }
1124863406b8SStefano Zampini 
1125863406b8SStefano Zampini #undef __FUNCT__
1126863406b8SStefano Zampini #define __FUNCT__ "PCHYPRESetDiscreteCurl"
1127863406b8SStefano Zampini /*@
1128863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1129863406b8SStefano Zampini 
1130863406b8SStefano Zampini    Collective on PC
1131863406b8SStefano Zampini 
1132863406b8SStefano Zampini    Input Parameters:
1133863406b8SStefano Zampini +  pc - the preconditioning context
1134863406b8SStefano Zampini -  C - the discrete curl
1135863406b8SStefano Zampini 
1136863406b8SStefano Zampini    Level: intermediate
1137863406b8SStefano Zampini 
1138863406b8SStefano 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
1139863406b8SStefano 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
1140863406b8SStefano Zampini 
1141863406b8SStefano Zampini .seealso:
1142863406b8SStefano Zampini @*/
1143863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1144863406b8SStefano Zampini {
1145863406b8SStefano Zampini   PetscErrorCode ierr;
1146863406b8SStefano Zampini 
1147863406b8SStefano Zampini   PetscFunctionBegin;
1148863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1149863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1150863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1151863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1152863406b8SStefano Zampini   PetscFunctionReturn(0);
1153863406b8SStefano Zampini }
1154863406b8SStefano Zampini 
1155863406b8SStefano Zampini #undef __FUNCT__
11564cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS"
11574cb006feSStefano Zampini static PetscErrorCode PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
11584cb006feSStefano Zampini {
11594cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
11604cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_alpha_Poisson;
11614cb006feSStefano Zampini   PetscErrorCode     ierr;
11624cb006feSStefano Zampini 
11634cb006feSStefano Zampini   PetscFunctionBegin;
11644cb006feSStefano Zampini   /* throw away any matrix if already set */
11654cb006feSStefano Zampini   if (jac->alpha_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->alpha_Poisson));
11664cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->alpha_Poisson);CHKERRQ(ierr);
11674cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->alpha_Poisson);CHKERRQ(ierr);
11684cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->alpha_Poisson,(void**)(&parcsr_alpha_Poisson)));
11694cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr_alpha_Poisson));
11704cb006feSStefano Zampini   PetscFunctionReturn(0);
11714cb006feSStefano Zampini }
11724cb006feSStefano Zampini 
11734cb006feSStefano Zampini #undef __FUNCT__
11744cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetAlphaPoissonMatrix"
11754cb006feSStefano Zampini /*@
11764cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
11774cb006feSStefano Zampini 
11784cb006feSStefano Zampini    Collective on PC
11794cb006feSStefano Zampini 
11804cb006feSStefano Zampini    Input Parameters:
11814cb006feSStefano Zampini +  pc - the preconditioning context
11824cb006feSStefano Zampini -  A - the matrix
11834cb006feSStefano Zampini 
11844cb006feSStefano Zampini    Level: intermediate
11854cb006feSStefano Zampini 
11864cb006feSStefano Zampini    Notes: A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
11874cb006feSStefano Zampini 
11884cb006feSStefano Zampini .seealso:
11894cb006feSStefano Zampini @*/
11904cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
11914cb006feSStefano Zampini {
11924cb006feSStefano Zampini   PetscErrorCode ierr;
11934cb006feSStefano Zampini 
11944cb006feSStefano Zampini   PetscFunctionBegin;
11954cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
11964cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
11974cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
11984cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetAlphaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
11994cb006feSStefano Zampini   PetscFunctionReturn(0);
12004cb006feSStefano Zampini }
12014cb006feSStefano Zampini 
12024cb006feSStefano Zampini #undef __FUNCT__
12034cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix_HYPRE_AMS"
12044cb006feSStefano Zampini static PetscErrorCode PCHYPRESetBetaPoissonMatrix_HYPRE_AMS(PC pc, Mat A)
12054cb006feSStefano Zampini {
12064cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
12074cb006feSStefano Zampini   HYPRE_ParCSRMatrix parcsr_beta_Poisson;
12084cb006feSStefano Zampini   PetscErrorCode     ierr;
12094cb006feSStefano Zampini 
12104cb006feSStefano Zampini   PetscFunctionBegin;
12114cb006feSStefano Zampini   if (!A) {
1212484796dcSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
12134cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_TRUE;
12144cb006feSStefano Zampini     PetscFunctionReturn(0);
12154cb006feSStefano Zampini   }
12164cb006feSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
12174cb006feSStefano Zampini   /* throw away any matrix if already set */
12184cb006feSStefano Zampini   if (jac->beta_Poisson) PetscStackCallStandard(HYPRE_IJMatrixDestroy,(jac->beta_Poisson));
12194cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCreate(A,&jac->beta_Poisson);CHKERRQ(ierr);
12204cb006feSStefano Zampini   ierr = MatHYPRE_IJMatrixCopy(A,jac->beta_Poisson);CHKERRQ(ierr);
12214cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(jac->beta_Poisson,(void**)(&parcsr_beta_Poisson)));
12224cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr_beta_Poisson));
12234cb006feSStefano Zampini   PetscFunctionReturn(0);
12244cb006feSStefano Zampini }
12254cb006feSStefano Zampini 
12264cb006feSStefano Zampini #undef __FUNCT__
12274cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetBetaPoissonMatrix"
12284cb006feSStefano Zampini /*@
12294cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
12304cb006feSStefano Zampini 
12314cb006feSStefano Zampini    Collective on PC
12324cb006feSStefano Zampini 
12334cb006feSStefano Zampini    Input Parameters:
12344cb006feSStefano Zampini +  pc - the preconditioning context
12354cb006feSStefano Zampini -  A - the matrix
12364cb006feSStefano Zampini 
12374cb006feSStefano Zampini    Level: intermediate
12384cb006feSStefano Zampini 
12394cb006feSStefano Zampini    Notes: A should be obtained by discretizing the Poisson problem with linear finite elements.
12404cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
12414cb006feSStefano Zampini 
12424cb006feSStefano Zampini .seealso:
12434cb006feSStefano Zampini @*/
12444cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
12454cb006feSStefano Zampini {
12464cb006feSStefano Zampini   PetscErrorCode ierr;
12474cb006feSStefano Zampini 
12484cb006feSStefano Zampini   PetscFunctionBegin;
12494cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
12504cb006feSStefano Zampini   if (A) {
12514cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
12524cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
12534cb006feSStefano Zampini   }
12544cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetBetaPoissonMatrix_C",(PC,Mat),(pc,A));CHKERRQ(ierr);
12554cb006feSStefano Zampini   PetscFunctionReturn(0);
12564cb006feSStefano Zampini }
12574cb006feSStefano Zampini 
12584cb006feSStefano Zampini #undef __FUNCT__
12594cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors_HYPRE_AMS"
12604cb006feSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE_AMS(PC pc,Vec ozz, Vec zoz, Vec zzo)
12614cb006feSStefano Zampini {
12624cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
12634cb006feSStefano Zampini   HYPRE_ParVector    par_ozz,par_zoz,par_zzo;
126412ddd1b6SStefano Zampini   PetscInt           dim;
12654cb006feSStefano Zampini   PetscErrorCode     ierr;
12664cb006feSStefano Zampini 
12674cb006feSStefano Zampini   PetscFunctionBegin;
12684cb006feSStefano Zampini   /* throw away any vector if already set */
12694cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
12704cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
12714cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
12724cb006feSStefano Zampini   jac->constants[0] = NULL;
12734cb006feSStefano Zampini   jac->constants[1] = NULL;
12744cb006feSStefano Zampini   jac->constants[2] = NULL;
12754cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
12764cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
12774cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&par_ozz)));
12784cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
12794cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
12804cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&par_zoz)));
128112ddd1b6SStefano Zampini   dim = 2;
12824cb006feSStefano Zampini   if (zzo) {
12834cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
12844cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
12854cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&par_zzo)));
128612ddd1b6SStefano Zampini     dim++;
12874cb006feSStefano Zampini   }
12884cb006feSStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,par_ozz,par_zoz,par_zzo));
128912ddd1b6SStefano Zampini   PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,dim));
12904cb006feSStefano Zampini   PetscFunctionReturn(0);
12914cb006feSStefano Zampini }
12924cb006feSStefano Zampini 
12934cb006feSStefano Zampini #undef __FUNCT__
12944cb006feSStefano Zampini #define __FUNCT__ "PCHYPRESetEdgeConstantVectors"
12954cb006feSStefano Zampini /*@
12964cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
12974cb006feSStefano Zampini 
12984cb006feSStefano Zampini    Collective on PC
12994cb006feSStefano Zampini 
13004cb006feSStefano Zampini    Input Parameters:
13014cb006feSStefano Zampini +  pc - the preconditioning context
13024cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
13034cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
13044cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
13054cb006feSStefano Zampini 
13064cb006feSStefano Zampini    Level: intermediate
13074cb006feSStefano Zampini 
13084cb006feSStefano Zampini    Notes:
13094cb006feSStefano Zampini 
13104cb006feSStefano Zampini .seealso:
13114cb006feSStefano Zampini @*/
13124cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
13134cb006feSStefano Zampini {
13144cb006feSStefano Zampini   PetscErrorCode ierr;
13154cb006feSStefano Zampini 
13164cb006feSStefano Zampini   PetscFunctionBegin;
13174cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
13184cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
13194cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
13204cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
13214cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
13224cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
13234cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
13244cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
13254cb006feSStefano Zampini   PetscFunctionReturn(0);
13264cb006feSStefano Zampini }
13274cb006feSStefano Zampini 
13284cb006feSStefano Zampini #undef __FUNCT__
1329863406b8SStefano Zampini #define __FUNCT__ "PCSetCoordinates_HYPRE"
1330863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
13314cb006feSStefano Zampini {
13324cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
13334cb006feSStefano Zampini   Vec             tv;
13344cb006feSStefano Zampini   HYPRE_ParVector par_coords[3];
13354cb006feSStefano Zampini   PetscInt        i;
13364cb006feSStefano Zampini   PetscErrorCode  ierr;
13374cb006feSStefano Zampini 
13384cb006feSStefano Zampini   PetscFunctionBegin;
13394cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
13404cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
13414cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
13424cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
13434cb006feSStefano Zampini   /* set problem's dimension */
1344863406b8SStefano Zampini   if (jac->setdim) {
1345863406b8SStefano Zampini     PetscStackCall("Hypre set dim",ierr = (*jac->setdim)(jac->hsolver,dim);CHKERRQ(ierr););
1346863406b8SStefano Zampini   }
13474cb006feSStefano Zampini   /* compute IJ vector for coordinates */
13484cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
13494cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
13504cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
13514cb006feSStefano Zampini   for (i=0;i<dim;i++) {
13524cb006feSStefano Zampini     PetscScalar *array;
13534cb006feSStefano Zampini     PetscInt    j;
13544cb006feSStefano Zampini 
13554cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
13564cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
13574cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
13584cb006feSStefano Zampini       array[j] = coords[j*dim+i];
13594cb006feSStefano Zampini     }
13604cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,array));
13614cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
13624cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
13634cb006feSStefano Zampini   }
13644cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
13654cb006feSStefano Zampini   /* pass parCSR vectors to AMS solver */
13664cb006feSStefano Zampini   par_coords[0] = NULL;
13674cb006feSStefano Zampini   par_coords[1] = NULL;
13684cb006feSStefano Zampini   par_coords[2] = NULL;
13694cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&par_coords[0])));
13704cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&par_coords[1])));
13714cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&par_coords[2])));
1372863406b8SStefano Zampini   PetscStackCall("Hypre set coords",ierr = (*jac->setcoord)(jac->hsolver,par_coords[0],par_coords[1],par_coords[2]);CHKERRQ(ierr););
13734cb006feSStefano Zampini   PetscFunctionReturn(0);
13744cb006feSStefano Zampini }
13754cb006feSStefano Zampini 
137616d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
137716d9e3a6SLisandro Dalcin 
137816d9e3a6SLisandro Dalcin #undef __FUNCT__
137916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType_HYPRE"
1380f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
138116d9e3a6SLisandro Dalcin {
138216d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
138316d9e3a6SLisandro Dalcin 
138416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
138516d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
138616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
138716d9e3a6SLisandro Dalcin }
138816d9e3a6SLisandro Dalcin 
138916d9e3a6SLisandro Dalcin #undef __FUNCT__
139016d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType_HYPRE"
1391f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
139216d9e3a6SLisandro Dalcin {
139316d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
139416d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1395ace3abfcSBarry Smith   PetscBool      flag;
139616d9e3a6SLisandro Dalcin 
139716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
139816d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
139916d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1400ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
140116d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
140216d9e3a6SLisandro Dalcin   } else {
140316d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
140416d9e3a6SLisandro Dalcin   }
140516d9e3a6SLisandro Dalcin 
140616d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
140716d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
140816d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
140916d9e3a6SLisandro Dalcin 
141016d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
141116d9e3a6SLisandro Dalcin   if (flag) {
1412fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
141316d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
141416d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
141516d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
141616d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
141716d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
141816d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
141916d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
142016d9e3a6SLisandro Dalcin   }
142116d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
142216d9e3a6SLisandro Dalcin   if (flag) {
1423fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
142416d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
142516d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
142616d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
142716d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
142816d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
142916d9e3a6SLisandro Dalcin     /* initialize */
143016d9e3a6SLisandro Dalcin     jac->nlevels    = 1;
143116d9e3a6SLisandro Dalcin     jac->threshhold = .1;
143216d9e3a6SLisandro Dalcin     jac->filter     = .1;
143316d9e3a6SLisandro Dalcin     jac->loadbal    = 0;
14342fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
14352fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
14362fa5cd67SKarl Rupp 
143716d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
143816d9e3a6SLisandro Dalcin     jac->symt = 0;
1439fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshhold,jac->nlevels));
1440fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1441fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1442fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1443fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1444fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
144516d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
144616d9e3a6SLisandro Dalcin   }
144716d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
144816d9e3a6SLisandro Dalcin   if (flag) {
144916d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
145016d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
145116d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
145216d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
145316d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
145416d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
145516d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
145616d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
145716d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
145816d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
145916d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
146016d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
146116d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
14628f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
146316d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
146416d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
146516d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
146616d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
146716d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
14680f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
14696a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1470b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
14711810e44eSEike Mueller     jac->eu_level         = 0;
14721810e44eSEike Mueller     jac->eu_droptolerance = 0;
14731810e44eSEike Mueller     jac->eu_bj            = 0;
14748f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
14750f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
147616d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
147716d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
147816d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
14790f1074feSSatish Balay     jac->interptype       = 0;
14800f1074feSSatish Balay     jac->agg_nl           = 0;
14810f1074feSSatish Balay     jac->pmax             = 0;
14820f1074feSSatish Balay     jac->truncfactor      = 0.0;
14830f1074feSSatish Balay     jac->agg_num_paths    = 1;
14848f87f92bSBarry Smith 
14858f87f92bSBarry Smith     jac->nodal_coarsen      = 0;
14868f87f92bSBarry Smith     jac->nodal_relax        = PETSC_FALSE;
14878f87f92bSBarry Smith     jac->nodal_relax_levels = 1;
1488fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1489fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1490fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1491fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1492fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1493fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1494fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1495fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1496fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1497fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1498fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1499fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1500fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1501fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1502fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1503fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
150416d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
150516d9e3a6SLisandro Dalcin   }
15064cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
15074cb006feSStefano Zampini   if (flag) {
15084cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
15094cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
15104cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
15114cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
15124cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
15134cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
1514863406b8SStefano Zampini     jac->setdgrad            = HYPRE_AMSSetDiscreteGradient;
1515863406b8SStefano Zampini     jac->setcoord            = HYPRE_AMSSetCoordinateVectors;
1516863406b8SStefano Zampini     jac->setdim              = HYPRE_AMSSetDimension;
15174cb006feSStefano Zampini     jac->coords[0]           = NULL;
15184cb006feSStefano Zampini     jac->coords[1]           = NULL;
15194cb006feSStefano Zampini     jac->coords[2]           = NULL;
15204cb006feSStefano Zampini     jac->G                   = NULL;
15214cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1522863406b8SStefano Zampini     jac->as_print           = 0;
1523863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1524863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
15254cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
15264cb006feSStefano Zampini     /* Smoothing options */
1527863406b8SStefano Zampini     jac->as_relax_type      = 2;
1528863406b8SStefano Zampini     jac->as_relax_times     = 1;
1529863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1530863406b8SStefano Zampini     jac->as_omega           = 1.0;
15314cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1532863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1533863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
15340bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1535863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1536863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1537863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
15384cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
15394cb006feSStefano Zampini     jac->ams_beta_is_zero = PETSC_FALSE;
1540863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1541863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
15420bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1543863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1544863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1545863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1546863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1547863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
15484cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1549863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1550863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1551863406b8SStefano Zampini                                                                       jac->as_relax_times,
1552863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1553863406b8SStefano Zampini                                                                       jac->as_omega));
1554863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1555863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1556863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1557863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1558863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1559863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1560863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1561863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1562863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1563863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1564863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1565863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1566863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1567863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
15684cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE_AMS);CHKERRQ(ierr);
15694cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetAlphaPoissonMatrix_C",PCHYPRESetAlphaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
15704cb006feSStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetBetaPoissonMatrix_C",PCHYPRESetBetaPoissonMatrix_HYPRE_AMS);CHKERRQ(ierr);
15714cb006feSStefano Zampini     PetscFunctionReturn(0);
15724cb006feSStefano Zampini   }
1573863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1574863406b8SStefano Zampini   if (flag) {
1575863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1576863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1577863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1578863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1579863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1580863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1581863406b8SStefano Zampini     jac->setdgrad            = HYPRE_ADSSetDiscreteGradient;
1582863406b8SStefano Zampini     jac->setdcurl            = HYPRE_ADSSetDiscreteCurl;
1583863406b8SStefano Zampini     jac->setcoord            = HYPRE_ADSSetCoordinateVectors;
1584863406b8SStefano Zampini     jac->coords[0]           = NULL;
1585863406b8SStefano Zampini     jac->coords[1]           = NULL;
1586863406b8SStefano Zampini     jac->coords[2]           = NULL;
1587863406b8SStefano Zampini     jac->G                   = NULL;
1588863406b8SStefano Zampini     jac->C                   = NULL;
1589863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1590863406b8SStefano Zampini     jac->as_print           = 0;
1591863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1592863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1593863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1594863406b8SStefano Zampini     /* Smoothing options */
1595863406b8SStefano Zampini     jac->as_relax_type      = 2;
1596863406b8SStefano Zampini     jac->as_relax_times     = 1;
1597863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1598863406b8SStefano Zampini     jac->as_omega           = 1.0;
1599863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1600863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1601863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1602863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1603863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1604863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1605863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1606863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1607863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1608863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1609863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1610863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1611863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1612863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1613863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1614863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1615863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1616863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1617863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1618863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1619863406b8SStefano Zampini                                                                       jac->as_relax_times,
1620863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1621863406b8SStefano Zampini                                                                       jac->as_omega));
1622863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1623863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1624863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1625863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1626863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1627863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1628863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1629863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1630863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1631863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1632863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1633863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1634863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1635863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
1636863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
1637863406b8SStefano Zampini     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
1638863406b8SStefano Zampini     PetscFunctionReturn(0);
1639863406b8SStefano Zampini   }
1640503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
16412fa5cd67SKarl Rupp 
16420298fd71SBarry Smith   jac->hypre_type = NULL;
164333263987SBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are pilut, parasails, boomeramg, ams",name);
164416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
164516d9e3a6SLisandro Dalcin }
164616d9e3a6SLisandro Dalcin 
164716d9e3a6SLisandro Dalcin /*
164816d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
164916d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
165016d9e3a6SLisandro Dalcin */
165116d9e3a6SLisandro Dalcin #undef __FUNCT__
165216d9e3a6SLisandro Dalcin #define __FUNCT__ "PCSetFromOptions_HYPRE"
16534416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc)
165416d9e3a6SLisandro Dalcin {
165516d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
16564ddd07fcSJed Brown   PetscInt       indx;
1657863406b8SStefano Zampini   const char     *type[] = {"pilut","parasails","boomeramg","ams","ads"};
1658ace3abfcSBarry Smith   PetscBool      flg;
165916d9e3a6SLisandro Dalcin 
166016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16619fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
16629c81f712SBarry Smith   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,4,"boomeramg",&indx,&flg);CHKERRQ(ierr);
166316d9e3a6SLisandro Dalcin   if (flg) {
166416d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
166502a17cd4SBarry Smith   } else {
166602a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
166716d9e3a6SLisandro Dalcin   }
166816d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
16693931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
167016d9e3a6SLisandro Dalcin   }
167116d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
167216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
167316d9e3a6SLisandro Dalcin }
167416d9e3a6SLisandro Dalcin 
167516d9e3a6SLisandro Dalcin #undef __FUNCT__
167616d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPRESetType"
167716d9e3a6SLisandro Dalcin /*@C
167816d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
167916d9e3a6SLisandro Dalcin 
168016d9e3a6SLisandro Dalcin    Input Parameters:
168116d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1682863406b8SStefano Zampini -     name - either  pilut, parasails, boomeramg, ams, ads
168316d9e3a6SLisandro Dalcin 
168416d9e3a6SLisandro Dalcin    Options Database Keys:
1685863406b8SStefano Zampini    -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
168616d9e3a6SLisandro Dalcin 
168716d9e3a6SLisandro Dalcin    Level: intermediate
168816d9e3a6SLisandro Dalcin 
168916d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
169016d9e3a6SLisandro Dalcin            PCHYPRE
169116d9e3a6SLisandro Dalcin 
169216d9e3a6SLisandro Dalcin @*/
16937087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
169416d9e3a6SLisandro Dalcin {
16954ac538c5SBarry Smith   PetscErrorCode ierr;
169616d9e3a6SLisandro Dalcin 
169716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
16980700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
169916d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
17004ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
170116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
170216d9e3a6SLisandro Dalcin }
170316d9e3a6SLisandro Dalcin 
170416d9e3a6SLisandro Dalcin #undef __FUNCT__
170516d9e3a6SLisandro Dalcin #define __FUNCT__ "PCHYPREGetType"
170616d9e3a6SLisandro Dalcin /*@C
170716d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
170816d9e3a6SLisandro Dalcin 
170916d9e3a6SLisandro Dalcin    Input Parameter:
171016d9e3a6SLisandro Dalcin .     pc - the preconditioner context
171116d9e3a6SLisandro Dalcin 
171216d9e3a6SLisandro Dalcin    Output Parameter:
1713863406b8SStefano Zampini .     name - either  pilut, parasails, boomeramg, ams, ads
171416d9e3a6SLisandro Dalcin 
171516d9e3a6SLisandro Dalcin    Level: intermediate
171616d9e3a6SLisandro Dalcin 
171716d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
171816d9e3a6SLisandro Dalcin            PCHYPRE
171916d9e3a6SLisandro Dalcin 
172016d9e3a6SLisandro Dalcin @*/
17217087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
172216d9e3a6SLisandro Dalcin {
17234ac538c5SBarry Smith   PetscErrorCode ierr;
172416d9e3a6SLisandro Dalcin 
172516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
17260700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
172716d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
17284ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
172916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
173016d9e3a6SLisandro Dalcin }
173116d9e3a6SLisandro Dalcin 
173216d9e3a6SLisandro Dalcin /*MC
173316d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
173416d9e3a6SLisandro Dalcin 
173516d9e3a6SLisandro Dalcin    Options Database Keys:
1736863406b8SStefano Zampini +   -pc_hypre_type - One of pilut, parasails, boomeramg, ams, ads
173716d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
173816d9e3a6SLisandro Dalcin           preconditioner
173916d9e3a6SLisandro Dalcin 
174016d9e3a6SLisandro Dalcin    Level: intermediate
174116d9e3a6SLisandro Dalcin 
174216d9e3a6SLisandro Dalcin    Notes: Apart from pc_hypre_type (for which there is PCHYPRESetType()),
174316d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
174416d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
174516d9e3a6SLisandro Dalcin 
174616d9e3a6SLisandro Dalcin           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_rtol refer to the number of iterations
17470f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
17480f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
17490f1074feSSatish Balay           (-pc_hypre_boomeramg_rtol should be set to 0.0 - the default - to strictly use a fixed number of
17508f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
17510f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
17520f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
175316d9e3a6SLisandro Dalcin 
17540f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
17550f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
17560f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
175716d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
175816d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
175916d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
176016d9e3a6SLisandro Dalcin 
176116d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
176216d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
176316d9e3a6SLisandro Dalcin 
17645272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
17655272c319SBarry Smith           the two options:
17665272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
1767cbc39033SBarry Smith -   -pc_hypre_boomeramg_vec_interp_variant <v> where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
17685272c319SBarry Smith 
17695272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
17705272c319SBarry Smith 
17719e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
17729e5bc791SBarry Smith 
177316d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
17749e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
177516d9e3a6SLisandro Dalcin 
177616d9e3a6SLisandro Dalcin M*/
177716d9e3a6SLisandro Dalcin 
177816d9e3a6SLisandro Dalcin #undef __FUNCT__
177916d9e3a6SLisandro Dalcin #define __FUNCT__ "PCCreate_HYPRE"
17808cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
178116d9e3a6SLisandro Dalcin {
178216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
178316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
178416d9e3a6SLisandro Dalcin 
178516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1786b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
17872fa5cd67SKarl Rupp 
178816d9e3a6SLisandro Dalcin   pc->data                = jac;
17898695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
179016d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
179116d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
179216d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
179316d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
179416d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
17950298fd71SBarry Smith   jac->hypre_type         = NULL;
17964cb006feSStefano Zampini   jac->coords[0]          = NULL;
17974cb006feSStefano Zampini   jac->coords[1]          = NULL;
17984cb006feSStefano Zampini   jac->coords[2]          = NULL;
17994cb006feSStefano Zampini   jac->constants[0]       = NULL;
18004cb006feSStefano Zampini   jac->constants[1]       = NULL;
18014cb006feSStefano Zampini   jac->constants[2]       = NULL;
1802863406b8SStefano Zampini   jac->G                  = NULL;
1803863406b8SStefano Zampini   jac->C                  = NULL;
1804863406b8SStefano Zampini   jac->alpha_Poisson      = NULL;
1805863406b8SStefano Zampini   jac->beta_Poisson       = NULL;
1806fd444223SStefano Zampini   jac->setdim             = NULL;
18075272c319SBarry Smith   jac->hmnull             = NULL;
18085272c319SBarry Smith   jac->n_hmnull           = 0;
180916d9e3a6SLisandro Dalcin   /* duplicate communicator for hypre */
1810ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1811bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
1812bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
181316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
181416d9e3a6SLisandro Dalcin }
1815ebc551c0SBarry Smith 
1816f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
1817f91d8e95SBarry Smith 
1818b862ddfaSBarry Smith /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
1819af0996ceSBarry Smith #include <petsc/private/matimpl.h>
1820ebc551c0SBarry Smith 
1821ebc551c0SBarry Smith typedef struct {
182268326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
1823f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
18249e5bc791SBarry Smith 
18259e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
18264ddd07fcSJed Brown   PetscInt its;
18279e5bc791SBarry Smith   double   tol;
18284ddd07fcSJed Brown   PetscInt relax_type;
18294ddd07fcSJed Brown   PetscInt rap_type;
18304ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
18314ddd07fcSJed Brown   PetscInt max_levels;
1832ebc551c0SBarry Smith } PC_PFMG;
1833ebc551c0SBarry Smith 
1834ebc551c0SBarry Smith #undef __FUNCT__
1835ebc551c0SBarry Smith #define __FUNCT__ "PCDestroy_PFMG"
1836ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
1837ebc551c0SBarry Smith {
1838ebc551c0SBarry Smith   PetscErrorCode ierr;
1839f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1840ebc551c0SBarry Smith 
1841ebc551c0SBarry Smith   PetscFunctionBegin;
18422fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1843f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
1844c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
1845ebc551c0SBarry Smith   PetscFunctionReturn(0);
1846ebc551c0SBarry Smith }
1847ebc551c0SBarry Smith 
18489e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
18499e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
18509e5bc791SBarry Smith 
1851ebc551c0SBarry Smith #undef __FUNCT__
1852ebc551c0SBarry Smith #define __FUNCT__ "PCView_PFMG"
1853ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
1854ebc551c0SBarry Smith {
1855ebc551c0SBarry Smith   PetscErrorCode ierr;
1856ace3abfcSBarry Smith   PetscBool      iascii;
1857f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1858ebc551c0SBarry Smith 
1859ebc551c0SBarry Smith   PetscFunctionBegin;
1860251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
18619e5bc791SBarry Smith   if (iascii) {
18629e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
18639e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
18649e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
18659e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
18669e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
18679e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
18683b46a515SGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG: max levels %d\n",ex->max_levels);CHKERRQ(ierr);
18699e5bc791SBarry Smith   }
1870ebc551c0SBarry Smith   PetscFunctionReturn(0);
1871ebc551c0SBarry Smith }
1872ebc551c0SBarry Smith 
18739e5bc791SBarry Smith 
1874ebc551c0SBarry Smith #undef __FUNCT__
1875ebc551c0SBarry Smith #define __FUNCT__ "PCSetFromOptions_PFMG"
18764416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc)
1877ebc551c0SBarry Smith {
1878ebc551c0SBarry Smith   PetscErrorCode ierr;
1879f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
1880ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
1881ebc551c0SBarry Smith 
1882ebc551c0SBarry Smith   PetscFunctionBegin;
1883e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
18840298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
188568326731SBarry Smith   if (flg) {
1886a0324ebeSBarry Smith     int level=3;
1887fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,level));
188868326731SBarry Smith   }
18890298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
1890fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
18910298fd71SBarry 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);
1892fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
18930298fd71SBarry 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);
1894fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
18959e5bc791SBarry Smith 
18960298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
1897fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
18983b46a515SGlenn Hammond 
18990298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
1900fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
19010298fd71SBarry 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);
1902fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
19030298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
1904fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
1905ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
1906ebc551c0SBarry Smith   PetscFunctionReturn(0);
1907ebc551c0SBarry Smith }
1908ebc551c0SBarry Smith 
1909f91d8e95SBarry Smith #undef __FUNCT__
1910f91d8e95SBarry Smith #define __FUNCT__ "PCApply_PFMG"
1911f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
1912f91d8e95SBarry Smith {
1913f91d8e95SBarry Smith   PetscErrorCode    ierr;
1914f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
1915d9ca1df4SBarry Smith   PetscScalar       *yy;
1916d9ca1df4SBarry Smith   const PetscScalar *xx;
19174ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
191868326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1919f91d8e95SBarry Smith 
1920f91d8e95SBarry Smith   PetscFunctionBegin;
1921dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1922aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
1923f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
1924f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
1925f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
1926f91d8e95SBarry Smith 
1927f91d8e95SBarry Smith   /* copy x values over to hypre */
1928fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
1929d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1930d9ca1df4SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,(PetscScalar*)xx));
1931d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1932fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
1933fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1934f91d8e95SBarry Smith 
1935f91d8e95SBarry Smith   /* copy solution values back to PETSc */
1936f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
19378b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,yy));
1938f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1939f91d8e95SBarry Smith   PetscFunctionReturn(0);
1940f91d8e95SBarry Smith }
1941f91d8e95SBarry Smith 
19429e5bc791SBarry Smith #undef __FUNCT__
19439e5bc791SBarry Smith #define __FUNCT__ "PCApplyRichardson_PFMG"
1944ace3abfcSBarry 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)
19459e5bc791SBarry Smith {
19469e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
19479e5bc791SBarry Smith   PetscErrorCode ierr;
19484ddd07fcSJed Brown   PetscInt       oits;
19499e5bc791SBarry Smith 
19509e5bc791SBarry Smith   PetscFunctionBegin;
1951dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
1952fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
1953fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
19549e5bc791SBarry Smith 
19559e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
19568b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,(HYPRE_Int *)&oits));
19579e5bc791SBarry Smith   *outits = oits;
19589e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
19599e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
1960fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
1961fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
19629e5bc791SBarry Smith   PetscFunctionReturn(0);
19639e5bc791SBarry Smith }
19649e5bc791SBarry Smith 
19659e5bc791SBarry Smith 
19663a32d3dbSGlenn Hammond #undef __FUNCT__
19673a32d3dbSGlenn Hammond #define __FUNCT__ "PCSetUp_PFMG"
19683a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
19693a32d3dbSGlenn Hammond {
19703a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
19713a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
19723a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
1973ace3abfcSBarry Smith   PetscBool       flg;
19743a32d3dbSGlenn Hammond 
19753a32d3dbSGlenn Hammond   PetscFunctionBegin;
1976251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
1977ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
19783a32d3dbSGlenn Hammond 
19793a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
19802fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
1981fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
1982fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
1983fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
19843a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
19853a32d3dbSGlenn Hammond }
19863a32d3dbSGlenn Hammond 
1987ebc551c0SBarry Smith 
1988ebc551c0SBarry Smith /*MC
1989ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
1990ebc551c0SBarry Smith 
1991ebc551c0SBarry Smith    Level: advanced
1992ebc551c0SBarry Smith 
19939e5bc791SBarry Smith    Options Database:
19949e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
19959e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
19969e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
19979e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
19989e5bc791SBarry 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
19999e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
2000f91d8e95SBarry Smith 
20019e5bc791SBarry Smith    Notes:  This is for CELL-centered descretizations
20029e5bc791SBarry Smith 
20038e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
2004aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
20059e5bc791SBarry Smith 
20069e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
2007ebc551c0SBarry Smith M*/
2008ebc551c0SBarry Smith 
2009ebc551c0SBarry Smith #undef __FUNCT__
2010ebc551c0SBarry Smith #define __FUNCT__ "PCCreate_PFMG"
20118cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
2012ebc551c0SBarry Smith {
2013ebc551c0SBarry Smith   PetscErrorCode ierr;
2014ebc551c0SBarry Smith   PC_PFMG        *ex;
2015ebc551c0SBarry Smith 
2016ebc551c0SBarry Smith   PetscFunctionBegin;
2017b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
201868326731SBarry Smith   pc->data = ex;
2019ebc551c0SBarry Smith 
20209e5bc791SBarry Smith   ex->its            = 1;
20219e5bc791SBarry Smith   ex->tol            = 1.e-8;
20229e5bc791SBarry Smith   ex->relax_type     = 1;
20239e5bc791SBarry Smith   ex->rap_type       = 0;
20249e5bc791SBarry Smith   ex->num_pre_relax  = 1;
20259e5bc791SBarry Smith   ex->num_post_relax = 1;
20263b46a515SGlenn Hammond   ex->max_levels     = 0;
20279e5bc791SBarry Smith 
2028ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2029ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2030ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2031f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
20329e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
203368326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
20342fa5cd67SKarl Rupp 
2035ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2036fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2037ebc551c0SBarry Smith   PetscFunctionReturn(0);
2038ebc551c0SBarry Smith }
2039d851a50bSGlenn Hammond 
2040325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2041325fc9f4SBarry Smith 
2042d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2043d851a50bSGlenn Hammond typedef struct {
2044d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2045d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2046d851a50bSGlenn Hammond 
2047d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
20484ddd07fcSJed Brown   PetscInt its;
2049d851a50bSGlenn Hammond   double   tol;
20504ddd07fcSJed Brown   PetscInt relax_type;
20514ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2052d851a50bSGlenn Hammond } PC_SysPFMG;
2053d851a50bSGlenn Hammond 
2054d851a50bSGlenn Hammond #undef __FUNCT__
2055d851a50bSGlenn Hammond #define __FUNCT__ "PCDestroy_SysPFMG"
2056d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2057d851a50bSGlenn Hammond {
2058d851a50bSGlenn Hammond   PetscErrorCode ierr;
2059d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2060d851a50bSGlenn Hammond 
2061d851a50bSGlenn Hammond   PetscFunctionBegin;
20622fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2063d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2064c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2065d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2066d851a50bSGlenn Hammond }
2067d851a50bSGlenn Hammond 
2068d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2069d851a50bSGlenn Hammond 
2070d851a50bSGlenn Hammond #undef __FUNCT__
2071d851a50bSGlenn Hammond #define __FUNCT__ "PCView_SysPFMG"
2072d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2073d851a50bSGlenn Hammond {
2074d851a50bSGlenn Hammond   PetscErrorCode ierr;
2075ace3abfcSBarry Smith   PetscBool      iascii;
2076d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2077d851a50bSGlenn Hammond 
2078d851a50bSGlenn Hammond   PetscFunctionBegin;
2079251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2080d851a50bSGlenn Hammond   if (iascii) {
2081d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2082d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: max iterations %d\n",ex->its);CHKERRQ(ierr);
2083d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: tolerance %g\n",ex->tol);CHKERRQ(ierr);
2084d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2085d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG: number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2086d851a50bSGlenn Hammond   }
2087d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2088d851a50bSGlenn Hammond }
2089d851a50bSGlenn Hammond 
2090d851a50bSGlenn Hammond 
2091d851a50bSGlenn Hammond #undef __FUNCT__
2092d851a50bSGlenn Hammond #define __FUNCT__ "PCSetFromOptions_SysPFMG"
20934416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2094d851a50bSGlenn Hammond {
2095d851a50bSGlenn Hammond   PetscErrorCode ierr;
2096d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2097ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2098d851a50bSGlenn Hammond 
2099d851a50bSGlenn Hammond   PetscFunctionBegin;
2100e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
21010298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2102d851a50bSGlenn Hammond   if (flg) {
2103d851a50bSGlenn Hammond     int level=3;
2104fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,level));
2105d851a50bSGlenn Hammond   }
21060298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2107fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
21080298fd71SBarry 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);
2109fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
21100298fd71SBarry 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);
2111fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2112d851a50bSGlenn Hammond 
21130298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2114fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
21150298fd71SBarry 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);
2116fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2117d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2118d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2119d851a50bSGlenn Hammond }
2120d851a50bSGlenn Hammond 
2121d851a50bSGlenn Hammond #undef __FUNCT__
2122d851a50bSGlenn Hammond #define __FUNCT__ "PCApply_SysPFMG"
2123d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2124d851a50bSGlenn Hammond {
2125d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2126d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2127d9ca1df4SBarry Smith   PetscScalar       *yy;
2128d9ca1df4SBarry Smith   const PetscScalar *xx;
21294ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
2130d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
21314ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
21324ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
21334ddd07fcSJed Brown   PetscInt          part    = 0;
21344ddd07fcSJed Brown   PetscInt          size;
21354ddd07fcSJed Brown   PetscInt          i;
2136d851a50bSGlenn Hammond 
2137d851a50bSGlenn Hammond   PetscFunctionBegin;
2138dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2139aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
2140d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2141d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2142d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
2143d851a50bSGlenn Hammond 
2144d851a50bSGlenn Hammond   size = 1;
21452fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
21462fa5cd67SKarl Rupp 
2147d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2148d851a50bSGlenn Hammond   if (ordering) {
2149fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2150d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2151d9ca1df4SBarry 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)));
2152d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2153fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2154fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2155fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2156d851a50bSGlenn Hammond 
2157d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2158d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
21598b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,yy+(size*i)));
2160d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2161a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2162d851a50bSGlenn Hammond     PetscScalar *z;
21634ddd07fcSJed Brown     PetscInt    j, k;
2164d851a50bSGlenn Hammond 
2165785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2166fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2167d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2168d851a50bSGlenn Hammond 
2169d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2170d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2171d851a50bSGlenn Hammond       k= i*nvars;
21722fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2173d851a50bSGlenn Hammond     }
21748b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2175d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2176fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2177fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2178d851a50bSGlenn Hammond 
2179d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2180d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
21818b1f7689SBarry Smith     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,(HYPRE_Int *)ilower,(HYPRE_Int *)iupper,i,z+(size*i)));
2182d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2183d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2184d851a50bSGlenn Hammond       k= i*nvars;
21852fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2186d851a50bSGlenn Hammond     }
2187d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2188d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2189d851a50bSGlenn Hammond   }
2190d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2191d851a50bSGlenn Hammond }
2192d851a50bSGlenn Hammond 
2193d851a50bSGlenn Hammond #undef __FUNCT__
2194d851a50bSGlenn Hammond #define __FUNCT__ "PCApplyRichardson_SysPFMG"
2195ace3abfcSBarry 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)
2196d851a50bSGlenn Hammond {
2197d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2198d851a50bSGlenn Hammond   PetscErrorCode ierr;
21994ddd07fcSJed Brown   PetscInt       oits;
2200d851a50bSGlenn Hammond 
2201d851a50bSGlenn Hammond   PetscFunctionBegin;
2202dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2203fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2204fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2205d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
22068b1f7689SBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,(HYPRE_Int *)&oits));
2207d851a50bSGlenn Hammond   *outits = oits;
2208d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2209d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2210fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2211fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2212d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2213d851a50bSGlenn Hammond }
2214d851a50bSGlenn Hammond 
2215d851a50bSGlenn Hammond 
2216d851a50bSGlenn Hammond #undef __FUNCT__
2217d851a50bSGlenn Hammond #define __FUNCT__ "PCSetUp_SysPFMG"
2218d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2219d851a50bSGlenn Hammond {
2220d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2221d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2222d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2223ace3abfcSBarry Smith   PetscBool        flg;
2224d851a50bSGlenn Hammond 
2225d851a50bSGlenn Hammond   PetscFunctionBegin;
2226251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2227ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2228d851a50bSGlenn Hammond 
2229d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
22302fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2231fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2232fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2233fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2234d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2235d851a50bSGlenn Hammond }
2236d851a50bSGlenn Hammond 
2237d851a50bSGlenn Hammond 
2238d851a50bSGlenn Hammond /*MC
2239d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2240d851a50bSGlenn Hammond 
2241d851a50bSGlenn Hammond    Level: advanced
2242d851a50bSGlenn Hammond 
2243d851a50bSGlenn Hammond    Options Database:
2244d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2245d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2246d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2247d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2248d851a50bSGlenn Hammond . -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2249d851a50bSGlenn Hammond 
2250d851a50bSGlenn Hammond    Notes:  This is for CELL-centered descretizations
2251d851a50bSGlenn Hammond 
2252f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2253aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2254d851a50bSGlenn Hammond            Also, only cell-centered variables.
2255d851a50bSGlenn Hammond 
2256d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2257d851a50bSGlenn Hammond M*/
2258d851a50bSGlenn Hammond 
2259d851a50bSGlenn Hammond #undef __FUNCT__
2260d851a50bSGlenn Hammond #define __FUNCT__ "PCCreate_SysPFMG"
22618cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2262d851a50bSGlenn Hammond {
2263d851a50bSGlenn Hammond   PetscErrorCode ierr;
2264d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2265d851a50bSGlenn Hammond 
2266d851a50bSGlenn Hammond   PetscFunctionBegin;
2267b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2268d851a50bSGlenn Hammond   pc->data = ex;
2269d851a50bSGlenn Hammond 
2270d851a50bSGlenn Hammond   ex->its            = 1;
2271d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2272d851a50bSGlenn Hammond   ex->relax_type     = 1;
2273d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2274d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2275d851a50bSGlenn Hammond 
2276d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2277d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2278d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2279d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2280d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2281d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
22822fa5cd67SKarl Rupp 
2283ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2284fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2285d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2286d851a50bSGlenn Hammond }
2287