xref: /petsc/src/ksp/pc/impls/hypre/hypre.c (revision 0b1a5bd95a5f3e6e329feb6dcc879c57b73b8abe)
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);
48816d9e3a6SLisandro Dalcin   if (jac->comm_hypre != MPI_COMM_NULL) { ierr = MPI_Comm_free(&(jac->comm_hypre));CHKERRQ(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;
558db966c6cSHong Zhang   PetscBool      flag;
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));
564db966c6cSHong Zhang   ierr = PetscOptionsTail();CHKERRQ(ierr);
565db966c6cSHong Zhang   PetscFunctionReturn(0);
566db966c6cSHong Zhang }
567db966c6cSHong Zhang 
568db966c6cSHong Zhang static PetscErrorCode PCView_HYPRE_Euclid(PC pc,PetscViewer viewer)
569db966c6cSHong Zhang {
570db966c6cSHong Zhang   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
571db966c6cSHong Zhang   PetscErrorCode ierr;
572db966c6cSHong Zhang   PetscBool      iascii;
573db966c6cSHong Zhang 
574db966c6cSHong Zhang   PetscFunctionBegin;
575db966c6cSHong Zhang   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
576db966c6cSHong Zhang   if (iascii) {
577db966c6cSHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE Euclid preconditioning\n");CHKERRQ(ierr);
578db966c6cSHong Zhang     if (jac->eu_level != PETSC_DEFAULT) {
579db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    factorization levels %d\n",jac->eu_level);CHKERRQ(ierr);
580db966c6cSHong Zhang     } else {
581db966c6cSHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"    default factorization levels \n");CHKERRQ(ierr);
582db966c6cSHong Zhang     }
583db966c6cSHong Zhang   }
584db966c6cSHong Zhang   PetscFunctionReturn(0);
585db966c6cSHong Zhang }
586db966c6cSHong Zhang 
587db966c6cSHong Zhang /* --------------------------------------------------------------------------------------------*/
58816d9e3a6SLisandro Dalcin 
58916d9e3a6SLisandro Dalcin static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)
59016d9e3a6SLisandro Dalcin {
59116d9e3a6SLisandro Dalcin   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
59249a781f5SStefano Zampini   Mat_HYPRE          *hjac = (Mat_HYPRE*)(jac->hpmat->data);
59316d9e3a6SLisandro Dalcin   PetscErrorCode     ierr;
59416d9e3a6SLisandro Dalcin   HYPRE_ParCSRMatrix hmat;
59539accc25SStefano Zampini   HYPRE_Complex      *xv,*bv;
59639accc25SStefano Zampini   HYPRE_Complex      *sbv,*sxv;
59716d9e3a6SLisandro Dalcin   HYPRE_ParVector    jbv,jxv;
5984ddd07fcSJed Brown   PetscInt           hierr;
59916d9e3a6SLisandro Dalcin 
60016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
601dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
60216d9e3a6SLisandro Dalcin   ierr = VecSet(x,0.0);CHKERRQ(ierr);
60339accc25SStefano Zampini   ierr = VecGetArrayRead(b,(const PetscScalar**)&bv);CHKERRQ(ierr);
60439accc25SStefano Zampini   ierr = VecGetArray(x,(PetscScalar**)&xv);CHKERRQ(ierr);
60539accc25SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,bv,sbv);
60658968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,xv,sxv);
60716d9e3a6SLisandro Dalcin 
60849a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hjac->ij,(void**)&hmat));
60949a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->b,(void**)&jbv));
61049a781f5SStefano Zampini   PetscStackCallStandard(HYPRE_IJVectorGetObject,(hjac->x,(void**)&jxv));
61116d9e3a6SLisandro Dalcin 
61216d9e3a6SLisandro Dalcin   hierr = HYPRE_BoomerAMGSolveT(jac->hsolver,hmat,jbv,jxv);
61316d9e3a6SLisandro Dalcin   /* error code of 1 in BoomerAMG merely means convergence not achieved */
614e32f2f54SBarry Smith   if (hierr && (hierr != 1)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in HYPRE solver, error code %d",hierr);
61516d9e3a6SLisandro Dalcin   if (hierr) hypre__global_error = 0;
61616d9e3a6SLisandro Dalcin 
61758968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->b,sbv,bv);
61858968eb6SStefano Zampini   VecHYPRE_ParVectorReplacePointer(hjac->x,sxv,xv);
61939accc25SStefano Zampini   ierr = VecRestoreArray(x,(PetscScalar**)&xv);CHKERRQ(ierr);
62039accc25SStefano Zampini   ierr = VecRestoreArrayRead(b,(const PetscScalar**)&bv);CHKERRQ(ierr);
62116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
62216d9e3a6SLisandro Dalcin }
62316d9e3a6SLisandro Dalcin 
624a669f990SJed Brown /* static array length */
625a669f990SJed Brown #define ALEN(a) (sizeof(a)/sizeof((a)[0]))
626a669f990SJed Brown 
62716d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[]   = {"","V","W"};
6280f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP","Ruge-Stueben","","modifiedRuge-Stueben","","","Falgout", "", "PMIS", "", "HMIS"};
62916d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local","global"};
63065de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
6316a251517SEike Mueller static const char *HYPREBoomerAMGSmoothType[]  = {"Schwarz-smoothers","Pilut","ParaSails","Euclid"};
63265de4495SJed Brown static const char *HYPREBoomerAMGRelaxType[]   = {"Jacobi","sequential-Gauss-Seidel","seqboundary-Gauss-Seidel","SOR/Jacobi","backward-SOR/Jacobi",
63365de4495SJed Brown                                                   "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */,"symmetric-SOR/Jacobi",
63465de4495SJed Brown                                                   "" /* 7 */,"l1scaled-SOR/Jacobi","Gaussian-elimination",
6357b7fa87dSPierre Jolivet                                                   "" /* 10 */, "" /* 11 */, "" /* 12 */, "l1-Gauss-Seidel" /* nonsymmetric */, "backward-l1-Gauss-Seidel" /* nonsymmetric */,
63665de4495SJed Brown                                                   "CG" /* non-stationary */,"Chebyshev","FCF-Jacobi","l1scaled-Jacobi"};
6370f1074feSSatish Balay static const char *HYPREBoomerAMGInterpType[]  = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i",
638e2287abbSStefano Zampini                                                   "ext+i-cc", "standard", "standard-wts", "block", "block-wtd", "FF", "FF1"};
6394416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PetscOptionItems *PetscOptionsObject,PC pc)
64016d9e3a6SLisandro Dalcin {
64116d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
64216d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
64322e51d31SStefano Zampini   PetscInt       bs,n,indx,level;
644ace3abfcSBarry Smith   PetscBool      flg, tmp_truth;
64516d9e3a6SLisandro Dalcin   double         tmpdbl, twodbl[2];
64616d9e3a6SLisandro Dalcin 
64716d9e3a6SLisandro Dalcin   PetscFunctionBegin;
648e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE BoomerAMG Options");CHKERRQ(ierr);
6494336a9eeSBarry Smith   ierr = PetscOptionsEList("-pc_hypre_boomeramg_cycle_type","Cycle type","None",HYPREBoomerAMGCycleType+1,2,HYPREBoomerAMGCycleType[jac->cycletype],&indx,&flg);CHKERRQ(ierr);
65016d9e3a6SLisandro Dalcin   if (flg) {
6514336a9eeSBarry Smith     jac->cycletype = indx+1;
652fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
65316d9e3a6SLisandro Dalcin   }
65416d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_levels","Number of levels (of grids) allowed","None",jac->maxlevels,&jac->maxlevels,&flg);CHKERRQ(ierr);
65516d9e3a6SLisandro Dalcin   if (flg) {
656ce94432eSBarry Smith     if (jac->maxlevels < 2) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of levels %d must be at least two",jac->maxlevels);
657fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
65816d9e3a6SLisandro Dalcin   }
65916d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_max_iter","Maximum iterations used PER hypre call","None",jac->maxiter,&jac->maxiter,&flg);CHKERRQ(ierr);
66016d9e3a6SLisandro Dalcin   if (flg) {
661ce94432eSBarry Smith     if (jac->maxiter < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Number of iterations %d must be at least one",jac->maxiter);
662fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
66316d9e3a6SLisandro Dalcin   }
66439accc25SStefano 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);
66516d9e3a6SLisandro Dalcin   if (flg) {
66657622a8eSBarry 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);
667fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
66816d9e3a6SLisandro Dalcin   }
66922e51d31SStefano Zampini   bs = 1;
67022e51d31SStefano Zampini   if (pc->pmat) {
67122e51d31SStefano Zampini     ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr);
67222e51d31SStefano Zampini   }
67322e51d31SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_boomeramg_numfunctions","Number of functions","HYPRE_BoomerAMGSetNumFunctions",bs,&bs,&flg);CHKERRQ(ierr);
67422e51d31SStefano Zampini   if (flg) {
67522e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNumFunctions,(jac->hsolver,bs));
67622e51d31SStefano Zampini   }
67716d9e3a6SLisandro Dalcin 
67839accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_truncfactor","Truncation factor for interpolation (0=no truncation)","None",jac->truncfactor,&jac->truncfactor,&flg);CHKERRQ(ierr);
67916d9e3a6SLisandro Dalcin   if (flg) {
68057622a8eSBarry 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);
681fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
68216d9e3a6SLisandro Dalcin   }
68316d9e3a6SLisandro Dalcin 
6840f1074feSSatish 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);
6850f1074feSSatish Balay   if (flg) {
68657622a8eSBarry 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);
687fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
6880f1074feSSatish Balay   }
6890f1074feSSatish Balay 
6900f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_agg_nl","Number of levels of aggressive coarsening","None",jac->agg_nl,&jac->agg_nl,&flg);CHKERRQ(ierr);
6910f1074feSSatish Balay   if (flg) {
69257622a8eSBarry 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);
6930f1074feSSatish Balay 
694fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
6950f1074feSSatish Balay   }
6960f1074feSSatish Balay 
6970f1074feSSatish 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);
6980f1074feSSatish Balay   if (flg) {
69957622a8eSBarry 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);
7000f1074feSSatish Balay 
701fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
7020f1074feSSatish Balay   }
7030f1074feSSatish Balay 
7040f1074feSSatish Balay 
70539accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_strong_threshold","Threshold for being strongly connected","None",jac->strongthreshold,&jac->strongthreshold,&flg);CHKERRQ(ierr);
70616d9e3a6SLisandro Dalcin   if (flg) {
70757622a8eSBarry 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);
708fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
70916d9e3a6SLisandro Dalcin   }
71039accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_max_row_sum","Maximum row sum","None",jac->maxrowsum,&jac->maxrowsum,&flg);CHKERRQ(ierr);
71116d9e3a6SLisandro Dalcin   if (flg) {
71257622a8eSBarry 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);
71357622a8eSBarry 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);
714fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
71516d9e3a6SLisandro Dalcin   }
71616d9e3a6SLisandro Dalcin 
71716d9e3a6SLisandro Dalcin   /* Grid sweeps */
7180f1074feSSatish 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);
71916d9e3a6SLisandro Dalcin   if (flg) {
720fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver,indx));
72116d9e3a6SLisandro Dalcin     /* modify the jac structure so we can view the updated options with PC_View */
72216d9e3a6SLisandro Dalcin     jac->gridsweeps[0] = indx;
7230f1074feSSatish Balay     jac->gridsweeps[1] = indx;
7240f1074feSSatish Balay     /*defaults coarse to 1 */
7250f1074feSSatish Balay     jac->gridsweeps[2] = 1;
72616d9e3a6SLisandro Dalcin   }
7275272c319SBarry 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);
7285272c319SBarry Smith   if (flg) {
7295272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNodal,(jac->hsolver,jac->nodal_coarsening));
7305272c319SBarry Smith   }
73122e51d31SStefano 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);
73222e51d31SStefano Zampini   if (flg) {
73322e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetNodalDiag,(jac->hsolver,jac->nodal_coarsening_diag));
73422e51d31SStefano Zampini   }
735cbc39033SBarry 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);
7365272c319SBarry Smith   if (flg) {
7375272c319SBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecVariant,(jac->hsolver,jac->vec_interp_variant));
7385272c319SBarry Smith   }
73922e51d31SStefano 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);
74022e51d31SStefano Zampini   if (flg) {
74122e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpVecQMax,(jac->hsolver,jac->vec_interp_qmax));
74222e51d31SStefano Zampini   }
74322e51d31SStefano 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);
74422e51d31SStefano Zampini   if (flg) {
74522e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothInterpVectors,(jac->hsolver,jac->vec_interp_smooth));
74622e51d31SStefano Zampini   }
74722e51d31SStefano 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);
74822e51d31SStefano Zampini   if (flg) {
74922e51d31SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpRefine,(jac->hsolver,jac->interp_refine));
75022e51d31SStefano Zampini   }
7510f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down","Number of sweeps for the down cycles","None",jac->gridsweeps[0], &indx,&flg);CHKERRQ(ierr);
75216d9e3a6SLisandro Dalcin   if (flg) {
753fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 1));
7540f1074feSSatish Balay     jac->gridsweeps[0] = indx;
75516d9e3a6SLisandro Dalcin   }
75616d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up","Number of sweeps for the up cycles","None",jac->gridsweeps[1],&indx,&flg);CHKERRQ(ierr);
75716d9e3a6SLisandro Dalcin   if (flg) {
758fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 2));
7590f1074feSSatish Balay     jac->gridsweeps[1] = indx;
76016d9e3a6SLisandro Dalcin   }
7610f1074feSSatish Balay   ierr = PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse","Number of sweeps for the coarse level","None",jac->gridsweeps[2],&indx,&flg);CHKERRQ(ierr);
76216d9e3a6SLisandro Dalcin   if (flg) {
763fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleNumSweeps,(jac->hsolver,indx, 3));
7640f1074feSSatish Balay     jac->gridsweeps[2] = indx;
76516d9e3a6SLisandro Dalcin   }
76616d9e3a6SLisandro Dalcin 
7676a251517SEike Mueller   /* Smooth type */
7686a251517SEike Mueller   ierr = PetscOptionsEList("-pc_hypre_boomeramg_smooth_type","Enable more complex smoothers","None",HYPREBoomerAMGSmoothType,ALEN(HYPREBoomerAMGSmoothType),HYPREBoomerAMGSmoothType[0],&indx,&flg);
7696a251517SEike Mueller   if (flg) {
7706a251517SEike Mueller     jac->smoothtype = indx;
7716a251517SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,indx+6));
7728131ecf7SEike Mueller     jac->smoothnumlevels = 25;
7738131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,25));
7748131ecf7SEike Mueller   }
7758131ecf7SEike Mueller 
7768131ecf7SEike Mueller   /* Number of smoothing levels */
7778131ecf7SEike 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);
7788131ecf7SEike Mueller   if (flg && (jac->smoothtype != -1)) {
7798131ecf7SEike Mueller     jac->smoothnumlevels = indx;
7808131ecf7SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,indx));
7816a251517SEike Mueller   }
7826a251517SEike Mueller 
7831810e44eSEike Mueller   /* Number of levels for ILU(k) for Euclid */
7841810e44eSEike Mueller   ierr = PetscOptionsInt("-pc_hypre_boomeramg_eu_level","Number of levels for ILU(k) in Euclid smoother","None",0,&indx,&flg);CHKERRQ(ierr);
7851810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
7861810e44eSEike Mueller     jac->eu_level = indx;
7871810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,indx));
7881810e44eSEike Mueller   }
7891810e44eSEike Mueller 
7901810e44eSEike Mueller   /* Filter for ILU(k) for Euclid */
7911810e44eSEike Mueller   double droptolerance;
79239accc25SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_boomeramg_eu_droptolerance","Drop tolerance for ILU(k) in Euclid smoother","None",0,&droptolerance,&flg);CHKERRQ(ierr);
7931810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
7941810e44eSEike Mueller     jac->eu_droptolerance = droptolerance;
7951810e44eSEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuLevel,(jac->hsolver,droptolerance));
7961810e44eSEike Mueller   }
7971810e44eSEike Mueller 
7981810e44eSEike Mueller   /* Use Block Jacobi ILUT for Euclid */
7991810e44eSEike Mueller   ierr = PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
8001810e44eSEike Mueller   if (flg && (jac->smoothtype == 3)) {
8011810e44eSEike Mueller     jac->eu_bj = tmp_truth;
802493fc9d9SEike Mueller     PetscStackCallStandard(HYPRE_BoomerAMGSetEuBJ,(jac->hsolver,jac->eu_bj));
8031810e44eSEike Mueller   }
8041810e44eSEike Mueller 
80516d9e3a6SLisandro Dalcin   /* Relax type */
806a669f990SJed 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);
80716d9e3a6SLisandro Dalcin   if (flg) {
8080f1074feSSatish Balay     jac->relaxtype[0] = jac->relaxtype[1]  = indx;
809fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, indx));
8100f1074feSSatish Balay     /* by default, coarse type set to 9 */
8110f1074feSSatish Balay     jac->relaxtype[2] = 9;
812ddbeb582SStefano Zampini     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, 9, 3));
81316d9e3a6SLisandro Dalcin   }
814a669f990SJed 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);
81516d9e3a6SLisandro Dalcin   if (flg) {
81616d9e3a6SLisandro Dalcin     jac->relaxtype[0] = indx;
817fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 1));
81816d9e3a6SLisandro Dalcin   }
819a669f990SJed 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);
82016d9e3a6SLisandro Dalcin   if (flg) {
8210f1074feSSatish Balay     jac->relaxtype[1] = indx;
822fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 2));
82316d9e3a6SLisandro Dalcin   }
824a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse","Relax type on coarse grid","None",HYPREBoomerAMGRelaxType,ALEN(HYPREBoomerAMGRelaxType),HYPREBoomerAMGRelaxType[9],&indx,&flg);CHKERRQ(ierr);
82516d9e3a6SLisandro Dalcin   if (flg) {
8260f1074feSSatish Balay     jac->relaxtype[2] = indx;
827fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleRelaxType,(jac->hsolver, indx, 3));
82816d9e3a6SLisandro Dalcin   }
82916d9e3a6SLisandro Dalcin 
83016d9e3a6SLisandro Dalcin   /* Relaxation Weight */
83116d9e3a6SLisandro 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);
83216d9e3a6SLisandro Dalcin   if (flg) {
833fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxWt,(jac->hsolver,tmpdbl));
83416d9e3a6SLisandro Dalcin     jac->relaxweight = tmpdbl;
83516d9e3a6SLisandro Dalcin   }
83616d9e3a6SLisandro Dalcin 
83716d9e3a6SLisandro Dalcin   n         = 2;
83816d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
83916d9e3a6SLisandro 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);
84016d9e3a6SLisandro Dalcin   if (flg) {
84116d9e3a6SLisandro Dalcin     if (n == 2) {
84216d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
843fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelRelaxWt,(jac->hsolver,twodbl[0],indx));
844ce94432eSBarry 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);
84516d9e3a6SLisandro Dalcin   }
84616d9e3a6SLisandro Dalcin 
84716d9e3a6SLisandro Dalcin   /* Outer relaxation Weight */
84816d9e3a6SLisandro 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);
84916d9e3a6SLisandro Dalcin   if (flg) {
850fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOuterWt,(jac->hsolver, tmpdbl));
85116d9e3a6SLisandro Dalcin     jac->outerrelaxweight = tmpdbl;
85216d9e3a6SLisandro Dalcin   }
85316d9e3a6SLisandro Dalcin 
85416d9e3a6SLisandro Dalcin   n         = 2;
85516d9e3a6SLisandro Dalcin   twodbl[0] = twodbl[1] = 1.0;
85616d9e3a6SLisandro 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);
85716d9e3a6SLisandro Dalcin   if (flg) {
85816d9e3a6SLisandro Dalcin     if (n == 2) {
85916d9e3a6SLisandro Dalcin       indx =  (int)PetscAbsReal(twodbl[1]);
860fd3f9acdSBarry Smith       PetscStackCallStandard(HYPRE_BoomerAMGSetLevelOuterWt,(jac->hsolver, twodbl[0], indx));
861ce94432eSBarry 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);
86216d9e3a6SLisandro Dalcin   }
86316d9e3a6SLisandro Dalcin 
86416d9e3a6SLisandro Dalcin   /* the Relax Order */
865acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
86616d9e3a6SLisandro Dalcin 
8678afaa268SBarry Smith   if (flg && tmp_truth) {
86816d9e3a6SLisandro Dalcin     jac->relaxorder = 0;
869fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
87016d9e3a6SLisandro Dalcin   }
871a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_measure_type","Measure type","None",HYPREBoomerAMGMeasureType,ALEN(HYPREBoomerAMGMeasureType),HYPREBoomerAMGMeasureType[0],&indx,&flg);CHKERRQ(ierr);
87216d9e3a6SLisandro Dalcin   if (flg) {
87316d9e3a6SLisandro Dalcin     jac->measuretype = indx;
874fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
87516d9e3a6SLisandro Dalcin   }
8760f1074feSSatish Balay   /* update list length 3/07 */
877a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type","Coarsen type","None",HYPREBoomerAMGCoarsenType,ALEN(HYPREBoomerAMGCoarsenType),HYPREBoomerAMGCoarsenType[6],&indx,&flg);CHKERRQ(ierr);
87816d9e3a6SLisandro Dalcin   if (flg) {
87916d9e3a6SLisandro Dalcin     jac->coarsentype = indx;
880fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
88116d9e3a6SLisandro Dalcin   }
8820f1074feSSatish Balay 
8830f1074feSSatish Balay   /* new 3/07 */
884a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_boomeramg_interp_type","Interpolation type","None",HYPREBoomerAMGInterpType,ALEN(HYPREBoomerAMGInterpType),HYPREBoomerAMGInterpType[0],&indx,&flg);CHKERRQ(ierr);
8850f1074feSSatish Balay   if (flg) {
8860f1074feSSatish Balay     jac->interptype = indx;
887fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
8880f1074feSSatish Balay   }
8890f1074feSSatish Balay 
890b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_statistics","Print statistics","None",&flg);CHKERRQ(ierr);
89116d9e3a6SLisandro Dalcin   if (flg) {
892b96a4a96SBarry Smith     level = 3;
8930298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_statistics","Print statistics","None",level,&level,NULL);CHKERRQ(ierr);
8942fa5cd67SKarl Rupp 
895b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
896fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPrintLevel,(jac->hsolver,level));
8972ae77aedSBarry Smith   }
8982ae77aedSBarry Smith 
899b96a4a96SBarry Smith   ierr = PetscOptionsName("-pc_hypre_boomeramg_print_debug","Print debug information","None",&flg);CHKERRQ(ierr);
9002ae77aedSBarry Smith   if (flg) {
901b96a4a96SBarry Smith     level = 3;
9020298fd71SBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_print_debug","Print debug information","None",level,&level,NULL);CHKERRQ(ierr);
9032fa5cd67SKarl Rupp 
904b96a4a96SBarry Smith     jac->printstatistics = PETSC_TRUE;
905fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDebugFlag,(jac->hsolver,level));
90616d9e3a6SLisandro Dalcin   }
9078f87f92bSBarry Smith 
908acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg);CHKERRQ(ierr);
9098f87f92bSBarry Smith   if (flg && tmp_truth) {
9108f87f92bSBarry Smith     PetscInt tmp_int;
9118f87f92bSBarry Smith     ierr = PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None",jac->nodal_relax_levels,&tmp_int,&flg);CHKERRQ(ierr);
9128f87f92bSBarry Smith     if (flg) jac->nodal_relax_levels = tmp_int;
913fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothType,(jac->hsolver,6));
914fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetDomainType,(jac->hsolver,1));
915fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetOverlap,(jac->hsolver,0));
916fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetSmoothNumLevels,(jac->hsolver,jac->nodal_relax_levels));
9178f87f92bSBarry Smith   }
9188f87f92bSBarry Smith 
91916d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
92016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
92116d9e3a6SLisandro Dalcin }
92216d9e3a6SLisandro Dalcin 
923ace3abfcSBarry 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)
92416d9e3a6SLisandro Dalcin {
92516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
92616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
9272cf14000SStefano Zampini   HYPRE_Int      oits;
92816d9e3a6SLisandro Dalcin 
92916d9e3a6SLisandro Dalcin   PetscFunctionBegin;
930dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
931fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,its*jac->maxiter));
932fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,rtol));
93316d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_TRUE;
93416d9e3a6SLisandro Dalcin   ierr                 = PCApply_HYPRE(pc,b,y);CHKERRQ(ierr);
93516d9e3a6SLisandro Dalcin   jac->applyrichardson = PETSC_FALSE;
9362cf14000SStefano Zampini   PetscStackCallStandard(HYPRE_BoomerAMGGetNumIterations,(jac->hsolver,&oits));
9374d0a8057SBarry Smith   *outits = oits;
9384d0a8057SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
9394d0a8057SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
940fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
941fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
94216d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
94316d9e3a6SLisandro Dalcin }
94416d9e3a6SLisandro Dalcin 
94516d9e3a6SLisandro Dalcin 
94616d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)
94716d9e3a6SLisandro Dalcin {
94816d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
94916d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
950ace3abfcSBarry Smith   PetscBool      iascii;
95116d9e3a6SLisandro Dalcin 
95216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
953251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
95416d9e3a6SLisandro Dalcin   if (iascii) {
95516d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE BoomerAMG preconditioning\n");CHKERRQ(ierr);
956efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Cycle type %s\n",HYPREBoomerAMGCycleType[jac->cycletype]);CHKERRQ(ierr);
95722e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of levels %D\n",jac->maxlevels);CHKERRQ(ierr);
95822e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum number of iterations PER hypre call %D\n",jac->maxiter);CHKERRQ(ierr);
959efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Convergence tolerance PER hypre call %g\n",(double)jac->tol);CHKERRQ(ierr);
960efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Threshold for strong coupling %g\n",(double)jac->strongthreshold);CHKERRQ(ierr);
961efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation truncation factor %g\n",(double)jac->truncfactor);CHKERRQ(ierr);
96222e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: max elements per row %D\n",jac->pmax);CHKERRQ(ierr);
96322e51d31SStefano Zampini     if (jac->interp_refine) {
96422e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation: number of steps of weighted refinement %D\n",jac->interp_refine);CHKERRQ(ierr);
96522e51d31SStefano Zampini     }
96622e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of levels of aggressive coarsening %D\n",jac->agg_nl);CHKERRQ(ierr);
96722e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Number of paths for aggressive coarsening %D\n",jac->agg_num_paths);CHKERRQ(ierr);
9680f1074feSSatish Balay 
969efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Maximum row sums %g\n",(double)jac->maxrowsum);CHKERRQ(ierr);
97016d9e3a6SLisandro Dalcin 
97122e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps down         %D\n",jac->gridsweeps[0]);CHKERRQ(ierr);
97222e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps up           %D\n",jac->gridsweeps[1]);CHKERRQ(ierr);
97322e51d31SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"    Sweeps on coarse    %D\n",jac->gridsweeps[2]);CHKERRQ(ierr);
97416d9e3a6SLisandro Dalcin 
975efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax down          %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[0]]);CHKERRQ(ierr);
976efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax up            %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[1]]);CHKERRQ(ierr);
977efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax on coarse     %s\n",HYPREBoomerAMGRelaxType[jac->relaxtype[2]]);CHKERRQ(ierr);
97816d9e3a6SLisandro Dalcin 
979efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Relax weight  (all)      %g\n",(double)jac->relaxweight);CHKERRQ(ierr);
980efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Outer relax weight (all) %g\n",(double)jac->outerrelaxweight);CHKERRQ(ierr);
98116d9e3a6SLisandro Dalcin 
98216d9e3a6SLisandro Dalcin     if (jac->relaxorder) {
983efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using CF-relaxation\n");CHKERRQ(ierr);
98416d9e3a6SLisandro Dalcin     } else {
985efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using CF-relaxation\n");CHKERRQ(ierr);
98616d9e3a6SLisandro Dalcin     }
9876a251517SEike Mueller     if (jac->smoothtype!=-1) {
988efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth type          %s\n",HYPREBoomerAMGSmoothType[jac->smoothtype]);CHKERRQ(ierr);
98922e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Smooth num levels    %D\n",jac->smoothnumlevels);CHKERRQ(ierr);
9907e352d70SEike Mueller     } else {
991efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Not using more complex smoothers.\n");CHKERRQ(ierr);
9921810e44eSEike Mueller     }
9931810e44eSEike Mueller     if (jac->smoothtype==3) {
99422e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) levels %D\n",jac->eu_level);CHKERRQ(ierr);
99522e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU(k) drop tolerance %g\n",(double)jac->eu_droptolerance);CHKERRQ(ierr);
99622e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Euclid ILU use Block-Jacobi? %D\n",jac->eu_bj);CHKERRQ(ierr);
9976a251517SEike Mueller     }
998efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Measure type        %s\n",HYPREBoomerAMGMeasureType[jac->measuretype]);CHKERRQ(ierr);
999efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Coarsen type        %s\n",HYPREBoomerAMGCoarsenType[jac->coarsentype]);CHKERRQ(ierr);
1000efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Interpolation type  %s\n",HYPREBoomerAMGInterpType[jac->interptype]);CHKERRQ(ierr);
10015272c319SBarry Smith     if (jac->nodal_coarsening) {
1002efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal coarsening (with HYPRE_BOOMERAMGSetNodal() %D\n",jac->nodal_coarsening);CHKERRQ(ierr);
10035272c319SBarry Smith     }
10045272c319SBarry Smith     if (jac->vec_interp_variant) {
1005efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecVariant() %D\n",jac->vec_interp_variant);CHKERRQ(ierr);
100622e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetInterpVecQMax() %D\n",jac->vec_interp_qmax);CHKERRQ(ierr);
100722e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n",jac->vec_interp_smooth);CHKERRQ(ierr);
10088f87f92bSBarry Smith     }
10098f87f92bSBarry Smith     if (jac->nodal_relax) {
101022e51d31SStefano Zampini       ierr = PetscViewerASCIIPrintf(viewer,"    Using nodal relaxation via Schwarz smoothing on levels %D\n",jac->nodal_relax_levels);CHKERRQ(ierr);
10118f87f92bSBarry Smith     }
101216d9e3a6SLisandro Dalcin   }
101316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
101416d9e3a6SLisandro Dalcin }
101516d9e3a6SLisandro Dalcin 
101616d9e3a6SLisandro Dalcin /* --------------------------------------------------------------------------------------------*/
10174416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PetscOptionItems *PetscOptionsObject,PC pc)
101816d9e3a6SLisandro Dalcin {
101916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
102016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
10214ddd07fcSJed Brown   PetscInt       indx;
1022ace3abfcSBarry Smith   PetscBool      flag;
102316d9e3a6SLisandro Dalcin   const char     *symtlist[] = {"nonsymmetric","SPD","nonsymmetric,SPD"};
102416d9e3a6SLisandro Dalcin 
102516d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1026e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ParaSails Options");CHKERRQ(ierr);
102716d9e3a6SLisandro Dalcin   ierr = PetscOptionsInt("-pc_hypre_parasails_nlevels","Number of number of levels","None",jac->nlevels,&jac->nlevels,0);CHKERRQ(ierr);
10288966356dSPierre Jolivet   ierr = PetscOptionsReal("-pc_hypre_parasails_thresh","Threshold","None",jac->threshold,&jac->threshold,&flag);CHKERRQ(ierr);
10298966356dSPierre Jolivet   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshold,jac->nlevels));
103016d9e3a6SLisandro Dalcin 
103116d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_filter","filter","None",jac->filter,&jac->filter,&flag);CHKERRQ(ierr);
10322fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
103316d9e3a6SLisandro Dalcin 
103416d9e3a6SLisandro Dalcin   ierr = PetscOptionsReal("-pc_hypre_parasails_loadbal","Load balance","None",jac->loadbal,&jac->loadbal,&flag);CHKERRQ(ierr);
10352fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
103616d9e3a6SLisandro Dalcin 
1037acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_logging","Print info to screen","None",(PetscBool)jac->logging,(PetscBool*)&jac->logging,&flag);CHKERRQ(ierr);
10382fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
103916d9e3a6SLisandro Dalcin 
1040acfcf0e5SJed Brown   ierr = PetscOptionsBool("-pc_hypre_parasails_reuse","Reuse nonzero pattern in preconditioner","None",(PetscBool)jac->ruse,(PetscBool*)&jac->ruse,&flag);CHKERRQ(ierr);
10412fa5cd67SKarl Rupp   if (flag) PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
104216d9e3a6SLisandro Dalcin 
1043a669f990SJed Brown   ierr = PetscOptionsEList("-pc_hypre_parasails_sym","Symmetry of matrix and preconditioner","None",symtlist,ALEN(symtlist),symtlist[0],&indx,&flag);CHKERRQ(ierr);
104416d9e3a6SLisandro Dalcin   if (flag) {
104516d9e3a6SLisandro Dalcin     jac->symt = indx;
1046fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
104716d9e3a6SLisandro Dalcin   }
104816d9e3a6SLisandro Dalcin 
104916d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
105016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
105116d9e3a6SLisandro Dalcin }
105216d9e3a6SLisandro Dalcin 
105316d9e3a6SLisandro Dalcin static PetscErrorCode PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)
105416d9e3a6SLisandro Dalcin {
105516d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
105616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1057ace3abfcSBarry Smith   PetscBool      iascii;
1058feb237baSPierre Jolivet   const char     *symt = 0;
105916d9e3a6SLisandro Dalcin 
106016d9e3a6SLisandro Dalcin   PetscFunctionBegin;
1061251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
106216d9e3a6SLisandro Dalcin   if (iascii) {
106316d9e3a6SLisandro Dalcin     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ParaSails preconditioning\n");CHKERRQ(ierr);
1064efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    nlevels %d\n",jac->nlevels);CHKERRQ(ierr);
10658966356dSPierre Jolivet     ierr = PetscViewerASCIIPrintf(viewer,"    threshold %g\n",(double)jac->threshold);CHKERRQ(ierr);
1066efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    filter %g\n",(double)jac->filter);CHKERRQ(ierr);
1067efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    load balance %g\n",(double)jac->loadbal);CHKERRQ(ierr);
1068efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    reuse nonzero structure %s\n",PetscBools[jac->ruse]);CHKERRQ(ierr);
1069efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    print info to screen %s\n",PetscBools[jac->logging]);CHKERRQ(ierr);
10702fa5cd67SKarl Rupp     if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
10712fa5cd67SKarl Rupp     else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
10722fa5cd67SKarl Rupp     else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
1073ce94432eSBarry Smith     else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Unknown HYPRE ParaSails symmetric option %d",jac->symt);
1074efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    %s\n",symt);CHKERRQ(ierr);
107516d9e3a6SLisandro Dalcin   }
107616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
107716d9e3a6SLisandro Dalcin }
10784cb006feSStefano Zampini /* --------------------------------------------------------------------------------------------*/
10794416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PetscOptionItems *PetscOptionsObject,PC pc)
10804cb006feSStefano Zampini {
10814cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
10824cb006feSStefano Zampini   PetscErrorCode ierr;
10834cb006feSStefano Zampini   PetscInt       n;
10844cb006feSStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
10854cb006feSStefano Zampini 
10864cb006feSStefano Zampini   PetscFunctionBegin;
10879fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE AMS Options");CHKERRQ(ierr);
1088863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ams_print_level","Debugging output level for AMS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1089863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1090863406b8SStefano 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);
1091863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
10924cb006feSStefano 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);
10934cb006feSStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1094863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_tol","Error tolerance for AMS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1095863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1096863406b8SStefano 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);
1097863406b8SStefano 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);
1098863406b8SStefano 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);
1099863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ams_omega","SSOR coefficient for AMS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
11004cb006feSStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1101863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1102863406b8SStefano Zampini                                                                       jac->as_relax_times,
1103863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1104863406b8SStefano Zampini                                                                       jac->as_omega));
11054cb006feSStefano Zampini   }
1106863406b8SStefano 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);
11074cb006feSStefano Zampini   n = 5;
1108863406b8SStefano Zampini   ierr = PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options","AMG options for vector Poisson","None",jac->as_amg_alpha_opts,&n,&flag2);CHKERRQ(ierr);
11094cb006feSStefano Zampini   if (flag || flag2) {
1110863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1111863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1112863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1113863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1114863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1115863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
11164cb006feSStefano Zampini   }
1117863406b8SStefano 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);
11184cb006feSStefano Zampini   n = 5;
1119863406b8SStefano 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);
11204cb006feSStefano Zampini   if (flag || flag2) {
1121863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1122863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1123863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1124863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1125863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1126863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
11274cb006feSStefano Zampini   }
112823df4f25SStefano 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);
112923df4f25SStefano Zampini   if (flag) { /* override HYPRE's default only if the options is used */
113023df4f25SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetProjectionFrequency,(jac->hsolver,jac->ams_proj_freq));
113123df4f25SStefano Zampini   }
11324cb006feSStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
11334cb006feSStefano Zampini   PetscFunctionReturn(0);
11344cb006feSStefano Zampini }
11354cb006feSStefano Zampini 
11364cb006feSStefano Zampini static PetscErrorCode PCView_HYPRE_AMS(PC pc,PetscViewer viewer)
11374cb006feSStefano Zampini {
11384cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
11394cb006feSStefano Zampini   PetscErrorCode ierr;
11404cb006feSStefano Zampini   PetscBool      iascii;
11414cb006feSStefano Zampini 
11424cb006feSStefano Zampini   PetscFunctionBegin;
11434cb006feSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
11444cb006feSStefano Zampini   if (iascii) {
11454cb006feSStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE AMS preconditioning\n");CHKERRQ(ierr);
1146efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1147efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1148efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1149efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1150efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1151efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1152efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
11534cb006feSStefano Zampini     if (jac->alpha_Poisson) {
1154efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (passed in by user)\n");CHKERRQ(ierr);
11554cb006feSStefano Zampini     } else {
1156efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver (computed) \n");CHKERRQ(ierr);
11574cb006feSStefano Zampini     }
1158efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1159efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1160efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1161efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1162efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1163efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
11644cb006feSStefano Zampini     if (!jac->ams_beta_is_zero) {
11654cb006feSStefano Zampini       if (jac->beta_Poisson) {
1166efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (passed in by user)\n");CHKERRQ(ierr);
11674cb006feSStefano Zampini       } else {
1168efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver (computed) \n");CHKERRQ(ierr);
11694cb006feSStefano Zampini       }
1170efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1171efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1172efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1173efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1174efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1175efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"        boomerAMG strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
117623df4f25SStefano Zampini       if (jac->ams_beta_is_zero_part) {
1177efd4aadfSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"        compatible subspace projection frequency %d (-1 HYPRE uses default)\n",jac->ams_proj_freq);CHKERRQ(ierr);
117823df4f25SStefano Zampini       }
117923df4f25SStefano Zampini     } else {
1180efd4aadfSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"    scalar Poisson solver not used (zero-conductivity everywhere) \n");CHKERRQ(ierr);
11814cb006feSStefano Zampini     }
11824cb006feSStefano Zampini   }
11834cb006feSStefano Zampini   PetscFunctionReturn(0);
11844cb006feSStefano Zampini }
11854cb006feSStefano Zampini 
11864416b707SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PetscOptionItems *PetscOptionsObject,PC pc)
1187863406b8SStefano Zampini {
1188863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1189863406b8SStefano Zampini   PetscErrorCode ierr;
1190863406b8SStefano Zampini   PetscInt       n;
1191863406b8SStefano Zampini   PetscBool      flag,flag2,flag3,flag4;
1192863406b8SStefano Zampini 
1193863406b8SStefano Zampini   PetscFunctionBegin;
1194863406b8SStefano Zampini   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE ADS Options");CHKERRQ(ierr);
1195863406b8SStefano Zampini   ierr = PetscOptionsInt("-pc_hypre_ads_print_level","Debugging output level for ADS","None",jac->as_print,&jac->as_print,&flag);CHKERRQ(ierr);
1196863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1197863406b8SStefano 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);
1198863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1199863406b8SStefano 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);
1200863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ads_cycle_type));
1201863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_tol","Error tolerance for ADS multigrid","None",jac->as_tol,&jac->as_tol,&flag);CHKERRQ(ierr);
1202863406b8SStefano Zampini   if (flag) PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1203863406b8SStefano 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);
1204863406b8SStefano 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);
1205863406b8SStefano 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);
1206863406b8SStefano Zampini   ierr = PetscOptionsReal("-pc_hypre_ads_omega","SSOR coefficient for ADS smoother","None",jac->as_omega,&jac->as_omega,&flag4);CHKERRQ(ierr);
1207863406b8SStefano Zampini   if (flag || flag2 || flag3 || flag4) {
1208863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1209863406b8SStefano Zampini                                                                       jac->as_relax_times,
1210863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1211863406b8SStefano Zampini                                                                       jac->as_omega));
1212863406b8SStefano Zampini   }
1213863406b8SStefano 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);
1214863406b8SStefano Zampini   n = 5;
1215863406b8SStefano 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);
1216863406b8SStefano 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);
1217863406b8SStefano Zampini   if (flag || flag2 || flag3) {
1218863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMS cycle type */
1219863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1220863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1221863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1222863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1223863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1224863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1225863406b8SStefano Zampini   }
1226863406b8SStefano 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);
1227863406b8SStefano Zampini   n = 5;
1228863406b8SStefano 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);
1229863406b8SStefano Zampini   if (flag || flag2) {
1230863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1231863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1232863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1233863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1234863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1235863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1236863406b8SStefano Zampini   }
1237863406b8SStefano Zampini   ierr = PetscOptionsTail();CHKERRQ(ierr);
1238863406b8SStefano Zampini   PetscFunctionReturn(0);
1239863406b8SStefano Zampini }
1240863406b8SStefano Zampini 
1241863406b8SStefano Zampini static PetscErrorCode PCView_HYPRE_ADS(PC pc,PetscViewer viewer)
1242863406b8SStefano Zampini {
1243863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
1244863406b8SStefano Zampini   PetscErrorCode ierr;
1245863406b8SStefano Zampini   PetscBool      iascii;
1246863406b8SStefano Zampini 
1247863406b8SStefano Zampini   PetscFunctionBegin;
1248863406b8SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1249863406b8SStefano Zampini   if (iascii) {
1250863406b8SStefano Zampini     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE ADS preconditioning\n");CHKERRQ(ierr);
1251efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iterations per application %d\n",jac->as_max_iter);CHKERRQ(ierr);
1252efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace cycle type %d\n",jac->ads_cycle_type);CHKERRQ(ierr);
1253efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    subspace iteration tolerance %g\n",jac->as_tol);CHKERRQ(ierr);
1254efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother type %d\n",jac->as_relax_type);CHKERRQ(ierr);
1255efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number of smoothing steps %d\n",jac->as_relax_times);CHKERRQ(ierr);
1256efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother weight %g\n",jac->as_relax_weight);CHKERRQ(ierr);
1257efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    smoother omega %g\n",jac->as_omega);CHKERRQ(ierr);
1258efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    AMS solver using boomerAMG\n");CHKERRQ(ierr);
1259efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        subspace cycle type %d\n",jac->ams_cycle_type);CHKERRQ(ierr);
1260efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_alpha_opts[0]);CHKERRQ(ierr);
1261efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_alpha_opts[1]);CHKERRQ(ierr);
1262efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_alpha_opts[2]);CHKERRQ(ierr);
1263efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_alpha_opts[3]);CHKERRQ(ierr);
1264efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_alpha_opts[4]);CHKERRQ(ierr);
1265efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_alpha_theta);CHKERRQ(ierr);
1266efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    vector Poisson solver using boomerAMG\n");CHKERRQ(ierr);
1267efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        coarsening type %d\n",jac->as_amg_beta_opts[0]);CHKERRQ(ierr);
1268efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        levels of aggressive coarsening %d\n",jac->as_amg_beta_opts[1]);CHKERRQ(ierr);
1269efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        relaxation type %d\n",jac->as_amg_beta_opts[2]);CHKERRQ(ierr);
1270efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        interpolation type %d\n",jac->as_amg_beta_opts[3]);CHKERRQ(ierr);
1271efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        max nonzero elements in interpolation rows %d\n",jac->as_amg_beta_opts[4]);CHKERRQ(ierr);
1272efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"        strength threshold %g\n",jac->as_amg_beta_theta);CHKERRQ(ierr);
1273863406b8SStefano Zampini   }
1274863406b8SStefano Zampini   PetscFunctionReturn(0);
1275863406b8SStefano Zampini }
1276863406b8SStefano Zampini 
1277863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
12784cb006feSStefano Zampini {
12794cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
12805ac14e1cSStefano Zampini   PetscBool      ishypre;
12814cb006feSStefano Zampini   PetscErrorCode ierr;
12824cb006feSStefano Zampini 
12834cb006feSStefano Zampini   PetscFunctionBegin;
12845ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)G,MATHYPRE,&ishypre);CHKERRQ(ierr);
12855ac14e1cSStefano Zampini   if (ishypre) {
12865ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)G);CHKERRQ(ierr);
12875ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
12885ac14e1cSStefano Zampini     jac->G = G;
12895ac14e1cSStefano Zampini   } else {
12906bf688a0SCe Qin     ierr = MatDestroy(&jac->G);CHKERRQ(ierr);
12916bf688a0SCe Qin     ierr = MatConvert(G,MATHYPRE,MAT_INITIAL_MATRIX,&jac->G);CHKERRQ(ierr);
12925ac14e1cSStefano Zampini   }
12934cb006feSStefano Zampini   PetscFunctionReturn(0);
12944cb006feSStefano Zampini }
12954cb006feSStefano Zampini 
12964cb006feSStefano Zampini /*@
12974cb006feSStefano Zampini  PCHYPRESetDiscreteGradient - Set discrete gradient matrix
12984cb006feSStefano Zampini 
12994cb006feSStefano Zampini    Collective on PC
13004cb006feSStefano Zampini 
13014cb006feSStefano Zampini    Input Parameters:
13024cb006feSStefano Zampini +  pc - the preconditioning context
13034cb006feSStefano Zampini -  G - the discrete gradient
13044cb006feSStefano Zampini 
13054cb006feSStefano Zampini    Level: intermediate
13064cb006feSStefano Zampini 
130795452b02SPatrick Sanan    Notes:
130895452b02SPatrick Sanan     G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh
1309863406b8SStefano 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
13104cb006feSStefano Zampini 
13114cb006feSStefano Zampini .seealso:
13124cb006feSStefano Zampini @*/
13134cb006feSStefano Zampini PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
13144cb006feSStefano Zampini {
13154cb006feSStefano Zampini   PetscErrorCode ierr;
13164cb006feSStefano Zampini 
13174cb006feSStefano Zampini   PetscFunctionBegin;
13184cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
13194cb006feSStefano Zampini   PetscValidHeaderSpecific(G,MAT_CLASSID,2);
13204cb006feSStefano Zampini   PetscCheckSameComm(pc,1,G,2);
13214cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteGradient_C",(PC,Mat),(pc,G));CHKERRQ(ierr);
13224cb006feSStefano Zampini   PetscFunctionReturn(0);
13234cb006feSStefano Zampini }
13244cb006feSStefano Zampini 
1325863406b8SStefano Zampini static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1326863406b8SStefano Zampini {
1327863406b8SStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
13285ac14e1cSStefano Zampini   PetscBool      ishypre;
1329863406b8SStefano Zampini   PetscErrorCode ierr;
1330863406b8SStefano Zampini 
1331863406b8SStefano Zampini   PetscFunctionBegin;
13325ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)C,MATHYPRE,&ishypre);CHKERRQ(ierr);
13335ac14e1cSStefano Zampini   if (ishypre) {
13345ac14e1cSStefano Zampini     ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr);
13355ac14e1cSStefano Zampini     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
13365ac14e1cSStefano Zampini     jac->C = C;
13375ac14e1cSStefano Zampini   } else {
13386bf688a0SCe Qin     ierr = MatDestroy(&jac->C);CHKERRQ(ierr);
13396bf688a0SCe Qin     ierr = MatConvert(C,MATHYPRE,MAT_INITIAL_MATRIX,&jac->C);CHKERRQ(ierr);
13405ac14e1cSStefano Zampini   }
1341863406b8SStefano Zampini   PetscFunctionReturn(0);
1342863406b8SStefano Zampini }
1343863406b8SStefano Zampini 
1344863406b8SStefano Zampini /*@
1345863406b8SStefano Zampini  PCHYPRESetDiscreteCurl - Set discrete curl matrix
1346863406b8SStefano Zampini 
1347863406b8SStefano Zampini    Collective on PC
1348863406b8SStefano Zampini 
1349863406b8SStefano Zampini    Input Parameters:
1350863406b8SStefano Zampini +  pc - the preconditioning context
1351863406b8SStefano Zampini -  C - the discrete curl
1352863406b8SStefano Zampini 
1353863406b8SStefano Zampini    Level: intermediate
1354863406b8SStefano Zampini 
135595452b02SPatrick Sanan    Notes:
135695452b02SPatrick Sanan     C should have as many rows as the number of faces and as many columns as the number of edges in the mesh
1357863406b8SStefano 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
1358863406b8SStefano Zampini 
1359863406b8SStefano Zampini .seealso:
1360863406b8SStefano Zampini @*/
1361863406b8SStefano Zampini PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1362863406b8SStefano Zampini {
1363863406b8SStefano Zampini   PetscErrorCode ierr;
1364863406b8SStefano Zampini 
1365863406b8SStefano Zampini   PetscFunctionBegin;
1366863406b8SStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1367863406b8SStefano Zampini   PetscValidHeaderSpecific(C,MAT_CLASSID,2);
1368863406b8SStefano Zampini   PetscCheckSameComm(pc,1,C,2);
1369863406b8SStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetDiscreteCurl_C",(PC,Mat),(pc,C));CHKERRQ(ierr);
1370863406b8SStefano Zampini   PetscFunctionReturn(0);
1371863406b8SStefano Zampini }
1372863406b8SStefano Zampini 
13736bf688a0SCe Qin static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
13746bf688a0SCe Qin {
13756bf688a0SCe Qin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
13766bf688a0SCe Qin   PetscBool      ishypre;
13776bf688a0SCe Qin   PetscErrorCode ierr;
13786bf688a0SCe Qin   PetscInt       i;
13796bf688a0SCe Qin   PetscFunctionBegin;
13806bf688a0SCe Qin 
13816bf688a0SCe Qin   ierr = MatDestroy(&jac->RT_PiFull);CHKERRQ(ierr);
13826bf688a0SCe Qin   ierr = MatDestroy(&jac->ND_PiFull);CHKERRQ(ierr);
13836bf688a0SCe Qin   for (i=0;i<3;++i) {
13846bf688a0SCe Qin     ierr = MatDestroy(&jac->RT_Pi[i]);CHKERRQ(ierr);
13856bf688a0SCe Qin     ierr = MatDestroy(&jac->ND_Pi[i]);CHKERRQ(ierr);
13866bf688a0SCe Qin   }
13876bf688a0SCe Qin 
13886bf688a0SCe Qin   jac->dim = dim;
13896bf688a0SCe Qin   if (RT_PiFull) {
13906bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)RT_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
13916bf688a0SCe Qin     if (ishypre) {
13926bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)RT_PiFull);CHKERRQ(ierr);
13936bf688a0SCe Qin       jac->RT_PiFull = RT_PiFull;
13946bf688a0SCe Qin     } else {
13956bf688a0SCe Qin       ierr = MatConvert(RT_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_PiFull);CHKERRQ(ierr);
13966bf688a0SCe Qin     }
13976bf688a0SCe Qin   }
13986bf688a0SCe Qin   if (RT_Pi) {
13996bf688a0SCe Qin     for (i=0;i<dim;++i) {
14006bf688a0SCe Qin       if (RT_Pi[i]) {
14016bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)RT_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
14026bf688a0SCe Qin         if (ishypre) {
14036bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)RT_Pi[i]);CHKERRQ(ierr);
14046bf688a0SCe Qin           jac->RT_Pi[i] = RT_Pi[i];
14056bf688a0SCe Qin         } else {
14066bf688a0SCe Qin           ierr = MatConvert(RT_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->RT_Pi[i]);CHKERRQ(ierr);
14076bf688a0SCe Qin         }
14086bf688a0SCe Qin       }
14096bf688a0SCe Qin     }
14106bf688a0SCe Qin   }
14116bf688a0SCe Qin   if (ND_PiFull) {
14126bf688a0SCe Qin     ierr = PetscObjectTypeCompare((PetscObject)ND_PiFull,MATHYPRE,&ishypre);CHKERRQ(ierr);
14136bf688a0SCe Qin     if (ishypre) {
14146bf688a0SCe Qin       ierr = PetscObjectReference((PetscObject)ND_PiFull);CHKERRQ(ierr);
14156bf688a0SCe Qin       jac->ND_PiFull = ND_PiFull;
14166bf688a0SCe Qin     } else {
14176bf688a0SCe Qin       ierr = MatConvert(ND_PiFull,MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_PiFull);CHKERRQ(ierr);
14186bf688a0SCe Qin     }
14196bf688a0SCe Qin   }
14206bf688a0SCe Qin   if (ND_Pi) {
14216bf688a0SCe Qin     for (i=0;i<dim;++i) {
14226bf688a0SCe Qin       if (ND_Pi[i]) {
14236bf688a0SCe Qin         ierr = PetscObjectTypeCompare((PetscObject)ND_Pi[i],MATHYPRE,&ishypre);CHKERRQ(ierr);
14246bf688a0SCe Qin         if (ishypre) {
14256bf688a0SCe Qin           ierr = PetscObjectReference((PetscObject)ND_Pi[i]);CHKERRQ(ierr);
14266bf688a0SCe Qin           jac->ND_Pi[i] = ND_Pi[i];
14276bf688a0SCe Qin         } else {
14286bf688a0SCe Qin           ierr = MatConvert(ND_Pi[i],MATHYPRE,MAT_INITIAL_MATRIX,&jac->ND_Pi[i]);CHKERRQ(ierr);
14296bf688a0SCe Qin         }
14306bf688a0SCe Qin       }
14316bf688a0SCe Qin     }
14326bf688a0SCe Qin   }
14336bf688a0SCe Qin 
14346bf688a0SCe Qin   PetscFunctionReturn(0);
14356bf688a0SCe Qin }
14366bf688a0SCe Qin 
14376bf688a0SCe Qin /*@
14386bf688a0SCe Qin  PCHYPRESetInterpolations - Set interpolation matrices for AMS/ADS preconditioner
14396bf688a0SCe Qin 
14406bf688a0SCe Qin    Collective on PC
14416bf688a0SCe Qin 
14426bf688a0SCe Qin    Input Parameters:
14436bf688a0SCe Qin +  pc - the preconditioning context
14446bf688a0SCe Qin -  dim - the dimension of the problem, only used in AMS
14456bf688a0SCe Qin -  RT_PiFull - Raviart-Thomas interpolation matrix
14466bf688a0SCe Qin -  RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix
14476bf688a0SCe Qin -  ND_PiFull - Nedelec interpolation matrix
14486bf688a0SCe Qin -  ND_Pi - x/y/z component of Nedelec interpolation matrix
14496bf688a0SCe Qin 
145095452b02SPatrick Sanan    Notes:
145195452b02SPatrick Sanan     For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL.
14526bf688a0SCe Qin           For ADS, both type of interpolation matrices are needed.
14536bf688a0SCe Qin    Level: intermediate
14546bf688a0SCe Qin 
14556bf688a0SCe Qin .seealso:
14566bf688a0SCe Qin @*/
14576bf688a0SCe Qin PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
14586bf688a0SCe Qin {
14596bf688a0SCe Qin   PetscErrorCode ierr;
14606bf688a0SCe Qin   PetscInt       i;
14616bf688a0SCe Qin 
14626bf688a0SCe Qin   PetscFunctionBegin;
14636bf688a0SCe Qin   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
14646bf688a0SCe Qin   if (RT_PiFull) {
14656bf688a0SCe Qin     PetscValidHeaderSpecific(RT_PiFull,MAT_CLASSID,3);
14666bf688a0SCe Qin     PetscCheckSameComm(pc,1,RT_PiFull,3);
14676bf688a0SCe Qin   }
14686bf688a0SCe Qin   if (RT_Pi) {
14696bf688a0SCe Qin     PetscValidPointer(RT_Pi,4);
14706bf688a0SCe Qin     for (i=0;i<dim;++i) {
14716bf688a0SCe Qin       if (RT_Pi[i]) {
14726bf688a0SCe Qin         PetscValidHeaderSpecific(RT_Pi[i],MAT_CLASSID,4);
14736bf688a0SCe Qin         PetscCheckSameComm(pc,1,RT_Pi[i],4);
14746bf688a0SCe Qin       }
14756bf688a0SCe Qin     }
14766bf688a0SCe Qin   }
14776bf688a0SCe Qin   if (ND_PiFull) {
14786bf688a0SCe Qin     PetscValidHeaderSpecific(ND_PiFull,MAT_CLASSID,5);
14796bf688a0SCe Qin     PetscCheckSameComm(pc,1,ND_PiFull,5);
14806bf688a0SCe Qin   }
14816bf688a0SCe Qin   if (ND_Pi) {
14826bf688a0SCe Qin     PetscValidPointer(ND_Pi,6);
14836bf688a0SCe Qin     for (i=0;i<dim;++i) {
14846bf688a0SCe Qin       if (ND_Pi[i]) {
14856bf688a0SCe Qin         PetscValidHeaderSpecific(ND_Pi[i],MAT_CLASSID,6);
14866bf688a0SCe Qin         PetscCheckSameComm(pc,1,ND_Pi[i],6);
14876bf688a0SCe Qin       }
14886bf688a0SCe Qin     }
14896bf688a0SCe Qin   }
14906bf688a0SCe Qin   ierr = PetscTryMethod(pc,"PCHYPRESetInterpolations_C",(PC,PetscInt,Mat,Mat[],Mat,Mat[]),(pc,dim,RT_PiFull,RT_Pi,ND_PiFull,ND_Pi));CHKERRQ(ierr);
14916bf688a0SCe Qin   PetscFunctionReturn(0);
14926bf688a0SCe Qin }
14936bf688a0SCe Qin 
14945ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha)
14954cb006feSStefano Zampini {
14964cb006feSStefano Zampini   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
14975ac14e1cSStefano Zampini   PetscBool      ishypre;
14984cb006feSStefano Zampini   PetscErrorCode ierr;
14994cb006feSStefano Zampini 
15004cb006feSStefano Zampini   PetscFunctionBegin;
15015ac14e1cSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr);
15025ac14e1cSStefano Zampini   if (ishypre) {
15035ac14e1cSStefano Zampini     if (isalpha) {
15045ac14e1cSStefano Zampini       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
15055ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
15065ac14e1cSStefano Zampini       jac->alpha_Poisson = A;
15075ac14e1cSStefano Zampini     } else {
15085ac14e1cSStefano Zampini       if (A) {
15095ac14e1cSStefano Zampini         ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
15105ac14e1cSStefano Zampini       } else {
15115ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
15125ac14e1cSStefano Zampini       }
15135ac14e1cSStefano Zampini       ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
15145ac14e1cSStefano Zampini       jac->beta_Poisson = A;
15155ac14e1cSStefano Zampini     }
15165ac14e1cSStefano Zampini   } else {
15175ac14e1cSStefano Zampini     if (isalpha) {
15186bf688a0SCe Qin       ierr = MatDestroy(&jac->alpha_Poisson);CHKERRQ(ierr);
15196bf688a0SCe Qin       ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->alpha_Poisson);CHKERRQ(ierr);
15205ac14e1cSStefano Zampini     } else {
15215ac14e1cSStefano Zampini       if (A) {
15226bf688a0SCe Qin         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
15236bf688a0SCe Qin         ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&jac->beta_Poisson);CHKERRQ(ierr);
15245ac14e1cSStefano Zampini       } else {
15255ac14e1cSStefano Zampini         ierr = MatDestroy(&jac->beta_Poisson);CHKERRQ(ierr);
15265ac14e1cSStefano Zampini         jac->ams_beta_is_zero = PETSC_TRUE;
15275ac14e1cSStefano Zampini       }
15285ac14e1cSStefano Zampini     }
15295ac14e1cSStefano Zampini   }
15304cb006feSStefano Zampini   PetscFunctionReturn(0);
15314cb006feSStefano Zampini }
15324cb006feSStefano Zampini 
15334cb006feSStefano Zampini /*@
15344cb006feSStefano Zampini  PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix
15354cb006feSStefano Zampini 
15364cb006feSStefano Zampini    Collective on PC
15374cb006feSStefano Zampini 
15384cb006feSStefano Zampini    Input Parameters:
15394cb006feSStefano Zampini +  pc - the preconditioning context
15404cb006feSStefano Zampini -  A - the matrix
15414cb006feSStefano Zampini 
15424cb006feSStefano Zampini    Level: intermediate
15434cb006feSStefano Zampini 
154495452b02SPatrick Sanan    Notes:
154595452b02SPatrick Sanan     A should be obtained by discretizing the vector valued Poisson problem with linear finite elements
15464cb006feSStefano Zampini 
15474cb006feSStefano Zampini .seealso:
15484cb006feSStefano Zampini @*/
15494cb006feSStefano Zampini PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
15504cb006feSStefano Zampini {
15514cb006feSStefano Zampini   PetscErrorCode ierr;
15524cb006feSStefano Zampini 
15534cb006feSStefano Zampini   PetscFunctionBegin;
15544cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15554cb006feSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
15564cb006feSStefano Zampini   PetscCheckSameComm(pc,1,A,2);
15575ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_TRUE));CHKERRQ(ierr);
15584cb006feSStefano Zampini   PetscFunctionReturn(0);
15594cb006feSStefano Zampini }
15604cb006feSStefano Zampini 
15614cb006feSStefano Zampini /*@
15624cb006feSStefano Zampini  PCHYPRESetBetaPoissonMatrix - Set Poisson matrix
15634cb006feSStefano Zampini 
15644cb006feSStefano Zampini    Collective on PC
15654cb006feSStefano Zampini 
15664cb006feSStefano Zampini    Input Parameters:
15674cb006feSStefano Zampini +  pc - the preconditioning context
15684cb006feSStefano Zampini -  A - the matrix
15694cb006feSStefano Zampini 
15704cb006feSStefano Zampini    Level: intermediate
15714cb006feSStefano Zampini 
157295452b02SPatrick Sanan    Notes:
157395452b02SPatrick Sanan     A should be obtained by discretizing the Poisson problem with linear finite elements.
15744cb006feSStefano Zampini           Following HYPRE convention, the scalar Poisson solver of AMS can be turned off by passing NULL.
15754cb006feSStefano Zampini 
15764cb006feSStefano Zampini .seealso:
15774cb006feSStefano Zampini @*/
15784cb006feSStefano Zampini PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
15794cb006feSStefano Zampini {
15804cb006feSStefano Zampini   PetscErrorCode ierr;
15814cb006feSStefano Zampini 
15824cb006feSStefano Zampini   PetscFunctionBegin;
15834cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
15844cb006feSStefano Zampini   if (A) {
15854cb006feSStefano Zampini     PetscValidHeaderSpecific(A,MAT_CLASSID,2);
15864cb006feSStefano Zampini     PetscCheckSameComm(pc,1,A,2);
15874cb006feSStefano Zampini   }
15885ac14e1cSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetPoissonMatrix_C",(PC,Mat,PetscBool),(pc,A,PETSC_FALSE));CHKERRQ(ierr);
15894cb006feSStefano Zampini   PetscFunctionReturn(0);
15904cb006feSStefano Zampini }
15914cb006feSStefano Zampini 
15925ac14e1cSStefano Zampini static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz, Vec zoz, Vec zzo)
15934cb006feSStefano Zampini {
15944cb006feSStefano Zampini   PC_HYPRE           *jac = (PC_HYPRE*)pc->data;
15954cb006feSStefano Zampini   PetscErrorCode     ierr;
15964cb006feSStefano Zampini 
15974cb006feSStefano Zampini   PetscFunctionBegin;
15984cb006feSStefano Zampini   /* throw away any vector if already set */
15994cb006feSStefano Zampini   if (jac->constants[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[0]));
16004cb006feSStefano Zampini   if (jac->constants[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[1]));
16014cb006feSStefano Zampini   if (jac->constants[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->constants[2]));
16024cb006feSStefano Zampini   jac->constants[0] = NULL;
16034cb006feSStefano Zampini   jac->constants[1] = NULL;
16044cb006feSStefano Zampini   jac->constants[2] = NULL;
16054cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(ozz,&jac->constants[0]);CHKERRQ(ierr);
16064cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(ozz,jac->constants[0]);CHKERRQ(ierr);
16074cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCreate(zoz,&jac->constants[1]);CHKERRQ(ierr);
16084cb006feSStefano Zampini   ierr = VecHYPRE_IJVectorCopy(zoz,jac->constants[1]);CHKERRQ(ierr);
16095ac14e1cSStefano Zampini   jac->dim = 2;
16104cb006feSStefano Zampini   if (zzo) {
16114cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(zzo,&jac->constants[2]);CHKERRQ(ierr);
16124cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCopy(zzo,jac->constants[2]);CHKERRQ(ierr);
16135ac14e1cSStefano Zampini     jac->dim++;
16144cb006feSStefano Zampini   }
16154cb006feSStefano Zampini   PetscFunctionReturn(0);
16164cb006feSStefano Zampini }
16174cb006feSStefano Zampini 
16184cb006feSStefano Zampini /*@
16194cb006feSStefano Zampini  PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in edge element basis
16204cb006feSStefano Zampini 
16214cb006feSStefano Zampini    Collective on PC
16224cb006feSStefano Zampini 
16234cb006feSStefano Zampini    Input Parameters:
16244cb006feSStefano Zampini +  pc - the preconditioning context
16254cb006feSStefano Zampini -  ozz - vector representing (1,0,0) (or (1,0) in 2D)
16264cb006feSStefano Zampini -  zoz - vector representing (0,1,0) (or (0,1) in 2D)
16274cb006feSStefano Zampini -  zzo - vector representing (0,0,1) (use NULL in 2D)
16284cb006feSStefano Zampini 
16294cb006feSStefano Zampini    Level: intermediate
16304cb006feSStefano Zampini 
16314cb006feSStefano Zampini    Notes:
16324cb006feSStefano Zampini 
16334cb006feSStefano Zampini .seealso:
16344cb006feSStefano Zampini @*/
16354cb006feSStefano Zampini PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
16364cb006feSStefano Zampini {
16374cb006feSStefano Zampini   PetscErrorCode ierr;
16384cb006feSStefano Zampini 
16394cb006feSStefano Zampini   PetscFunctionBegin;
16404cb006feSStefano Zampini   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
16414cb006feSStefano Zampini   PetscValidHeaderSpecific(ozz,VEC_CLASSID,2);
16424cb006feSStefano Zampini   PetscValidHeaderSpecific(zoz,VEC_CLASSID,3);
16434cb006feSStefano Zampini   if (zzo) PetscValidHeaderSpecific(zzo,VEC_CLASSID,4);
16444cb006feSStefano Zampini   PetscCheckSameComm(pc,1,ozz,2);
16454cb006feSStefano Zampini   PetscCheckSameComm(pc,1,zoz,3);
16464cb006feSStefano Zampini   if (zzo) PetscCheckSameComm(pc,1,zzo,4);
16474cb006feSStefano Zampini   ierr = PetscTryMethod(pc,"PCHYPRESetEdgeConstantVectors_C",(PC,Vec,Vec,Vec),(pc,ozz,zoz,zzo));CHKERRQ(ierr);
16484cb006feSStefano Zampini   PetscFunctionReturn(0);
16494cb006feSStefano Zampini }
16504cb006feSStefano Zampini 
1651863406b8SStefano Zampini static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
16524cb006feSStefano Zampini {
16534cb006feSStefano Zampini   PC_HYPRE        *jac = (PC_HYPRE*)pc->data;
16544cb006feSStefano Zampini   Vec             tv;
16554cb006feSStefano Zampini   PetscInt        i;
16564cb006feSStefano Zampini   PetscErrorCode  ierr;
16574cb006feSStefano Zampini 
16584cb006feSStefano Zampini   PetscFunctionBegin;
16594cb006feSStefano Zampini   /* throw away any coordinate vector if already set */
16604cb006feSStefano Zampini   if (jac->coords[0]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[0]));
16614cb006feSStefano Zampini   if (jac->coords[1]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[1]));
16624cb006feSStefano Zampini   if (jac->coords[2]) PetscStackCallStandard(HYPRE_IJVectorDestroy,(jac->coords[2]));
16635ac14e1cSStefano Zampini   jac->dim = dim;
16645ac14e1cSStefano Zampini 
16654cb006feSStefano Zampini   /* compute IJ vector for coordinates */
16664cb006feSStefano Zampini   ierr = VecCreate(PetscObjectComm((PetscObject)pc),&tv);CHKERRQ(ierr);
16674cb006feSStefano Zampini   ierr = VecSetType(tv,VECSTANDARD);CHKERRQ(ierr);
16684cb006feSStefano Zampini   ierr = VecSetSizes(tv,nloc,PETSC_DECIDE);CHKERRQ(ierr);
16694cb006feSStefano Zampini   for (i=0;i<dim;i++) {
16704cb006feSStefano Zampini     PetscScalar *array;
16714cb006feSStefano Zampini     PetscInt    j;
16724cb006feSStefano Zampini 
16734cb006feSStefano Zampini     ierr = VecHYPRE_IJVectorCreate(tv,&jac->coords[i]);CHKERRQ(ierr);
16744cb006feSStefano Zampini     ierr = VecGetArray(tv,&array);CHKERRQ(ierr);
16754cb006feSStefano Zampini     for (j=0;j<nloc;j++) {
16764cb006feSStefano Zampini       array[j] = coords[j*dim+i];
16774cb006feSStefano Zampini     }
167839accc25SStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorSetValues,(jac->coords[i],nloc,NULL,(HYPRE_Complex*)array));
16794cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_IJVectorAssemble,(jac->coords[i]));
16804cb006feSStefano Zampini     ierr = VecRestoreArray(tv,&array);CHKERRQ(ierr);
16814cb006feSStefano Zampini   }
16824cb006feSStefano Zampini   ierr = VecDestroy(&tv);CHKERRQ(ierr);
16834cb006feSStefano Zampini   PetscFunctionReturn(0);
16844cb006feSStefano Zampini }
16854cb006feSStefano Zampini 
168616d9e3a6SLisandro Dalcin /* ---------------------------------------------------------------------------------*/
168716d9e3a6SLisandro Dalcin 
1688f7a08781SBarry Smith static PetscErrorCode  PCHYPREGetType_HYPRE(PC pc,const char *name[])
168916d9e3a6SLisandro Dalcin {
169016d9e3a6SLisandro Dalcin   PC_HYPRE *jac = (PC_HYPRE*)pc->data;
169116d9e3a6SLisandro Dalcin 
169216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
169316d9e3a6SLisandro Dalcin   *name = jac->hypre_type;
169416d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
169516d9e3a6SLisandro Dalcin }
169616d9e3a6SLisandro Dalcin 
1697f7a08781SBarry Smith static PetscErrorCode  PCHYPRESetType_HYPRE(PC pc,const char name[])
169816d9e3a6SLisandro Dalcin {
169916d9e3a6SLisandro Dalcin   PC_HYPRE       *jac = (PC_HYPRE*)pc->data;
170016d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
1701ace3abfcSBarry Smith   PetscBool      flag;
170216d9e3a6SLisandro Dalcin 
170316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
170416d9e3a6SLisandro Dalcin   if (jac->hypre_type) {
170516d9e3a6SLisandro Dalcin     ierr = PetscStrcmp(jac->hypre_type,name,&flag);CHKERRQ(ierr);
1706ce94432eSBarry Smith     if (!flag) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ORDER,"Cannot reset the HYPRE preconditioner type once it has been set");
170716d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
170816d9e3a6SLisandro Dalcin   } else {
170916d9e3a6SLisandro Dalcin     ierr = PetscStrallocpy(name, &jac->hypre_type);CHKERRQ(ierr);
171016d9e3a6SLisandro Dalcin   }
171116d9e3a6SLisandro Dalcin 
171216d9e3a6SLisandro Dalcin   jac->maxiter         = PETSC_DEFAULT;
171316d9e3a6SLisandro Dalcin   jac->tol             = PETSC_DEFAULT;
171416d9e3a6SLisandro Dalcin   jac->printstatistics = PetscLogPrintInfo;
171516d9e3a6SLisandro Dalcin 
171616d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("pilut",jac->hypre_type,&flag);CHKERRQ(ierr);
171716d9e3a6SLisandro Dalcin   if (flag) {
1718572a0576SBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1719fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParCSRPilutCreate,(jac->comm_hypre,&jac->hsolver));
172016d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
172116d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_Pilut;
172216d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParCSRPilutDestroy;
172316d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParCSRPilutSetup;
172416d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParCSRPilutSolve;
172516d9e3a6SLisandro Dalcin     jac->factorrowsize      = PETSC_DEFAULT;
172616d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
172716d9e3a6SLisandro Dalcin   }
1728db966c6cSHong Zhang   ierr = PetscStrcmp("euclid",jac->hypre_type,&flag);CHKERRQ(ierr);
1729db966c6cSHong Zhang   if (flag) {
1730db966c6cSHong Zhang     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1731db966c6cSHong Zhang     PetscStackCallStandard(HYPRE_EuclidCreate,(jac->comm_hypre,&jac->hsolver));
1732db966c6cSHong Zhang     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
1733db966c6cSHong Zhang     pc->ops->view           = PCView_HYPRE_Euclid;
1734db966c6cSHong Zhang     jac->destroy            = HYPRE_EuclidDestroy;
1735db966c6cSHong Zhang     jac->setup              = HYPRE_EuclidSetup;
1736db966c6cSHong Zhang     jac->solve              = HYPRE_EuclidSolve;
1737db966c6cSHong Zhang     jac->factorrowsize      = PETSC_DEFAULT;
1738db966c6cSHong Zhang     jac->eu_level           = PETSC_DEFAULT; /* default */
1739db966c6cSHong Zhang     PetscFunctionReturn(0);
1740db966c6cSHong Zhang   }
174116d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("parasails",jac->hypre_type,&flag);CHKERRQ(ierr);
174216d9e3a6SLisandro Dalcin   if (flag) {
1743572a0576SBarry Smith     ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(jac->comm_hypre));CHKERRQ(ierr);
1744fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsCreate,(jac->comm_hypre,&jac->hsolver));
174516d9e3a6SLisandro Dalcin     pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
174616d9e3a6SLisandro Dalcin     pc->ops->view           = PCView_HYPRE_ParaSails;
174716d9e3a6SLisandro Dalcin     jac->destroy            = HYPRE_ParaSailsDestroy;
174816d9e3a6SLisandro Dalcin     jac->setup              = HYPRE_ParaSailsSetup;
174916d9e3a6SLisandro Dalcin     jac->solve              = HYPRE_ParaSailsSolve;
175016d9e3a6SLisandro Dalcin     /* initialize */
175116d9e3a6SLisandro Dalcin     jac->nlevels   = 1;
17528966356dSPierre Jolivet     jac->threshold = .1;
175316d9e3a6SLisandro Dalcin     jac->filter    = .1;
175416d9e3a6SLisandro Dalcin     jac->loadbal   = 0;
17552fa5cd67SKarl Rupp     if (PetscLogPrintInfo) jac->logging = (int) PETSC_TRUE;
17562fa5cd67SKarl Rupp     else jac->logging = (int) PETSC_FALSE;
17572fa5cd67SKarl Rupp 
175816d9e3a6SLisandro Dalcin     jac->ruse = (int) PETSC_FALSE;
175916d9e3a6SLisandro Dalcin     jac->symt = 0;
17608966356dSPierre Jolivet     PetscStackCallStandard(HYPRE_ParaSailsSetParams,(jac->hsolver,jac->threshold,jac->nlevels));
1761fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetFilter,(jac->hsolver,jac->filter));
1762fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLoadbal,(jac->hsolver,jac->loadbal));
1763fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetLogging,(jac->hsolver,jac->logging));
1764fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetReuse,(jac->hsolver,jac->ruse));
1765fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_ParaSailsSetSym,(jac->hsolver,jac->symt));
176616d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
176716d9e3a6SLisandro Dalcin   }
176816d9e3a6SLisandro Dalcin   ierr = PetscStrcmp("boomeramg",jac->hypre_type,&flag);CHKERRQ(ierr);
176916d9e3a6SLisandro Dalcin   if (flag) {
177016d9e3a6SLisandro Dalcin     ierr                     = HYPRE_BoomerAMGCreate(&jac->hsolver);
177116d9e3a6SLisandro Dalcin     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_BoomerAMG;
177216d9e3a6SLisandro Dalcin     pc->ops->view            = PCView_HYPRE_BoomerAMG;
177316d9e3a6SLisandro Dalcin     pc->ops->applytranspose  = PCApplyTranspose_HYPRE_BoomerAMG;
177416d9e3a6SLisandro Dalcin     pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
1775fd2dd295SFande Kong     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetInterpolations_C",PCGetInterpolations_BoomerAMG);CHKERRQ(ierr);
1776fd2dd295SFande Kong     ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGetCoarseOperators_C",PCGetCoarseOperators_BoomerAMG);CHKERRQ(ierr);
177716d9e3a6SLisandro Dalcin     jac->destroy             = HYPRE_BoomerAMGDestroy;
177816d9e3a6SLisandro Dalcin     jac->setup               = HYPRE_BoomerAMGSetup;
177916d9e3a6SLisandro Dalcin     jac->solve               = HYPRE_BoomerAMGSolve;
178016d9e3a6SLisandro Dalcin     jac->applyrichardson     = PETSC_FALSE;
178116d9e3a6SLisandro Dalcin     /* these defaults match the hypre defaults */
178216d9e3a6SLisandro Dalcin     jac->cycletype        = 1;
178316d9e3a6SLisandro Dalcin     jac->maxlevels        = 25;
178416d9e3a6SLisandro Dalcin     jac->maxiter          = 1;
17858f87f92bSBarry Smith     jac->tol              = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
178616d9e3a6SLisandro Dalcin     jac->truncfactor      = 0.0;
178716d9e3a6SLisandro Dalcin     jac->strongthreshold  = .25;
178816d9e3a6SLisandro Dalcin     jac->maxrowsum        = .9;
178916d9e3a6SLisandro Dalcin     jac->coarsentype      = 6;
179016d9e3a6SLisandro Dalcin     jac->measuretype      = 0;
17910f1074feSSatish Balay     jac->gridsweeps[0]    = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
17926a251517SEike Mueller     jac->smoothtype       = -1; /* Not set by default */
1793b9eb5777SEike Mueller     jac->smoothnumlevels  = 25;
17941810e44eSEike Mueller     jac->eu_level         = 0;
17951810e44eSEike Mueller     jac->eu_droptolerance = 0;
17961810e44eSEike Mueller     jac->eu_bj            = 0;
17978f87f92bSBarry Smith     jac->relaxtype[0]     = jac->relaxtype[1] = 6; /* Defaults to SYMMETRIC since in PETSc we are using a a PC - most likely with CG */
17980f1074feSSatish Balay     jac->relaxtype[2]     = 9; /*G.E. */
179916d9e3a6SLisandro Dalcin     jac->relaxweight      = 1.0;
180016d9e3a6SLisandro Dalcin     jac->outerrelaxweight = 1.0;
180116d9e3a6SLisandro Dalcin     jac->relaxorder       = 1;
18020f1074feSSatish Balay     jac->interptype       = 0;
18030f1074feSSatish Balay     jac->agg_nl           = 0;
18040f1074feSSatish Balay     jac->pmax             = 0;
18050f1074feSSatish Balay     jac->truncfactor      = 0.0;
18060f1074feSSatish Balay     jac->agg_num_paths    = 1;
18078f87f92bSBarry Smith 
180822e51d31SStefano Zampini     jac->nodal_coarsening      = 0;
180922e51d31SStefano Zampini     jac->nodal_coarsening_diag = 0;
181022e51d31SStefano Zampini     jac->vec_interp_variant    = 0;
181122e51d31SStefano Zampini     jac->vec_interp_qmax       = 0;
181222e51d31SStefano Zampini     jac->vec_interp_smooth     = PETSC_FALSE;
181322e51d31SStefano Zampini     jac->interp_refine         = 0;
18148f87f92bSBarry Smith     jac->nodal_relax           = PETSC_FALSE;
18158f87f92bSBarry Smith     jac->nodal_relax_levels    = 1;
1816fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCycleType,(jac->hsolver,jac->cycletype));
1817fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxLevels,(jac->hsolver,jac->maxlevels));
1818fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxIter,(jac->hsolver,jac->maxiter));
1819fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTol,(jac->hsolver,jac->tol));
1820fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetTruncFactor,(jac->hsolver,jac->truncfactor));
1821fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetStrongThreshold,(jac->hsolver,jac->strongthreshold));
1822fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMaxRowSum,(jac->hsolver,jac->maxrowsum));
1823fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetCoarsenType,(jac->hsolver,jac->coarsentype));
1824fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetMeasureType,(jac->hsolver,jac->measuretype));
1825fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxOrder,(jac->hsolver, jac->relaxorder));
1826fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetInterpType,(jac->hsolver,jac->interptype));
1827fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetAggNumLevels,(jac->hsolver,jac->agg_nl));
1828fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetPMaxElmts,(jac->hsolver,jac->pmax));
1829fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumPaths,(jac->hsolver,jac->agg_num_paths));
1830fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetRelaxType,(jac->hsolver, jac->relaxtype[0]));  /*defaults coarse to 9*/
1831fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_BoomerAMGSetNumSweeps,(jac->hsolver, jac->gridsweeps[0])); /*defaults coarse to 1 */
183216d9e3a6SLisandro Dalcin     PetscFunctionReturn(0);
183316d9e3a6SLisandro Dalcin   }
18344cb006feSStefano Zampini   ierr = PetscStrcmp("ams",jac->hypre_type,&flag);CHKERRQ(ierr);
18354cb006feSStefano Zampini   if (flag) {
18364cb006feSStefano Zampini     ierr                     = HYPRE_AMSCreate(&jac->hsolver);
18374cb006feSStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_AMS;
18384cb006feSStefano Zampini     pc->ops->view            = PCView_HYPRE_AMS;
18394cb006feSStefano Zampini     jac->destroy             = HYPRE_AMSDestroy;
18404cb006feSStefano Zampini     jac->setup               = HYPRE_AMSSetup;
18414cb006feSStefano Zampini     jac->solve               = HYPRE_AMSSolve;
18424cb006feSStefano Zampini     jac->coords[0]           = NULL;
18434cb006feSStefano Zampini     jac->coords[1]           = NULL;
18444cb006feSStefano Zampini     jac->coords[2]           = NULL;
18454cb006feSStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
1846863406b8SStefano Zampini     jac->as_print           = 0;
1847863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1848863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
18494cb006feSStefano Zampini     jac->ams_cycle_type     = 13;
18504cb006feSStefano Zampini     /* Smoothing options */
1851863406b8SStefano Zampini     jac->as_relax_type      = 2;
1852863406b8SStefano Zampini     jac->as_relax_times     = 1;
1853863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1854863406b8SStefano Zampini     jac->as_omega           = 1.0;
18554cb006feSStefano Zampini     /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1856863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1857863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
18580bdd8552SBarry Smith     jac->as_amg_alpha_opts[2] = 6;
1859863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1860863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1861863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
18624cb006feSStefano Zampini     /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1863863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1864863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
18650bdd8552SBarry Smith     jac->as_amg_beta_opts[2] = 6;
1866863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1867863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1868863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1869863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetPrintLevel,(jac->hsolver,jac->as_print));
1870863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetMaxIter,(jac->hsolver,jac->as_max_iter));
18714cb006feSStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1872863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetTol,(jac->hsolver,jac->as_tol));
1873863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1874863406b8SStefano Zampini                                                                       jac->as_relax_times,
1875863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1876863406b8SStefano Zampini                                                                       jac->as_omega));
1877863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetAlphaAMGOptions,(jac->hsolver,jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1878863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1879863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1880863406b8SStefano Zampini                                                                      jac->as_amg_alpha_theta,
1881863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1882863406b8SStefano Zampini                                                                      jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1883863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_AMSSetBetaAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1884863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1885863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[2],       /* AMG relax_type */
1886863406b8SStefano Zampini                                                                     jac->as_amg_beta_theta,
1887863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[3],       /* AMG interp_type */
1888863406b8SStefano Zampini                                                                     jac->as_amg_beta_opts[4]));     /* AMG Pmax */
188923df4f25SStefano Zampini     /* Zero conductivity */
189023df4f25SStefano Zampini     jac->ams_beta_is_zero      = PETSC_FALSE;
189123df4f25SStefano Zampini     jac->ams_beta_is_zero_part = PETSC_FALSE;
18924cb006feSStefano Zampini     PetscFunctionReturn(0);
18934cb006feSStefano Zampini   }
1894863406b8SStefano Zampini   ierr = PetscStrcmp("ads",jac->hypre_type,&flag);CHKERRQ(ierr);
1895863406b8SStefano Zampini   if (flag) {
1896863406b8SStefano Zampini     ierr                     = HYPRE_ADSCreate(&jac->hsolver);
1897863406b8SStefano Zampini     pc->ops->setfromoptions  = PCSetFromOptions_HYPRE_ADS;
1898863406b8SStefano Zampini     pc->ops->view            = PCView_HYPRE_ADS;
1899863406b8SStefano Zampini     jac->destroy             = HYPRE_ADSDestroy;
1900863406b8SStefano Zampini     jac->setup               = HYPRE_ADSSetup;
1901863406b8SStefano Zampini     jac->solve               = HYPRE_ADSSolve;
1902863406b8SStefano Zampini     jac->coords[0]           = NULL;
1903863406b8SStefano Zampini     jac->coords[1]           = NULL;
1904863406b8SStefano Zampini     jac->coords[2]           = NULL;
1905863406b8SStefano Zampini     /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
1906863406b8SStefano Zampini     jac->as_print           = 0;
1907863406b8SStefano Zampini     jac->as_max_iter        = 1; /* used as a preconditioner */
1908863406b8SStefano Zampini     jac->as_tol             = 0.; /* used as a preconditioner */
1909863406b8SStefano Zampini     jac->ads_cycle_type     = 13;
1910863406b8SStefano Zampini     /* Smoothing options */
1911863406b8SStefano Zampini     jac->as_relax_type      = 2;
1912863406b8SStefano Zampini     jac->as_relax_times     = 1;
1913863406b8SStefano Zampini     jac->as_relax_weight    = 1.0;
1914863406b8SStefano Zampini     jac->as_omega           = 1.0;
1915863406b8SStefano Zampini     /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
1916863406b8SStefano Zampini     jac->ams_cycle_type       = 14;
1917863406b8SStefano Zampini     jac->as_amg_alpha_opts[0] = 10;
1918863406b8SStefano Zampini     jac->as_amg_alpha_opts[1] = 1;
1919863406b8SStefano Zampini     jac->as_amg_alpha_opts[2] = 6;
1920863406b8SStefano Zampini     jac->as_amg_alpha_opts[3] = 6;
1921863406b8SStefano Zampini     jac->as_amg_alpha_opts[4] = 4;
1922863406b8SStefano Zampini     jac->as_amg_alpha_theta   = 0.25;
1923863406b8SStefano Zampini     /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
1924863406b8SStefano Zampini     jac->as_amg_beta_opts[0] = 10;
1925863406b8SStefano Zampini     jac->as_amg_beta_opts[1] = 1;
1926863406b8SStefano Zampini     jac->as_amg_beta_opts[2] = 6;
1927863406b8SStefano Zampini     jac->as_amg_beta_opts[3] = 6;
1928863406b8SStefano Zampini     jac->as_amg_beta_opts[4] = 4;
1929863406b8SStefano Zampini     jac->as_amg_beta_theta   = 0.25;
1930863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetPrintLevel,(jac->hsolver,jac->as_print));
1931863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetMaxIter,(jac->hsolver,jac->as_max_iter));
1932863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetCycleType,(jac->hsolver,jac->ams_cycle_type));
1933863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetTol,(jac->hsolver,jac->as_tol));
1934863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetSmoothingOptions,(jac->hsolver,jac->as_relax_type,
1935863406b8SStefano Zampini                                                                       jac->as_relax_times,
1936863406b8SStefano Zampini                                                                       jac->as_relax_weight,
1937863406b8SStefano Zampini                                                                       jac->as_omega));
1938863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMSOptions,(jac->hsolver,jac->ams_cycle_type,             /* AMG coarsen type */
1939863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[0],       /* AMG coarsen type */
1940863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[1],       /* AMG agg_levels */
1941863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[2],       /* AMG relax_type */
1942863406b8SStefano Zampini                                                                 jac->as_amg_alpha_theta,
1943863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[3],       /* AMG interp_type */
1944863406b8SStefano Zampini                                                                 jac->as_amg_alpha_opts[4]));     /* AMG Pmax */
1945863406b8SStefano Zampini     PetscStackCallStandard(HYPRE_ADSSetAMGOptions,(jac->hsolver,jac->as_amg_beta_opts[0],       /* AMG coarsen type */
1946863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[1],       /* AMG agg_levels */
1947863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[2],       /* AMG relax_type */
1948863406b8SStefano Zampini                                                                 jac->as_amg_beta_theta,
1949863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[3],       /* AMG interp_type */
1950863406b8SStefano Zampini                                                                 jac->as_amg_beta_opts[4]));     /* AMG Pmax */
1951863406b8SStefano Zampini     PetscFunctionReturn(0);
1952863406b8SStefano Zampini   }
1953503cfb0cSBarry Smith   ierr = PetscFree(jac->hypre_type);CHKERRQ(ierr);
19542fa5cd67SKarl Rupp 
19550298fd71SBarry Smith   jac->hypre_type = NULL;
1956db966c6cSHong Zhang   SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown HYPRE preconditioner %s; Choices are euclid, pilut, parasails, boomeramg, ams",name);
195716d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
195816d9e3a6SLisandro Dalcin }
195916d9e3a6SLisandro Dalcin 
196016d9e3a6SLisandro Dalcin /*
196116d9e3a6SLisandro Dalcin     It only gets here if the HYPRE type has not been set before the call to
196216d9e3a6SLisandro Dalcin    ...SetFromOptions() which actually is most of the time
196316d9e3a6SLisandro Dalcin */
1964360ee056SFande Kong PetscErrorCode PCSetFromOptions_HYPRE(PetscOptionItems *PetscOptionsObject,PC pc)
196516d9e3a6SLisandro Dalcin {
196616d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
19674ddd07fcSJed Brown   PetscInt       indx;
1968db966c6cSHong Zhang   const char     *type[] = {"euclid","pilut","parasails","boomeramg","ams","ads"};
1969ace3abfcSBarry Smith   PetscBool      flg;
197016d9e3a6SLisandro Dalcin 
197116d9e3a6SLisandro Dalcin   PetscFunctionBegin;
19729fa463a7SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"HYPRE preconditioner options");CHKERRQ(ierr);
1973cab5ea25SPierre Jolivet   ierr = PetscOptionsEList("-pc_hypre_type","HYPRE preconditioner type","PCHYPRESetType",type,ALEN(type),"boomeramg",&indx,&flg);CHKERRQ(ierr);
197416d9e3a6SLisandro Dalcin   if (flg) {
197516d9e3a6SLisandro Dalcin     ierr = PCHYPRESetType_HYPRE(pc,type[indx]);CHKERRQ(ierr);
197602a17cd4SBarry Smith   } else {
197702a17cd4SBarry Smith     ierr = PCHYPRESetType_HYPRE(pc,"boomeramg");CHKERRQ(ierr);
197816d9e3a6SLisandro Dalcin   }
197916d9e3a6SLisandro Dalcin   if (pc->ops->setfromoptions) {
19803931853cSBarry Smith     ierr = pc->ops->setfromoptions(PetscOptionsObject,pc);CHKERRQ(ierr);
198116d9e3a6SLisandro Dalcin   }
198216d9e3a6SLisandro Dalcin   ierr = PetscOptionsTail();CHKERRQ(ierr);
198316d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
198416d9e3a6SLisandro Dalcin }
198516d9e3a6SLisandro Dalcin 
198616d9e3a6SLisandro Dalcin /*@C
198716d9e3a6SLisandro Dalcin      PCHYPRESetType - Sets which hypre preconditioner you wish to use
198816d9e3a6SLisandro Dalcin 
198916d9e3a6SLisandro Dalcin    Input Parameters:
199016d9e3a6SLisandro Dalcin +     pc - the preconditioner context
1991db966c6cSHong Zhang -     name - either  euclid, pilut, parasails, boomeramg, ams, ads
199216d9e3a6SLisandro Dalcin 
199316d9e3a6SLisandro Dalcin    Options Database Keys:
1994db966c6cSHong Zhang    -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
199516d9e3a6SLisandro Dalcin 
199616d9e3a6SLisandro Dalcin    Level: intermediate
199716d9e3a6SLisandro Dalcin 
199816d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
199916d9e3a6SLisandro Dalcin            PCHYPRE
200016d9e3a6SLisandro Dalcin 
200116d9e3a6SLisandro Dalcin @*/
20027087cfbeSBarry Smith PetscErrorCode  PCHYPRESetType(PC pc,const char name[])
200316d9e3a6SLisandro Dalcin {
20044ac538c5SBarry Smith   PetscErrorCode ierr;
200516d9e3a6SLisandro Dalcin 
200616d9e3a6SLisandro Dalcin   PetscFunctionBegin;
20070700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
200816d9e3a6SLisandro Dalcin   PetscValidCharPointer(name,2);
20094ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPRESetType_C",(PC,const char[]),(pc,name));CHKERRQ(ierr);
201016d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
201116d9e3a6SLisandro Dalcin }
201216d9e3a6SLisandro Dalcin 
201316d9e3a6SLisandro Dalcin /*@C
201416d9e3a6SLisandro Dalcin      PCHYPREGetType - Gets which hypre preconditioner you are using
201516d9e3a6SLisandro Dalcin 
201616d9e3a6SLisandro Dalcin    Input Parameter:
201716d9e3a6SLisandro Dalcin .     pc - the preconditioner context
201816d9e3a6SLisandro Dalcin 
201916d9e3a6SLisandro Dalcin    Output Parameter:
2020db966c6cSHong Zhang .     name - either  euclid, pilut, parasails, boomeramg, ams, ads
202116d9e3a6SLisandro Dalcin 
202216d9e3a6SLisandro Dalcin    Level: intermediate
202316d9e3a6SLisandro Dalcin 
202416d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCHYPRESetType(), PCType (for list of available types), PC,
202516d9e3a6SLisandro Dalcin            PCHYPRE
202616d9e3a6SLisandro Dalcin 
202716d9e3a6SLisandro Dalcin @*/
20287087cfbeSBarry Smith PetscErrorCode  PCHYPREGetType(PC pc,const char *name[])
202916d9e3a6SLisandro Dalcin {
20304ac538c5SBarry Smith   PetscErrorCode ierr;
203116d9e3a6SLisandro Dalcin 
203216d9e3a6SLisandro Dalcin   PetscFunctionBegin;
20330700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
203416d9e3a6SLisandro Dalcin   PetscValidPointer(name,2);
20354ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCHYPREGetType_C",(PC,const char*[]),(pc,name));CHKERRQ(ierr);
203616d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
203716d9e3a6SLisandro Dalcin }
203816d9e3a6SLisandro Dalcin 
203916d9e3a6SLisandro Dalcin /*MC
204016d9e3a6SLisandro Dalcin      PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre
204116d9e3a6SLisandro Dalcin 
204216d9e3a6SLisandro Dalcin    Options Database Keys:
2043db966c6cSHong Zhang +   -pc_hypre_type - One of euclid, pilut, parasails, boomeramg, ams, ads
204416d9e3a6SLisandro Dalcin -   Too many others to list, run with -pc_type hypre -pc_hypre_type XXX -help to see options for the XXX
204516d9e3a6SLisandro Dalcin           preconditioner
204616d9e3a6SLisandro Dalcin 
204716d9e3a6SLisandro Dalcin    Level: intermediate
204816d9e3a6SLisandro Dalcin 
204995452b02SPatrick Sanan    Notes:
205095452b02SPatrick Sanan     Apart from pc_hypre_type (for which there is PCHYPRESetType()),
205116d9e3a6SLisandro Dalcin           the many hypre options can ONLY be set via the options database (e.g. the command line
205216d9e3a6SLisandro Dalcin           or with PetscOptionsSetValue(), there are no functions to set them)
205316d9e3a6SLisandro Dalcin 
2054c231f9e3SBarryFSmith           The options -pc_hypre_boomeramg_max_iter and -pc_hypre_boomeramg_tol refer to the number of iterations
20550f1074feSSatish Balay           (V-cycles) and tolerance that boomeramg does EACH time it is called. So for example, if
20560f1074feSSatish Balay           -pc_hypre_boomeramg_max_iter is set to 2 then 2-V-cycles are being used to define the preconditioner
2057c231f9e3SBarryFSmith           (-pc_hypre_boomeramg_tol should be set to 0.0 - the default - to strictly use a fixed number of
20588f87f92bSBarry Smith           iterations per hypre call). -ksp_max_it and -ksp_rtol STILL determine the total number of iterations
20590f1074feSSatish Balay           and tolerance for the Krylov solver. For example, if -pc_hypre_boomeramg_max_iter is 2 and -ksp_max_it is 10
20600f1074feSSatish Balay           then AT MOST twenty V-cycles of boomeramg will be called.
206116d9e3a6SLisandro Dalcin 
20620f1074feSSatish Balay            Note that the option -pc_hypre_boomeramg_relax_type_all defaults to symmetric relaxation
20630f1074feSSatish Balay            (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
20640f1074feSSatish Balay            Otherwise, you may want to use -pc_hypre_boomeramg_relax_type_all SOR/Jacobi.
206516d9e3a6SLisandro Dalcin           If you wish to use BoomerAMG WITHOUT a Krylov method use -ksp_type richardson NOT -ksp_type preonly
206616d9e3a6SLisandro Dalcin           and use -ksp_max_it to control the number of V-cycles.
206716d9e3a6SLisandro Dalcin           (see the PETSc FAQ.html at the PETSc website under the Documentation tab).
206816d9e3a6SLisandro Dalcin 
206916d9e3a6SLisandro Dalcin           2007-02-03 Using HYPRE-1.11.1b, the routine HYPRE_BoomerAMGSolveT and the option
207016d9e3a6SLisandro Dalcin           -pc_hypre_parasails_reuse were failing with SIGSEGV. Dalcin L.
207116d9e3a6SLisandro Dalcin 
20725272c319SBarry Smith           MatSetNearNullSpace() - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use
2073fdd15c9aSJunchao Zhang           the following two options:
2074*0b1a5bd9SEric Chamberland 
2075fdd15c9aSJunchao Zhang    Options Database Keys:
20765272c319SBarry Smith +   -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see HYPRE_BOOMERAMGSetNodal())
2077fdd15c9aSJunchao Zhang -   -pc_hypre_boomeramg_vec_interp_variant <v> - where v is from 1 to 3 (see HYPRE_BoomerAMGSetInterpVecVariant())
20785272c319SBarry Smith 
20795272c319SBarry Smith           Depending on the linear system you may see the same or different convergence depending on the values you use.
20805272c319SBarry Smith 
20819e5bc791SBarry Smith           See PCPFMG for access to the hypre Struct PFMG solver
20829e5bc791SBarry Smith 
208316d9e3a6SLisandro Dalcin .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
20849e5bc791SBarry Smith            PCHYPRESetType(), PCPFMG
208516d9e3a6SLisandro Dalcin 
208616d9e3a6SLisandro Dalcin M*/
208716d9e3a6SLisandro Dalcin 
20888cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
208916d9e3a6SLisandro Dalcin {
209016d9e3a6SLisandro Dalcin   PC_HYPRE       *jac;
209116d9e3a6SLisandro Dalcin   PetscErrorCode ierr;
209216d9e3a6SLisandro Dalcin 
209316d9e3a6SLisandro Dalcin   PetscFunctionBegin;
2094b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
20952fa5cd67SKarl Rupp 
209616d9e3a6SLisandro Dalcin   pc->data                = jac;
20978695de01SBarry Smith   pc->ops->reset          = PCReset_HYPRE;
209816d9e3a6SLisandro Dalcin   pc->ops->destroy        = PCDestroy_HYPRE;
209916d9e3a6SLisandro Dalcin   pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
210016d9e3a6SLisandro Dalcin   pc->ops->setup          = PCSetUp_HYPRE;
210116d9e3a6SLisandro Dalcin   pc->ops->apply          = PCApply_HYPRE;
210216d9e3a6SLisandro Dalcin   jac->comm_hypre         = MPI_COMM_NULL;
2103bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetType_C",PCHYPRESetType_HYPRE);CHKERRQ(ierr);
2104bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPREGetType_C",PCHYPREGetType_HYPRE);CHKERRQ(ierr);
21055ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCSetCoordinates_C",PCSetCoordinates_HYPRE);CHKERRQ(ierr);
21065ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteGradient_C",PCHYPRESetDiscreteGradient_HYPRE);CHKERRQ(ierr);
21075ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetDiscreteCurl_C",PCHYPRESetDiscreteCurl_HYPRE);CHKERRQ(ierr);
21086bf688a0SCe Qin   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetInterpolations_C",PCHYPRESetInterpolations_HYPRE);CHKERRQ(ierr);
21095ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetEdgeConstantVectors_C",PCHYPRESetEdgeConstantVectors_HYPRE);CHKERRQ(ierr);
21105ac14e1cSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCHYPRESetPoissonMatrix_C",PCHYPRESetPoissonMatrix_HYPRE);CHKERRQ(ierr);
211116d9e3a6SLisandro Dalcin   PetscFunctionReturn(0);
211216d9e3a6SLisandro Dalcin }
2113ebc551c0SBarry Smith 
2114f91d8e95SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------*/
2115f91d8e95SBarry Smith 
2116ebc551c0SBarry Smith typedef struct {
211768326731SBarry Smith   MPI_Comm           hcomm;        /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
2118f91d8e95SBarry Smith   HYPRE_StructSolver hsolver;
21199e5bc791SBarry Smith 
21209e5bc791SBarry Smith   /* keep copy of PFMG options used so may view them */
21214ddd07fcSJed Brown   PetscInt its;
21229e5bc791SBarry Smith   double   tol;
21234ddd07fcSJed Brown   PetscInt relax_type;
21244ddd07fcSJed Brown   PetscInt rap_type;
21254ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
21264ddd07fcSJed Brown   PetscInt max_levels;
2127ebc551c0SBarry Smith } PC_PFMG;
2128ebc551c0SBarry Smith 
2129ebc551c0SBarry Smith PetscErrorCode PCDestroy_PFMG(PC pc)
2130ebc551c0SBarry Smith {
2131ebc551c0SBarry Smith   PetscErrorCode ierr;
2132f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2133ebc551c0SBarry Smith 
2134ebc551c0SBarry Smith   PetscFunctionBegin;
21352fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2136f91d8e95SBarry Smith   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2137c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2138ebc551c0SBarry Smith   PetscFunctionReturn(0);
2139ebc551c0SBarry Smith }
2140ebc551c0SBarry Smith 
21419e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi","Weighted-Jacobi","symmetric-Red/Black-Gauss-Seidel","Red/Black-Gauss-Seidel"};
21429e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin","non-Galerkin"};
21439e5bc791SBarry Smith 
2144ebc551c0SBarry Smith PetscErrorCode PCView_PFMG(PC pc,PetscViewer viewer)
2145ebc551c0SBarry Smith {
2146ebc551c0SBarry Smith   PetscErrorCode ierr;
2147ace3abfcSBarry Smith   PetscBool      iascii;
2148f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2149ebc551c0SBarry Smith 
2150ebc551c0SBarry Smith   PetscFunctionBegin;
2151251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
21529e5bc791SBarry Smith   if (iascii) {
21539e5bc791SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE PFMG preconditioning\n");CHKERRQ(ierr);
2154efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max iterations %d\n",ex->its);CHKERRQ(ierr);
2155efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    tolerance %g\n",ex->tol);CHKERRQ(ierr);
2156efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2157efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    RAP type %s\n",PFMGRAPType[ex->rap_type]);CHKERRQ(ierr);
2158efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2159efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    max levels %d\n",ex->max_levels);CHKERRQ(ierr);
21609e5bc791SBarry Smith   }
2161ebc551c0SBarry Smith   PetscFunctionReturn(0);
2162ebc551c0SBarry Smith }
2163ebc551c0SBarry Smith 
21644416b707SBarry Smith PetscErrorCode PCSetFromOptions_PFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2165ebc551c0SBarry Smith {
2166ebc551c0SBarry Smith   PetscErrorCode ierr;
2167f91d8e95SBarry Smith   PC_PFMG        *ex = (PC_PFMG*) pc->data;
2168ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2169ebc551c0SBarry Smith 
2170ebc551c0SBarry Smith   PetscFunctionBegin;
2171e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"PFMG options");CHKERRQ(ierr);
21720298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_pfmg_print_statistics","Print statistics","HYPRE_StructPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
217368326731SBarry Smith   if (flg) {
21745bd1e576SStefano Zampini     PetscStackCallStandard(HYPRE_StructPFMGSetPrintLevel,(ex->hsolver,3));
217568326731SBarry Smith   }
21760298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_its","Number of iterations of PFMG to use as preconditioner","HYPRE_StructPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2177fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(ex->hsolver,ex->its));
21780298fd71SBarry 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);
2179fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPreRelax,(ex->hsolver,ex->num_pre_relax));
21800298fd71SBarry 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);
2181fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetNumPostRelax,(ex->hsolver,ex->num_post_relax));
21829e5bc791SBarry Smith 
21830298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_pfmg_max_levels","Max Levels for MG hierarchy","HYPRE_StructPFMGSetMaxLevels",ex->max_levels,&ex->max_levels,NULL);CHKERRQ(ierr);
2184fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxLevels,(ex->hsolver,ex->max_levels));
21853b46a515SGlenn Hammond 
21860298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_pfmg_tol","Tolerance of PFMG","HYPRE_StructPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2187fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(ex->hsolver,ex->tol));
21880298fd71SBarry 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);
2189fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRelaxType,(ex->hsolver, ex->relax_type));
21900298fd71SBarry Smith   ierr = PetscOptionsEList("-pc_pfmg_rap_type","RAP type","HYPRE_StructPFMGSetRAPType",PFMGRAPType,ALEN(PFMGRAPType),PFMGRAPType[ex->rap_type],&ex->rap_type,NULL);CHKERRQ(ierr);
2191fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetRAPType,(ex->hsolver, ex->rap_type));
2192ebc551c0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
2193ebc551c0SBarry Smith   PetscFunctionReturn(0);
2194ebc551c0SBarry Smith }
2195ebc551c0SBarry Smith 
2196f91d8e95SBarry Smith PetscErrorCode PCApply_PFMG(PC pc,Vec x,Vec y)
2197f91d8e95SBarry Smith {
2198f91d8e95SBarry Smith   PetscErrorCode    ierr;
2199f91d8e95SBarry Smith   PC_PFMG           *ex = (PC_PFMG*) pc->data;
2200d9ca1df4SBarry Smith   PetscScalar       *yy;
2201d9ca1df4SBarry Smith   const PetscScalar *xx;
22024ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
22032cf14000SStefano Zampini   HYPRE_Int         hlower[3],hupper[3];
220468326731SBarry Smith   Mat_HYPREStruct   *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2205f91d8e95SBarry Smith 
2206f91d8e95SBarry Smith   PetscFunctionBegin;
2207dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2208aa219208SBarry Smith   ierr = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
22092cf14000SStefano Zampini   /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
2210f91d8e95SBarry Smith   iupper[0] += ilower[0] - 1;
2211f91d8e95SBarry Smith   iupper[1] += ilower[1] - 1;
2212f91d8e95SBarry Smith   iupper[2] += ilower[2] - 1;
22132cf14000SStefano Zampini   hlower[0]  = (HYPRE_Int)ilower[0];
22142cf14000SStefano Zampini   hlower[1]  = (HYPRE_Int)ilower[1];
22152cf14000SStefano Zampini   hlower[2]  = (HYPRE_Int)ilower[2];
22162cf14000SStefano Zampini   hupper[0]  = (HYPRE_Int)iupper[0];
22172cf14000SStefano Zampini   hupper[1]  = (HYPRE_Int)iupper[1];
22182cf14000SStefano Zampini   hupper[2]  = (HYPRE_Int)iupper[2];
2219f91d8e95SBarry Smith 
2220f91d8e95SBarry Smith   /* copy x values over to hypre */
2221fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorSetConstantValues,(mx->hb,0.0));
2222d9ca1df4SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
222339accc25SStefano Zampini   PetscStackCallStandard(HYPRE_StructVectorSetBoxValues,(mx->hb,hlower,hupper,(HYPRE_Complex*)xx));
2224d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2225fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructVectorAssemble,(mx->hb));
2226fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSolve,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2227f91d8e95SBarry Smith 
2228f91d8e95SBarry Smith   /* copy solution values back to PETSc */
2229f91d8e95SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
223039accc25SStefano Zampini   PetscStackCallStandard(HYPRE_StructVectorGetBoxValues,(mx->hx,hlower,hupper,(HYPRE_Complex*)yy));
2231f91d8e95SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2232f91d8e95SBarry Smith   PetscFunctionReturn(0);
2233f91d8e95SBarry Smith }
2234f91d8e95SBarry Smith 
2235ace3abfcSBarry 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)
22369e5bc791SBarry Smith {
22379e5bc791SBarry Smith   PC_PFMG        *jac = (PC_PFMG*)pc->data;
22389e5bc791SBarry Smith   PetscErrorCode ierr;
22392cf14000SStefano Zampini   HYPRE_Int      oits;
22409e5bc791SBarry Smith 
22419e5bc791SBarry Smith   PetscFunctionBegin;
2242dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2243fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,its*jac->its));
2244fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,rtol));
22459e5bc791SBarry Smith 
22469e5bc791SBarry Smith   ierr = PCApply_PFMG(pc,b,y);CHKERRQ(ierr);
22472cf14000SStefano Zampini   PetscStackCallStandard(HYPRE_StructPFMGGetNumIterations,(jac->hsolver,&oits));
22489e5bc791SBarry Smith   *outits = oits;
22499e5bc791SBarry Smith   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
22509e5bc791SBarry Smith   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2251fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetTol,(jac->hsolver,jac->tol));
2252fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetMaxIter,(jac->hsolver,jac->its));
22539e5bc791SBarry Smith   PetscFunctionReturn(0);
22549e5bc791SBarry Smith }
22559e5bc791SBarry Smith 
22569e5bc791SBarry Smith 
22573a32d3dbSGlenn Hammond PetscErrorCode PCSetUp_PFMG(PC pc)
22583a32d3dbSGlenn Hammond {
22593a32d3dbSGlenn Hammond   PetscErrorCode  ierr;
22603a32d3dbSGlenn Hammond   PC_PFMG         *ex = (PC_PFMG*) pc->data;
22613a32d3dbSGlenn Hammond   Mat_HYPREStruct *mx = (Mat_HYPREStruct*)(pc->pmat->data);
2262ace3abfcSBarry Smith   PetscBool       flg;
22633a32d3dbSGlenn Hammond 
22643a32d3dbSGlenn Hammond   PetscFunctionBegin;
2265251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESTRUCT,&flg);CHKERRQ(ierr);
2266ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESTRUCT with this preconditioner");
22673a32d3dbSGlenn Hammond 
22683a32d3dbSGlenn Hammond   /* create the hypre solver object and set its information */
22692fa5cd67SKarl Rupp   if (ex->hsolver) PetscStackCallStandard(HYPRE_StructPFMGDestroy,(ex->hsolver));
2270fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2271fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetup,(ex->hsolver,mx->hmat,mx->hb,mx->hx));
2272fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGSetZeroGuess,(ex->hsolver));
22733a32d3dbSGlenn Hammond   PetscFunctionReturn(0);
22743a32d3dbSGlenn Hammond }
22753a32d3dbSGlenn Hammond 
2276ebc551c0SBarry Smith /*MC
2277ebc551c0SBarry Smith      PCPFMG - the hypre PFMG multigrid solver
2278ebc551c0SBarry Smith 
2279ebc551c0SBarry Smith    Level: advanced
2280ebc551c0SBarry Smith 
22819e5bc791SBarry Smith    Options Database:
22829e5bc791SBarry Smith + -pc_pfmg_its <its> number of iterations of PFMG to use as preconditioner
22839e5bc791SBarry Smith . -pc_pfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
22849e5bc791SBarry Smith . -pc_pfmg_num_post_relax <steps> number of smoothing steps after coarse grid
22859e5bc791SBarry Smith . -pc_pfmg_tol <tol> tolerance of PFMG
22869e5bc791SBarry 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
22879e5bc791SBarry Smith - -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
2288f91d8e95SBarry Smith 
228995452b02SPatrick Sanan    Notes:
229095452b02SPatrick Sanan     This is for CELL-centered descretizations
22919e5bc791SBarry Smith 
22928e395302SJed Brown            This must be used with the MATHYPRESTRUCT matrix type.
2293aa219208SBarry Smith            This is less general than in hypre, it supports only one block per process defined by a PETSc DMDA.
22949e5bc791SBarry Smith 
22959e5bc791SBarry Smith .seealso:  PCMG, MATHYPRESTRUCT
2296ebc551c0SBarry Smith M*/
2297ebc551c0SBarry Smith 
22988cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
2299ebc551c0SBarry Smith {
2300ebc551c0SBarry Smith   PetscErrorCode ierr;
2301ebc551c0SBarry Smith   PC_PFMG        *ex;
2302ebc551c0SBarry Smith 
2303ebc551c0SBarry Smith   PetscFunctionBegin;
2304b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
230568326731SBarry Smith   pc->data = ex;
2306ebc551c0SBarry Smith 
23079e5bc791SBarry Smith   ex->its            = 1;
23089e5bc791SBarry Smith   ex->tol            = 1.e-8;
23099e5bc791SBarry Smith   ex->relax_type     = 1;
23109e5bc791SBarry Smith   ex->rap_type       = 0;
23119e5bc791SBarry Smith   ex->num_pre_relax  = 1;
23129e5bc791SBarry Smith   ex->num_post_relax = 1;
23133b46a515SGlenn Hammond   ex->max_levels     = 0;
23149e5bc791SBarry Smith 
2315ebc551c0SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_PFMG;
2316ebc551c0SBarry Smith   pc->ops->view            = PCView_PFMG;
2317ebc551c0SBarry Smith   pc->ops->destroy         = PCDestroy_PFMG;
2318f91d8e95SBarry Smith   pc->ops->apply           = PCApply_PFMG;
23199e5bc791SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_PFMG;
232068326731SBarry Smith   pc->ops->setup           = PCSetUp_PFMG;
23212fa5cd67SKarl Rupp 
2322ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2323fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_StructPFMGCreate,(ex->hcomm,&ex->hsolver));
2324ebc551c0SBarry Smith   PetscFunctionReturn(0);
2325ebc551c0SBarry Smith }
2326d851a50bSGlenn Hammond 
2327325fc9f4SBarry Smith /* ---------------------------------------------------------------------------------------------------------------------------------------------------*/
2328325fc9f4SBarry Smith 
2329d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2330d851a50bSGlenn Hammond typedef struct {
2331d851a50bSGlenn Hammond   MPI_Comm            hcomm;       /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2332d851a50bSGlenn Hammond   HYPRE_SStructSolver ss_solver;
2333d851a50bSGlenn Hammond 
2334d851a50bSGlenn Hammond   /* keep copy of SYSPFMG options used so may view them */
23354ddd07fcSJed Brown   PetscInt its;
2336d851a50bSGlenn Hammond   double   tol;
23374ddd07fcSJed Brown   PetscInt relax_type;
23384ddd07fcSJed Brown   PetscInt num_pre_relax,num_post_relax;
2339d851a50bSGlenn Hammond } PC_SysPFMG;
2340d851a50bSGlenn Hammond 
2341d851a50bSGlenn Hammond PetscErrorCode PCDestroy_SysPFMG(PC pc)
2342d851a50bSGlenn Hammond {
2343d851a50bSGlenn Hammond   PetscErrorCode ierr;
2344d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2345d851a50bSGlenn Hammond 
2346d851a50bSGlenn Hammond   PetscFunctionBegin;
23472fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2348d851a50bSGlenn Hammond   ierr = MPI_Comm_free(&ex->hcomm);CHKERRQ(ierr);
2349c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2350d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2351d851a50bSGlenn Hammond }
2352d851a50bSGlenn Hammond 
2353d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi","Red/Black-Gauss-Seidel"};
2354d851a50bSGlenn Hammond 
2355d851a50bSGlenn Hammond PetscErrorCode PCView_SysPFMG(PC pc,PetscViewer viewer)
2356d851a50bSGlenn Hammond {
2357d851a50bSGlenn Hammond   PetscErrorCode ierr;
2358ace3abfcSBarry Smith   PetscBool      iascii;
2359d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2360d851a50bSGlenn Hammond 
2361d851a50bSGlenn Hammond   PetscFunctionBegin;
2362251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2363d851a50bSGlenn Hammond   if (iascii) {
2364d851a50bSGlenn Hammond     ierr = PetscViewerASCIIPrintf(viewer,"  HYPRE SysPFMG preconditioning\n");CHKERRQ(ierr);
2365efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  max iterations %d\n",ex->its);CHKERRQ(ierr);
2366efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerance %g\n",ex->tol);CHKERRQ(ierr);
2367efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  relax type %s\n",PFMGRelaxType[ex->relax_type]);CHKERRQ(ierr);
2368efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  number pre-relax %d post-relax %d\n",ex->num_pre_relax,ex->num_post_relax);CHKERRQ(ierr);
2369d851a50bSGlenn Hammond   }
2370d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2371d851a50bSGlenn Hammond }
2372d851a50bSGlenn Hammond 
23734416b707SBarry Smith PetscErrorCode PCSetFromOptions_SysPFMG(PetscOptionItems *PetscOptionsObject,PC pc)
2374d851a50bSGlenn Hammond {
2375d851a50bSGlenn Hammond   PetscErrorCode ierr;
2376d851a50bSGlenn Hammond   PC_SysPFMG     *ex = (PC_SysPFMG*) pc->data;
2377ace3abfcSBarry Smith   PetscBool      flg = PETSC_FALSE;
2378d851a50bSGlenn Hammond 
2379d851a50bSGlenn Hammond   PetscFunctionBegin;
2380e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"SysPFMG options");CHKERRQ(ierr);
23810298fd71SBarry Smith   ierr = PetscOptionsBool("-pc_syspfmg_print_statistics","Print statistics","HYPRE_SStructSysPFMGSetPrintLevel",flg,&flg,NULL);CHKERRQ(ierr);
2382d851a50bSGlenn Hammond   if (flg) {
23835bd1e576SStefano Zampini     PetscStackCallStandard(HYPRE_SStructSysPFMGSetPrintLevel,(ex->ss_solver,3));
2384d851a50bSGlenn Hammond   }
23850298fd71SBarry Smith   ierr = PetscOptionsInt("-pc_syspfmg_its","Number of iterations of SysPFMG to use as preconditioner","HYPRE_SStructSysPFMGSetMaxIter",ex->its,&ex->its,NULL);CHKERRQ(ierr);
2386fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(ex->ss_solver,ex->its));
23870298fd71SBarry 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);
2388fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPreRelax,(ex->ss_solver,ex->num_pre_relax));
23890298fd71SBarry 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);
2390fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetNumPostRelax,(ex->ss_solver,ex->num_post_relax));
2391d851a50bSGlenn Hammond 
23920298fd71SBarry Smith   ierr = PetscOptionsReal("-pc_syspfmg_tol","Tolerance of SysPFMG","HYPRE_SStructSysPFMGSetTol",ex->tol,&ex->tol,NULL);CHKERRQ(ierr);
2393fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(ex->ss_solver,ex->tol));
239461710fbeSStefano 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);
2395fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetRelaxType,(ex->ss_solver, ex->relax_type));
2396d851a50bSGlenn Hammond   ierr = PetscOptionsTail();CHKERRQ(ierr);
2397d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2398d851a50bSGlenn Hammond }
2399d851a50bSGlenn Hammond 
2400d851a50bSGlenn Hammond PetscErrorCode PCApply_SysPFMG(PC pc,Vec x,Vec y)
2401d851a50bSGlenn Hammond {
2402d851a50bSGlenn Hammond   PetscErrorCode    ierr;
2403d851a50bSGlenn Hammond   PC_SysPFMG        *ex = (PC_SysPFMG*) pc->data;
2404d9ca1df4SBarry Smith   PetscScalar       *yy;
2405d9ca1df4SBarry Smith   const PetscScalar *xx;
24064ddd07fcSJed Brown   PetscInt          ilower[3],iupper[3];
24072cf14000SStefano Zampini   HYPRE_Int         hlower[3],hupper[3];
2408d851a50bSGlenn Hammond   Mat_HYPRESStruct  *mx     = (Mat_HYPRESStruct*)(pc->pmat->data);
24094ddd07fcSJed Brown   PetscInt          ordering= mx->dofs_order;
24104ddd07fcSJed Brown   PetscInt          nvars   = mx->nvars;
24114ddd07fcSJed Brown   PetscInt          part    = 0;
24124ddd07fcSJed Brown   PetscInt          size;
24134ddd07fcSJed Brown   PetscInt          i;
2414d851a50bSGlenn Hammond 
2415d851a50bSGlenn Hammond   PetscFunctionBegin;
2416dff31646SBarry Smith   ierr       = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2417aa219208SBarry Smith   ierr       = DMDAGetCorners(mx->da,&ilower[0],&ilower[1],&ilower[2],&iupper[0],&iupper[1],&iupper[2]);CHKERRQ(ierr);
24182cf14000SStefano Zampini   /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
2419d851a50bSGlenn Hammond   iupper[0] += ilower[0] - 1;
2420d851a50bSGlenn Hammond   iupper[1] += ilower[1] - 1;
2421d851a50bSGlenn Hammond   iupper[2] += ilower[2] - 1;
24222cf14000SStefano Zampini   hlower[0]  = (HYPRE_Int)ilower[0];
24232cf14000SStefano Zampini   hlower[1]  = (HYPRE_Int)ilower[1];
24242cf14000SStefano Zampini   hlower[2]  = (HYPRE_Int)ilower[2];
24252cf14000SStefano Zampini   hupper[0]  = (HYPRE_Int)iupper[0];
24262cf14000SStefano Zampini   hupper[1]  = (HYPRE_Int)iupper[1];
24272cf14000SStefano Zampini   hupper[2]  = (HYPRE_Int)iupper[2];
2428d851a50bSGlenn Hammond 
2429d851a50bSGlenn Hammond   size = 1;
24302fa5cd67SKarl Rupp   for (i= 0; i< 3; i++) size *= (iupper[i]-ilower[i]+1);
24312fa5cd67SKarl Rupp 
2432d851a50bSGlenn Hammond   /* copy x values over to hypre for variable ordering */
2433d851a50bSGlenn Hammond   if (ordering) {
2434fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2435d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
243639accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(xx+(size*i))));
2437d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2438fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2439fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructMatrixMatvec,(1.0,mx->ss_mat,mx->ss_b,0.0,mx->ss_x));
2440fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2441d851a50bSGlenn Hammond 
2442d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2443d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
244439accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(yy+(size*i))));
2445d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2446a65764d7SBarry Smith   } else {      /* nodal ordering must be mapped to variable ordering for sys_pfmg */
2447d851a50bSGlenn Hammond     PetscScalar *z;
24484ddd07fcSJed Brown     PetscInt    j, k;
2449d851a50bSGlenn Hammond 
2450785e854fSJed Brown     ierr = PetscMalloc1(nvars*size,&z);CHKERRQ(ierr);
2451fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorSetConstantValues,(mx->ss_b,0.0));
2452d9ca1df4SBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2453d851a50bSGlenn Hammond 
2454d851a50bSGlenn Hammond     /* transform nodal to hypre's variable ordering for sys_pfmg */
2455d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2456d851a50bSGlenn Hammond       k= i*nvars;
24572fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) z[j*size+i]= xx[k+j];
2458d851a50bSGlenn Hammond     }
245939accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorSetBoxValues,(mx->ss_b,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i))));
2460d9ca1df4SBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2461fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructVectorAssemble,(mx->ss_b));
2462fd3f9acdSBarry Smith     PetscStackCallStandard(HYPRE_SStructSysPFMGSolve,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2463d851a50bSGlenn Hammond 
2464d851a50bSGlenn Hammond     /* copy solution values back to PETSc */
2465d851a50bSGlenn Hammond     ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
246639accc25SStefano Zampini     for (i= 0; i< nvars; i++) PetscStackCallStandard(HYPRE_SStructVectorGetBoxValues,(mx->ss_x,part,hlower,hupper,i,(HYPRE_Complex*)(z+(size*i))));
2467d851a50bSGlenn Hammond     /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
2468d851a50bSGlenn Hammond     for (i= 0; i< size; i++) {
2469d851a50bSGlenn Hammond       k= i*nvars;
24702fa5cd67SKarl Rupp       for (j= 0; j< nvars; j++) yy[k+j]= z[j*size+i];
2471d851a50bSGlenn Hammond     }
2472d851a50bSGlenn Hammond     ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2473d851a50bSGlenn Hammond     ierr = PetscFree(z);CHKERRQ(ierr);
2474d851a50bSGlenn Hammond   }
2475d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2476d851a50bSGlenn Hammond }
2477d851a50bSGlenn Hammond 
2478ace3abfcSBarry 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)
2479d851a50bSGlenn Hammond {
2480d851a50bSGlenn Hammond   PC_SysPFMG     *jac = (PC_SysPFMG*)pc->data;
2481d851a50bSGlenn Hammond   PetscErrorCode ierr;
24822cf14000SStefano Zampini   HYPRE_Int      oits;
2483d851a50bSGlenn Hammond 
2484d851a50bSGlenn Hammond   PetscFunctionBegin;
2485dff31646SBarry Smith   ierr = PetscCitationsRegister(hypreCitation,&cite);CHKERRQ(ierr);
2486fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,its*jac->its));
2487fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,rtol));
2488d851a50bSGlenn Hammond   ierr = PCApply_SysPFMG(pc,b,y);CHKERRQ(ierr);
24892cf14000SStefano Zampini   PetscStackCallStandard(HYPRE_SStructSysPFMGGetNumIterations,(jac->ss_solver,&oits));
2490d851a50bSGlenn Hammond   *outits = oits;
2491d851a50bSGlenn Hammond   if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
2492d851a50bSGlenn Hammond   else             *reason = PCRICHARDSON_CONVERGED_RTOL;
2493fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetTol,(jac->ss_solver,jac->tol));
2494fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetMaxIter,(jac->ss_solver,jac->its));
2495d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2496d851a50bSGlenn Hammond }
2497d851a50bSGlenn Hammond 
2498d851a50bSGlenn Hammond PetscErrorCode PCSetUp_SysPFMG(PC pc)
2499d851a50bSGlenn Hammond {
2500d851a50bSGlenn Hammond   PetscErrorCode   ierr;
2501d851a50bSGlenn Hammond   PC_SysPFMG       *ex = (PC_SysPFMG*) pc->data;
2502d851a50bSGlenn Hammond   Mat_HYPRESStruct *mx = (Mat_HYPRESStruct*)(pc->pmat->data);
2503ace3abfcSBarry Smith   PetscBool        flg;
2504d851a50bSGlenn Hammond 
2505d851a50bSGlenn Hammond   PetscFunctionBegin;
2506251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATHYPRESSTRUCT,&flg);CHKERRQ(ierr);
2507ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_INCOMP,"Must use MATHYPRESSTRUCT with this preconditioner");
2508d851a50bSGlenn Hammond 
2509d851a50bSGlenn Hammond   /* create the hypre sstruct solver object and set its information */
25102fa5cd67SKarl Rupp   if (ex->ss_solver) PetscStackCallStandard(HYPRE_SStructSysPFMGDestroy,(ex->ss_solver));
2511fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2512fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetZeroGuess,(ex->ss_solver));
2513fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGSetup,(ex->ss_solver,mx->ss_mat,mx->ss_b,mx->ss_x));
2514d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2515d851a50bSGlenn Hammond }
2516d851a50bSGlenn Hammond 
2517d851a50bSGlenn Hammond /*MC
2518d851a50bSGlenn Hammond      PCSysPFMG - the hypre SysPFMG multigrid solver
2519d851a50bSGlenn Hammond 
2520d851a50bSGlenn Hammond    Level: advanced
2521d851a50bSGlenn Hammond 
2522d851a50bSGlenn Hammond    Options Database:
2523d851a50bSGlenn Hammond + -pc_syspfmg_its <its> number of iterations of SysPFMG to use as preconditioner
2524d851a50bSGlenn Hammond . -pc_syspfmg_num_pre_relax <steps> number of smoothing steps before coarse grid
2525d851a50bSGlenn Hammond . -pc_syspfmg_num_post_relax <steps> number of smoothing steps after coarse grid
2526d851a50bSGlenn Hammond . -pc_syspfmg_tol <tol> tolerance of SysPFMG
2527a2b725a8SWilliam Gropp - -pc_syspfmg_relax_type -relaxation type for the up and down cycles, one of Weighted-Jacobi,Red/Black-Gauss-Seidel
2528d851a50bSGlenn Hammond 
252995452b02SPatrick Sanan    Notes:
253095452b02SPatrick Sanan     This is for CELL-centered descretizations
2531d851a50bSGlenn Hammond 
2532f6680f47SSatish Balay            This must be used with the MATHYPRESSTRUCT matrix type.
2533aa219208SBarry Smith            This is less general than in hypre, it supports only one part, and one block per process defined by a PETSc DMDA.
2534d851a50bSGlenn Hammond            Also, only cell-centered variables.
2535d851a50bSGlenn Hammond 
2536d851a50bSGlenn Hammond .seealso:  PCMG, MATHYPRESSTRUCT
2537d851a50bSGlenn Hammond M*/
2538d851a50bSGlenn Hammond 
25398cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
2540d851a50bSGlenn Hammond {
2541d851a50bSGlenn Hammond   PetscErrorCode ierr;
2542d851a50bSGlenn Hammond   PC_SysPFMG     *ex;
2543d851a50bSGlenn Hammond 
2544d851a50bSGlenn Hammond   PetscFunctionBegin;
2545b00a9115SJed Brown   ierr     = PetscNew(&ex);CHKERRQ(ierr); \
2546d851a50bSGlenn Hammond   pc->data = ex;
2547d851a50bSGlenn Hammond 
2548d851a50bSGlenn Hammond   ex->its            = 1;
2549d851a50bSGlenn Hammond   ex->tol            = 1.e-8;
2550d851a50bSGlenn Hammond   ex->relax_type     = 1;
2551d851a50bSGlenn Hammond   ex->num_pre_relax  = 1;
2552d851a50bSGlenn Hammond   ex->num_post_relax = 1;
2553d851a50bSGlenn Hammond 
2554d851a50bSGlenn Hammond   pc->ops->setfromoptions  = PCSetFromOptions_SysPFMG;
2555d851a50bSGlenn Hammond   pc->ops->view            = PCView_SysPFMG;
2556d851a50bSGlenn Hammond   pc->ops->destroy         = PCDestroy_SysPFMG;
2557d851a50bSGlenn Hammond   pc->ops->apply           = PCApply_SysPFMG;
2558d851a50bSGlenn Hammond   pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
2559d851a50bSGlenn Hammond   pc->ops->setup           = PCSetUp_SysPFMG;
25602fa5cd67SKarl Rupp 
2561ce94432eSBarry Smith   ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)pc),&(ex->hcomm));CHKERRQ(ierr);
2562fd3f9acdSBarry Smith   PetscStackCallStandard(HYPRE_SStructSysPFMGCreate,(ex->hcomm,&ex->ss_solver));
2563d851a50bSGlenn Hammond   PetscFunctionReturn(0);
2564d851a50bSGlenn Hammond }
2565