xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 55b25c41ced27fd629b906d0f249638c16189078)
116d9e3a6SLisandro Dalcin /*
216d9e3a6SLisandro Dalcin    Provides an interface to the LLNL package hypre
316d9e3a6SLisandro Dalcin */
40f1074feSSatish Balay 
50f1074feSSatish Balay /* Must use hypre 2.0.0 or more recent. */
60f1074feSSatish Balay 
7af0996ceSBarry Smith #include <petsc/private/pcimpl.h>          /*I "petscpc.h" I*/
849a781f5SStefano Zampini /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
949a781f5SStefano Zampini #include <petsc/private/matimpl.h>
1058968eb6SStefano Zampini #include <../src/vec/vec/impls/hypre/vhyp.h>
1149a781f5SStefano Zampini #include <../src/mat/impls/hypre/mhypre.h>
12c6db04a5SJed Brown #include <../src/dm/impls/da/hypre/mhyp.h>
134cb006feSStefano Zampini #include <_hypre_parcsr_ls.h>
148a2c336bSFande Kong #include <petscmathypre.h>
1516d9e3a6SLisandro Dalcin 
16dff31646SBarry Smith static PetscBool cite = PETSC_FALSE;
17a8d69d7bSBarry 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{https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods}}\n}\n";
181f817a21SBarry Smith 
1916d9e3a6SLisandro Dalcin /*
2016d9e3a6SLisandro Dalcin    Private context (data structure) for the  preconditioner.
2116d9e3a6SLisandro Dalcin */
2216d9e3a6SLisandro Dalcin typedef struct {
2316d9e3a6SLisandro Dalcin   HYPRE_Solver   hsolver;
2449a781f5SStefano Zampini   Mat            hpmat; /* MatHYPRE */
2516d9e3a6SLisandro Dalcin 
264ddd07fcSJed Brown   HYPRE_Int (*destroy)(HYPRE_Solver);
274ddd07fcSJed Brown   HYPRE_Int (*solve)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
284ddd07fcSJed Brown   HYPRE_Int (*setup)(HYPRE_Solver,HYPRE_ParCSRMatrix,HYPRE_ParVector,HYPRE_ParVector);
2916d9e3a6SLisandro Dalcin 
3016d9e3a6SLisandro Dalcin   MPI_Comm comm_hypre;
3116d9e3a6SLisandro Dalcin   char     *hypre_type;
3216d9e3a6SLisandro Dalcin 
3316d9e3a6SLisandro Dalcin   /* options for Pilut and BoomerAMG*/
344ddd07fcSJed Brown   PetscInt  maxiter;
3539accc25SStefano Zampini   PetscReal tol;
3616d9e3a6SLisandro Dalcin 
3716d9e3a6SLisandro Dalcin   /* options for Pilut */
384ddd07fcSJed Brown   PetscInt factorrowsize;
3916d9e3a6SLisandro Dalcin 
4016d9e3a6SLisandro Dalcin   /* options for ParaSails */
414ddd07fcSJed Brown   PetscInt  nlevels;
428966356dSPierre Jolivet   PetscReal threshold;
4339accc25SStefano Zampini   PetscReal filter;
444ddd07fcSJed Brown   PetscInt  sym;
4539accc25SStefano Zampini   PetscReal loadbal;
464ddd07fcSJed Brown   PetscInt  logging;
474ddd07fcSJed Brown   PetscInt  ruse;
484ddd07fcSJed Brown   PetscInt  symt;
4916d9e3a6SLisandro Dalcin 
5022b6d1caSBarry Smith   /* options for BoomerAMG */
51ace3abfcSBarry Smith   PetscBool printstatistics;
5216d9e3a6SLisandro Dalcin 
5316d9e3a6SLisandro Dalcin   /* options for BoomerAMG */
544ddd07fcSJed Brown   PetscInt  cycletype;
554ddd07fcSJed Brown   PetscInt  maxlevels;
5639accc25SStefano Zampini   PetscReal strongthreshold;
5739accc25SStefano Zampini   PetscReal maxrowsum;
584ddd07fcSJed Brown   PetscInt  gridsweeps[3];
594ddd07fcSJed Brown   PetscInt  coarsentype;
604ddd07fcSJed Brown   PetscInt  measuretype;
616a251517SEike Mueller   PetscInt  smoothtype;
628131ecf7SEike Mueller   PetscInt  smoothnumlevels;
63ec64516dSEike Mueller   PetscInt  eu_level;   /* Number of levels for ILU(k) in Euclid */
6439accc25SStefano Zampini   PetscReal eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */
65ec64516dSEike Mueller   PetscInt  eu_bj;      /* Defines use of Block Jacobi ILU in Euclid */
664ddd07fcSJed Brown   PetscInt  relaxtype[3];
6739accc25SStefano Zampini   PetscReal relaxweight;
6839accc25SStefano Zampini   PetscReal outerrelaxweight;
694ddd07fcSJed Brown   PetscInt  relaxorder;
7039accc25SStefano Zampini   PetscReal truncfactor;
71ace3abfcSBarry Smith   PetscBool applyrichardson;
724ddd07fcSJed Brown   PetscInt  pmax;
734ddd07fcSJed Brown   PetscInt  interptype;
744ddd07fcSJed Brown   PetscInt  agg_nl;
754ddd07fcSJed Brown   PetscInt  agg_num_paths;
76ace3abfcSBarry Smith   PetscBool nodal_relax;
774ddd07fcSJed Brown   PetscInt  nodal_relax_levels;
784cb006feSStefano Zampini 
795272c319SBarry Smith   PetscInt  nodal_coarsening;
8022e51d31SStefano Zampini   PetscInt  nodal_coarsening_diag;
815272c319SBarry Smith   PetscInt  vec_interp_variant;
8222e51d31SStefano Zampini   PetscInt  vec_interp_qmax;
8322e51d31SStefano Zampini   PetscBool vec_interp_smooth;
8422e51d31SStefano Zampini   PetscInt  interp_refine;
8522e51d31SStefano Zampini 
865272c319SBarry Smith   HYPRE_IJVector  *hmnull;
875272c319SBarry Smith   HYPRE_ParVector *phmnull;  /* near null space passed to hypre */
885272c319SBarry Smith   PetscInt        n_hmnull;
895272c319SBarry Smith   Vec             hmnull_constant;
9039accc25SStefano Zampini   HYPRE_Complex   **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 */
915272c319SBarry Smith 
92863406b8SStefano Zampini   /* options for AS (Auxiliary Space preconditioners) */
93863406b8SStefano Zampini   PetscInt  as_print;
94863406b8SStefano Zampini   PetscInt  as_max_iter;
95863406b8SStefano Zampini   PetscReal as_tol;
96863406b8SStefano Zampini   PetscInt  as_relax_type;
97863406b8SStefano Zampini   PetscInt  as_relax_times;
98863406b8SStefano Zampini   PetscReal as_relax_weight;
99863406b8SStefano Zampini   PetscReal as_omega;
100863406b8SStefano 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) */
101863406b8SStefano Zampini   PetscReal as_amg_alpha_theta;   /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
102863406b8SStefano 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) */
103863406b8SStefano Zampini   PetscReal as_amg_beta_theta;    /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS)  */
1044cb006feSStefano Zampini   PetscInt  ams_cycle_type;
105863406b8SStefano Zampini   PetscInt  ads_cycle_type;
1064cb006feSStefano Zampini 
1074cb006feSStefano Zampini   /* additional data */
1085ac14e1cSStefano Zampini   Mat G;             /* MatHYPRE */
1095ac14e1cSStefano Zampini   Mat C;             /* MatHYPRE */
1105ac14e1cSStefano Zampini   Mat alpha_Poisson; /* MatHYPRE */
1115ac14e1cSStefano Zampini   Mat beta_Poisson;  /* MatHYPRE */
1125ac14e1cSStefano Zampini 
1135ac14e1cSStefano Zampini   /* extra information for AMS */
1145ac14e1cSStefano Zampini   PetscInt       dim; /* geometrical dimension */
1154cb006feSStefano Zampini   HYPRE_IJVector coords[3];
1164cb006feSStefano Zampini   HYPRE_IJVector constants[3];
1176bf688a0SCe Qin   Mat            RT_PiFull, RT_Pi[3];
1186bf688a0SCe Qin   Mat            ND_PiFull, ND_Pi[3];
1194cb006feSStefano Zampini   PetscBool      ams_beta_is_zero;
12023df4f25SStefano Zampini   PetscBool      ams_beta_is_zero_part;
12123df4f25SStefano Zampini   PetscInt       ams_proj_freq;
12216d9e3a6SLisandro Dalcin } PC_HYPRE;
12316d9e3a6SLisandro Dalcin 
124d2128fa2SBarry Smith PetscErrorCode PCHYPREGetSolver(PC pc,HYPRE_Solver *hsolver)
125d2128fa2SBarry Smith {
126d2128fa2SBarry Smith   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
127d2128fa2SBarry Smith 
128d2128fa2SBarry Smith   PetscFunctionBegin;
129d2128fa2SBarry Smith   *hsolver = jac->hsolver;
130d2128fa2SBarry Smith   PetscFunctionReturn(0);
131d2128fa2SBarry Smith }
13216d9e3a6SLisandro Dalcin 
133fd2dd295SFande Kong /*
1348a2c336bSFande Kong   Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix
1358a2c336bSFande Kong   is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine.
1368a2c336bSFande Kong   It is used in PCHMG. Other users should avoid using this function.
137fd2dd295SFande Kong */
138fd2dd295SFande Kong static PetscErrorCode PCGetCoarseOperators_BoomerAMG(PC pc,PetscInt *nlevels,Mat *operators[])
1398a2c336bSFande Kong {
1408a2c336bSFande Kong   PC_HYPRE             *jac  = (PC_HYPRE*)pc->data;
1418a2c336bSFande Kong   PetscBool            same = PETSC_FALSE;
1428a2c336bSFande Kong   PetscErrorCode       ierr;
1438a2c336bSFande Kong   PetscInt             num_levels,l;
1448a2c336bSFande Kong   Mat                  *mattmp;
1458a2c336bSFande Kong   hypre_ParCSRMatrix   **A_array;
1468a2c336bSFande Kong 
1478a2c336bSFande Kong   PetscFunctionBegin;
1488a2c336bSFande Kong   ierr = PetscStrcmp(jac->hypre_type,"boomeramg",&same);CHKERRQ(ierr);
1498a2c336bSFande Kong   if (!same) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_NOTSAMETYPE,"Hypre type is not BoomerAMG \n");
1508a2c336bSFande Kong   num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData*) (jac->hsolver));
1518a2c336bSFande Kong   ierr = PetscMalloc1(num_levels,&mattmp);CHKERRQ(ierr);
1528a2c336bSFande Kong   A_array    = hypre_ParAMGDataAArray((hypre_ParAMGData*) (jac->hsolver));
1538a2c336bSFande Kong   for (l=1; l<num_levels; l++) {
1548a2c336bSFande Kong     ierr = MatCreateFromParCSR(A_array[l],MATAIJ,PETSC_OWN_POINTER, &(mattmp[num_levels-1-l]));CHKERRQ(ierr);
1558a2c336bSFande Kong     /* We want to own the data, and HYPRE can not touch this matrix any more */
1568a2c336bSFande Kong     A_array[l] = NULL;
1578a2c336bSFande Kong   }
1588a2c336bSFande Kong   *nlevels = num_levels;
1598a2c336bSFande Kong   *operators = mattmp;
1608a2c336bSFande Kong   PetscFunctionReturn(0);
1618a2c336bSFande Kong }
1628a2c336bSFande Kong 
163fd2dd295SFande Kong /*
1648a2c336bSFande Kong   Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix
1658a2c336bSFande Kong   is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine.
1668a2c336bSFande Kong   It is used in PCHMG. Other users should avoid using this function.
167fd2dd295SFande Kong */
168fd2dd295SFande Kong static PetscErrorCode PCGetInterpolations_BoomerAMG(PC pc,PetscInt *nlevels,Mat *interpolations[])
1698a2c336bSFande Kong {
1708a2c336bSFande Kong   PC_HYPRE             *jac  = (PC_HYPRE*)pc->data;
1718a2c336bSFande Kong   PetscBool            same = PETSC_FALSE;
1728a2c336bSFande Kong   PetscErrorCode       ierr;
1738a2c336bSFande Kong   PetscInt             num_levels,l;
1748a2c336bSFande Kong   Mat                  *mattmp;
1758a2c336bSFande Kong   hypre_ParCSRMatrix   **P_array;
1768a2c336bSFande Kong 
1778a2c336bSFande Kong   PetscFunctionBegin;
1788a2c336bSFande Kong   ierr = PetscStrcmp(jac->hypre_type,"boomeramg",&same);CHKERRQ(ierr);
1798a2c336bSFande Kong   if (!same) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_NOTSAMETYPE,"Hypre type is not BoomerAMG \n");
1808a2c336bSFande Kong   num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData*) (jac->hsolver));
1818a2c336bSFande Kong   ierr = PetscMalloc1(num_levels,&mattmp);CHKERRQ(ierr);
1828a2c336bSFande Kong   P_array  = hypre_ParAMGDataPArray((hypre_ParAMGData*) (jac->hsolver));
1838a2c336bSFande Kong   for (l=1; l<num_levels; l++) {
1848a2c336bSFande Kong     ierr = MatCreateFromParCSR(P_array[num_levels-1-l],MATAIJ,PETSC_OWN_POINTER, &(mattmp[l-1]));CHKERRQ(ierr);
1858a2c336bSFande Kong     /* We want to own the data, and HYPRE can not touch this matrix any more */
1868a2c336bSFande Kong     P_array[num_levels-1-l] = NULL;
1878a2c336bSFande Kong   }
1888a2c336bSFande Kong   *nlevels = num_levels;
1898a2c336bSFande Kong   *interpolations = mattmp;
1908a2c336bSFande Kong   PetscFunctionReturn(0);
1918a2c336bSFande Kong }
1928a2c336bSFande Kong 
193ce6a8a0dSJed Brown /* Resets (frees) Hypre's representation of the near null space */
194ce6a8a0dSJed Brown static PetscErrorCode PCHYPREResetNearNullSpace_Private(PC pc)
195ce6a8a0dSJed Brown {
196ce6a8a0dSJed Brown   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
197ce6a8a0dSJed Brown   PetscInt       i;
1989d678128SJed Brown   PetscErrorCode ierr;
199ce6a8a0dSJed Brown 
2009d678128SJed Brown   PetscFunctionBegin;
201ce6a8a0dSJed Brown   for (i=0; i<jac->n_hmnull; i++) {
20239accc25SStefano Zampini     PETSC_UNUSED HYPRE_Complex *harray;
20339accc25SStefano Zampini     VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],jac->hmnull_hypre_data_array[i],harray);
204ce6a8a0dSJed Brown     PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->hmnull[i]));
205ce6a8a0dSJed Brown   }
206ce6a8a0dSJed Brown   ierr = PetscFree(jac->hmnull);CHKERRQ(ierr);
207ce6a8a0dSJed Brown   ierr = PetscFree(jac->hmnull_hypre_data_array);CHKERRQ(ierr);
208ce6a8a0dSJed Brown   ierr = PetscFree(jac->phmnull);CHKERRQ(ierr);
209ce6a8a0dSJed Brown   ierr = VecDestroy(&jac->hmnull_constant);CHKERRQ(ierr);
2109d678128SJed Brown   jac->n_hmnull = 0;
211ce6a8a0dSJed Brown   PetscFunctionReturn(0);
212ce6a8a0dSJed Brown }
213ce6a8a0dSJed Brown 
21416d9e3a6SLisandro Dalcin static PetscErrorCode PCSetUp_HYPRE(PC pc)
21516d9e3a6SLisandro Dalcin {
21616d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
21749a781f5SStefano Zampini   Mat_HYPRE          *hjac;
21816d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
21916d9e3a6SLisandro Dalcin   HYPRE_ParVector    bv,xv;
22049a781f5SStefano Zampini   PetscBool          ishypre;
22149a781f5SStefano Zampini   PetscErrorCode     ierr;
22216d9e3a6SLisandro Dalcin 
22316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
22416d9e3a6SLisandro Dalcin   if (!jac->hypre_type) {
22502a17cd4SBarry Smith     ierr = PCHYPRESetType(pc,"boomeramg");CHKERRQ(ierr);
22616d9e3a6SLisandro Dalcin   }
2275f5c5b43SBarry Smith 
22849a781f5SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRE,&ishypre);CHKERRQ(ierr);
22949a781f5SStefano Zampini   if (!ishypre) {
2306bf688a0SCe Qin     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
2316bf688a0SCe Qin     ierr = MatConvert(pc->pmat,MATHYPRE,MAT_INITIAL_MATRIX,&jac->hpmat);CHKERRQ(ierr);
23249a781f5SStefano Zampini   } else {
23349a781f5SStefano Zampini     ierr = PetscObjectReference((PetscObject)pc->pmat);CHKERRQ(ierr);
23449a781f5SStefano Zampini     ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
23549a781f5SStefano Zampini     jac->hpmat = pc->pmat;
23616d9e3a6SLisandro Dalcin   }
23749a781f5SStefano Zampini   hjac = (Mat_HYPRE*)(jac->hpmat->data);
2385f5c5b43SBarry Smith 
23916d9e3a6SLisandro Dalcin   /* special case for BoomerAMG */
24016d9e3a6SLisandro Dalcin   if (jac->setup == HYPRE_BoomerAMGSetup) {
2415272c319SBarry Smith     MatNullSpace    mnull;
2425272c319SBarry Smith     PetscBool       has_const;
24349a781f5SStefano Zampini     PetscInt        bs,nvec,i;
2445272c319SBarry Smith     const Vec       *vecs;
24539accc25SStefano Zampini     HYPRE_Complex   *petscvecarray;
2465272c319SBarry Smith 
24716d9e3a6SLisandro Dalcin     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
2482fa5cd67SKarl Rupp     if (bs > 1) PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
2495272c319SBarry Smith     ierr = MatGetNearNullSpace(pc->mat, &mnull);CHKERRQ(ierr);
2505272c319SBarry Smith     if (mnull) {
251ce6a8a0dSJed Brown       ierr = PCHYPREResetNearNullSpace_Private(pc);CHKERRQ(ierr);
2525272c319SBarry Smith       ierr = MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs);CHKERRQ(ierr);
2535272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull);CHKERRQ(ierr);
25472827435SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->hmnull_hypre_data_array);CHKERRQ(ierr);
2555272c319SBarry Smith       ierr = PetscMalloc1(nvec+1,&jac->phmnull);CHKERRQ(ierr);
2565272c319SBarry Smith       for (i=0; i<nvec; i++) {
2575272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(vecs[i],&jac->hmnull[i]);CHKERRQ(ierr);
25872827435SBarry Smith         ierr = VecGetArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
25958968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[i],petscvecarray,jac->hmnull_hypre_data_array[i]);
26072827435SBarry Smith         ierr = VecRestoreArrayRead(vecs[i],(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
2615272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[i],(void**)&jac->phmnull[i]));
2625272c319SBarry Smith       }
2635272c319SBarry Smith       if (has_const) {
2645272c319SBarry Smith         ierr = MatCreateVecs(pc->pmat,&jac->hmnull_constant,NULL);CHKERRQ(ierr);
2655272c319SBarry Smith         ierr = VecSet(jac->hmnull_constant,1);CHKERRQ(ierr);
2665272c319SBarry Smith         ierr = VecNormalize(jac->hmnull_constant,NULL);
2675272c319SBarry Smith         ierr = VecHYPRE_IJVectorCreate(jac->hmnull_constant,&jac->hmnull[nvec]);CHKERRQ(ierr);
26872827435SBarry Smith         ierr = VecGetArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
26958968eb6SStefano Zampini         VecHYPRE_ParVectorReplacePointer(jac->hmnull[nvec],petscvecarray,jac->hmnull_hypre_data_array[nvec]);
27072827435SBarry Smith         ierr = VecRestoreArrayRead(jac->hmnull_constant,(const PetscScalar **)&petscvecarray);CHKERRQ(ierr);
2715272c319SBarry Smith         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->hmnull[nvec],(void**)&jac->phmnull[nvec]));
2725272c319SBarry Smith         nvec++;
2735272c319SBarry Smith       }
2745272c319SBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVectors,(jac->hsolver,nvec,jac->phmnull));
2755272c319SBarry Smith       jac->n_hmnull = nvec;
2765272c319SBarry Smith     }
2774cb006feSStefano Zampini   }
278863406b8SStefano Zampini 
2794cb006feSStefano Zampini   /* special case for AMS */
2804cb006feSStefano Zampini   if (jac->setup == HYPRE_AMSSetup) {
2815ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
2825ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
2836bf688a0SCe Qin     if (!jac->coords[0] && !jac->constants[0] && !(jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
2846bf688a0SCe Qin       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the edge constant vectors via PCHYPRESetEdgeConstantVectors() or the interpolation matrix via PCHYPRESetInterpolations");
2856bf688a0SCe Qin     }
2865ac14e1cSStefano Zampini     if (jac->dim) {
2875ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetDimension,(jac->hsolver,jac->dim));
2885ac14e1cSStefano Zampini     }
2895ac14e1cSStefano Zampini     if (jac->constants[0]) {
2905ac14e1cSStefano Zampini       HYPRE_ParVector ozz,zoz,zzo = NULL;
2915ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[0],(void**)(&ozz)));
2925ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[1],(void**)(&zoz)));
2935ac14e1cSStefano Zampini       if (jac->constants[2]) {
2945ac14e1cSStefano Zampini         PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->constants[2],(void**)(&zzo)));
2955ac14e1cSStefano Zampini       }
2965ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetEdgeConstantVectors,(jac->hsolver,ozz,zoz,zzo));
2975ac14e1cSStefano Zampini     }
2985ac14e1cSStefano Zampini     if (jac->coords[0]) {
2995ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
3005ac14e1cSStefano Zampini       coords[0] = NULL;
3015ac14e1cSStefano Zampini       coords[1] = NULL;
3025ac14e1cSStefano Zampini       coords[2] = NULL;
3035ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
3045ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
3055ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
3065ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
3075ac14e1cSStefano Zampini     }
30849a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
3095ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
3105ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3115ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetDiscreteGradient,(jac->hsolver,parcsr));
3125ac14e1cSStefano Zampini     if (jac->alpha_Poisson) {
3135ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->alpha_Poisson->data);
3145ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3155ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetAlphaPoissonMatrix,(jac->hsolver,parcsr));
3165ac14e1cSStefano Zampini     }
3175ac14e1cSStefano Zampini     if (jac->ams_beta_is_zero) {
3185ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,NULL));
3195ac14e1cSStefano Zampini     } else if (jac->beta_Poisson) {
3205ac14e1cSStefano Zampini       hm = (Mat_HYPRE*)(jac->beta_Poisson->data);
3215ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3225ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_AMSSetBetaPoissonMatrix,(jac->hsolver,parcsr));
3235ac14e1cSStefano Zampini     }
3246bf688a0SCe Qin     if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) {
3256bf688a0SCe Qin       PetscInt           i;
3266bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
3276bf688a0SCe Qin       if (jac->ND_PiFull) {
3286bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
3296bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
3306bf688a0SCe Qin       } else {
3316bf688a0SCe Qin         nd_parcsrfull = NULL;
3326bf688a0SCe Qin       }
3336bf688a0SCe Qin       for (i=0;i<3;++i) {
3346bf688a0SCe Qin         if (jac->ND_Pi[i]) {
3356bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
3366bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
3376bf688a0SCe Qin         } else {
3386bf688a0SCe Qin           nd_parcsr[i] = NULL;
3396bf688a0SCe Qin         }
3406bf688a0SCe Qin       }
3416bf688a0SCe Qin       PetscStackCallStandard(HYPRE_AMSSetInterpolations,(jac->hsolver,nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]));
3426bf688a0SCe Qin     }
3434cb006feSStefano Zampini   }
344863406b8SStefano Zampini   /* special case for ADS */
345863406b8SStefano Zampini   if (jac->setup == HYPRE_ADSSetup) {
3465ac14e1cSStefano Zampini     Mat_HYPRE          *hm;
3475ac14e1cSStefano Zampini     HYPRE_ParCSRMatrix parcsr;
3486bf688a0SCe Qin     if (!jac->coords[0] && !((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])))) {
3496bf688a0SCe Qin       SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations");
3506bf688a0SCe Qin     }
35137096e45SBarry 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");
35249a781f5SStefano Zampini     if (!jac->G) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
35349a781f5SStefano Zampini     if (!jac->C) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient");
3545ac14e1cSStefano Zampini     if (jac->coords[0]) {
3555ac14e1cSStefano Zampini       HYPRE_ParVector coords[3];
3565ac14e1cSStefano Zampini       coords[0] = NULL;
3575ac14e1cSStefano Zampini       coords[1] = NULL;
3585ac14e1cSStefano Zampini       coords[2] = NULL;
3595ac14e1cSStefano Zampini       if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[0],(void**)(&coords[0])));
3605ac14e1cSStefano Zampini       if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[1],(void**)(&coords[1])));
3615ac14e1cSStefano Zampini       if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorGetObject,(jac->coords[2],(void**)(&coords[2])));
3625ac14e1cSStefano Zampini       PetscStackCallStandard(HYPRE_ADSSetCoordinateVectors,(jac->hsolver,coords[0],coords[1],coords[2]));
3635ac14e1cSStefano Zampini     }
3645ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->G->data);
3655ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3665ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteGradient,(jac->hsolver,parcsr));
3675ac14e1cSStefano Zampini     hm = (Mat_HYPRE*)(jac->C->data);
3685ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&parcsr)));
3695ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetDiscreteCurl,(jac->hsolver,parcsr));
3706bf688a0SCe Qin     if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
3716bf688a0SCe Qin       PetscInt           i;
3726bf688a0SCe Qin       HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3];
3736bf688a0SCe Qin       HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
3746bf688a0SCe Qin       if (jac->RT_PiFull) {
3756bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->RT_PiFull->data);
3766bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsrfull)));
3776bf688a0SCe Qin       } else {
3786bf688a0SCe Qin         rt_parcsrfull = NULL;
3796bf688a0SCe Qin       }
3806bf688a0SCe Qin       for (i=0;i<3;++i) {
3816bf688a0SCe Qin         if (jac->RT_Pi[i]) {
3826bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->RT_Pi[i]->data);
3836bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&rt_parcsr[i])));
3846bf688a0SCe Qin         } else {
3856bf688a0SCe Qin           rt_parcsr[i] = NULL;
3866bf688a0SCe Qin         }
3876bf688a0SCe Qin       }
3886bf688a0SCe Qin       if (jac->ND_PiFull) {
3896bf688a0SCe Qin         hm = (Mat_HYPRE*)(jac->ND_PiFull->data);
3906bf688a0SCe Qin         PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsrfull)));
3916bf688a0SCe Qin       } else {
3926bf688a0SCe Qin         nd_parcsrfull = NULL;
3936bf688a0SCe Qin       }
3946bf688a0SCe Qin       for (i=0;i<3;++i) {
3956bf688a0SCe Qin         if (jac->ND_Pi[i]) {
3966bf688a0SCe Qin           hm = (Mat_HYPRE*)(jac->ND_Pi[i]->data);
3976bf688a0SCe Qin           PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hm->ij,(void**)(&nd_parcsr[i])));
3986bf688a0SCe Qin         } else {
3996bf688a0SCe Qin           nd_parcsr[i] = NULL;
4006bf688a0SCe Qin         }
4016bf688a0SCe Qin       }
4026bf688a0SCe Qin       PetscStackCallStandard(HYPRE_ADSSetInterpolations,(jac->hsolver,rt_parcsrfull,rt_parcsr[0],rt_parcsr[1],rt_parcsr[2],nd_parcsrfull,nd_parcsr[0],nd_parcsr[1],nd_parcsr[2]));
4036bf688a0SCe Qin     }
404863406b8SStefano Zampini   }
40549a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
40649a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&bv));
40749a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&xv));
40822e51d31SStefano Zampini   PetscStackCallStandard(jac->setup,(jac->hsolver,hmat,bv,xv));
40916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
41016d9e3a6SLisandro Dalcin }
41116d9e3a6SLisandro Dalcin 
41216d9e3a6SLisandro Dalcin static PetscErrorCode PCApply_HYPRE(PC pc,Vec b,Vec x)
41316d9e3a6SLisandro Dalcin {
41416d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
41549a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
41616d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
41716d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
41839accc25SStefano Zampini   HYPRE_Complex      *xv,*sxv;
41939accc25SStefano Zampini   HYPRE_Complex      *bv,*sbv;
42016d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
4214ddd07fcSJed Brown   PetscInt           hierr;
42216d9e3a6SLisandro Dalcin 
42316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
424dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
42516d9e3a6SLisandro Dalcin   if (!jac->applyrichardson) {ierr = VecSet(x,0.0);CHKERRQ(ierr);}
42639accc25SStefano Zampini   ierr = VecGetArrayRead(b,(const PetscScalar **)&bv);CHKERRQ(ierr);
42739accc25SStefano Zampini   ierr = VecGetArray(x,(PetscScalar **)&xv);CHKERRQ(ierr);
42839accc25SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,bv,sbv);
42958968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
43016d9e3a6SLisandro Dalcin 
43149a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
43249a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
43349a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
434fd3f9acdSBarry Smith   PetscStackCall("Hypre solve",hierr = (*jac->solve)(jac->hsolver,hmat,jbv,jxv);
43565e19b50SBarry Smith   if (hierr && hierr != HYPRE_ERROR_CONV) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
436fd3f9acdSBarry Smith   if (hierr) hypre__global_error = 0;);
43716d9e3a6SLisandro Dalcin 
43823df4f25SStefano Zampini   if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) {
4395ac14e1cSStefano Zampini     PetscStackCallStandard(HYPRE_AMSProjectOutGradients,(jac->hsolver,jxv));
44021df291bSStefano Zampini   }
44139accc25SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,sbv,bv);
44258968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
44339accc25SStefano Zampini   ierr = VecRestoreArray(x,(PetscScalar **)&xv);CHKERRQ(ierr);
44439accc25SStefano Zampini   ierr = VecRestoreArrayRead(b,(const PetscScalar **)&bv);CHKERRQ(ierr);
44516d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
44616d9e3a6SLisandro Dalcin }
44716d9e3a6SLisandro Dalcin 
4488695de01SBarry Smith static PetscErrorCode PCReset_HYPRE(PC pc)
4498695de01SBarry Smith {
4508695de01SBarry Smith   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
4518695de01SBarry Smith   PetscErrorCode ierr;
4528695de01SBarry Smith 
4538695de01SBarry Smith   PetscFunctionBegin;
45449a781f5SStefano Zampini   ierr = MatDestroy(&jac->hpmat);CHKERRQ(ierr);
4555ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
4565ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
4575ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
4585ac14e1cSStefano Zampini   ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
4596bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
4606bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[0]);CHKERRQ(ierr);
4616bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[1]);CHKERRQ(ierr);
4626bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_Pi[2]);CHKERRQ(ierr);
4636bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
4646bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[0]);CHKERRQ(ierr);
4656bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[1]);CHKERRQ(ierr);
4666bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_Pi[2]);CHKERRQ(ierr);
4678695de01SBarry Smith   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0])); jac->coords[0] = NULL;
4688695de01SBarry Smith   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1])); jac->coords[1] = NULL;
4698695de01SBarry Smith   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2])); jac->coords[2] = NULL;
4708695de01SBarry Smith   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0])); jac->constants[0] = NULL;
4718695de01SBarry Smith   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1])); jac->constants[1] = NULL;
4728695de01SBarry Smith   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2])); jac->constants[2] = NULL;
473ce6a8a0dSJed Brown   ierr = PCHYPREResetNearNullSpace_Private(pc);CHKERRQ(ierr);
4745ac14e1cSStefano Zampini   jac->ams_beta_is_zero = PETSC_FALSE;
4755ac14e1cSStefano Zampini   jac->dim = 0;
4768695de01SBarry Smith   PetscFunctionReturn(0);
4778695de01SBarry Smith }
4788695de01SBarry Smith 
47916d9e3a6SLisandro Dalcin static PetscErrorCode PCDestroy_HYPRE(PC pc)
48016d9e3a6SLisandro Dalcin {
48116d9e3a6SLisandro Dalcin   PC_HYPRE                 *jac = (PC_HYPRE*)pc->data;
48216d9e3a6SLisandro Dalcin   PetscErrorCode           ierr;
48316d9e3a6SLisandro Dalcin 
48416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
4858695de01SBarry Smith   ierr = PCReset_HYPRE(pc);CHKERRQ(ierr);
48622e51d31SStefano Zampini   if (jac->destroy) PetscStackCallStandard(jac->destroy,(jac->hsolver));
487503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
488ffc4695bSBarry Smith   if (jac->comm_hypre != MPI_COMM_NULL) {ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRMPI(ierr);}
489c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
49016d9e3a6SLisandro Dalcin 
49116d9e3a6SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr);
492bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",NULL);CHKERRQ(ierr);
493bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",NULL);CHKERRQ(ierr);
4944cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetCoordinates_C",NULL);CHKERRQ(ierr);
4954cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",NULL);CHKERRQ(ierr);
496863406b8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",NULL);CHKERRQ(ierr);
4976bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",NULL);CHKERRQ(ierr);
4984cb006feSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetConstantEdgeVectors_C",NULL);CHKERRQ(ierr);
4995ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",NULL);CHKERRQ(ierr);
500fd2dd295SFande Kong   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",NULL);CHKERRQ(ierr);
501fd2dd295SFande Kong   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",NULL);CHKERRQ(ierr);
50216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
50316d9e3a6SLisandro Dalcin }
50416d9e3a6SLisandro Dalcin 
50516d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
5064416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PetscOptionItems *PetscOptionsObject,PC pc)
50716d9e3a6SLisandro Dalcin {
50816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
50916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
510ace3abfcSBarry Smith   PetscBool      flag;
51116d9e3a6SLisandro Dalcin 
51216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
513e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Pilut Options");CHKERRQ(ierr);
51416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_maxiter","Number of iterations","None",jac->maxiter,&jac->maxiter,&flag);CHKERRQ(ierr);
515fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetMaxIter,(jac->hsolver,jac->maxiter));
51616d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_pilut_tol","Drop tolerance","None",jac->tol,&jac->tol,&flag);CHKERRQ(ierr);
517fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetDropTolerance,(jac->hsolver,jac->tol));
51816d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_pilut_factorrowsize","FactorRowSize","None",jac->factorrowsize,&jac->factorrowsize,&flag);CHKERRQ(ierr);
519fd3f9acdSBarry Smith   if (flag) PetscStackCallStandard(HYPRE_ParCSRPilutSetFactorRowSize,(jac->hsolver,jac->factorrowsize));
52016d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
52116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
52216d9e3a6SLisandro Dalcin }
52316d9e3a6SLisandro Dalcin 
52416d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)
52516d9e3a6SLisandro Dalcin {
52616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
52716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
528ace3abfcSBarry Smith   PetscBool      iascii;
52916d9e3a6SLisandro Dalcin 
53016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
531251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
53216d9e3a6SLisandro Dalcin   if (iascii) {
53316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Pilut preconditioning\n");CHKERRQ(ierr);
53416d9e3a6SLisandro Dalcin     if (jac->maxiter != PETSC_DEFAULT) {
535efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    maximum number of iterations %d\n",jac->maxiter);CHKERRQ(ierr);
53616d9e3a6SLisandro Dalcin     } else {
537efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default maximum number of iterations \n");CHKERRQ(ierr);
53816d9e3a6SLisandro Dalcin     }
53916d9e3a6SLisandro Dalcin     if (jac->tol != PETSC_DEFAULT) {
540efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->tol);CHKERRQ(ierr);
54116d9e3a6SLisandro Dalcin     } else {
542efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default drop tolerance \n");CHKERRQ(ierr);
54316d9e3a6SLisandro Dalcin     }
54416d9e3a6SLisandro Dalcin     if (jac->factorrowsize != PETSC_DEFAULT) {
545efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    factor row size %d\n",jac->factorrowsize);CHKERRQ(ierr);
54616d9e3a6SLisandro Dalcin     } else {
547efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    default factor row size \n");CHKERRQ(ierr);
54816d9e3a6SLisandro Dalcin     }
54916d9e3a6SLisandro Dalcin   }
55016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
55116d9e3a6SLisandro Dalcin }
55216d9e3a6SLisandro Dalcin 
55316d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
554db966c6cSHong Zhang static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PetscOptionItems *PetscOptionsObject,PC pc)
555db966c6cSHong Zhang {
556db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
557db966c6cSHong Zhang   PetscErrorCode ierr;
5588bf83915SBarry Smith   PetscBool      flag,eu_bj = jac->eu_bj ? PETSC_TRUE : PETSC_FALSE;
559db966c6cSHong Zhang 
560db966c6cSHong Zhang   PetscFunctionBegin;
561db966c6cSHong Zhang   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE Euclid Options");CHKERRQ(ierr);
562db966c6cSHong Zhang   ierr = PetscOptionsInt("-pc_hypre_euclid_level","Factorization levels","None",jac->eu_level,&jac->eu_level,&flag);CHKERRQ(ierr);
563db966c6cSHong Zhang   if (flag) PetscStackCallStandard(HYPRE_EuclidSetLevel,(jac->hsolver,jac->eu_level));
5648bf83915SBarry Smith 
5658bf83915SBarry Smith   ierr = PetscOptionsReal("-pc_hypre_euclid_droptolerance","Drop tolerance for ILU(k) in Euclid","None",jac->eu_droptolerance,&jac->eu_droptolerance,&flag);CHKERRQ(ierr);
5668bf83915SBarry Smith   if (flag){
5678bf83915SBarry Smith     PetscMPIInt size;
5688bf83915SBarry Smith 
569*55b25c41SPierre Jolivet     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRMPI(ierr);
5708bf83915SBarry Smith     if (size > 1) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"hypre's Euclid does not support a parallel drop tolerance");
5718bf83915SBarry Smith     PetscStackCallStandard(HYPRE_EuclidSetILUT,(jac->hsolver,jac->eu_droptolerance));
5728bf83915SBarry Smith   }
5738bf83915SBarry Smith 
5748bf83915SBarry Smith   ierr = PetscOptionsBool("-pc_hypre_euclid_bj", "Use Block Jacobi for ILU in Euclid", "None", eu_bj,&eu_bj,&flag);CHKERRQ(ierr);
5758bf83915SBarry Smith   if (flag) {
5768bf83915SBarry Smith     jac->eu_bj = eu_bj ? 1 : 0;
5778bf83915SBarry Smith     PetscStackCallStandard(HYPRE_EuclidSetBJ,(jac->hsolver,jac->eu_bj));
5788bf83915SBarry Smith   }
579db966c6cSHong Zhang   ierr = PetscOptionsTail();CHKERRQ(ierr);
580db966c6cSHong Zhang   PetscFunctionReturn(0);
581db966c6cSHong Zhang }
582db966c6cSHong Zhang 
583db966c6cSHong Zhang static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer)
584db966c6cSHong Zhang {
585db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
586db966c6cSHong Zhang   PetscErrorCode ierr;
587db966c6cSHong Zhang   PetscBool      iascii;
588db966c6cSHong Zhang 
589db966c6cSHong Zhang   PetscFunctionBegin;
590db966c6cSHong Zhang   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
591db966c6cSHong Zhang   if (iascii) {
592db966c6cSHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid preconditioning\n");CHKERRQ(ierr);
593db966c6cSHong Zhang     if (jac->eu_level != PETSC_DEFAULT) {
594db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    factorization levels %d\n",jac->eu_level);CHKERRQ(ierr);
595db966c6cSHong Zhang     } else {
596db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    default factorization levels \n");CHKERRQ(ierr);
597db966c6cSHong Zhang     }
5988bf83915SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    drop tolerance %g\n",(double)jac->eu_droptolerance);CHKERRQ(ierr);
5998bf83915SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    use Block-Jacobi? %D\n",jac->eu_bj);CHKERRQ(ierr);
600db966c6cSHong Zhang   }
601db966c6cSHong Zhang   PetscFunctionReturn(0);
602db966c6cSHong Zhang }
603db966c6cSHong Zhang 
604db966c6cSHong Zhang /* --------------------------------------------------------------------------------------------*/
60516d9e3a6SLisandro Dalcin 
60616d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
60716d9e3a6SLisandro Dalcin {
60816d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
60949a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
61016d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
61116d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
61239accc25SStefano Zampini   HYPRE_Complex      *xv,*bv;
61339accc25SStefano Zampini   HYPRE_Complex      *sbv,*sxv;
61416d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
6154ddd07fcSJed Brown   PetscInt           hierr;
61616d9e3a6SLisandro Dalcin 
61716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
618dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
61916d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
62039accc25SStefano Zampini   ierr = VecGetArrayRead(b,(const PetscScalar**)&bv);CHKERRQ(ierr);
62139accc25SStefano Zampini   ierr = VecGetArray(x,(PetscScalar**)&xv);CHKERRQ(ierr);
62239accc25SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,bv,sbv);
62358968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
62416d9e3a6SLisandro Dalcin 
62549a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
62649a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
62749a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
62816d9e3a6SLisandro Dalcin 
62916d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
63016d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
631e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
63216d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
63316d9e3a6SLisandro Dalcin 
63458968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,sbv,bv);
63558968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
63639accc25SStefano Zampini   ierr = VecRestoreArray(x,(PetscScalar**)&xv);CHKERRQ(ierr);
63739accc25SStefano Zampini   ierr = VecRestoreArrayRead(b,(const PetscScalar**)&bv);CHKERRQ(ierr);
63816d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
63916d9e3a6SLisandro Dalcin }
64016d9e3a6SLisandro Dalcin 
641a669f990SJed Brown /* static array length */
642a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
643a669f990SJed Brown 
64416d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
6450f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
64616d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
64765de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
6486a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]  = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
64965de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
65065de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
65165de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
6527b7fa87dSPierre Jolivet                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "l1-Gauss-Seidel" /* nonsymmetric */, "backward-l1-Gauss-Seidel" /* nonsymmetric */,
65365de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
6540f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
655e2287abbSStefano Zampini                                                   "ext+i-cc", "standard", "standard-wts", "block", "block-wtd", "FF", "FF1"};
6564416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc)
65716d9e3a6SLisandro Dalcin {
65816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
65916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
66022e51d31SStefano Zampini   PetscInt       bs,n,indx,level;
661ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
66216d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
66316d9e3a6SLisandro Dalcin 
66416d9e3a6SLisandro Dalcin   PetscFunctionBegin;
665e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
6664336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
66716d9e3a6SLisandro Dalcin   if (flg) {
6684336a9eeSBarry Smith     jac->cycletype = indx+1;
669fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
67016d9e3a6SLisandro Dalcin   }
67116d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
67216d9e3a6SLisandro Dalcin   if (flg) {
673ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
674fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
67516d9e3a6SLisandro Dalcin   }
67616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
67716d9e3a6SLisandro Dalcin   if (flg) {
678ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
679fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
68016d9e3a6SLisandro Dalcin   }
68139accc25SStefano Zampini   ierr = PetscOptionsReal("-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);
68216d9e3a6SLisandro Dalcin   if (flg) {
68357622a8eSBarry 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);
684fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
68516d9e3a6SLisandro Dalcin   }
68622e51d31SStefano Zampini   bs = 1;
68722e51d31SStefano Zampini   if (pc->pmat) {
68822e51d31SStefano Zampini     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
68922e51d31SStefano Zampini   }
69022e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_numfunctions","Number of functions","HYPRE_BoomerAMGSetNumFunctions",bs,&bs,&flg);CHKERRQ(ierr);
69122e51d31SStefano Zampini   if (flg) {
69222e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
69322e51d31SStefano Zampini   }
69416d9e3a6SLisandro Dalcin 
69539accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
69616d9e3a6SLisandro Dalcin   if (flg) {
69757622a8eSBarry 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);
698fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
69916d9e3a6SLisandro Dalcin   }
70016d9e3a6SLisandro Dalcin 
7010f1074feSSatish 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);
7020f1074feSSatish Balay   if (flg) {
70357622a8eSBarry 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);
704fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
7050f1074feSSatish Balay   }
7060f1074feSSatish Balay 
7070f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
7080f1074feSSatish Balay   if (flg) {
70957622a8eSBarry 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);
7100f1074feSSatish Balay 
711fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
7120f1074feSSatish Balay   }
7130f1074feSSatish Balay 
7140f1074feSSatish 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);
7150f1074feSSatish Balay   if (flg) {
71657622a8eSBarry 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);
7170f1074feSSatish Balay 
718fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
7190f1074feSSatish Balay   }
7200f1074feSSatish Balay 
7210f1074feSSatish Balay 
72239accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
72316d9e3a6SLisandro Dalcin   if (flg) {
72457622a8eSBarry 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);
725fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
72616d9e3a6SLisandro Dalcin   }
72739accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
72816d9e3a6SLisandro Dalcin   if (flg) {
72957622a8eSBarry 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);
73057622a8eSBarry 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);
731fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
73216d9e3a6SLisandro Dalcin   }
73316d9e3a6SLisandro Dalcin 
73416d9e3a6SLisandro Dalcin   /* Grid sweeps */
7350f1074feSSatish 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);
73616d9e3a6SLisandro Dalcin   if (flg) {
737fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
73816d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
73916d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
7400f1074feSSatish Balay     jac->gridsweeps[1] = indx;
7410f1074feSSatish Balay     /*defaults coarse to 1 */
7420f1074feSSatish Balay     jac->gridsweeps[2] = 1;
74316d9e3a6SLisandro Dalcin   }
7445272c319SBarry 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);
7455272c319SBarry Smith   if (flg) {
7465272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,jac->nodal_coarsening));
7475272c319SBarry Smith   }
74822e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_coarsen_diag","Diagonal in strength matrix for nodal based coarsening 0-2","HYPRE_BoomerAMGSetNodalDiag",jac->nodal_coarsening_diag,&jac->nodal_coarsening_diag,&flg);CHKERRQ(ierr);
74922e51d31SStefano Zampini   if (flg) {
75022e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNodalDiag,(jac->hsolver,jac->nodal_coarsening_diag));
75122e51d31SStefano Zampini   }
752cbc39033SBarry 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);
7535272c319SBarry Smith   if (flg) {
7545272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,(jac->hsolver,jac->vec_interp_variant));
7555272c319SBarry Smith   }
75622e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_vec_interp_qmax","Max elements per row for each Q","HYPRE_BoomerAMGSetInterpVecQMax",jac->vec_interp_qmax, &jac->vec_interp_qmax,&flg);CHKERRQ(ierr);
75722e51d31SStefano Zampini   if (flg) {
75822e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecQMax,(jac->hsolver,jac->vec_interp_qmax));
75922e51d31SStefano Zampini   }
76022e51d31SStefano Zampini   ierr = PetscOptionsBool("-pc_hypre_boomeramg_vec_interp_smooth","Whether to smooth the interpolation vectors","HYPRE_BoomerAMGSetSmoothInterpVectors",jac->vec_interp_smooth, &jac->vec_interp_smooth,&flg);CHKERRQ(ierr);
76122e51d31SStefano Zampini   if (flg) {
76222e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothInterpVectors,(jac->hsolver,jac->vec_interp_smooth));
76322e51d31SStefano Zampini   }
76422e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_interp_refine","Preprocess the interpolation matrix through iterative weight refinement","HYPRE_BoomerAMGSetInterpRefine",jac->interp_refine, &jac->interp_refine,&flg);CHKERRQ(ierr);
76522e51d31SStefano Zampini   if (flg) {
76622e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpRefine,(jac->hsolver,jac->interp_refine));
76722e51d31SStefano Zampini   }
7680f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
76916d9e3a6SLisandro Dalcin   if (flg) {
770fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
7710f1074feSSatish Balay     jac->gridsweeps[0] = indx;
77216d9e3a6SLisandro Dalcin   }
77316d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
77416d9e3a6SLisandro Dalcin   if (flg) {
775fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
7760f1074feSSatish Balay     jac->gridsweeps[1] = indx;
77716d9e3a6SLisandro Dalcin   }
7780f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
77916d9e3a6SLisandro Dalcin   if (flg) {
780fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
7810f1074feSSatish Balay     jac->gridsweeps[2] = indx;
78216d9e3a6SLisandro Dalcin   }
78316d9e3a6SLisandro Dalcin 
7846a251517SEike Mueller   /* Smooth type */
7856a251517SEike Mueller   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);
7866a251517SEike Mueller   if (flg) {
7876a251517SEike Mueller     jac->smoothtype = indx;
7886a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
7898131ecf7SEike Mueller     jac->smoothnumlevels = 25;
7908131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
7918131ecf7SEike Mueller   }
7928131ecf7SEike Mueller 
7938131ecf7SEike Mueller   /* Number of smoothing levels */
7948131ecf7SEike 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);
7958131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
7968131ecf7SEike Mueller     jac->smoothnumlevels = indx;
7978131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
7986a251517SEike Mueller   }
7996a251517SEike Mueller 
8001810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
8011810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
8021810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8031810e44eSEike Mueller     jac->eu_level = indx;
8041810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
8051810e44eSEike Mueller   }
8061810e44eSEike Mueller 
8071810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
8081810e44eSEike Mueller   double droptolerance;
80939accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
8101810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8111810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
8121810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
8131810e44eSEike Mueller   }
8141810e44eSEike Mueller 
8151810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
8161810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
8171810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8181810e44eSEike Mueller     jac->eu_bj = tmp_truth;
819493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
8201810e44eSEike Mueller   }
8211810e44eSEike Mueller 
82216d9e3a6SLisandro Dalcin   /* Relax type */
823a669f990SJed 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);
82416d9e3a6SLisandro Dalcin   if (flg) {
8250f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
826fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
8270f1074feSSatish Balay     /* by default, coarse type set to 9 */
8280f1074feSSatish Balay     jac->relaxtype[2] = 9;
829ddbeb582SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, 9, 3));
83016d9e3a6SLisandro Dalcin   }
831a669f990SJed 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);
83216d9e3a6SLisandro Dalcin   if (flg) {
83316d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
834fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
83516d9e3a6SLisandro Dalcin   }
836a669f990SJed 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);
83716d9e3a6SLisandro Dalcin   if (flg) {
8380f1074feSSatish Balay     jac->relaxtype[1] = indx;
839fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
84016d9e3a6SLisandro Dalcin   }
841a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
84216d9e3a6SLisandro Dalcin   if (flg) {
8430f1074feSSatish Balay     jac->relaxtype[2] = indx;
844fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
84516d9e3a6SLisandro Dalcin   }
84616d9e3a6SLisandro Dalcin 
84716d9e3a6SLisandro Dalcin   /* Relaxation Weight */
84816d9e3a6SLisandro 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);
84916d9e3a6SLisandro Dalcin   if (flg) {
850fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
85116d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
85216d9e3a6SLisandro Dalcin   }
85316d9e3a6SLisandro Dalcin 
85416d9e3a6SLisandro Dalcin   n         = 2;
85516d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
85616d9e3a6SLisandro 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);
85716d9e3a6SLisandro Dalcin   if (flg) {
85816d9e3a6SLisandro Dalcin     if (n == 2) {
85916d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
860fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
861ce94432eSBarry 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);
86216d9e3a6SLisandro Dalcin   }
86316d9e3a6SLisandro Dalcin 
86416d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
86516d9e3a6SLisandro 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);
86616d9e3a6SLisandro Dalcin   if (flg) {
867fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
86816d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
86916d9e3a6SLisandro Dalcin   }
87016d9e3a6SLisandro Dalcin 
87116d9e3a6SLisandro Dalcin   n         = 2;
87216d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
87316d9e3a6SLisandro 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);
87416d9e3a6SLisandro Dalcin   if (flg) {
87516d9e3a6SLisandro Dalcin     if (n == 2) {
87616d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
877fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
878ce94432eSBarry 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);
87916d9e3a6SLisandro Dalcin   }
88016d9e3a6SLisandro Dalcin 
88116d9e3a6SLisandro Dalcin   /* the Relax Order */
882acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
88316d9e3a6SLisandro Dalcin 
8848afaa268SBarry Smith   if (flg && tmp_truth) {
88516d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
886fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
88716d9e3a6SLisandro Dalcin   }
888a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
88916d9e3a6SLisandro Dalcin   if (flg) {
89016d9e3a6SLisandro Dalcin     jac->measuretype = indx;
891fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
89216d9e3a6SLisandro Dalcin   }
8930f1074feSSatish Balay   /* update list length 3/07 */
894a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
89516d9e3a6SLisandro Dalcin   if (flg) {
89616d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
897fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
89816d9e3a6SLisandro Dalcin   }
8990f1074feSSatish Balay 
9000f1074feSSatish Balay   /* new 3/07 */
901a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
9020f1074feSSatish Balay   if (flg) {
9030f1074feSSatish Balay     jac->interptype = indx;
904fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
9050f1074feSSatish Balay   }
9060f1074feSSatish Balay 
907b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
90816d9e3a6SLisandro Dalcin   if (flg) {
909b96a4a96SBarry Smith     level = 3;
9100298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
9112fa5cd67SKarl Rupp 
912b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
913fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
9142ae77aedSBarry Smith   }
9152ae77aedSBarry Smith 
916b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
9172ae77aedSBarry Smith   if (flg) {
918b96a4a96SBarry Smith     level = 3;
9190298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
9202fa5cd67SKarl Rupp 
921b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
922fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
92316d9e3a6SLisandro Dalcin   }
9248f87f92bSBarry Smith 
925acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
9268f87f92bSBarry Smith   if (flg && tmp_truth) {
9278f87f92bSBarry Smith     PetscInt tmp_int;
9288f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
9298f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
930fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
931fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
932fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
933fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
9348f87f92bSBarry Smith   }
9358f87f92bSBarry Smith 
93616d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
93716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
93816d9e3a6SLisandro Dalcin }
93916d9e3a6SLisandro Dalcin 
940ace3abfcSBarry 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)
94116d9e3a6SLisandro Dalcin {
94216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
94316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
9442cf14000SStefano Zampini   HYPRE_Int      oits;
94516d9e3a6SLisandro Dalcin 
94616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
947dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
948fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
949fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
95016d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
95116d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
95216d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
9532cf14000SStefano Zampini   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,&oits));
9544d0a8057SBarry Smith   *outits = oits;
9554d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
9564d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
957fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
958fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
95916d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
96016d9e3a6SLisandro Dalcin }
96116d9e3a6SLisandro Dalcin 
96216d9e3a6SLisandro Dalcin 
96316d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
96416d9e3a6SLisandro Dalcin {
96516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
96616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
967ace3abfcSBarry Smith   PetscBool      iascii;
96816d9e3a6SLisandro Dalcin 
96916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
970251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
97116d9e3a6SLisandro Dalcin   if (iascii) {
97216d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
973efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
97422e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of levels %D\n",jac->maxlevels);CHKERRQ(ierr);
97522e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of iterations PER hypre call %D\n",jac->maxiter);CHKERRQ(ierr);
976efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
977efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
978efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
97922e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: max elements per row %D\n",jac->pmax);CHKERRQ(ierr);
98022e51d31SStefano Zampini     if (jac->interp_refine) {
98122e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: number of steps of weighted refinement %D\n",jac->interp_refine);CHKERRQ(ierr);
98222e51d31SStefano Zampini     }
98322e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of levels of aggressive coarsening %D\n",jac->agg_nl);CHKERRQ(ierr);
98422e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of paths for aggressive coarsening %D\n",jac->agg_num_paths);CHKERRQ(ierr);
9850f1074feSSatish Balay 
986efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
98716d9e3a6SLisandro Dalcin 
98822e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps down         %D\n",jac->gridsweeps[0]);CHKERRQ(ierr);
98922e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps up           %D\n",jac->gridsweeps[1]);CHKERRQ(ierr);
99022e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps on coarse    %D\n",jac->gridsweeps[2]);CHKERRQ(ierr);
99116d9e3a6SLisandro Dalcin 
992efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
993efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
994efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
99516d9e3a6SLisandro Dalcin 
996efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
997efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
99816d9e3a6SLisandro Dalcin 
99916d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
1000efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using CF-relaxation\n");CHKERRQ(ierr);
100116d9e3a6SLisandro Dalcin     } else {
1002efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using CF-relaxation\n");CHKERRQ(ierr);
100316d9e3a6SLisandro Dalcin     }
10046a251517SEike Mueller     if (jac->smoothtype!=-1) {
1005efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
100622e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth num levels    %D\n",jac->smoothnumlevels);CHKERRQ(ierr);
10077e352d70SEike Mueller     } else {
1008efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using more complex smoothers.\n");CHKERRQ(ierr);
10091810e44eSEike Mueller     }
10101810e44eSEike Mueller     if (jac->smoothtype==3) {
101122e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) levels %D\n",jac->eu_level);CHKERRQ(ierr);
101222e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) drop tolerance %g\n",(double)jac->eu_droptolerance);CHKERRQ(ierr);
101322e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU use Block-Jacobi? %D\n",jac->eu_bj);CHKERRQ(ierr);
10146a251517SEike Mueller     }
1015efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
1016efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
1017efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
10185272c319SBarry Smith     if (jac->nodal_coarsening) {
1019efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
10205272c319SBarry Smith     }
10215272c319SBarry Smith     if (jac->vec_interp_variant) {
1022efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
102322e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecQMax() %D\n",jac->vec_interp_qmax);CHKERRQ(ierr);
102422e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n",jac->vec_interp_smooth);CHKERRQ(ierr);
10258f87f92bSBarry Smith     }
10268f87f92bSBarry Smith     if (jac->nodal_relax) {
102722e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal relaxation via Schwarz smoothing on levels %D\n",jac->nodal_relax_levels);CHKERRQ(ierr);
10288f87f92bSBarry Smith     }
102916d9e3a6SLisandro Dalcin   }
103016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
103116d9e3a6SLisandro Dalcin }
103216d9e3a6SLisandro Dalcin 
103316d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
10344416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc)
103516d9e3a6SLisandro Dalcin {
103616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
103716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
10384ddd07fcSJed Brown   PetscInt       indx;
1039ace3abfcSBarry Smith   PetscBool      flag;
104016d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
104116d9e3a6SLisandro Dalcin 
104216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1043e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
104416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
10458966356dSPierre Jolivet   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshold,&jac->threshold,&flag);CHKERRQ(ierr);
10468966356dSPierre Jolivet   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshold,jac->nlevels));
104716d9e3a6SLisandro Dalcin 
104816d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
10492fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
105016d9e3a6SLisandro Dalcin 
105116d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
10522fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
105316d9e3a6SLisandro Dalcin 
1054acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
10552fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
105616d9e3a6SLisandro Dalcin 
1057acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
10582fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
105916d9e3a6SLisandro Dalcin 
1060a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
106116d9e3a6SLisandro Dalcin   if (flag) {
106216d9e3a6SLisandro Dalcin     jac->symt = indx;
1063fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
106416d9e3a6SLisandro Dalcin   }
106516d9e3a6SLisandro Dalcin 
106616d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
106716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
106816d9e3a6SLisandro Dalcin }
106916d9e3a6SLisandro Dalcin 
107016d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
107116d9e3a6SLisandro Dalcin {
107216d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
107316d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1074ace3abfcSBarry Smith   PetscBool      iascii;
1075feb237baSPierre Jolivet   const char     *symt = 0;
107616d9e3a6SLisandro Dalcin 
107716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1078251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
107916d9e3a6SLisandro Dalcin   if (iascii) {
108016d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
1081efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
10828966356dSPierre Jolivet     ierr = PetscViewerASCIIPrintf(viewer,"    threshold %g\n",(double)jac->threshold);CHKERRQ(ierr);
1083efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    filter %g\n",(double)jac->filter);CHKERRQ(ierr);
1084efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
1085efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
1086efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
10872fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
10882fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
10892fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
1090ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
1091efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    %s\n",symt);CHKERRQ(ierr);
109216d9e3a6SLisandro Dalcin   }
109316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
109416d9e3a6SLisandro Dalcin }
10954cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
10964416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc)
10974cb006feSStefano Zampini {
10984cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
10994cb006feSStefano Zampini   PetscErrorCode ierr;
11004cb006feSStefano Zampini   PetscInt       n;
11014cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
11024cb006feSStefano Zampini 
11034cb006feSStefano Zampini   PetscFunctionBegin;
11049fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
1105863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1106863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1107863406b8SStefano 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);
1108863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
11094cb006feSStefano 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);
11104cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1111863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1112863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1113863406b8SStefano 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);
1114863406b8SStefano 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);
1115863406b8SStefano 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);
1116863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
11174cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1118863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1119863406b8SStefano Zampini                                                                       jac->as_relax_times,
1120863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1121863406b8SStefano Zampini                                                                       jac->as_omega));
11224cb006feSStefano Zampini   }
1123863406b8SStefano 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);
11244cb006feSStefano Zampini   n = 5;
1125863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
11264cb006feSStefano Zampini   if (flag || flag2) {
1127863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1128863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1129863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1130863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1131863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1132863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
11334cb006feSStefano Zampini   }
1134863406b8SStefano 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);
11354cb006feSStefano Zampini   n = 5;
1136863406b8SStefano 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);
11374cb006feSStefano Zampini   if (flag || flag2) {
1138863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1139863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1140863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1141863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1142863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1143863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
11444cb006feSStefano Zampini   }
114523df4f25SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_projection_frequency","Frequency at which a projection onto the compatible subspace for problems with zero conductivity regions is performed","None",jac->ams_proj_freq,&jac->ams_proj_freq,&flag);CHKERRQ(ierr);
114623df4f25SStefano Zampini   if (flag) { /* override HYPRE's default only if the options is used */
114723df4f25SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetProjectionFrequency,(jac->hsolver,jac->ams_proj_freq));
114823df4f25SStefano Zampini   }
11494cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
11504cb006feSStefano Zampini   PetscFunctionReturn(0);
11514cb006feSStefano Zampini }
11524cb006feSStefano Zampini 
11534cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
11544cb006feSStefano Zampini {
11554cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
11564cb006feSStefano Zampini   PetscErrorCode ierr;
11574cb006feSStefano Zampini   PetscBool      iascii;
11584cb006feSStefano Zampini 
11594cb006feSStefano Zampini   PetscFunctionBegin;
11604cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
11614cb006feSStefano Zampini   if (iascii) {
11624cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
1163efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1164efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1165efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1166efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1167efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1168efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1169efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
11704cb006feSStefano Zampini     if (jac->alpha_Poisson) {
1171efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
11724cb006feSStefano Zampini     } else {
1173efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (computed) \n");CHKERRQ(ierr);
11744cb006feSStefano Zampini     }
1175efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1176efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1177efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1178efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1179efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1180efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
11814cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
11824cb006feSStefano Zampini       if (jac->beta_Poisson) {
1183efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
11844cb006feSStefano Zampini       } else {
1185efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (computed) \n");CHKERRQ(ierr);
11864cb006feSStefano Zampini       }
1187efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1188efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1189efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1190efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1191efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1192efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
119323df4f25SStefano Zampini       if (jac->ams_beta_is_zero_part) {
1194efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"        compatible subspace projection frequency %d (-1 HYPRE uses default)\n",jac->ams_proj_freq);CHKERRQ(ierr);
119523df4f25SStefano Zampini       }
119623df4f25SStefano Zampini     } else {
1197efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver not used (zero-conductivity everywhere) \n");CHKERRQ(ierr);
11984cb006feSStefano Zampini     }
11994cb006feSStefano Zampini   }
12004cb006feSStefano Zampini   PetscFunctionReturn(0);
12014cb006feSStefano Zampini }
12024cb006feSStefano Zampini 
12034416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc)
1204863406b8SStefano Zampini {
1205863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1206863406b8SStefano Zampini   PetscErrorCode ierr;
1207863406b8SStefano Zampini   PetscInt       n;
1208863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
1209863406b8SStefano Zampini 
1210863406b8SStefano Zampini   PetscFunctionBegin;
1211863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
1212863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1213863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1214863406b8SStefano 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);
1215863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1216863406b8SStefano 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);
1217863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
1218863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1219863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1220863406b8SStefano 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);
1221863406b8SStefano 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);
1222863406b8SStefano 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);
1223863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
1224863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1225863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1226863406b8SStefano Zampini                                                                       jac->as_relax_times,
1227863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1228863406b8SStefano Zampini                                                                       jac->as_omega));
1229863406b8SStefano Zampini   }
1230863406b8SStefano 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);
1231863406b8SStefano Zampini   n = 5;
1232863406b8SStefano 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);
1233863406b8SStefano 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);
1234863406b8SStefano Zampini   if (flag || flag2 || flag3) {
1235863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
1236863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1237863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1238863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1239863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1240863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1241863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1242863406b8SStefano Zampini   }
1243863406b8SStefano 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);
1244863406b8SStefano Zampini   n = 5;
1245863406b8SStefano 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);
1246863406b8SStefano Zampini   if (flag || flag2) {
1247863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1248863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1249863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1250863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1251863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1252863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1253863406b8SStefano Zampini   }
1254863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
1255863406b8SStefano Zampini   PetscFunctionReturn(0);
1256863406b8SStefano Zampini }
1257863406b8SStefano Zampini 
1258863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1259863406b8SStefano Zampini {
1260863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1261863406b8SStefano Zampini   PetscErrorCode ierr;
1262863406b8SStefano Zampini   PetscBool      iascii;
1263863406b8SStefano Zampini 
1264863406b8SStefano Zampini   PetscFunctionBegin;
1265863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1266863406b8SStefano Zampini   if (iascii) {
1267863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
1268efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1269efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
1270efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1271efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1272efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1273efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1274efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
1275efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    AMS solver using boomerAMG\n");CHKERRQ(ierr);
1276efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1277efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1278efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1279efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1280efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1281efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1282efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
1283efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver using boomerAMG\n");CHKERRQ(ierr);
1284efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1285efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1286efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1287efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1288efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1289efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
1290863406b8SStefano Zampini   }
1291863406b8SStefano Zampini   PetscFunctionReturn(0);
1292863406b8SStefano Zampini }
1293863406b8SStefano Zampini 
1294863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
12954cb006feSStefano Zampini {
12964cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12975ac14e1cSStefano Zampini   PetscBool      ishypre;
12984cb006feSStefano Zampini   PetscErrorCode ierr;
12994cb006feSStefano Zampini 
13004cb006feSStefano Zampini   PetscFunctionBegin;
13015ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)G,MATHYPRE,&ishypre);CHKERRQ(ierr);
13025ac14e1cSStefano Zampini   if (ishypre) {
13035ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr);
13045ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
13055ac14e1cSStefano Zampini     jac->G = G;
13065ac14e1cSStefano Zampini   } else {
13076bf688a0SCe Qin     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
13086bf688a0SCe Qin     ierr = MatConvert(G,MATHYPRE,MAT_INITIAL_MATRIX,&jac->G);CHKERRQ(ierr);
13095ac14e1cSStefano Zampini   }
13104cb006feSStefano Zampini   PetscFunctionReturn(0);
13114cb006feSStefano Zampini }
13124cb006feSStefano Zampini 
13134cb006feSStefano Zampini /*@
13144cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
13154cb006feSStefano Zampini 
13164cb006feSStefano Zampini    Collective on PC
13174cb006feSStefano Zampini 
13184cb006feSStefano Zampini    Input Parameters:
13194cb006feSStefano Zampini +  pc - the preconditioning context
13204cb006feSStefano Zampini -  G - the discrete gradient
13214cb006feSStefano Zampini 
13224cb006feSStefano Zampini    Level: intermediate
13234cb006feSStefano Zampini 
132495452b02SPatrick Sanan    Notes:
132595452b02SPatrick Sanan     G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh
1326863406b8SStefano 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
13274cb006feSStefano Zampini 
13284cb006feSStefano Zampini .seealso:
13294cb006feSStefano Zampini @*/
13304cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
13314cb006feSStefano Zampini {
13324cb006feSStefano Zampini   PetscErrorCode ierr;
13334cb006feSStefano Zampini 
13344cb006feSStefano Zampini   PetscFunctionBegin;
13354cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
13364cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
13374cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
13384cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
13394cb006feSStefano Zampini   PetscFunctionReturn(0);
13404cb006feSStefano Zampini }
13414cb006feSStefano Zampini 
1342863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1343863406b8SStefano Zampini {
1344863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
13455ac14e1cSStefano Zampini   PetscBool      ishypre;
1346863406b8SStefano Zampini   PetscErrorCode ierr;
1347863406b8SStefano Zampini 
1348863406b8SStefano Zampini   PetscFunctionBegin;
13495ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)C,MATHYPRE,&ishypre);CHKERRQ(ierr);
13505ac14e1cSStefano Zampini   if (ishypre) {
13515ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr);
13525ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
13535ac14e1cSStefano Zampini     jac->C = C;
13545ac14e1cSStefano Zampini   } else {
13556bf688a0SCe Qin     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
13566bf688a0SCe Qin     ierr = MatConvert(C,MATHYPRE,MAT_INITIAL_MATRIX,&jac->C);CHKERRQ(ierr);
13575ac14e1cSStefano Zampini   }
1358863406b8SStefano Zampini   PetscFunctionReturn(0);
1359863406b8SStefano Zampini }
1360863406b8SStefano Zampini 
1361863406b8SStefano Zampini /*@
1362863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1363863406b8SStefano Zampini 
1364863406b8SStefano Zampini    Collective on PC
1365863406b8SStefano Zampini 
1366863406b8SStefano Zampini    Input Parameters:
1367863406b8SStefano Zampini +  pc - the preconditioning context
1368863406b8SStefano Zampini -  C - the discrete curl
1369863406b8SStefano Zampini 
1370863406b8SStefano Zampini    Level: intermediate
1371863406b8SStefano Zampini 
137295452b02SPatrick Sanan    Notes:
137395452b02SPatrick Sanan     C should have as many rows as the number of faces and as many columns as the number of edges in the mesh
1374863406b8SStefano 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
1375863406b8SStefano Zampini 
1376863406b8SStefano Zampini .seealso:
1377863406b8SStefano Zampini @*/
1378863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1379863406b8SStefano Zampini {
1380863406b8SStefano Zampini   PetscErrorCode ierr;
1381863406b8SStefano Zampini 
1382863406b8SStefano Zampini   PetscFunctionBegin;
1383863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1384863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1385863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1386863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1387863406b8SStefano Zampini   PetscFunctionReturn(0);
1388863406b8SStefano Zampini }
1389863406b8SStefano Zampini 
13906bf688a0SCe Qin static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
13916bf688a0SCe Qin {
13926bf688a0SCe Qin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
13936bf688a0SCe Qin   PetscBool      ishypre;
13946bf688a0SCe Qin   PetscErrorCode ierr;
13956bf688a0SCe Qin   PetscInt       i;
13966bf688a0SCe Qin   PetscFunctionBegin;
13976bf688a0SCe Qin 
13986bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
13996bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
14006bf688a0SCe Qin   for (i=0;i<3;++i) {
14016bf688a0SCe Qin     ierr = MatDestroy(&jac->RT_Pi[i]);CHKERRQ(ierr);
14026bf688a0SCe Qin     ierr = MatDestroy(&jac->ND_Pi[i]);CHKERRQ(ierr);
14036bf688a0SCe Qin   }
14046bf688a0SCe Qin 
14056bf688a0SCe Qin   jac->dim = dim;
14066bf688a0SCe Qin   if (RT_PiFull) {
14076bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)RT_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
14086bf688a0SCe Qin     if (ishypre) {
14096bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)RT_PiFull);CHKERRQ(ierr);
14106bf688a0SCe Qin       jac->RT_PiFull = RT_PiFull;
14116bf688a0SCe Qin     } else {
14126bf688a0SCe Qin       ierr = MatConvert(RT_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_PiFull);CHKERRQ(ierr);
14136bf688a0SCe Qin     }
14146bf688a0SCe Qin   }
14156bf688a0SCe Qin   if (RT_Pi) {
14166bf688a0SCe Qin     for (i=0;i<dim;++i) {
14176bf688a0SCe Qin       if (RT_Pi[i]) {
14186bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)RT_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
14196bf688a0SCe Qin         if (ishypre) {
14206bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)RT_Pi[i]);CHKERRQ(ierr);
14216bf688a0SCe Qin           jac->RT_Pi[i] = RT_Pi[i];
14226bf688a0SCe Qin         } else {
14236bf688a0SCe Qin           ierr = MatConvert(RT_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_Pi[i]);CHKERRQ(ierr);
14246bf688a0SCe Qin         }
14256bf688a0SCe Qin       }
14266bf688a0SCe Qin     }
14276bf688a0SCe Qin   }
14286bf688a0SCe Qin   if (ND_PiFull) {
14296bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)ND_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
14306bf688a0SCe Qin     if (ishypre) {
14316bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)ND_PiFull);CHKERRQ(ierr);
14326bf688a0SCe Qin       jac->ND_PiFull = ND_PiFull;
14336bf688a0SCe Qin     } else {
14346bf688a0SCe Qin       ierr = MatConvert(ND_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_PiFull);CHKERRQ(ierr);
14356bf688a0SCe Qin     }
14366bf688a0SCe Qin   }
14376bf688a0SCe Qin   if (ND_Pi) {
14386bf688a0SCe Qin     for (i=0;i<dim;++i) {
14396bf688a0SCe Qin       if (ND_Pi[i]) {
14406bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)ND_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
14416bf688a0SCe Qin         if (ishypre) {
14426bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)ND_Pi[i]);CHKERRQ(ierr);
14436bf688a0SCe Qin           jac->ND_Pi[i] = ND_Pi[i];
14446bf688a0SCe Qin         } else {
14456bf688a0SCe Qin           ierr = MatConvert(ND_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_Pi[i]);CHKERRQ(ierr);
14466bf688a0SCe Qin         }
14476bf688a0SCe Qin       }
14486bf688a0SCe Qin     }
14496bf688a0SCe Qin   }
14506bf688a0SCe Qin 
14516bf688a0SCe Qin   PetscFunctionReturn(0);
14526bf688a0SCe Qin }
14536bf688a0SCe Qin 
14546bf688a0SCe Qin /*@
14556bf688a0SCe Qin  PCHYPRESetInterpolations - Set interpolation matrices for AMS/ADS preconditioner
14566bf688a0SCe Qin 
14576bf688a0SCe Qin    Collective on PC
14586bf688a0SCe Qin 
14596bf688a0SCe Qin    Input Parameters:
14606bf688a0SCe Qin +  pc - the preconditioning context
14616bf688a0SCe Qin -  dim - the dimension of the problem, only used in AMS
14626bf688a0SCe Qin -  RT_PiFull - Raviart-Thomas interpolation matrix
14636bf688a0SCe Qin -  RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix
14646bf688a0SCe Qin -  ND_PiFull - Nedelec interpolation matrix
14656bf688a0SCe Qin -  ND_Pi - x/y/z component of Nedelec interpolation matrix
14666bf688a0SCe Qin 
146795452b02SPatrick Sanan    Notes:
146895452b02SPatrick Sanan     For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL.
14696bf688a0SCe Qin           For ADS, both type of interpolation matrices are needed.
14706bf688a0SCe Qin    Level: intermediate
14716bf688a0SCe Qin 
14726bf688a0SCe Qin .seealso:
14736bf688a0SCe Qin @*/
14746bf688a0SCe Qin PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
14756bf688a0SCe Qin {
14766bf688a0SCe Qin   PetscErrorCode ierr;
14776bf688a0SCe Qin   PetscInt       i;
14786bf688a0SCe Qin 
14796bf688a0SCe Qin   PetscFunctionBegin;
14806bf688a0SCe Qin   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
14816bf688a0SCe Qin   if (RT_PiFull) {
14826bf688a0SCe Qin     PetscValidHeaderSpecific(RT_PiFull,MAT_CLASSID,3);
14836bf688a0SCe Qin     PetscCheckSameComm(pc,1,RT_PiFull,3);
14846bf688a0SCe Qin   }
14856bf688a0SCe Qin   if (RT_Pi) {
14866bf688a0SCe Qin     PetscValidPointer(RT_Pi,4);
14876bf688a0SCe Qin     for (i=0;i<dim;++i) {
14886bf688a0SCe Qin       if (RT_Pi[i]) {
14896bf688a0SCe Qin         PetscValidHeaderSpecific(RT_Pi[i],MAT_CLASSID,4);
14906bf688a0SCe Qin         PetscCheckSameComm(pc,1,RT_Pi[i],4);
14916bf688a0SCe Qin       }
14926bf688a0SCe Qin     }
14936bf688a0SCe Qin   }
14946bf688a0SCe Qin   if (ND_PiFull) {
14956bf688a0SCe Qin     PetscValidHeaderSpecific(ND_PiFull,MAT_CLASSID,5);
14966bf688a0SCe Qin     PetscCheckSameComm(pc,1,ND_PiFull,5);
14976bf688a0SCe Qin   }
14986bf688a0SCe Qin   if (ND_Pi) {
14996bf688a0SCe Qin     PetscValidPointer(ND_Pi,6);
15006bf688a0SCe Qin     for (i=0;i<dim;++i) {
15016bf688a0SCe Qin       if (ND_Pi[i]) {
15026bf688a0SCe Qin         PetscValidHeaderSpecific(ND_Pi[i],MAT_CLASSID,6);
15036bf688a0SCe Qin         PetscCheckSameComm(pc,1,ND_Pi[i],6);
15046bf688a0SCe Qin       }
15056bf688a0SCe Qin     }
15066bf688a0SCe Qin   }
15076bf688a0SCe Qin   ierr = PetscTryMethod(pc,"PCHYPRESetInterpolations_C",(PC,PetscInt,Mat,Mat[],Mat,Mat[]),(pc,dim,RT_PiFull,RT_Pi,ND_PiFull,ND_Pi));CHKERRQ(ierr);
15086bf688a0SCe Qin   PetscFunctionReturn(0);
15096bf688a0SCe Qin }
15106bf688a0SCe Qin 
15115ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha)
15124cb006feSStefano Zampini {
15134cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
15145ac14e1cSStefano Zampini   PetscBool      ishypre;
15154cb006feSStefano Zampini   PetscErrorCode ierr;
15164cb006feSStefano Zampini 
15174cb006feSStefano Zampini   PetscFunctionBegin;
15185ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr);
15195ac14e1cSStefano Zampini   if (ishypre) {
15205ac14e1cSStefano Zampini     if (isalpha) {
15215ac14e1cSStefano Zampini       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
15225ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
15235ac14e1cSStefano Zampini       jac->alpha_Poisson = A;
15245ac14e1cSStefano Zampini     } else {
15255ac14e1cSStefano Zampini       if (A) {
15265ac14e1cSStefano Zampini         ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
15275ac14e1cSStefano Zampini       } else {
15285ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
15295ac14e1cSStefano Zampini       }
15305ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
15315ac14e1cSStefano Zampini       jac->beta_Poisson = A;
15325ac14e1cSStefano Zampini     }
15335ac14e1cSStefano Zampini   } else {
15345ac14e1cSStefano Zampini     if (isalpha) {
15356bf688a0SCe Qin       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
15366bf688a0SCe Qin       ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->alpha_Poisson);CHKERRQ(ierr);
15375ac14e1cSStefano Zampini     } else {
15385ac14e1cSStefano Zampini       if (A) {
15396bf688a0SCe Qin         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
15406bf688a0SCe Qin         ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->beta_Poisson);CHKERRQ(ierr);
15415ac14e1cSStefano Zampini       } else {
15425ac14e1cSStefano Zampini         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
15435ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
15445ac14e1cSStefano Zampini       }
15455ac14e1cSStefano Zampini     }
15465ac14e1cSStefano Zampini   }
15474cb006feSStefano Zampini   PetscFunctionReturn(0);
15484cb006feSStefano Zampini }
15494cb006feSStefano Zampini 
15504cb006feSStefano Zampini /*@
15514cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
15524cb006feSStefano Zampini 
15534cb006feSStefano Zampini    Collective on PC
15544cb006feSStefano Zampini 
15554cb006feSStefano Zampini    Input Parameters:
15564cb006feSStefano Zampini +  pc - the preconditioning context
15574cb006feSStefano Zampini -  A - the matrix
15584cb006feSStefano Zampini 
15594cb006feSStefano Zampini    Level: intermediate
15604cb006feSStefano Zampini 
156195452b02SPatrick Sanan    Notes:
156295452b02SPatrick Sanan     A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
15634cb006feSStefano Zampini 
15644cb006feSStefano Zampini .seealso:
15654cb006feSStefano Zampini @*/
15664cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
15674cb006feSStefano Zampini {
15684cb006feSStefano Zampini   PetscErrorCode ierr;
15694cb006feSStefano Zampini 
15704cb006feSStefano Zampini   PetscFunctionBegin;
15714cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15724cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
15734cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
15745ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_TRUE));CHKERRQ(ierr);
15754cb006feSStefano Zampini   PetscFunctionReturn(0);
15764cb006feSStefano Zampini }
15774cb006feSStefano Zampini 
15784cb006feSStefano Zampini /*@
15794cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
15804cb006feSStefano Zampini 
15814cb006feSStefano Zampini    Collective on PC
15824cb006feSStefano Zampini 
15834cb006feSStefano Zampini    Input Parameters:
15844cb006feSStefano Zampini +  pc - the preconditioning context
15854cb006feSStefano Zampini -  A - the matrix
15864cb006feSStefano Zampini 
15874cb006feSStefano Zampini    Level: intermediate
15884cb006feSStefano Zampini 
158995452b02SPatrick Sanan    Notes:
159095452b02SPatrick Sanan     A should be obtained by discretizing the Poisson problem with linear finite elements.
15914cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
15924cb006feSStefano Zampini 
15934cb006feSStefano Zampini .seealso:
15944cb006feSStefano Zampini @*/
15954cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
15964cb006feSStefano Zampini {
15974cb006feSStefano Zampini   PetscErrorCode ierr;
15984cb006feSStefano Zampini 
15994cb006feSStefano Zampini   PetscFunctionBegin;
16004cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
16014cb006feSStefano Zampini   if (A) {
16024cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
16034cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
16044cb006feSStefano Zampini   }
16055ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_FALSE));CHKERRQ(ierr);
16064cb006feSStefano Zampini   PetscFunctionReturn(0);
16074cb006feSStefano Zampini }
16084cb006feSStefano Zampini 
16095ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz, Vec zoz, Vec zzo)
16104cb006feSStefano Zampini {
16114cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
16124cb006feSStefano Zampini   PetscErrorCode     ierr;
16134cb006feSStefano Zampini 
16144cb006feSStefano Zampini   PetscFunctionBegin;
16154cb006feSStefano Zampini   /* throw away any vector if already set */
16164cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
16174cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
16184cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
16194cb006feSStefano Zampini   jac->constants[0] = NULL;
16204cb006feSStefano Zampini   jac->constants[1] = NULL;
16214cb006feSStefano Zampini   jac->constants[2] = NULL;
16224cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
16234cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
16244cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
16254cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
16265ac14e1cSStefano Zampini   jac->dim = 2;
16274cb006feSStefano Zampini   if (zzo) {
16284cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
16294cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
16305ac14e1cSStefano Zampini     jac->dim++;
16314cb006feSStefano Zampini   }
16324cb006feSStefano Zampini   PetscFunctionReturn(0);
16334cb006feSStefano Zampini }
16344cb006feSStefano Zampini 
16354cb006feSStefano Zampini /*@
16364cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
16374cb006feSStefano Zampini 
16384cb006feSStefano Zampini    Collective on PC
16394cb006feSStefano Zampini 
16404cb006feSStefano Zampini    Input Parameters:
16414cb006feSStefano Zampini +  pc - the preconditioning context
16424cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
16434cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
16444cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
16454cb006feSStefano Zampini 
16464cb006feSStefano Zampini    Level: intermediate
16474cb006feSStefano Zampini 
16484cb006feSStefano Zampini    Notes:
16494cb006feSStefano Zampini 
16504cb006feSStefano Zampini .seealso:
16514cb006feSStefano Zampini @*/
16524cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
16534cb006feSStefano Zampini {
16544cb006feSStefano Zampini   PetscErrorCode ierr;
16554cb006feSStefano Zampini 
16564cb006feSStefano Zampini   PetscFunctionBegin;
16574cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
16584cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
16594cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
16604cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
16614cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
16624cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
16634cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
16644cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
16654cb006feSStefano Zampini   PetscFunctionReturn(0);
16664cb006feSStefano Zampini }
16674cb006feSStefano Zampini 
1668863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
16694cb006feSStefano Zampini {
16704cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
16714cb006feSStefano Zampini   Vec             tv;
16724cb006feSStefano Zampini   PetscInt        i;
16734cb006feSStefano Zampini   PetscErrorCode  ierr;
16744cb006feSStefano Zampini 
16754cb006feSStefano Zampini   PetscFunctionBegin;
16764cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
16774cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
16784cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
16794cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
16805ac14e1cSStefano Zampini   jac->dim = dim;
16815ac14e1cSStefano Zampini 
16824cb006feSStefano Zampini   /* compute IJ vector for coordinates */
16834cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
16844cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
16854cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
16864cb006feSStefano Zampini   for (i=0;i<dim;i++) {
16874cb006feSStefano Zampini     PetscScalar *array;
16884cb006feSStefano Zampini     PetscInt    j;
16894cb006feSStefano Zampini 
16904cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
16914cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
16924cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
16934cb006feSStefano Zampini       array[j] = coords[j*dim+i];
16944cb006feSStefano Zampini     }
169539accc25SStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,(HYPRE_Complex*)array));
16964cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
16974cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
16984cb006feSStefano Zampini   }
16994cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
17004cb006feSStefano Zampini   PetscFunctionReturn(0);
17014cb006feSStefano Zampini }
17024cb006feSStefano Zampini 
170316d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
170416d9e3a6SLisandro Dalcin 
1705f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
170616d9e3a6SLisandro Dalcin {
170716d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
170816d9e3a6SLisandro Dalcin 
170916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
171016d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
171116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
171216d9e3a6SLisandro Dalcin }
171316d9e3a6SLisandro Dalcin 
1714f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
171516d9e3a6SLisandro Dalcin {
171616d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
171716d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1718ace3abfcSBarry Smith   PetscBool      flag;
171916d9e3a6SLisandro Dalcin 
172016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
172116d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
172216d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1723ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
172416d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
172516d9e3a6SLisandro Dalcin   } else {
172616d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
172716d9e3a6SLisandro Dalcin   }
172816d9e3a6SLisandro Dalcin 
172916d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
173016d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
173116d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
173216d9e3a6SLisandro Dalcin 
173316d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
173416d9e3a6SLisandro Dalcin   if (flag) {
1735ffc4695bSBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRMPI(ierr);
1736fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
173716d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
173816d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
173916d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
174016d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
174116d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
174216d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
174316d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
174416d9e3a6SLisandro Dalcin   }
1745db966c6cSHong Zhang   ierr = PetscStrcmp("euclid",jac->hypre_type,&flag);CHKERRQ(ierr);
1746db966c6cSHong Zhang   if (flag) {
17478bf83915SBarry Smith #if defined(PETSC_HAVE_64BIT_INDICES)
17488bf83915SBarry Smith     SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Hypre Euclid not support with 64 bit indices");
17498bf83915SBarry Smith #endif
1750ffc4695bSBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRMPI(ierr);
1751db966c6cSHong Zhang     PetscStackCallStandard(HYPRE_EuclidCreate,(jac->comm_hypre,&jac->hsolver));
1752db966c6cSHong Zhang     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
1753db966c6cSHong Zhang     pc->ops->view           = PCView_HYPRE_Euclid;
1754db966c6cSHong Zhang     jac->destroy            = HYPRE_EuclidDestroy;
1755db966c6cSHong Zhang     jac->setup              = HYPRE_EuclidSetup;
1756db966c6cSHong Zhang     jac->solve              = HYPRE_EuclidSolve;
1757db966c6cSHong Zhang     jac->factorrowsize      = PETSC_DEFAULT;
1758db966c6cSHong Zhang     jac->eu_level           = PETSC_DEFAULT; /* default */
1759db966c6cSHong Zhang     PetscFunctionReturn(0);
1760db966c6cSHong Zhang   }
176116d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
176216d9e3a6SLisandro Dalcin   if (flag) {
1763ffc4695bSBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRMPI(ierr);
1764fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
176516d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
176616d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
176716d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
176816d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
176916d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
177016d9e3a6SLisandro Dalcin     /* initialize */
177116d9e3a6SLisandro Dalcin     jac->nlevels   = 1;
17728966356dSPierre Jolivet     jac->threshold = .1;
177316d9e3a6SLisandro Dalcin     jac->filter    = .1;
177416d9e3a6SLisandro Dalcin     jac->loadbal   = 0;
17752fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
17762fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
17772fa5cd67SKarl Rupp 
177816d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
177916d9e3a6SLisandro Dalcin     jac->symt = 0;
17808966356dSPierre Jolivet     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshold,jac->nlevels));
1781fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1782fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1783fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1784fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1785fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
178616d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
178716d9e3a6SLisandro Dalcin   }
178816d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
178916d9e3a6SLisandro Dalcin   if (flag) {
179016d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
179116d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
179216d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
179316d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
179416d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
1795fd2dd295SFande Kong     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",PCGetInterpolations_BoomerAMG);CHKERRQ(ierr);
1796fd2dd295SFande Kong     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",PCGetCoarseOperators_BoomerAMG);CHKERRQ(ierr);
179716d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
179816d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
179916d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
180016d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
180116d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
180216d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
180316d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
180416d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
18058f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
180616d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
180716d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
180816d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
180916d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
181016d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
18110f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
18126a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1813b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
18141810e44eSEike Mueller     jac->eu_level         = 0;
18151810e44eSEike Mueller     jac->eu_droptolerance = 0;
18161810e44eSEike Mueller     jac->eu_bj            = 0;
18178f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
18180f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
181916d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
182016d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
182116d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
18220f1074feSSatish Balay     jac->interptype       = 0;
18230f1074feSSatish Balay     jac->agg_nl           = 0;
18240f1074feSSatish Balay     jac->pmax             = 0;
18250f1074feSSatish Balay     jac->truncfactor      = 0.0;
18260f1074feSSatish Balay     jac->agg_num_paths    = 1;
18278f87f92bSBarry Smith 
182822e51d31SStefano Zampini     jac->nodal_coarsening      = 0;
182922e51d31SStefano Zampini     jac->nodal_coarsening_diag = 0;
183022e51d31SStefano Zampini     jac->vec_interp_variant    = 0;
183122e51d31SStefano Zampini     jac->vec_interp_qmax       = 0;
183222e51d31SStefano Zampini     jac->vec_interp_smooth     = PETSC_FALSE;
183322e51d31SStefano Zampini     jac->interp_refine         = 0;
18348f87f92bSBarry Smith     jac->nodal_relax           = PETSC_FALSE;
18358f87f92bSBarry Smith     jac->nodal_relax_levels    = 1;
1836fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1837fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1838fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1839fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1840fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1841fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1842fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1843fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1844fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1845fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1846fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1847fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1848fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1849fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1850fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1851fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
185216d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
185316d9e3a6SLisandro Dalcin   }
18544cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
18554cb006feSStefano Zampini   if (flag) {
18564cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
18574cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
18584cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
18594cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
18604cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
18614cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
18624cb006feSStefano Zampini     jac->coords[0]           = NULL;
18634cb006feSStefano Zampini     jac->coords[1]           = NULL;
18644cb006feSStefano Zampini     jac->coords[2]           = NULL;
18654cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1866863406b8SStefano Zampini     jac->as_print           = 0;
1867863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1868863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
18694cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
18704cb006feSStefano Zampini     /* Smoothing options */
1871863406b8SStefano Zampini     jac->as_relax_type      = 2;
1872863406b8SStefano Zampini     jac->as_relax_times     = 1;
1873863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1874863406b8SStefano Zampini     jac->as_omega           = 1.0;
18754cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1876863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1877863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
18780bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1879863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1880863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1881863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
18824cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1883863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1884863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
18850bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1886863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1887863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1888863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1889863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1890863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
18914cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1892863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1893863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1894863406b8SStefano Zampini                                                                       jac->as_relax_times,
1895863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1896863406b8SStefano Zampini                                                                       jac->as_omega));
1897863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1898863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1899863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1900863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1901863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1902863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1903863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1904863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1905863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1906863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1907863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1908863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
190923df4f25SStefano Zampini     /* Zero conductivity */
191023df4f25SStefano Zampini     jac->ams_beta_is_zero      = PETSC_FALSE;
191123df4f25SStefano Zampini     jac->ams_beta_is_zero_part = PETSC_FALSE;
19124cb006feSStefano Zampini     PetscFunctionReturn(0);
19134cb006feSStefano Zampini   }
1914863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1915863406b8SStefano Zampini   if (flag) {
1916863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1917863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1918863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1919863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1920863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1921863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1922863406b8SStefano Zampini     jac->coords[0]           = NULL;
1923863406b8SStefano Zampini     jac->coords[1]           = NULL;
1924863406b8SStefano Zampini     jac->coords[2]           = NULL;
1925863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1926863406b8SStefano Zampini     jac->as_print           = 0;
1927863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1928863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1929863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1930863406b8SStefano Zampini     /* Smoothing options */
1931863406b8SStefano Zampini     jac->as_relax_type      = 2;
1932863406b8SStefano Zampini     jac->as_relax_times     = 1;
1933863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1934863406b8SStefano Zampini     jac->as_omega           = 1.0;
1935863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1936863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1937863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1938863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1939863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1940863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1941863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1942863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1943863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1944863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1945863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1946863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1947863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1948863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1949863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1950863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1951863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1952863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1953863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1954863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1955863406b8SStefano Zampini                                                                       jac->as_relax_times,
1956863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1957863406b8SStefano Zampini                                                                       jac->as_omega));
1958863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1959863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1960863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1961863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1962863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1963863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1964863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1965863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1966863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1967863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1968863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1969863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1970863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1971863406b8SStefano Zampini     PetscFunctionReturn(0);
1972863406b8SStefano Zampini   }
1973503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
19742fa5cd67SKarl Rupp 
19750298fd71SBarry Smith   jac->hypre_type = NULL;
1976db966c6cSHong Zhang   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams",name);
197716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
197816d9e3a6SLisandro Dalcin }
197916d9e3a6SLisandro Dalcin 
198016d9e3a6SLisandro Dalcin /*
198116d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
198216d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
198316d9e3a6SLisandro Dalcin */
1984360ee056SFande Kong PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc)
198516d9e3a6SLisandro Dalcin {
198616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
19874ddd07fcSJed Brown   PetscInt       indx;
1988db966c6cSHong Zhang   const char     *type[] = {"euclid","pilut","parasails","boomeramg","ams","ads"};
1989ace3abfcSBarry Smith   PetscBool      flg;
199016d9e3a6SLisandro Dalcin 
199116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
19929fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
1993cab5ea25SPierre Jolivet   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,ALEN(type),"boomeramg",&indx,&flg);CHKERRQ(ierr);
199416d9e3a6SLisandro Dalcin   if (flg) {
199516d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
199602a17cd4SBarry Smith   } else {
199702a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
199816d9e3a6SLisandro Dalcin   }
199916d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
20003931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
200116d9e3a6SLisandro Dalcin   }
200216d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
200316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
200416d9e3a6SLisandro Dalcin }
200516d9e3a6SLisandro Dalcin 
200616d9e3a6SLisandro Dalcin /*@C
200716d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
200816d9e3a6SLisandro Dalcin 
200916d9e3a6SLisandro Dalcin    Input Parameters:
201016d9e3a6SLisandro Dalcin +     pc - the preconditioner context
2011db966c6cSHong Zhang -     name - either  euclid, pilut, parasails, boomeramg, ams, ads
201216d9e3a6SLisandro Dalcin 
201316d9e3a6SLisandro Dalcin    Options Database Keys:
2014db966c6cSHong Zhang    -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
201516d9e3a6SLisandro Dalcin 
201616d9e3a6SLisandro Dalcin    Level: intermediate
201716d9e3a6SLisandro Dalcin 
201816d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
201916d9e3a6SLisandro Dalcin            PCHYPRE
202016d9e3a6SLisandro Dalcin 
202116d9e3a6SLisandro Dalcin @*/
20227087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
202316d9e3a6SLisandro Dalcin {
20244ac538c5SBarry Smith   PetscErrorCode ierr;
202516d9e3a6SLisandro Dalcin 
202616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
20270700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
202816d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
20294ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
203016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
203116d9e3a6SLisandro Dalcin }
203216d9e3a6SLisandro Dalcin 
203316d9e3a6SLisandro Dalcin /*@C
203416d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
203516d9e3a6SLisandro Dalcin 
203616d9e3a6SLisandro Dalcin    Input Parameter:
203716d9e3a6SLisandro Dalcin .     pc - the preconditioner context
203816d9e3a6SLisandro Dalcin 
203916d9e3a6SLisandro Dalcin    Output Parameter:
2040db966c6cSHong Zhang .     name - either  euclid, pilut, parasails, boomeramg, ams, ads
204116d9e3a6SLisandro Dalcin 
204216d9e3a6SLisandro Dalcin    Level: intermediate
204316d9e3a6SLisandro Dalcin 
204416d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
204516d9e3a6SLisandro Dalcin            PCHYPRE
204616d9e3a6SLisandro Dalcin 
204716d9e3a6SLisandro Dalcin @*/
20487087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
204916d9e3a6SLisandro Dalcin {
20504ac538c5SBarry Smith   PetscErrorCode ierr;
205116d9e3a6SLisandro Dalcin 
205216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
20530700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
205416d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
20554ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
205616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
205716d9e3a6SLisandro Dalcin }
205816d9e3a6SLisandro Dalcin 
205916d9e3a6SLisandro Dalcin /*MC
206016d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
206116d9e3a6SLisandro Dalcin 
206216d9e3a6SLisandro Dalcin    Options Database Keys:
2063db966c6cSHong Zhang +   -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
206416d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
206516d9e3a6SLisandro Dalcin           preconditioner
206616d9e3a6SLisandro Dalcin 
206716d9e3a6SLisandro Dalcin    Level: intermediate
206816d9e3a6SLisandro Dalcin 
206995452b02SPatrick Sanan    Notes:
207095452b02SPatrick Sanan     Apart from pc_hypre_type (for which there is PCHYPRESetType()),
207116d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
207216d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
207316d9e3a6SLisandro Dalcin 
2074c231f9e3SBarryFSmith           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_tol refer to the number of iterations
20750f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
20760f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
2077c231f9e3SBarryFSmith           (-pc_hypre_boomeramg_tol should be set to 0.0 - the default - to strictly use a fixed number of
20788f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
20790f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
20800f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
208116d9e3a6SLisandro Dalcin 
20820f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
20830f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
20840f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
208516d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
208616d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
208716d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
208816d9e3a6SLisandro Dalcin 
208916d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
209016d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
209116d9e3a6SLisandro Dalcin 
20925272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
2093fdd15c9aSJunchao Zhang           the following two options:
2094fdd15c9aSJunchao Zhang    Options Database Keys:
20955272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
2096fdd15c9aSJunchao Zhang -   -pc_hypre_boomeramg_vec_interp_variant <v> - where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
20975272c319SBarry Smith 
20985272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
20995272c319SBarry Smith 
21009e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
21019e5bc791SBarry Smith 
210216d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
21039e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
210416d9e3a6SLisandro Dalcin 
210516d9e3a6SLisandro Dalcin M*/
210616d9e3a6SLisandro Dalcin 
21078cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
210816d9e3a6SLisandro Dalcin {
210916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
211016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
211116d9e3a6SLisandro Dalcin 
211216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
2113b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
21142fa5cd67SKarl Rupp 
211516d9e3a6SLisandro Dalcin   pc->data                = jac;
21168695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
211716d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
211816d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
211916d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
212016d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
212116d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
2122bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
2123bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
21245ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
21255ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
21265ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
21276bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",PCHYPRESetInterpolations_HYPRE);CHKERRQ(ierr);
21285ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE);CHKERRQ(ierr);
21295ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",PCHYPRESetPoissonMatrix_HYPRE);CHKERRQ(ierr);
213016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
213116d9e3a6SLisandro Dalcin }
2132ebc551c0SBarry Smith 
2133f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
2134f91d8e95SBarry Smith 
2135ebc551c0SBarry Smith typedef struct {
213668326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
2137f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
21389e5bc791SBarry Smith 
21399e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
21404ddd07fcSJed Brown   PetscInt its;
21419e5bc791SBarry Smith   double   tol;
21424ddd07fcSJed Brown   PetscInt relax_type;
21434ddd07fcSJed Brown   PetscInt rap_type;
21444ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
21454ddd07fcSJed Brown   PetscInt max_levels;
2146ebc551c0SBarry Smith } PC_PFMG;
2147ebc551c0SBarry Smith 
2148ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
2149ebc551c0SBarry Smith {
2150ebc551c0SBarry Smith   PetscErrorCode ierr;
2151f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2152ebc551c0SBarry Smith 
2153ebc551c0SBarry Smith   PetscFunctionBegin;
21542fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2155ffc4695bSBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRMPI(ierr);
2156c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2157ebc551c0SBarry Smith   PetscFunctionReturn(0);
2158ebc551c0SBarry Smith }
2159ebc551c0SBarry Smith 
21609e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
21619e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
21629e5bc791SBarry Smith 
2163ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
2164ebc551c0SBarry Smith {
2165ebc551c0SBarry Smith   PetscErrorCode ierr;
2166ace3abfcSBarry Smith   PetscBool      iascii;
2167f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2168ebc551c0SBarry Smith 
2169ebc551c0SBarry Smith   PetscFunctionBegin;
2170251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
21719e5bc791SBarry Smith   if (iascii) {
21729e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
2173efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max iterations %d\n",ex->its);CHKERRQ(ierr);
2174efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    tolerance %g\n",ex->tol);CHKERRQ(ierr);
2175efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2176efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
2177efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2178efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max levels %d\n",ex->max_levels);CHKERRQ(ierr);
21799e5bc791SBarry Smith   }
2180ebc551c0SBarry Smith   PetscFunctionReturn(0);
2181ebc551c0SBarry Smith }
2182ebc551c0SBarry Smith 
21834416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2184ebc551c0SBarry Smith {
2185ebc551c0SBarry Smith   PetscErrorCode ierr;
2186f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2187ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2188ebc551c0SBarry Smith 
2189ebc551c0SBarry Smith   PetscFunctionBegin;
2190e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
21910298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
219268326731SBarry Smith   if (flg) {
21935bd1e576SStefano Zampini     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,3));
219468326731SBarry Smith   }
21950298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2196fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
21970298fd71SBarry 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);
2198fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
21990298fd71SBarry 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);
2200fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
22019e5bc791SBarry Smith 
22020298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
2203fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
22043b46a515SGlenn Hammond 
22050298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2206fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
22070298fd71SBarry 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);
2208fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
22090298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
2210fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
2211ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
2212ebc551c0SBarry Smith   PetscFunctionReturn(0);
2213ebc551c0SBarry Smith }
2214ebc551c0SBarry Smith 
2215f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
2216f91d8e95SBarry Smith {
2217f91d8e95SBarry Smith   PetscErrorCode    ierr;
2218f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
2219d9ca1df4SBarry Smith   PetscScalar       *yy;
2220d9ca1df4SBarry Smith   const PetscScalar *xx;
22214ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
22222cf14000SStefano Zampini   HYPRE_Int         hlower[3],hupper[3];
222368326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2224f91d8e95SBarry Smith 
2225f91d8e95SBarry Smith   PetscFunctionBegin;
2226dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2227aa219208SBarry Smith   ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
22282cf14000SStefano Zampini   /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
2229f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
2230f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
2231f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
22322cf14000SStefano Zampini   hlower[0]  = (HYPRE_Int)ilower[0];
22332cf14000SStefano Zampini   hlower[1]  = (HYPRE_Int)ilower[1];
22342cf14000SStefano Zampini   hlower[2]  = (HYPRE_Int)ilower[2];
22352cf14000SStefano Zampini   hupper[0]  = (HYPRE_Int)iupper[0];
22362cf14000SStefano Zampini   hupper[1]  = (HYPRE_Int)iupper[1];
22372cf14000SStefano Zampini   hupper[2]  = (HYPRE_Int)iupper[2];
2238f91d8e95SBarry Smith 
2239f91d8e95SBarry Smith   /* copy x values over to hypre */
2240fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
2241d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
224239accc25SStefano Zampini   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,hlower,hupper,(HYPRE_Complex*)xx));
2243d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2244fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
2245fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2246f91d8e95SBarry Smith 
2247f91d8e95SBarry Smith   /* copy solution values back to PETSc */
2248f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
224939accc25SStefano Zampini   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,hlower,hupper,(HYPRE_Complex*)yy));
2250f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2251f91d8e95SBarry Smith   PetscFunctionReturn(0);
2252f91d8e95SBarry Smith }
2253f91d8e95SBarry Smith 
2254ace3abfcSBarry 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)
22559e5bc791SBarry Smith {
22569e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
22579e5bc791SBarry Smith   PetscErrorCode ierr;
22582cf14000SStefano Zampini   HYPRE_Int      oits;
22599e5bc791SBarry Smith 
22609e5bc791SBarry Smith   PetscFunctionBegin;
2261dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2262fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
2263fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
22649e5bc791SBarry Smith 
22659e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
22662cf14000SStefano Zampini   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,&oits));
22679e5bc791SBarry Smith   *outits = oits;
22689e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
22699e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2270fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
2271fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
22729e5bc791SBarry Smith   PetscFunctionReturn(0);
22739e5bc791SBarry Smith }
22749e5bc791SBarry Smith 
22759e5bc791SBarry Smith 
22763a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
22773a32d3dbSGlenn Hammond {
22783a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
22793a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
22803a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2281ace3abfcSBarry Smith   PetscBool       flg;
22823a32d3dbSGlenn Hammond 
22833a32d3dbSGlenn Hammond   PetscFunctionBegin;
2284251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
2285ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
22863a32d3dbSGlenn Hammond 
22873a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
22882fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2289fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2290fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2291fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
22923a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
22933a32d3dbSGlenn Hammond }
22943a32d3dbSGlenn Hammond 
2295ebc551c0SBarry Smith /*MC
2296ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
2297ebc551c0SBarry Smith 
2298ebc551c0SBarry Smith    Level: advanced
2299ebc551c0SBarry Smith 
23009e5bc791SBarry Smith    Options Database:
23019e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
23029e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
23039e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
23049e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
23059e5bc791SBarry 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
23069e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
2307f91d8e95SBarry Smith 
230895452b02SPatrick Sanan    Notes:
230995452b02SPatrick Sanan     This is for CELL-centered descretizations
23109e5bc791SBarry Smith 
23118e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
2312aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
23139e5bc791SBarry Smith 
23149e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
2315ebc551c0SBarry Smith M*/
2316ebc551c0SBarry Smith 
23178cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
2318ebc551c0SBarry Smith {
2319ebc551c0SBarry Smith   PetscErrorCode ierr;
2320ebc551c0SBarry Smith   PC_PFMG        *ex;
2321ebc551c0SBarry Smith 
2322ebc551c0SBarry Smith   PetscFunctionBegin;
2323b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
232468326731SBarry Smith   pc->data = ex;
2325ebc551c0SBarry Smith 
23269e5bc791SBarry Smith   ex->its            = 1;
23279e5bc791SBarry Smith   ex->tol            = 1.e-8;
23289e5bc791SBarry Smith   ex->relax_type     = 1;
23299e5bc791SBarry Smith   ex->rap_type       = 0;
23309e5bc791SBarry Smith   ex->num_pre_relax  = 1;
23319e5bc791SBarry Smith   ex->num_post_relax = 1;
23323b46a515SGlenn Hammond   ex->max_levels     = 0;
23339e5bc791SBarry Smith 
2334ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2335ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2336ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2337f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
23389e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
233968326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
23402fa5cd67SKarl Rupp 
2341ffc4695bSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRMPI(ierr);
2342fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2343ebc551c0SBarry Smith   PetscFunctionReturn(0);
2344ebc551c0SBarry Smith }
2345d851a50bSGlenn Hammond 
2346325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2347325fc9f4SBarry Smith 
2348d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2349d851a50bSGlenn Hammond typedef struct {
2350d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2351d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2352d851a50bSGlenn Hammond 
2353d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
23544ddd07fcSJed Brown   PetscInt its;
2355d851a50bSGlenn Hammond   double   tol;
23564ddd07fcSJed Brown   PetscInt relax_type;
23574ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2358d851a50bSGlenn Hammond } PC_SysPFMG;
2359d851a50bSGlenn Hammond 
2360d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2361d851a50bSGlenn Hammond {
2362d851a50bSGlenn Hammond   PetscErrorCode ierr;
2363d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2364d851a50bSGlenn Hammond 
2365d851a50bSGlenn Hammond   PetscFunctionBegin;
23662fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2367ffc4695bSBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRMPI(ierr);
2368c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2369d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2370d851a50bSGlenn Hammond }
2371d851a50bSGlenn Hammond 
2372d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2373d851a50bSGlenn Hammond 
2374d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2375d851a50bSGlenn Hammond {
2376d851a50bSGlenn Hammond   PetscErrorCode ierr;
2377ace3abfcSBarry Smith   PetscBool      iascii;
2378d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2379d851a50bSGlenn Hammond 
2380d851a50bSGlenn Hammond   PetscFunctionBegin;
2381251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2382d851a50bSGlenn Hammond   if (iascii) {
2383d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2384efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  max iterations %d\n",ex->its);CHKERRQ(ierr);
2385efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerance %g\n",ex->tol);CHKERRQ(ierr);
2386efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2387efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2388d851a50bSGlenn Hammond   }
2389d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2390d851a50bSGlenn Hammond }
2391d851a50bSGlenn Hammond 
23924416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2393d851a50bSGlenn Hammond {
2394d851a50bSGlenn Hammond   PetscErrorCode ierr;
2395d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2396ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2397d851a50bSGlenn Hammond 
2398d851a50bSGlenn Hammond   PetscFunctionBegin;
2399e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
24000298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2401d851a50bSGlenn Hammond   if (flg) {
24025bd1e576SStefano Zampini     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,3));
2403d851a50bSGlenn Hammond   }
24040298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2405fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
24060298fd71SBarry 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);
2407fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
24080298fd71SBarry 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);
2409fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2410d851a50bSGlenn Hammond 
24110298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2412fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
241361710fbeSStefano Zampini   ierr = PetscOptionsEList("-pc_syspfmg_relax_type","Relax type for the up and down cycles","HYPRE_SStructSysPFMGSetRelaxType",SysPFMGRelaxType,ALEN(SysPFMGRelaxType),SysPFMGRelaxType[ex->relax_type],&ex->relax_type,NULL);CHKERRQ(ierr);
2414fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2415d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2416d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2417d851a50bSGlenn Hammond }
2418d851a50bSGlenn Hammond 
2419d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2420d851a50bSGlenn Hammond {
2421d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2422d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2423d9ca1df4SBarry Smith   PetscScalar       *yy;
2424d9ca1df4SBarry Smith   const PetscScalar *xx;
24254ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
24262cf14000SStefano Zampini   HYPRE_Int         hlower[3],hupper[3];
2427d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
24284ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
24294ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
24304ddd07fcSJed Brown   PetscInt          part    = 0;
24314ddd07fcSJed Brown   PetscInt          size;
24324ddd07fcSJed Brown   PetscInt          i;
2433d851a50bSGlenn Hammond 
2434d851a50bSGlenn Hammond   PetscFunctionBegin;
2435dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2436aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
24372cf14000SStefano Zampini   /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
2438d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2439d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2440d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
24412cf14000SStefano Zampini   hlower[0]  = (HYPRE_Int)ilower[0];
24422cf14000SStefano Zampini   hlower[1]  = (HYPRE_Int)ilower[1];
24432cf14000SStefano Zampini   hlower[2]  = (HYPRE_Int)ilower[2];
24442cf14000SStefano Zampini   hupper[0]  = (HYPRE_Int)iupper[0];
24452cf14000SStefano Zampini   hupper[1]  = (HYPRE_Int)iupper[1];
24462cf14000SStefano Zampini   hupper[2]  = (HYPRE_Int)iupper[2];
2447d851a50bSGlenn Hammond 
2448d851a50bSGlenn Hammond   size = 1;
24492fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
24502fa5cd67SKarl Rupp 
2451d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2452d851a50bSGlenn Hammond   if (ordering) {
2453fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2454d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
245539accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(xx+(size*i))));
2456d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2457fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2458fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2459fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2460d851a50bSGlenn Hammond 
2461d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2462d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
246339accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(yy+(size*i))));
2464d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2465a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2466d851a50bSGlenn Hammond     PetscScalar *z;
24674ddd07fcSJed Brown     PetscInt    j, k;
2468d851a50bSGlenn Hammond 
2469785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2470fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2471d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2472d851a50bSGlenn Hammond 
2473d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2474d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2475d851a50bSGlenn Hammond       k= i*nvars;
24762fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2477d851a50bSGlenn Hammond     }
247839accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i))));
2479d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2480fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2481fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2482d851a50bSGlenn Hammond 
2483d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2484d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
248539accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i))));
2486d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2487d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2488d851a50bSGlenn Hammond       k= i*nvars;
24892fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2490d851a50bSGlenn Hammond     }
2491d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2492d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2493d851a50bSGlenn Hammond   }
2494d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2495d851a50bSGlenn Hammond }
2496d851a50bSGlenn Hammond 
2497ace3abfcSBarry 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)
2498d851a50bSGlenn Hammond {
2499d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2500d851a50bSGlenn Hammond   PetscErrorCode ierr;
25012cf14000SStefano Zampini   HYPRE_Int      oits;
2502d851a50bSGlenn Hammond 
2503d851a50bSGlenn Hammond   PetscFunctionBegin;
2504dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2505fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2506fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2507d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
25082cf14000SStefano Zampini   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,&oits));
2509d851a50bSGlenn Hammond   *outits = oits;
2510d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2511d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2512fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2513fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2514d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2515d851a50bSGlenn Hammond }
2516d851a50bSGlenn Hammond 
2517d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2518d851a50bSGlenn Hammond {
2519d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2520d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2521d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2522ace3abfcSBarry Smith   PetscBool        flg;
2523d851a50bSGlenn Hammond 
2524d851a50bSGlenn Hammond   PetscFunctionBegin;
2525251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2526ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2527d851a50bSGlenn Hammond 
2528d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
25292fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2530fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2531fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2532fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2533d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2534d851a50bSGlenn Hammond }
2535d851a50bSGlenn Hammond 
2536d851a50bSGlenn Hammond /*MC
2537d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2538d851a50bSGlenn Hammond 
2539d851a50bSGlenn Hammond    Level: advanced
2540d851a50bSGlenn Hammond 
2541d851a50bSGlenn Hammond    Options Database:
2542d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2543d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2544d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2545d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2546a2b725a8SWilliam Gropp - -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2547d851a50bSGlenn Hammond 
254895452b02SPatrick Sanan    Notes:
254995452b02SPatrick Sanan     This is for CELL-centered descretizations
2550d851a50bSGlenn Hammond 
2551f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2552aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2553d851a50bSGlenn Hammond            Also, only cell-centered variables.
2554d851a50bSGlenn Hammond 
2555d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2556d851a50bSGlenn Hammond M*/
2557d851a50bSGlenn Hammond 
25588cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2559d851a50bSGlenn Hammond {
2560d851a50bSGlenn Hammond   PetscErrorCode ierr;
2561d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2562d851a50bSGlenn Hammond 
2563d851a50bSGlenn Hammond   PetscFunctionBegin;
2564b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2565d851a50bSGlenn Hammond   pc->data = ex;
2566d851a50bSGlenn Hammond 
2567d851a50bSGlenn Hammond   ex->its            = 1;
2568d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2569d851a50bSGlenn Hammond   ex->relax_type     = 1;
2570d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2571d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2572d851a50bSGlenn Hammond 
2573d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2574d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2575d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2576d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2577d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2578d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
25792fa5cd67SKarl Rupp 
2580ffc4695bSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRMPI(ierr);
2581fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2582d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2583d851a50bSGlenn Hammond }
2584