116d9e3a6SLisandro Dalcin /*
216d9e3a6SLisandro Dalcin Provides an interface to the LLNL package hypre
316d9e3a6SLisandro Dalcin */
40f1074feSSatish Balay
5589dcaf0SStefano Zampini #include <petscpkg_version.h>
6af0996ceSBarry Smith #include <petsc/private/pcimpl.h> /*I "petscpc.h" I*/
749a781f5SStefano Zampini /* this include is needed ONLY to allow access to the private data inside the Mat object specific to hypre */
849a781f5SStefano Zampini #include <petsc/private/matimpl.h>
96ea7df73SStefano Zampini #include <petsc/private/vecimpl.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
16a4af0ceeSJacob Faibussowitsch #if defined(PETSC_HAVE_HYPRE_DEVICE)
17a4af0ceeSJacob Faibussowitsch #include <petsc/private/deviceimpl.h>
18a4af0ceeSJacob Faibussowitsch #endif
19a4af0ceeSJacob Faibussowitsch
20dff31646SBarry Smith static PetscBool cite = PETSC_FALSE;
219371c9d4SSatish Balay static const char hypreCitation[] = "@manual{hypre-web-page,\n title = {{\\sl hypre}: High Performance Preconditioners},\n organization = {Lawrence Livermore National Laboratory},\n note = "
22bd87328aSJed Brown "{\\url{https://www.llnl.gov/casc/hypre}}\n}\n";
231f817a21SBarry Smith
2416d9e3a6SLisandro Dalcin /*
2516d9e3a6SLisandro Dalcin Private context (data structure) for the preconditioner.
2616d9e3a6SLisandro Dalcin */
2716d9e3a6SLisandro Dalcin typedef struct {
2816d9e3a6SLisandro Dalcin HYPRE_Solver hsolver;
2949a781f5SStefano Zampini Mat hpmat; /* MatHYPRE */
3016d9e3a6SLisandro Dalcin
314ddd07fcSJed Brown HYPRE_Int (*destroy)(HYPRE_Solver);
324ddd07fcSJed Brown HYPRE_Int (*solve)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector);
334ddd07fcSJed Brown HYPRE_Int (*setup)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector);
3416d9e3a6SLisandro Dalcin
3516d9e3a6SLisandro Dalcin MPI_Comm comm_hypre;
3616d9e3a6SLisandro Dalcin char *hypre_type;
3716d9e3a6SLisandro Dalcin
3816d9e3a6SLisandro Dalcin /* options for Pilut and BoomerAMG*/
394ddd07fcSJed Brown PetscInt maxiter;
4039accc25SStefano Zampini PetscReal tol;
4116d9e3a6SLisandro Dalcin
4216d9e3a6SLisandro Dalcin /* options for Pilut */
434ddd07fcSJed Brown PetscInt factorrowsize;
4416d9e3a6SLisandro Dalcin
4516d9e3a6SLisandro Dalcin /* options for ParaSails */
464ddd07fcSJed Brown PetscInt nlevels;
478966356dSPierre Jolivet PetscReal threshold;
4839accc25SStefano Zampini PetscReal filter;
4939accc25SStefano Zampini PetscReal loadbal;
504ddd07fcSJed Brown PetscInt logging;
514ddd07fcSJed Brown PetscInt ruse;
524ddd07fcSJed Brown PetscInt symt;
5316d9e3a6SLisandro Dalcin
5422b6d1caSBarry Smith /* options for BoomerAMG */
55ace3abfcSBarry Smith PetscBool printstatistics;
5616d9e3a6SLisandro Dalcin
5716d9e3a6SLisandro Dalcin /* options for BoomerAMG */
584ddd07fcSJed Brown PetscInt cycletype;
594ddd07fcSJed Brown PetscInt maxlevels;
6039accc25SStefano Zampini PetscReal strongthreshold;
6139accc25SStefano Zampini PetscReal maxrowsum;
624ddd07fcSJed Brown PetscInt gridsweeps[3];
63d7185485SAlex Lindsay PetscObjectParameterDeclare(PetscInt, coarsentype);
644ddd07fcSJed Brown PetscInt measuretype;
656a251517SEike Mueller PetscInt smoothtype;
663c61a47dSLukas PetscInt smoothsweeps;
678131ecf7SEike Mueller PetscInt smoothnumlevels;
68ec64516dSEike Mueller PetscInt eu_level; /* Number of levels for ILU(k) in Euclid */
6939accc25SStefano Zampini PetscReal eu_droptolerance; /* Drop tolerance for ILU(k) in Euclid */
70ec64516dSEike Mueller PetscInt eu_bj; /* Defines use of Block Jacobi ILU in Euclid */
71d7185485SAlex Lindsay PetscObjectParameterDeclare(PetscInt, relaxtype[3]);
7239accc25SStefano Zampini PetscReal relaxweight;
7339accc25SStefano Zampini PetscReal outerrelaxweight;
74d7185485SAlex Lindsay PetscObjectParameterDeclare(PetscInt, relaxorder);
7539accc25SStefano Zampini PetscReal truncfactor;
76ace3abfcSBarry Smith PetscBool applyrichardson;
774ddd07fcSJed Brown PetscInt pmax;
78d7185485SAlex Lindsay PetscObjectParameterDeclare(PetscInt, interptype);
79589dcaf0SStefano Zampini PetscInt maxc;
80589dcaf0SStefano Zampini PetscInt minc;
81db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0)
82d7185485SAlex Lindsay PetscObjectParameterDeclarePtr(const char, spgemm_type); // this is a global hypre parameter but is closely associated with BoomerAMG
83db6f9c32SMark Adams #endif
846ea7df73SStefano Zampini /* GPU */
85abf5c9d9SBarry Smith PetscObjectParameterDeclare(PetscBool3, keeptranspose);
866ea7df73SStefano Zampini PetscInt rap2;
87d7185485SAlex Lindsay PetscObjectParameterDeclare(PetscInt, mod_rap2);
886ea7df73SStefano Zampini
89589dcaf0SStefano Zampini /* AIR */
90589dcaf0SStefano Zampini PetscInt Rtype;
91589dcaf0SStefano Zampini PetscReal Rstrongthreshold;
92589dcaf0SStefano Zampini PetscReal Rfilterthreshold;
93589dcaf0SStefano Zampini PetscInt Adroptype;
94589dcaf0SStefano Zampini PetscReal Adroptol;
95589dcaf0SStefano Zampini
964ddd07fcSJed Brown PetscInt agg_nl;
97d7185485SAlex Lindsay PetscObjectParameterDeclare(PetscInt, agg_interptype);
984ddd07fcSJed Brown PetscInt agg_num_paths;
99ace3abfcSBarry Smith PetscBool nodal_relax;
1004ddd07fcSJed Brown PetscInt nodal_relax_levels;
1014cb006feSStefano Zampini
1025272c319SBarry Smith PetscInt nodal_coarsening;
10322e51d31SStefano Zampini PetscInt nodal_coarsening_diag;
1045272c319SBarry Smith PetscInt vec_interp_variant;
10522e51d31SStefano Zampini PetscInt vec_interp_qmax;
10622e51d31SStefano Zampini PetscBool vec_interp_smooth;
10722e51d31SStefano Zampini PetscInt interp_refine;
10822e51d31SStefano Zampini
1096ea7df73SStefano Zampini /* NearNullSpace support */
1106ea7df73SStefano Zampini VecHYPRE_IJVector *hmnull;
1116ea7df73SStefano Zampini HYPRE_ParVector *phmnull;
1125272c319SBarry Smith PetscInt n_hmnull;
1135272c319SBarry Smith Vec hmnull_constant;
1145272c319SBarry Smith
115863406b8SStefano Zampini /* options for AS (Auxiliary Space preconditioners) */
116863406b8SStefano Zampini PetscInt as_print;
117863406b8SStefano Zampini PetscInt as_max_iter;
118863406b8SStefano Zampini PetscReal as_tol;
119863406b8SStefano Zampini PetscInt as_relax_type;
120863406b8SStefano Zampini PetscInt as_relax_times;
121863406b8SStefano Zampini PetscReal as_relax_weight;
122863406b8SStefano Zampini PetscReal as_omega;
123863406b8SStefano 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) */
124863406b8SStefano Zampini PetscReal as_amg_alpha_theta; /* AMG strength for vector Poisson (AMS) or Curl problem (ADS) */
125863406b8SStefano 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) */
126863406b8SStefano Zampini PetscReal as_amg_beta_theta; /* AMG strength for scalar Poisson (AMS) or vector Poisson (ADS) */
1274cb006feSStefano Zampini PetscInt ams_cycle_type;
128863406b8SStefano Zampini PetscInt ads_cycle_type;
1294cb006feSStefano Zampini
1304cb006feSStefano Zampini /* additional data */
1315ac14e1cSStefano Zampini Mat G; /* MatHYPRE */
1325ac14e1cSStefano Zampini Mat C; /* MatHYPRE */
1335ac14e1cSStefano Zampini Mat alpha_Poisson; /* MatHYPRE */
1345ac14e1cSStefano Zampini Mat beta_Poisson; /* MatHYPRE */
1355ac14e1cSStefano Zampini
1365ac14e1cSStefano Zampini /* extra information for AMS */
1375ac14e1cSStefano Zampini PetscInt dim; /* geometrical dimension */
1386ea7df73SStefano Zampini VecHYPRE_IJVector coords[3];
1396ea7df73SStefano Zampini VecHYPRE_IJVector constants[3];
140be14dc20SKerry Key VecHYPRE_IJVector interior;
1416bf688a0SCe Qin Mat RT_PiFull, RT_Pi[3];
1426bf688a0SCe Qin Mat ND_PiFull, ND_Pi[3];
1434cb006feSStefano Zampini PetscBool ams_beta_is_zero;
14423df4f25SStefano Zampini PetscBool ams_beta_is_zero_part;
14523df4f25SStefano Zampini PetscInt ams_proj_freq;
14616d9e3a6SLisandro Dalcin } PC_HYPRE;
14716d9e3a6SLisandro Dalcin
148fd2dd295SFande Kong /*
1498a2c336bSFande Kong Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix
1508a2c336bSFande Kong is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine.
1518a2c336bSFande Kong It is used in PCHMG. Other users should avoid using this function.
152fd2dd295SFande Kong */
PCGetCoarseOperators_BoomerAMG(PC pc,PetscInt * nlevels,Mat * operators[])153d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCGetCoarseOperators_BoomerAMG(PC pc, PetscInt *nlevels, Mat *operators[])
154d71ae5a4SJacob Faibussowitsch {
1558a2c336bSFande Kong PC_HYPRE *jac = (PC_HYPRE *)pc->data;
15642e5ec60SJeff-Hadley PetscBool same;
1578a2c336bSFande Kong PetscInt num_levels, l;
1588a2c336bSFande Kong Mat *mattmp;
1598a2c336bSFande Kong hypre_ParCSRMatrix **A_array;
1608a2c336bSFande Kong
1618a2c336bSFande Kong PetscFunctionBegin;
1629566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type, "boomeramg", &same));
1635f80ce2aSJacob Faibussowitsch PetscCheck(same, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_NOTSAMETYPE, "Hypre type is not BoomerAMG");
164f4f49eeaSPierre Jolivet num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData *)jac->hsolver);
1659566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(num_levels, &mattmp));
166f4f49eeaSPierre Jolivet A_array = hypre_ParAMGDataAArray((hypre_ParAMGData *)jac->hsolver);
1678a2c336bSFande Kong for (l = 1; l < num_levels; l++) {
168f4f49eeaSPierre Jolivet PetscCall(MatCreateFromParCSR(A_array[l], MATAIJ, PETSC_OWN_POINTER, &mattmp[num_levels - 1 - l]));
1698a2c336bSFande Kong /* We want to own the data, and HYPRE can not touch this matrix any more */
1708a2c336bSFande Kong A_array[l] = NULL;
1718a2c336bSFande Kong }
1728a2c336bSFande Kong *nlevels = num_levels;
1738a2c336bSFande Kong *operators = mattmp;
1743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1758a2c336bSFande Kong }
1768a2c336bSFande Kong
177fd2dd295SFande Kong /*
1788a2c336bSFande Kong Matrices with AIJ format are created IN PLACE with using (I,J,data) from BoomerAMG. Since the data format in hypre_ParCSRMatrix
1798a2c336bSFande Kong is different from that used in PETSc, the original hypre_ParCSRMatrix can not be used any more after call this routine.
1808a2c336bSFande Kong It is used in PCHMG. Other users should avoid using this function.
181fd2dd295SFande Kong */
PCGetInterpolations_BoomerAMG(PC pc,PetscInt * nlevels,Mat * interpolations[])182d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCGetInterpolations_BoomerAMG(PC pc, PetscInt *nlevels, Mat *interpolations[])
183d71ae5a4SJacob Faibussowitsch {
1848a2c336bSFande Kong PC_HYPRE *jac = (PC_HYPRE *)pc->data;
18542e5ec60SJeff-Hadley PetscBool same;
1868a2c336bSFande Kong PetscInt num_levels, l;
1878a2c336bSFande Kong Mat *mattmp;
1888a2c336bSFande Kong hypre_ParCSRMatrix **P_array;
1898a2c336bSFande Kong
1908a2c336bSFande Kong PetscFunctionBegin;
1919566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type, "boomeramg", &same));
1925f80ce2aSJacob Faibussowitsch PetscCheck(same, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_NOTSAMETYPE, "Hypre type is not BoomerAMG");
193f4f49eeaSPierre Jolivet num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData *)jac->hsolver);
1949566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(num_levels, &mattmp));
195f4f49eeaSPierre Jolivet P_array = hypre_ParAMGDataPArray((hypre_ParAMGData *)jac->hsolver);
1968a2c336bSFande Kong for (l = 1; l < num_levels; l++) {
197f4f49eeaSPierre Jolivet PetscCall(MatCreateFromParCSR(P_array[num_levels - 1 - l], MATAIJ, PETSC_OWN_POINTER, &mattmp[l - 1]));
1988a2c336bSFande Kong /* We want to own the data, and HYPRE can not touch this matrix any more */
1998a2c336bSFande Kong P_array[num_levels - 1 - l] = NULL;
2008a2c336bSFande Kong }
2018a2c336bSFande Kong *nlevels = num_levels;
2028a2c336bSFande Kong *interpolations = mattmp;
2033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2048a2c336bSFande Kong }
2058a2c336bSFande Kong
20642e5ec60SJeff-Hadley /*
20742e5ec60SJeff-Hadley Boolean Vecs are created IN PLACE with using data from BoomerAMG.
20842e5ec60SJeff-Hadley */
PCHYPREGetCFMarkers_BoomerAMG(PC pc,PetscInt * n_per_level[],PetscBT * CFMarkers[])20942e5ec60SJeff-Hadley static PetscErrorCode PCHYPREGetCFMarkers_BoomerAMG(PC pc, PetscInt *n_per_level[], PetscBT *CFMarkers[])
21042e5ec60SJeff-Hadley {
21142e5ec60SJeff-Hadley PC_HYPRE *jac = (PC_HYPRE *)pc->data;
21242e5ec60SJeff-Hadley PetscBool same;
21342e5ec60SJeff-Hadley PetscInt num_levels, fine_nodes = 0, coarse_nodes;
21442e5ec60SJeff-Hadley PetscInt *n_per_temp;
21542e5ec60SJeff-Hadley PetscBT *markertmp;
21642e5ec60SJeff-Hadley hypre_IntArray **CF_marker_array;
21742e5ec60SJeff-Hadley
21842e5ec60SJeff-Hadley PetscFunctionBegin;
21942e5ec60SJeff-Hadley PetscCall(PetscStrcmp(jac->hypre_type, "boomeramg", &same));
22042e5ec60SJeff-Hadley PetscCheck(same, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_NOTSAMETYPE, "Hypre type is not BoomerAMG");
22142e5ec60SJeff-Hadley num_levels = hypre_ParAMGDataNumLevels((hypre_ParAMGData *)jac->hsolver);
22242e5ec60SJeff-Hadley PetscCall(PetscMalloc1(num_levels, &n_per_temp));
22342e5ec60SJeff-Hadley PetscCall(PetscMalloc1(num_levels - 1, &markertmp));
22442e5ec60SJeff-Hadley CF_marker_array = hypre_ParAMGDataCFMarkerArray((hypre_ParAMGData *)jac->hsolver);
22542e5ec60SJeff-Hadley for (PetscInt l = 0, CFMaxIndex = num_levels - 2; CFMaxIndex >= 0; l++, CFMaxIndex--) {
22642e5ec60SJeff-Hadley fine_nodes = hypre_IntArraySize(CF_marker_array[CFMaxIndex]);
22742e5ec60SJeff-Hadley coarse_nodes = 0;
22842e5ec60SJeff-Hadley PetscCall(PetscBTCreate(fine_nodes, &markertmp[l]));
22942e5ec60SJeff-Hadley for (PetscInt k = 0; k < fine_nodes; k++) {
23042e5ec60SJeff-Hadley if (hypre_IntArrayDataI(CF_marker_array[CFMaxIndex], k) > 0) {
23142e5ec60SJeff-Hadley PetscCall(PetscBTSet(markertmp[l], k));
23242e5ec60SJeff-Hadley coarse_nodes++;
23342e5ec60SJeff-Hadley }
23442e5ec60SJeff-Hadley }
23542e5ec60SJeff-Hadley n_per_temp[l] = coarse_nodes;
23642e5ec60SJeff-Hadley }
23742e5ec60SJeff-Hadley n_per_temp[num_levels - 1] = fine_nodes;
23842e5ec60SJeff-Hadley *n_per_level = n_per_temp;
23942e5ec60SJeff-Hadley *CFMarkers = markertmp;
24042e5ec60SJeff-Hadley PetscFunctionReturn(PETSC_SUCCESS);
24142e5ec60SJeff-Hadley }
24242e5ec60SJeff-Hadley
243ce6a8a0dSJed Brown /* Resets (frees) Hypre's representation of the near null space */
PCHYPREResetNearNullSpace_Private(PC pc)244d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPREResetNearNullSpace_Private(PC pc)
245d71ae5a4SJacob Faibussowitsch {
246ce6a8a0dSJed Brown PC_HYPRE *jac = (PC_HYPRE *)pc->data;
247ce6a8a0dSJed Brown PetscInt i;
248ce6a8a0dSJed Brown
2499d678128SJed Brown PetscFunctionBegin;
25048a46eb9SPierre Jolivet for (i = 0; i < jac->n_hmnull; i++) PetscCall(VecHYPRE_IJVectorDestroy(&jac->hmnull[i]));
2519566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hmnull));
2529566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->phmnull));
2539566063dSJacob Faibussowitsch PetscCall(VecDestroy(&jac->hmnull_constant));
2549d678128SJed Brown jac->n_hmnull = 0;
2553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
256ce6a8a0dSJed Brown }
257ce6a8a0dSJed Brown
258d7185485SAlex Lindsay static const char *HYPRESpgemmTypes[] = {"cusparse", "hypre"};
PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc,const char name[])259d7185485SAlex Lindsay static PetscErrorCode PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc, const char name[])
260d7185485SAlex Lindsay {
261d7185485SAlex Lindsay PC_HYPRE *jac = (PC_HYPRE *)pc->data;
262d7185485SAlex Lindsay
263d7185485SAlex Lindsay #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0)
264d7185485SAlex Lindsay PetscFunctionBegin;
265abf5c9d9SBarry Smith jac->spgemm_type = name;
266d7185485SAlex Lindsay PetscFunctionReturn(PETSC_SUCCESS);
267d7185485SAlex Lindsay #endif
268d7185485SAlex Lindsay }
269d7185485SAlex Lindsay
PCSetUp_HYPRE(PC pc)270d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetUp_HYPRE(PC pc)
271d71ae5a4SJacob Faibussowitsch {
27216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data;
27349a781f5SStefano Zampini Mat_HYPRE *hjac;
27416d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat;
27516d9e3a6SLisandro Dalcin HYPRE_ParVector bv, xv;
27649a781f5SStefano Zampini PetscBool ishypre;
27716d9e3a6SLisandro Dalcin
27816d9e3a6SLisandro Dalcin PetscFunctionBegin;
2790df1829cSStefano Zampini /* default type is boomerAMG */
28048a46eb9SPierre Jolivet if (!jac->hypre_type) PetscCall(PCHYPRESetType(pc, "boomeramg"));
2815f5c5b43SBarry Smith
2820df1829cSStefano Zampini /* get hypre matrix */
2830df1829cSStefano Zampini if (pc->flag == DIFFERENT_NONZERO_PATTERN) PetscCall(MatDestroy(&jac->hpmat));
2849566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRE, &ishypre));
28549a781f5SStefano Zampini if (!ishypre) {
286e6519f9fSJunchao Zhang #if defined(PETSC_HAVE_HYPRE_DEVICE) && PETSC_PKG_HYPRE_VERSION_LE(2, 30, 0)
2870df1829cSStefano Zampini /* Temporary fix since we do not support MAT_REUSE_MATRIX with HYPRE device */
2880df1829cSStefano Zampini PetscBool iscuda, iship, iskokkos;
2890df1829cSStefano Zampini
2900df1829cSStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)pc->pmat, &iscuda, MATSEQAIJCUSPARSE, MATMPIAIJCUSPARSE, ""));
2910df1829cSStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)pc->pmat, &iship, MATSEQAIJHIPSPARSE, MATMPIAIJHIPSPARSE, ""));
2920df1829cSStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)pc->pmat, &iskokkos, MATSEQAIJKOKKOS, MATMPIAIJKOKKOS, ""));
2930df1829cSStefano Zampini if (iscuda || iship || iskokkos) PetscCall(MatDestroy(&jac->hpmat));
2940df1829cSStefano Zampini #endif
2950df1829cSStefano Zampini PetscCall(MatConvert(pc->pmat, MATHYPRE, jac->hpmat ? MAT_REUSE_MATRIX : MAT_INITIAL_MATRIX, &jac->hpmat));
29649a781f5SStefano Zampini } else {
2979566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)pc->pmat));
2989566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->hpmat));
29949a781f5SStefano Zampini jac->hpmat = pc->pmat;
30016d9e3a6SLisandro Dalcin }
3010df1829cSStefano Zampini
3026ea7df73SStefano Zampini /* allow debug */
3039566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(jac->hpmat, NULL, "-pc_hypre_mat_view"));
304f4f49eeaSPierre Jolivet hjac = (Mat_HYPRE *)jac->hpmat->data;
3055f5c5b43SBarry Smith
30616d9e3a6SLisandro Dalcin /* special case for BoomerAMG */
30716d9e3a6SLisandro Dalcin if (jac->setup == HYPRE_BoomerAMGSetup) {
3085272c319SBarry Smith MatNullSpace mnull;
3095272c319SBarry Smith PetscBool has_const;
31049a781f5SStefano Zampini PetscInt bs, nvec, i;
311d7185485SAlex Lindsay PetscMemType memtype;
3125272c319SBarry Smith const Vec *vecs;
3135272c319SBarry Smith
314d7185485SAlex Lindsay PetscCall(MatGetCurrentMemType(jac->hpmat, &memtype));
315d7185485SAlex Lindsay if (PetscMemTypeDevice(memtype)) {
316d7185485SAlex Lindsay /* GPU defaults
317d7185485SAlex Lindsay From https://hypre.readthedocs.io/en/latest/solvers-boomeramg.html#gpu-supported-options
318d7185485SAlex Lindsay and /src/parcsr_ls/par_amg.c
319d7185485SAlex Lindsay First handle options which users have interfaces for changing */
320d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, coarsentype, 8);
321d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, relaxorder, 0);
322d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, interptype, 6);
323d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, relaxtype[0], 18);
324d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, relaxtype[1], 18);
325d7185485SAlex Lindsay #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0)
326d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, spgemm_type, HYPRESpgemmTypes[0]);
327d7185485SAlex Lindsay #endif
328d7185485SAlex Lindsay #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0)
329abf5c9d9SBarry Smith PetscObjectParameterSetDefault(jac, keeptranspose, PETSC_BOOL3_TRUE);
330d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, mod_rap2, 1);
331d7185485SAlex Lindsay #endif
332d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, agg_interptype, 7);
333d7185485SAlex Lindsay } else {
334d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, coarsentype, 6);
335d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, relaxorder, 1);
336d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, interptype, 0);
337d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, relaxtype[0], 6);
338d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, relaxtype[1], 6); /* Defaults to SYMMETRIC since in PETSc we are using a PC - most likely with CG */
339d7185485SAlex Lindsay #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0)
340d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, spgemm_type, "hypre");
341d7185485SAlex Lindsay #endif
342d7185485SAlex Lindsay #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0)
343abf5c9d9SBarry Smith PetscObjectParameterSetDefault(jac, keeptranspose, PETSC_BOOL3_FALSE);
344d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, mod_rap2, 0);
345d7185485SAlex Lindsay #endif
346d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, agg_interptype, 4);
347d7185485SAlex Lindsay }
348f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetCycleType(jac->hsolver, (HYPRE_Int)jac->cycletype));
349f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetMaxLevels(jac->hsolver, (HYPRE_Int)jac->maxlevels));
350f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetMaxIter(jac->hsolver, (HYPRE_Int)jac->maxiter));
351a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetTol(jac->hsolver, jac->tol));
352a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetTruncFactor(jac->hsolver, jac->truncfactor));
353a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetStrongThreshold(jac->hsolver, jac->strongthreshold));
354a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetMaxRowSum(jac->hsolver, jac->maxrowsum));
355f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetMeasureType(jac->hsolver, (HYPRE_Int)jac->measuretype));
356f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetAggNumLevels(jac->hsolver, (HYPRE_Int)jac->agg_nl));
357f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetPMaxElmts(jac->hsolver, (HYPRE_Int)jac->pmax));
358f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetNumPaths(jac->hsolver, (HYPRE_Int)jac->agg_num_paths));
359f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetCycleNumSweeps(jac->hsolver, (HYPRE_Int)jac->gridsweeps[0], 1));
360f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetCycleNumSweeps(jac->hsolver, (HYPRE_Int)jac->gridsweeps[1], 2));
361f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetCycleNumSweeps(jac->hsolver, (HYPRE_Int)jac->gridsweeps[2], 3));
362f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetMaxCoarseSize(jac->hsolver, (HYPRE_Int)jac->maxc));
363f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetMinCoarseSize(jac->hsolver, (HYPRE_Int)jac->minc));
364f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetCoarsenType(jac->hsolver, (HYPRE_Int)jac->coarsentype));
365f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetRelaxOrder(jac->hsolver, (HYPRE_Int)jac->relaxorder));
366f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetInterpType(jac->hsolver, (HYPRE_Int)jac->interptype));
367f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetRelaxType(jac->hsolver, (HYPRE_Int)jac->relaxtype[0]));
368f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetCycleRelaxType(jac->hsolver, (HYPRE_Int)jac->relaxtype[0], 1));
369f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetCycleRelaxType(jac->hsolver, (HYPRE_Int)jac->relaxtype[1], 2));
370f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetCycleRelaxType(jac->hsolver, (HYPRE_Int)jac->relaxtype[2], 3));
371d7185485SAlex Lindsay /* GPU */
372d7185485SAlex Lindsay #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0)
373abf5c9d9SBarry Smith {
374abf5c9d9SBarry Smith PetscBool flg_cusparse, flg_hypre;
375abf5c9d9SBarry Smith
376abf5c9d9SBarry Smith PetscCall(PetscStrcmp("cusparse", jac->spgemm_type, &flg_cusparse));
377abf5c9d9SBarry Smith PetscCall(PetscStrcmp("hypre", jac->spgemm_type, &flg_hypre));
378a333fa2bSZach Atkins if (flg_cusparse) PetscCallHYPRE(HYPRE_SetSpGemmUseCusparse(1));
379a333fa2bSZach Atkins else if (flg_hypre) PetscCallHYPRE(HYPRE_SetSpGemmUseCusparse(0));
380abf5c9d9SBarry Smith else SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown HYPRE SpGEMM type %s; Choices are cusparse, hypre", jac->spgemm_type);
381abf5c9d9SBarry Smith }
382d7185485SAlex Lindsay #endif
383d7185485SAlex Lindsay #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0)
384a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetKeepTranspose(jac->hsolver, jac->keeptranspose == PETSC_BOOL3_TRUE ? 1 : 0));
385f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetRAP2(jac->hsolver, (HYPRE_Int)jac->rap2));
386f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetModuleRAP2(jac->hsolver, (HYPRE_Int)jac->mod_rap2));
387d7185485SAlex Lindsay #endif
388f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetAggInterpType(jac->hsolver, (HYPRE_Int)jac->agg_interptype));
389d7185485SAlex Lindsay
390d7185485SAlex Lindsay /* AIR */
391d7185485SAlex Lindsay #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0)
392f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetRestriction(jac->hsolver, (HYPRE_Int)jac->Rtype));
393a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetStrongThresholdR(jac->hsolver, jac->Rstrongthreshold));
394a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetFilterThresholdR(jac->hsolver, jac->Rfilterthreshold));
395a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetADropTol(jac->hsolver, jac->Adroptol));
396f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetADropType(jac->hsolver, (HYPRE_Int)jac->Adroptype));
397d7185485SAlex Lindsay #endif
398d7185485SAlex Lindsay
3999566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(pc->pmat, &bs));
400f2f41e48SZach Atkins if (bs > 1) PetscCallHYPRE(HYPRE_BoomerAMGSetNumFunctions(jac->hsolver, (HYPRE_Int)bs));
4019566063dSJacob Faibussowitsch PetscCall(MatGetNearNullSpace(pc->mat, &mnull));
4025272c319SBarry Smith if (mnull) {
4039566063dSJacob Faibussowitsch PetscCall(PCHYPREResetNearNullSpace_Private(pc));
4049566063dSJacob Faibussowitsch PetscCall(MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs));
4059566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvec + 1, &jac->hmnull));
4069566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvec + 1, &jac->phmnull));
4075272c319SBarry Smith for (i = 0; i < nvec; i++) {
4089566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(vecs[i]->map, &jac->hmnull[i]));
4099566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(vecs[i], jac->hmnull[i]));
410a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJVectorGetObject(jac->hmnull[i]->ij, (void **)&jac->phmnull[i]));
4115272c319SBarry Smith }
4125272c319SBarry Smith if (has_const) {
4139566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(pc->pmat, &jac->hmnull_constant, NULL));
4149566063dSJacob Faibussowitsch PetscCall(VecSet(jac->hmnull_constant, 1));
4159566063dSJacob Faibussowitsch PetscCall(VecNormalize(jac->hmnull_constant, NULL));
4169566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(jac->hmnull_constant->map, &jac->hmnull[nvec]));
4179566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(jac->hmnull_constant, jac->hmnull[nvec]));
418a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJVectorGetObject(jac->hmnull[nvec]->ij, (void **)&jac->phmnull[nvec]));
4195272c319SBarry Smith nvec++;
4205272c319SBarry Smith }
421f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetInterpVectors(jac->hsolver, (HYPRE_Int)nvec, jac->phmnull));
4225272c319SBarry Smith jac->n_hmnull = nvec;
4235272c319SBarry Smith }
4244cb006feSStefano Zampini }
425863406b8SStefano Zampini
4264cb006feSStefano Zampini /* special case for AMS */
4274cb006feSStefano Zampini if (jac->setup == HYPRE_AMSSetup) {
4285ac14e1cSStefano Zampini Mat_HYPRE *hm;
4295ac14e1cSStefano Zampini HYPRE_ParCSRMatrix parcsr;
430966bd95aSPierre Jolivet PetscCheck(jac->coords[0] || jac->constants[0] || jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]), 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()");
431f2f41e48SZach Atkins if (jac->dim) PetscCallHYPRE(HYPRE_AMSSetDimension(jac->hsolver, (HYPRE_Int)jac->dim));
4325ac14e1cSStefano Zampini if (jac->constants[0]) {
4335ac14e1cSStefano Zampini HYPRE_ParVector ozz, zoz, zzo = NULL;
434a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJVectorGetObject(jac->constants[0]->ij, (void **)(&ozz)));
435a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJVectorGetObject(jac->constants[1]->ij, (void **)(&zoz)));
436a333fa2bSZach Atkins if (jac->constants[2]) PetscCallHYPRE(HYPRE_IJVectorGetObject(jac->constants[2]->ij, (void **)(&zzo)));
437a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_AMSSetEdgeConstantVectors(jac->hsolver, ozz, zoz, zzo));
4385ac14e1cSStefano Zampini }
4395ac14e1cSStefano Zampini if (jac->coords[0]) {
4405ac14e1cSStefano Zampini HYPRE_ParVector coords[3];
4415ac14e1cSStefano Zampini coords[0] = NULL;
4425ac14e1cSStefano Zampini coords[1] = NULL;
4435ac14e1cSStefano Zampini coords[2] = NULL;
444a333fa2bSZach Atkins if (jac->coords[0]) PetscCallHYPRE(HYPRE_IJVectorGetObject(jac->coords[0]->ij, (void **)(&coords[0])));
445a333fa2bSZach Atkins if (jac->coords[1]) PetscCallHYPRE(HYPRE_IJVectorGetObject(jac->coords[1]->ij, (void **)(&coords[1])));
446a333fa2bSZach Atkins if (jac->coords[2]) PetscCallHYPRE(HYPRE_IJVectorGetObject(jac->coords[2]->ij, (void **)(&coords[2])));
447a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_AMSSetCoordinateVectors(jac->hsolver, coords[0], coords[1], coords[2]));
4485ac14e1cSStefano Zampini }
4495f80ce2aSJacob Faibussowitsch PetscCheck(jac->G, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
450f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->G->data;
451a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJMatrixGetObject(hm->ij, (void **)(&parcsr)));
452a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_AMSSetDiscreteGradient(jac->hsolver, parcsr));
4535ac14e1cSStefano Zampini if (jac->alpha_Poisson) {
454f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->alpha_Poisson->data;
455a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJMatrixGetObject(hm->ij, (void **)(&parcsr)));
456a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_AMSSetAlphaPoissonMatrix(jac->hsolver, parcsr));
4575ac14e1cSStefano Zampini }
4585ac14e1cSStefano Zampini if (jac->ams_beta_is_zero) {
459a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_AMSSetBetaPoissonMatrix(jac->hsolver, NULL));
4605ac14e1cSStefano Zampini } else if (jac->beta_Poisson) {
461f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->beta_Poisson->data;
462a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJMatrixGetObject(hm->ij, (void **)(&parcsr)));
463a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_AMSSetBetaPoissonMatrix(jac->hsolver, parcsr));
464be14dc20SKerry Key } else if (jac->ams_beta_is_zero_part) {
465be14dc20SKerry Key if (jac->interior) {
466be14dc20SKerry Key HYPRE_ParVector interior = NULL;
467a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJVectorGetObject(jac->interior->ij, (void **)(&interior)));
468a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_AMSSetInteriorNodes(jac->hsolver, interior));
469be14dc20SKerry Key } else {
470be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_FALSE;
471be14dc20SKerry Key }
4725ac14e1cSStefano Zampini }
4736bf688a0SCe Qin if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) {
4746bf688a0SCe Qin PetscInt i;
4756bf688a0SCe Qin HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
4766bf688a0SCe Qin if (jac->ND_PiFull) {
477f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->ND_PiFull->data;
478a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJMatrixGetObject(hm->ij, (void **)(&nd_parcsrfull)));
4796bf688a0SCe Qin } else {
4806bf688a0SCe Qin nd_parcsrfull = NULL;
4816bf688a0SCe Qin }
4826bf688a0SCe Qin for (i = 0; i < 3; ++i) {
4836bf688a0SCe Qin if (jac->ND_Pi[i]) {
484f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->ND_Pi[i]->data;
485a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJMatrixGetObject(hm->ij, (void **)(&nd_parcsr[i])));
4866bf688a0SCe Qin } else {
4876bf688a0SCe Qin nd_parcsr[i] = NULL;
4886bf688a0SCe Qin }
4896bf688a0SCe Qin }
490a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_AMSSetInterpolations(jac->hsolver, nd_parcsrfull, nd_parcsr[0], nd_parcsr[1], nd_parcsr[2]));
4916bf688a0SCe Qin }
4924cb006feSStefano Zampini }
493863406b8SStefano Zampini /* special case for ADS */
494863406b8SStefano Zampini if (jac->setup == HYPRE_ADSSetup) {
4955ac14e1cSStefano Zampini Mat_HYPRE *hm;
4965ac14e1cSStefano Zampini HYPRE_ParCSRMatrix parcsr;
4976bf688a0SCe 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])))) {
4986bf688a0SCe Qin SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations");
4999371c9d4SSatish Balay } else PetscCheck(jac->coords[1] && jac->coords[2], PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE ADS preconditioner has been designed for three dimensional problems! For two dimensional problems, use HYPRE AMS instead");
5005f80ce2aSJacob Faibussowitsch PetscCheck(jac->G, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient");
5015f80ce2aSJacob Faibussowitsch PetscCheck(jac->C, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient");
5025ac14e1cSStefano Zampini if (jac->coords[0]) {
5035ac14e1cSStefano Zampini HYPRE_ParVector coords[3];
5045ac14e1cSStefano Zampini coords[0] = NULL;
5055ac14e1cSStefano Zampini coords[1] = NULL;
5065ac14e1cSStefano Zampini coords[2] = NULL;
507a333fa2bSZach Atkins if (jac->coords[0]) PetscCallHYPRE(HYPRE_IJVectorGetObject(jac->coords[0]->ij, (void **)(&coords[0])));
508a333fa2bSZach Atkins if (jac->coords[1]) PetscCallHYPRE(HYPRE_IJVectorGetObject(jac->coords[1]->ij, (void **)(&coords[1])));
509a333fa2bSZach Atkins if (jac->coords[2]) PetscCallHYPRE(HYPRE_IJVectorGetObject(jac->coords[2]->ij, (void **)(&coords[2])));
510a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_ADSSetCoordinateVectors(jac->hsolver, coords[0], coords[1], coords[2]));
5115ac14e1cSStefano Zampini }
512f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->G->data;
513a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJMatrixGetObject(hm->ij, (void **)(&parcsr)));
514a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_ADSSetDiscreteGradient(jac->hsolver, parcsr));
515f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->C->data;
516a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJMatrixGetObject(hm->ij, (void **)(&parcsr)));
517a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_ADSSetDiscreteCurl(jac->hsolver, parcsr));
5186bf688a0SCe Qin if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) {
5196bf688a0SCe Qin PetscInt i;
5206bf688a0SCe Qin HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3];
5216bf688a0SCe Qin HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3];
5226bf688a0SCe Qin if (jac->RT_PiFull) {
523f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->RT_PiFull->data;
524a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJMatrixGetObject(hm->ij, (void **)(&rt_parcsrfull)));
5256bf688a0SCe Qin } else {
5266bf688a0SCe Qin rt_parcsrfull = NULL;
5276bf688a0SCe Qin }
5286bf688a0SCe Qin for (i = 0; i < 3; ++i) {
5296bf688a0SCe Qin if (jac->RT_Pi[i]) {
530f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->RT_Pi[i]->data;
531a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJMatrixGetObject(hm->ij, (void **)(&rt_parcsr[i])));
5326bf688a0SCe Qin } else {
5336bf688a0SCe Qin rt_parcsr[i] = NULL;
5346bf688a0SCe Qin }
5356bf688a0SCe Qin }
5366bf688a0SCe Qin if (jac->ND_PiFull) {
537f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->ND_PiFull->data;
538a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJMatrixGetObject(hm->ij, (void **)(&nd_parcsrfull)));
5396bf688a0SCe Qin } else {
5406bf688a0SCe Qin nd_parcsrfull = NULL;
5416bf688a0SCe Qin }
5426bf688a0SCe Qin for (i = 0; i < 3; ++i) {
5436bf688a0SCe Qin if (jac->ND_Pi[i]) {
544f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->ND_Pi[i]->data;
545a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJMatrixGetObject(hm->ij, (void **)(&nd_parcsr[i])));
5466bf688a0SCe Qin } else {
5476bf688a0SCe Qin nd_parcsr[i] = NULL;
5486bf688a0SCe Qin }
5496bf688a0SCe Qin }
550a333fa2bSZach Atkins PetscCallHYPRE(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]));
5516bf688a0SCe Qin }
552863406b8SStefano Zampini }
553a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJMatrixGetObject(hjac->ij, (void **)&hmat));
554a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJVectorGetObject(hjac->b->ij, (void **)&bv));
555a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJVectorGetObject(hjac->x->ij, (void **)&xv));
55697c1e3cbSStefano Zampini PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
557325a1edfSZach Atkins PetscCallHYPRE((*jac->setup)(jac->hsolver, hmat, bv, xv));
55897c1e3cbSStefano Zampini PetscCall(PetscFPTrapPop());
5593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
56016d9e3a6SLisandro Dalcin }
56116d9e3a6SLisandro Dalcin
PCApply_HYPRE(PC pc,Vec b,Vec x)562d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApply_HYPRE(PC pc, Vec b, Vec x)
563d71ae5a4SJacob Faibussowitsch {
56416d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data;
565f4f49eeaSPierre Jolivet Mat_HYPRE *hjac = (Mat_HYPRE *)jac->hpmat->data;
56616d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat;
56716d9e3a6SLisandro Dalcin HYPRE_ParVector jbv, jxv;
56816d9e3a6SLisandro Dalcin
56916d9e3a6SLisandro Dalcin PetscFunctionBegin;
5709566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite));
5719566063dSJacob Faibussowitsch if (!jac->applyrichardson) PetscCall(VecSet(x, 0.0));
5729566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hjac->b, b));
5739566063dSJacob Faibussowitsch if (jac->applyrichardson) PetscCall(VecHYPRE_IJVectorPushVec(hjac->x, x));
5749566063dSJacob Faibussowitsch else PetscCall(VecHYPRE_IJVectorPushVecWrite(hjac->x, x));
575a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJMatrixGetObject(hjac->ij, (void **)&hmat));
576a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJVectorGetObject(hjac->b->ij, (void **)&jbv));
577a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJVectorGetObject(hjac->x->ij, (void **)&jxv));
5789371c9d4SSatish Balay PetscStackCallExternalVoid(
5799371c9d4SSatish Balay "Hypre solve", do {
5805f80ce2aSJacob Faibussowitsch HYPRE_Int hierr = (*jac->solve)(jac->hsolver, hmat, jbv, jxv);
5815f80ce2aSJacob Faibussowitsch if (hierr) {
5825f80ce2aSJacob Faibussowitsch PetscCheck(hierr == HYPRE_ERROR_CONV, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in HYPRE solver, error code %d", (int)hierr);
58385245615SPierre Jolivet HYPRE_ClearAllErrors();
5845f80ce2aSJacob Faibussowitsch }
5855f80ce2aSJacob Faibussowitsch } while (0));
58616d9e3a6SLisandro Dalcin
587a333fa2bSZach Atkins if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) PetscCallHYPRE(HYPRE_AMSProjectOutGradients(jac->hsolver, jxv));
5889566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->x));
5899566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->b));
5903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
59116d9e3a6SLisandro Dalcin }
59216d9e3a6SLisandro Dalcin
PCMatApply_HYPRE_BoomerAMG(PC pc,Mat B,Mat X)59385245615SPierre Jolivet static PetscErrorCode PCMatApply_HYPRE_BoomerAMG(PC pc, Mat B, Mat X)
59485245615SPierre Jolivet {
59585245615SPierre Jolivet PC_HYPRE *jac = (PC_HYPRE *)pc->data;
596f4f49eeaSPierre Jolivet Mat_HYPRE *hjac = (Mat_HYPRE *)jac->hpmat->data;
59785245615SPierre Jolivet hypre_ParCSRMatrix *par_matrix;
59885245615SPierre Jolivet HYPRE_ParVector hb, hx;
59985245615SPierre Jolivet const PetscScalar *b;
60085245615SPierre Jolivet PetscScalar *x;
60185245615SPierre Jolivet PetscInt m, N, lda;
60285245615SPierre Jolivet hypre_Vector *x_local;
60385245615SPierre Jolivet PetscMemType type;
60485245615SPierre Jolivet
60585245615SPierre Jolivet PetscFunctionBegin;
60685245615SPierre Jolivet PetscCall(PetscCitationsRegister(hypreCitation, &cite));
607a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJMatrixGetObject(hjac->ij, (void **)&par_matrix));
60885245615SPierre Jolivet PetscCall(MatGetLocalSize(B, &m, NULL));
60985245615SPierre Jolivet PetscCall(MatGetSize(B, NULL, &N));
610f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_ParMultiVectorCreate(hypre_ParCSRMatrixComm(par_matrix), hypre_ParCSRMatrixGlobalNumRows(par_matrix), hypre_ParCSRMatrixRowStarts(par_matrix), (HYPRE_Int)N, &hb));
611f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_ParMultiVectorCreate(hypre_ParCSRMatrixComm(par_matrix), hypre_ParCSRMatrixGlobalNumRows(par_matrix), hypre_ParCSRMatrixRowStarts(par_matrix), (HYPRE_Int)N, &hx));
61285245615SPierre Jolivet PetscCall(MatZeroEntries(X));
61385245615SPierre Jolivet PetscCall(MatDenseGetArrayReadAndMemType(B, &b, &type));
61485245615SPierre Jolivet PetscCall(MatDenseGetLDA(B, &lda));
61585245615SPierre Jolivet PetscCheck(lda == m, PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "Cannot use a LDA different than the number of local rows: % " PetscInt_FMT " != % " PetscInt_FMT, lda, m);
61685245615SPierre Jolivet PetscCall(MatDenseGetLDA(X, &lda));
61785245615SPierre Jolivet PetscCheck(lda == m, PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "Cannot use a LDA different than the number of local rows: % " PetscInt_FMT " != % " PetscInt_FMT, lda, m);
61885245615SPierre Jolivet x_local = hypre_ParVectorLocalVector(hb);
619a333fa2bSZach Atkins PetscCallHYPRE(hypre_SeqVectorSetDataOwner(x_local, 0));
62085245615SPierre Jolivet hypre_VectorData(x_local) = (HYPRE_Complex *)b;
62185245615SPierre Jolivet PetscCall(MatDenseGetArrayWriteAndMemType(X, &x, NULL));
62285245615SPierre Jolivet x_local = hypre_ParVectorLocalVector(hx);
623a333fa2bSZach Atkins PetscCallHYPRE(hypre_SeqVectorSetDataOwner(x_local, 0));
62485245615SPierre Jolivet hypre_VectorData(x_local) = (HYPRE_Complex *)x;
625a333fa2bSZach Atkins PetscCallHYPRE(hypre_ParVectorInitialize_v2(hb, type == PETSC_MEMTYPE_HOST ? HYPRE_MEMORY_HOST : HYPRE_MEMORY_DEVICE));
626a333fa2bSZach Atkins PetscCallHYPRE(hypre_ParVectorInitialize_v2(hx, type == PETSC_MEMTYPE_HOST ? HYPRE_MEMORY_HOST : HYPRE_MEMORY_DEVICE));
62785245615SPierre Jolivet PetscStackCallExternalVoid(
62885245615SPierre Jolivet "Hypre solve", do {
62985245615SPierre Jolivet HYPRE_Int hierr = (*jac->solve)(jac->hsolver, par_matrix, hb, hx);
63085245615SPierre Jolivet if (hierr) {
63185245615SPierre Jolivet PetscCheck(hierr == HYPRE_ERROR_CONV, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in HYPRE solver, error code %d", (int)hierr);
63285245615SPierre Jolivet HYPRE_ClearAllErrors();
63385245615SPierre Jolivet }
63485245615SPierre Jolivet } while (0));
635a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_ParVectorDestroy(hb));
636a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_ParVectorDestroy(hx));
63785245615SPierre Jolivet PetscCall(MatDenseRestoreArrayReadAndMemType(B, &b));
63885245615SPierre Jolivet PetscCall(MatDenseRestoreArrayWriteAndMemType(X, &x));
63985245615SPierre Jolivet PetscFunctionReturn(PETSC_SUCCESS);
64085245615SPierre Jolivet }
64185245615SPierre Jolivet
PCReset_HYPRE(PC pc)642d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCReset_HYPRE(PC pc)
643d71ae5a4SJacob Faibussowitsch {
6448695de01SBarry Smith PC_HYPRE *jac = (PC_HYPRE *)pc->data;
6458695de01SBarry Smith
6468695de01SBarry Smith PetscFunctionBegin;
6479566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->hpmat));
6489566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G));
6499566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C));
6509566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson));
6519566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson));
6529566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_PiFull));
6539566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[0]));
6549566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[1]));
6559566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[2]));
6569566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_PiFull));
6579566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[0]));
6589566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[1]));
6599566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[2]));
6609566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[0]));
6619566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[1]));
6629566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[2]));
6639566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[0]));
6649566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[1]));
6659566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[2]));
666be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorDestroy(&jac->interior));
6679566063dSJacob Faibussowitsch PetscCall(PCHYPREResetNearNullSpace_Private(pc));
6685ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE;
669be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_FALSE;
6705ac14e1cSStefano Zampini jac->dim = 0;
6713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
6728695de01SBarry Smith }
6738695de01SBarry Smith
PCDestroy_HYPRE(PC pc)674d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCDestroy_HYPRE(PC pc)
675d71ae5a4SJacob Faibussowitsch {
67616d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data;
67716d9e3a6SLisandro Dalcin
67816d9e3a6SLisandro Dalcin PetscFunctionBegin;
6799566063dSJacob Faibussowitsch PetscCall(PCReset_HYPRE(pc));
680325a1edfSZach Atkins if (jac->destroy) PetscCallHYPRE((*jac->destroy)(jac->hsolver));
6819566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hypre_type));
6829566063dSJacob Faibussowitsch if (jac->comm_hypre != MPI_COMM_NULL) PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre));
6839566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data));
68416d9e3a6SLisandro Dalcin
6859566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)pc, 0));
6869566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetType_C", NULL));
6879566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREGetType_C", NULL));
6889566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteGradient_C", NULL));
6899566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteCurl_C", NULL));
6909566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetInterpolations_C", NULL));
6919566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetConstantEdgeVectors_C", NULL));
6929566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetPoissonMatrix_C", NULL));
6932e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetEdgeConstantVectors_C", NULL));
694be14dc20SKerry Key PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREAMSSetInteriorNodes_C", NULL));
6959566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetInterpolations_C", NULL));
6969566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetCoarseOperators_C", NULL));
69742e5ec60SJeff-Hadley PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREGetCFMarkers_C", NULL));
6989566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinSetMatProductAlgorithm_C", NULL));
6999566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinGetMatProductAlgorithm_C", NULL));
7002e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSetCoordinates_C", NULL));
7013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
70216d9e3a6SLisandro Dalcin }
70316d9e3a6SLisandro Dalcin
PCSetFromOptions_HYPRE_Pilut(PC pc,PetscOptionItems PetscOptionsObject)704ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PC pc, PetscOptionItems PetscOptionsObject)
705d71ae5a4SJacob Faibussowitsch {
70616d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data;
707ace3abfcSBarry Smith PetscBool flag;
70816d9e3a6SLisandro Dalcin
70916d9e3a6SLisandro Dalcin PetscFunctionBegin;
710d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE Pilut Options");
7119566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_pilut_maxiter", "Number of iterations", "None", jac->maxiter, &jac->maxiter, &flag));
712f2f41e48SZach Atkins if (flag) PetscCallHYPRE(HYPRE_ParCSRPilutSetMaxIter(jac->hsolver, (HYPRE_Int)jac->maxiter));
7139566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_pilut_tol", "Drop tolerance", "None", jac->tol, &jac->tol, &flag));
714a333fa2bSZach Atkins if (flag) PetscCallHYPRE(HYPRE_ParCSRPilutSetDropTolerance(jac->hsolver, jac->tol));
7159566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_pilut_factorrowsize", "FactorRowSize", "None", jac->factorrowsize, &jac->factorrowsize, &flag));
716f2f41e48SZach Atkins if (flag) PetscCallHYPRE(HYPRE_ParCSRPilutSetFactorRowSize(jac->hsolver, (HYPRE_Int)jac->factorrowsize));
717d0609cedSBarry Smith PetscOptionsHeadEnd();
7183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
71916d9e3a6SLisandro Dalcin }
72016d9e3a6SLisandro Dalcin
PCView_HYPRE_Pilut(PC pc,PetscViewer viewer)721d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_Pilut(PC pc, PetscViewer viewer)
722d71ae5a4SJacob Faibussowitsch {
72316d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data;
7249f196a02SMartin Diehl PetscBool isascii;
72516d9e3a6SLisandro Dalcin
72616d9e3a6SLisandro Dalcin PetscFunctionBegin;
7279f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
7289f196a02SMartin Diehl if (isascii) {
7299566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE Pilut preconditioning\n"));
73016d9e3a6SLisandro Dalcin if (jac->maxiter != PETSC_DEFAULT) {
73163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " maximum number of iterations %" PetscInt_FMT "\n", jac->maxiter));
73216d9e3a6SLisandro Dalcin } else {
7339566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default maximum number of iterations \n"));
73416d9e3a6SLisandro Dalcin }
73516d9e3a6SLisandro Dalcin if (jac->tol != PETSC_DEFAULT) {
7369566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " drop tolerance %g\n", (double)jac->tol));
73716d9e3a6SLisandro Dalcin } else {
7389566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default drop tolerance \n"));
73916d9e3a6SLisandro Dalcin }
74016d9e3a6SLisandro Dalcin if (jac->factorrowsize != PETSC_DEFAULT) {
74163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " factor row size %" PetscInt_FMT "\n", jac->factorrowsize));
74216d9e3a6SLisandro Dalcin } else {
7439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default factor row size \n"));
74416d9e3a6SLisandro Dalcin }
74516d9e3a6SLisandro Dalcin }
7463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
74716d9e3a6SLisandro Dalcin }
74816d9e3a6SLisandro Dalcin
7493c61a47dSLukas static const char *HYPREILUType[] = {
7503c61a47dSLukas "Block-Jacobi-ILUk", "Block-Jacobi-ILUT", "", "", "", "", "", "", "", "", /* 0-9 */
7513c61a47dSLukas "GMRES-ILUk", "GMRES-ILUT", "", "", "", "", "", "", "", "", /* 10-19 */
7523c61a47dSLukas "NSH-ILUk", "NSH-ILUT", "", "", "", "", "", "", "", "", /* 20-29 */
7533c61a47dSLukas "RAS-ILUk", "RAS-ILUT", "", "", "", "", "", "", "", "", /* 30-39 */
7543c61a47dSLukas "ddPQ-GMRES-ILUk", "ddPQ-GMRES-ILUT", "", "", "", "", "", "", "", "", /* 40-49 */
7553c61a47dSLukas "GMRES-ILU0" /* 50 */
7563c61a47dSLukas };
7573c61a47dSLukas
7583c61a47dSLukas static const char *HYPREILUIterSetup[] = {"default", "async-in-place", "async-explicit", "sync-explicit", "semisync-explicit"};
7593c61a47dSLukas
PCSetFromOptions_HYPRE_ILU(PC pc,PetscOptionItems PetscOptionsObject)760ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ILU(PC pc, PetscOptionItems PetscOptionsObject)
7613c61a47dSLukas {
7623c61a47dSLukas PC_HYPRE *jac = (PC_HYPRE *)pc->data;
7633c61a47dSLukas PetscBool flg;
7643c61a47dSLukas PetscInt indx;
7653c61a47dSLukas PetscReal tmpdbl;
7663c61a47dSLukas PetscBool tmp_truth;
7673c61a47dSLukas
7683c61a47dSLukas PetscFunctionBegin;
7693c61a47dSLukas PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE ILU Options");
7703c61a47dSLukas
7713c61a47dSLukas /* ILU: ILU Type */
7723c61a47dSLukas PetscCall(PetscOptionsEList("-pc_hypre_ilu_type", "Choose ILU Type", "None", HYPREILUType, PETSC_STATIC_ARRAY_LENGTH(HYPREILUType), HYPREILUType[0], &indx, &flg));
773f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_ILUSetType(jac->hsolver, (HYPRE_Int)indx));
7743c61a47dSLukas
7753c61a47dSLukas /* ILU: ILU iterative setup type*/
7763c61a47dSLukas PetscCall(PetscOptionsEList("-pc_hypre_ilu_iterative_setup_type", "Set ILU iterative setup type", "None", HYPREILUIterSetup, PETSC_STATIC_ARRAY_LENGTH(HYPREILUIterSetup), HYPREILUIterSetup[0], &indx, &flg));
777f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_ILUSetIterativeSetupType(jac->hsolver, (HYPRE_Int)indx));
7783c61a47dSLukas
7793c61a47dSLukas /* ILU: ILU iterative setup option*/
7803c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_iterative_setup_option", "Set ILU iterative setup option", "None", 0, &indx, &flg));
781f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_ILUSetIterativeSetupOption(jac->hsolver, (HYPRE_Int)indx));
7823c61a47dSLukas
7833c61a47dSLukas /* ILU: ILU iterative setup maxiter */
7843c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_iterative_setup_maxiter", "Set ILU iterative setup maximum iteration count", "None", 0, &indx, &flg));
785f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_ILUSetIterativeSetupMaxIter(jac->hsolver, (HYPRE_Int)indx));
7863c61a47dSLukas
7873c61a47dSLukas /* ILU: ILU iterative setup tolerance */
7883c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_ilu_iterative_setup_tolerance", "Set ILU iterative setup tolerance", "None", 0, &tmpdbl, &flg));
789a333fa2bSZach Atkins if (flg) PetscCallHYPRE(HYPRE_ILUSetIterativeSetupTolerance(jac->hsolver, tmpdbl));
7903c61a47dSLukas
7913c61a47dSLukas /* ILU: ILU Print Level */
7923c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_print_level", "Set ILU print level", "None", 0, &indx, &flg));
793f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_ILUSetPrintLevel(jac->hsolver, (HYPRE_Int)indx));
7943c61a47dSLukas
7953c61a47dSLukas /* ILU: Logging */
7963c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_logging", "Set ILU logging level", "None", 0, &indx, &flg));
797f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_ILUSetLogging(jac->hsolver, (HYPRE_Int)indx));
7983c61a47dSLukas
7993c61a47dSLukas /* ILU: ILU Level */
8003c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_level", "Set ILU level", "None", 0, &indx, &flg));
801f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_ILUSetLevelOfFill(jac->hsolver, (HYPRE_Int)indx));
8023c61a47dSLukas
8033c61a47dSLukas /* ILU: ILU Max NNZ per row */
8043c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_max_nnz_per_row", "Set maximum NNZ per row", "None", 0, &indx, &flg));
805f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_ILUSetMaxNnzPerRow(jac->hsolver, (HYPRE_Int)indx));
8063c61a47dSLukas
8073c61a47dSLukas /* ILU: tolerance */
8083c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_ilu_tol", "Tolerance for ILU", "None", 0, &tmpdbl, &flg));
809a333fa2bSZach Atkins if (flg) PetscCallHYPRE(HYPRE_ILUSetTol(jac->hsolver, tmpdbl));
8103c61a47dSLukas
8113c61a47dSLukas /* ILU: maximum iteration count */
8123c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_maxiter", "Set ILU max iterations", "None", 0, &indx, &flg));
813f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_ILUSetMaxIter(jac->hsolver, (HYPRE_Int)indx));
8143c61a47dSLukas
8153c61a47dSLukas /* ILU: drop threshold */
8163c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_ilu_drop_threshold", "Drop threshold for ILU", "None", 0, &tmpdbl, &flg));
817a333fa2bSZach Atkins if (flg) PetscCallHYPRE(HYPRE_ILUSetDropThreshold(jac->hsolver, tmpdbl));
8183c61a47dSLukas
8193c61a47dSLukas /* ILU: Triangular Solve */
8203c61a47dSLukas PetscCall(PetscOptionsBool("-pc_hypre_ilu_tri_solve", "Enable triangular solve", "None", PETSC_FALSE, &tmp_truth, &flg));
821a333fa2bSZach Atkins if (flg) PetscCallHYPRE(HYPRE_ILUSetTriSolve(jac->hsolver, tmp_truth));
8223c61a47dSLukas
8233c61a47dSLukas /* ILU: Lower Jacobi iteration */
8243c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_lower_jacobi_iters", "Set lower Jacobi iteration count", "None", 0, &indx, &flg));
825f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_ILUSetLowerJacobiIters(jac->hsolver, (HYPRE_Int)indx));
8263c61a47dSLukas
8273c61a47dSLukas /* ILU: Upper Jacobi iteration */
8283c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_upper_jacobi_iters", "Set upper Jacobi iteration count", "None", 0, &indx, &flg));
829f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_ILUSetUpperJacobiIters(jac->hsolver, (HYPRE_Int)indx));
8303c61a47dSLukas
8313c61a47dSLukas /* ILU: local reordering */
8323c61a47dSLukas PetscCall(PetscOptionsBool("-pc_hypre_ilu_local_reordering", "Enable local reordering", "None", PETSC_FALSE, &tmp_truth, &flg));
833a333fa2bSZach Atkins if (flg) PetscCallHYPRE(HYPRE_ILUSetLocalReordering(jac->hsolver, tmp_truth));
8343c61a47dSLukas
8353c61a47dSLukas PetscOptionsHeadEnd();
8363c61a47dSLukas PetscFunctionReturn(PETSC_SUCCESS);
8373c61a47dSLukas }
8383c61a47dSLukas
PCView_HYPRE_ILU(PC pc,PetscViewer viewer)8393c61a47dSLukas static PetscErrorCode PCView_HYPRE_ILU(PC pc, PetscViewer viewer)
8403c61a47dSLukas {
8413c61a47dSLukas PC_HYPRE *jac = (PC_HYPRE *)pc->data;
8423c61a47dSLukas hypre_ParILUData *ilu_data = (hypre_ParILUData *)jac->hsolver;
8439f196a02SMartin Diehl PetscBool isascii;
8443c61a47dSLukas PetscInt indx;
8453c61a47dSLukas PetscReal tmpdbl;
8463c61a47dSLukas PetscReal *tmpdbl3;
8473c61a47dSLukas
8483c61a47dSLukas PetscFunctionBegin;
8499f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
8509f196a02SMartin Diehl if (isascii) {
8513c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE ILU preconditioning\n"));
8523c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIluType", indx = hypre_ParILUDataIluType(ilu_data));
8533c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU type %s (%" PetscInt_FMT ")\n", HYPREILUType[indx], indx));
8543c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataLfil", indx = hypre_ParILUDataLfil(ilu_data));
8553c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU level %" PetscInt_FMT "\n", indx));
8563c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataMaxIter", indx = hypre_ParILUDataMaxIter(ilu_data));
8573c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU max iterations %" PetscInt_FMT "\n", indx));
8583c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataMaxRowNnz", indx = hypre_ParILUDataMaxRowNnz(ilu_data));
8593c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU max NNZ per row %" PetscInt_FMT "\n", indx));
8603c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataTriSolve", indx = hypre_ParILUDataTriSolve(ilu_data));
8613c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU triangular solve %" PetscInt_FMT "\n", indx));
8623c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataTol", tmpdbl = hypre_ParILUDataTol(ilu_data));
8633c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU tolerance %e\n", tmpdbl));
8643c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataDroptol", tmpdbl3 = hypre_ParILUDataDroptol(ilu_data));
8653c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU drop tolerance %e / %e / %e\n", tmpdbl3[0], tmpdbl3[1], tmpdbl3[2]));
8663c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataReorderingType", indx = hypre_ParILUDataReorderingType(ilu_data));
8673c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU local reordering %" PetscInt_FMT "\n", indx));
8683c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataLowerJacobiIters", indx = hypre_ParILUDataLowerJacobiIters(ilu_data));
8693c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU lower Jacobi iterations %" PetscInt_FMT "\n", indx));
8703c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataUpperJacobiIters", indx = hypre_ParILUDataUpperJacobiIters(ilu_data));
8713c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU upper Jacobi iterations %" PetscInt_FMT "\n", indx));
8723c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataPrintLevel", indx = hypre_ParILUDataPrintLevel(ilu_data));
8733c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU print level %" PetscInt_FMT "\n", indx));
8743c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataLogging", indx = hypre_ParILUDataLogging(ilu_data));
8753c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU logging level %" PetscInt_FMT "\n", indx));
8763c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIterativeSetupType", indx = hypre_ParILUDataIterativeSetupType(ilu_data));
8773c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup type %s (%" PetscInt_FMT ")\n", HYPREILUIterSetup[indx], indx));
8783c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIterativeSetupOption", indx = hypre_ParILUDataIterativeSetupOption(ilu_data));
8793c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup option %" PetscInt_FMT "\n", indx));
8803c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIterativeSetupMaxIter", indx = hypre_ParILUDataIterativeSetupMaxIter(ilu_data));
8813c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup max iterations %" PetscInt_FMT "\n", indx));
8823c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIterativeSetupTolerance", tmpdbl = hypre_ParILUDataIterativeSetupTolerance(ilu_data));
8833c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup tolerance %e\n", tmpdbl));
8843c61a47dSLukas }
8853c61a47dSLukas PetscFunctionReturn(PETSC_SUCCESS);
8863c61a47dSLukas }
8873c61a47dSLukas
PCSetFromOptions_HYPRE_Euclid(PC pc,PetscOptionItems PetscOptionsObject)888ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PC pc, PetscOptionItems PetscOptionsObject)
889d71ae5a4SJacob Faibussowitsch {
890db966c6cSHong Zhang PC_HYPRE *jac = (PC_HYPRE *)pc->data;
8918bf83915SBarry Smith PetscBool flag, eu_bj = jac->eu_bj ? PETSC_TRUE : PETSC_FALSE;
892db966c6cSHong Zhang
893db966c6cSHong Zhang PetscFunctionBegin;
894d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE Euclid Options");
8959566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_euclid_level", "Factorization levels", "None", jac->eu_level, &jac->eu_level, &flag));
896f2f41e48SZach Atkins if (flag) PetscCallHYPRE(HYPRE_EuclidSetLevel(jac->hsolver, (HYPRE_Int)jac->eu_level));
8978bf83915SBarry Smith
8989566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_euclid_droptolerance", "Drop tolerance for ILU(k) in Euclid", "None", jac->eu_droptolerance, &jac->eu_droptolerance, &flag));
8998bf83915SBarry Smith if (flag) {
9008bf83915SBarry Smith PetscMPIInt size;
9018bf83915SBarry Smith
9029566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pc), &size));
9037827d75bSBarry Smith PetscCheck(size == 1, PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "hypre's Euclid does not support a parallel drop tolerance");
904a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_EuclidSetILUT(jac->hsolver, jac->eu_droptolerance));
9058bf83915SBarry Smith }
9068bf83915SBarry Smith
9079566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_euclid_bj", "Use Block Jacobi for ILU in Euclid", "None", eu_bj, &eu_bj, &flag));
9088bf83915SBarry Smith if (flag) {
9098bf83915SBarry Smith jac->eu_bj = eu_bj ? 1 : 0;
910f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_EuclidSetBJ(jac->hsolver, (HYPRE_Int)jac->eu_bj));
9118bf83915SBarry Smith }
912d0609cedSBarry Smith PetscOptionsHeadEnd();
9133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
914db966c6cSHong Zhang }
915db966c6cSHong Zhang
PCView_HYPRE_Euclid(PC pc,PetscViewer viewer)916d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_Euclid(PC pc, PetscViewer viewer)
917d71ae5a4SJacob Faibussowitsch {
918db966c6cSHong Zhang PC_HYPRE *jac = (PC_HYPRE *)pc->data;
9199f196a02SMartin Diehl PetscBool isascii;
920db966c6cSHong Zhang
921db966c6cSHong Zhang PetscFunctionBegin;
9229f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
9239f196a02SMartin Diehl if (isascii) {
9249566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE Euclid preconditioning\n"));
925db966c6cSHong Zhang if (jac->eu_level != PETSC_DEFAULT) {
92663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " factorization levels %" PetscInt_FMT "\n", jac->eu_level));
927db966c6cSHong Zhang } else {
9289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default factorization levels \n"));
929db966c6cSHong Zhang }
9309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " drop tolerance %g\n", (double)jac->eu_droptolerance));
93163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " use Block-Jacobi? %" PetscInt_FMT "\n", jac->eu_bj));
932db966c6cSHong Zhang }
9333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
934db966c6cSHong Zhang }
935db966c6cSHong Zhang
PCApplyTranspose_HYPRE_BoomerAMG(PC pc,Vec b,Vec x)936d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc, Vec b, Vec x)
937d71ae5a4SJacob Faibussowitsch {
93816d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data;
939f4f49eeaSPierre Jolivet Mat_HYPRE *hjac = (Mat_HYPRE *)jac->hpmat->data;
94016d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat;
94116d9e3a6SLisandro Dalcin HYPRE_ParVector jbv, jxv;
94216d9e3a6SLisandro Dalcin
94316d9e3a6SLisandro Dalcin PetscFunctionBegin;
9449566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite));
9459566063dSJacob Faibussowitsch PetscCall(VecSet(x, 0.0));
946af221044SPierre Jolivet PetscCall(VecHYPRE_IJVectorPushVecRead(hjac->b, b));
947af221044SPierre Jolivet PetscCall(VecHYPRE_IJVectorPushVecWrite(hjac->x, x));
94816d9e3a6SLisandro Dalcin
949a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJMatrixGetObject(hjac->ij, (void **)&hmat));
950a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJVectorGetObject(hjac->b->ij, (void **)&jbv));
951a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_IJVectorGetObject(hjac->x->ij, (void **)&jxv));
95216d9e3a6SLisandro Dalcin
9539371c9d4SSatish Balay PetscStackCallExternalVoid(
9549371c9d4SSatish Balay "Hypre Transpose solve", do {
9555f80ce2aSJacob Faibussowitsch HYPRE_Int hierr = HYPRE_BoomerAMGSolveT(jac->hsolver, hmat, jbv, jxv);
9565f80ce2aSJacob Faibussowitsch if (hierr) {
95716d9e3a6SLisandro Dalcin /* error code of 1 in BoomerAMG merely means convergence not achieved */
9585f80ce2aSJacob Faibussowitsch PetscCheck(hierr == 1, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in HYPRE solver, error code %d", (int)hierr);
95985245615SPierre Jolivet HYPRE_ClearAllErrors();
9605f80ce2aSJacob Faibussowitsch }
9615f80ce2aSJacob Faibussowitsch } while (0));
96216d9e3a6SLisandro Dalcin
9639566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->x));
9649566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->b));
9653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
96616d9e3a6SLisandro Dalcin }
96716d9e3a6SLisandro Dalcin
PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc,const char * spgemm[])968d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc, const char *spgemm[])
969d71ae5a4SJacob Faibussowitsch {
970db6f9c32SMark Adams PC_HYPRE *jac = (PC_HYPRE *)pc->data;
971db6f9c32SMark Adams
972db6f9c32SMark Adams PetscFunctionBegin;
973db6f9c32SMark Adams PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
974db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0)
975db6f9c32SMark Adams *spgemm = jac->spgemm_type;
976db6f9c32SMark Adams #endif
9773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
978db6f9c32SMark Adams }
979db6f9c32SMark Adams
98016d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[] = {"", "V", "W"};
9810f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP", "Ruge-Stueben", "", "modifiedRuge-Stueben", "", "", "Falgout", "", "PMIS", "", "HMIS"};
98216d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local", "global"};
98365de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */
9843c61a47dSLukas static const char *HYPREBoomerAMGSmoothType[] = {"ILU", "Schwarz-smoothers", "Pilut", "ParaSails", "Euclid"};
9859371c9d4SSatish Balay static const char *HYPREBoomerAMGRelaxType[] = {"Jacobi", "sequential-Gauss-Seidel", "seqboundary-Gauss-Seidel", "SOR/Jacobi", "backward-SOR/Jacobi", "" /* [5] hybrid chaotic Gauss-Seidel (works only with OpenMP) */, "symmetric-SOR/Jacobi", "" /* 7 */, "l1scaled-SOR/Jacobi", "Gaussian-elimination", "" /* 10 */, "" /* 11 */, "" /* 12 */, "l1-Gauss-Seidel" /* nonsymmetric */, "backward-l1-Gauss-Seidel" /* nonsymmetric */, "CG" /* non-stationary */, "Chebyshev", "FCF-Jacobi", "l1scaled-Jacobi"};
9869371c9d4SSatish Balay static const char *HYPREBoomerAMGInterpType[] = {"classical", "", "", "direct", "multipass", "multipass-wts", "ext+i", "ext+i-cc", "standard", "standard-wts", "block", "block-wtd", "FF", "FF1", "ext", "ad-wts", "ext-mm", "ext+i-mm", "ext+e-mm"};
987d7185485SAlex Lindsay
PCSetFromOptions_HYPRE_BoomerAMG(PC pc,PetscOptionItems PetscOptionsObject)988ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PC pc, PetscOptionItems PetscOptionsObject)
989d71ae5a4SJacob Faibussowitsch {
99016d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data;
99122e51d31SStefano Zampini PetscInt bs, n, indx, level;
992ace3abfcSBarry Smith PetscBool flg, tmp_truth;
99373dcfd97SStefano Zampini PetscReal tmpdbl, twodbl[2];
994589dcaf0SStefano Zampini const char *symtlist[] = {"nonsymmetric", "SPD", "nonsymmetric,SPD"};
99516d9e3a6SLisandro Dalcin
99616d9e3a6SLisandro Dalcin PetscFunctionBegin;
997d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE BoomerAMG Options");
9989566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_cycle_type", "Cycle type", "None", HYPREBoomerAMGCycleType + 1, 2, HYPREBoomerAMGCycleType[jac->cycletype], &indx, &flg));
99916d9e3a6SLisandro Dalcin if (flg) {
10004336a9eeSBarry Smith jac->cycletype = indx + 1;
1001f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetCycleType(jac->hsolver, (HYPRE_Int)jac->cycletype));
100216d9e3a6SLisandro Dalcin }
100352ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedInt("-pc_hypre_boomeramg_max_levels", "Number of levels (of grids) allowed", "None", jac->maxlevels, &jac->maxlevels, &flg, 2));
1004f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetMaxLevels(jac->hsolver, (HYPRE_Int)jac->maxlevels));
100552ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedInt("-pc_hypre_boomeramg_max_iter", "Maximum iterations used PER hypre call", "None", jac->maxiter, &jac->maxiter, &flg, 1));
1006f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetMaxIter(jac->hsolver, (HYPRE_Int)jac->maxiter));
100752ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedReal("-pc_hypre_boomeramg_tol", "Convergence tolerance PER hypre call (0.0 = use a fixed number of iterations)", "None", jac->tol, &jac->tol, &flg, 0.0));
1008a333fa2bSZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetTol(jac->hsolver, jac->tol));
100922e51d31SStefano Zampini bs = 1;
101048a46eb9SPierre Jolivet if (pc->pmat) PetscCall(MatGetBlockSize(pc->pmat, &bs));
10119566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_numfunctions", "Number of functions", "HYPRE_BoomerAMGSetNumFunctions", bs, &bs, &flg));
1012f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetNumFunctions(jac->hsolver, (HYPRE_Int)bs));
101316d9e3a6SLisandro Dalcin
101452ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedReal("-pc_hypre_boomeramg_truncfactor", "Truncation factor for interpolation (0=no truncation)", "None", jac->truncfactor, &jac->truncfactor, &flg, 0.0));
1015a333fa2bSZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetTruncFactor(jac->hsolver, jac->truncfactor));
101616d9e3a6SLisandro Dalcin
101752ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedInt("-pc_hypre_boomeramg_P_max", "Max elements per row for interpolation operator (0=unlimited)", "None", jac->pmax, &jac->pmax, &flg, 0));
1018f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetPMaxElmts(jac->hsolver, (HYPRE_Int)jac->pmax));
10190f1074feSSatish Balay
10209566063dSJacob Faibussowitsch PetscCall(PetscOptionsRangeInt("-pc_hypre_boomeramg_agg_nl", "Number of levels of aggressive coarsening", "None", jac->agg_nl, &jac->agg_nl, &flg, 0, jac->maxlevels));
1021f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetAggNumLevels(jac->hsolver, (HYPRE_Int)jac->agg_nl));
10220f1074feSSatish Balay
102352ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedInt("-pc_hypre_boomeramg_agg_num_paths", "Number of paths for aggressive coarsening", "None", jac->agg_num_paths, &jac->agg_num_paths, &flg, 1));
1024f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetNumPaths(jac->hsolver, (HYPRE_Int)jac->agg_num_paths));
10250f1074feSSatish Balay
102652ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedReal("-pc_hypre_boomeramg_strong_threshold", "Threshold for being strongly connected", "None", jac->strongthreshold, &jac->strongthreshold, &flg, 0.0));
1027a333fa2bSZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetStrongThreshold(jac->hsolver, jac->strongthreshold));
102852ce0ab5SPierre Jolivet PetscCall(PetscOptionsRangeReal("-pc_hypre_boomeramg_max_row_sum", "Maximum row sum", "None", jac->maxrowsum, &jac->maxrowsum, &flg, 0.0, 1.0));
1029a333fa2bSZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetMaxRowSum(jac->hsolver, jac->maxrowsum));
103016d9e3a6SLisandro Dalcin
103116d9e3a6SLisandro Dalcin /* Grid sweeps */
10329566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_all", "Number of sweeps for the up and down grid levels", "None", jac->gridsweeps[0], &indx, &flg));
103316d9e3a6SLisandro Dalcin if (flg) {
103416d9e3a6SLisandro Dalcin /* modify the jac structure so we can view the updated options with PC_View */
103516d9e3a6SLisandro Dalcin jac->gridsweeps[0] = indx;
10360f1074feSSatish Balay jac->gridsweeps[1] = indx;
10370f1074feSSatish Balay /*defaults coarse to 1 */
10380f1074feSSatish Balay jac->gridsweeps[2] = 1;
103916d9e3a6SLisandro Dalcin }
10409566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_nodal_coarsen", "Use a nodal based coarsening 1-6", "HYPRE_BoomerAMGSetNodal", jac->nodal_coarsening, &jac->nodal_coarsening, &flg));
1041f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetNodal(jac->hsolver, (HYPRE_Int)jac->nodal_coarsening));
10429566063dSJacob Faibussowitsch PetscCall(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));
1043f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetNodalDiag(jac->hsolver, (HYPRE_Int)jac->nodal_coarsening_diag));
10449566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_vec_interp_variant", "Variant of algorithm 1-3", "HYPRE_BoomerAMGSetInterpVecVariant", jac->vec_interp_variant, &jac->vec_interp_variant, &flg));
1045f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetInterpVecVariant(jac->hsolver, (HYPRE_Int)jac->vec_interp_variant));
10469566063dSJacob Faibussowitsch PetscCall(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));
1047f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetInterpVecQMax(jac->hsolver, (HYPRE_Int)jac->vec_interp_qmax));
10489566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_vec_interp_smooth", "Whether to smooth the interpolation vectors", "HYPRE_BoomerAMGSetSmoothInterpVectors", jac->vec_interp_smooth, &jac->vec_interp_smooth, &flg));
1049a333fa2bSZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetSmoothInterpVectors(jac->hsolver, jac->vec_interp_smooth));
10509566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_interp_refine", "Preprocess the interpolation matrix through iterative weight refinement", "HYPRE_BoomerAMGSetInterpRefine", jac->interp_refine, &jac->interp_refine, &flg));
1051f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetInterpRefine(jac->hsolver, (HYPRE_Int)jac->interp_refine));
10529566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down", "Number of sweeps for the down cycles", "None", jac->gridsweeps[0], &indx, &flg));
105316d9e3a6SLisandro Dalcin if (flg) {
1054f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetCycleNumSweeps(jac->hsolver, (HYPRE_Int)indx, 1));
10550f1074feSSatish Balay jac->gridsweeps[0] = indx;
105616d9e3a6SLisandro Dalcin }
10579566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up", "Number of sweeps for the up cycles", "None", jac->gridsweeps[1], &indx, &flg));
105816d9e3a6SLisandro Dalcin if (flg) {
1059f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetCycleNumSweeps(jac->hsolver, (HYPRE_Int)indx, 2));
10600f1074feSSatish Balay jac->gridsweeps[1] = indx;
106116d9e3a6SLisandro Dalcin }
10629566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse", "Number of sweeps for the coarse level", "None", jac->gridsweeps[2], &indx, &flg));
106316d9e3a6SLisandro Dalcin if (flg) {
1064f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetCycleNumSweeps(jac->hsolver, (HYPRE_Int)indx, 3));
10650f1074feSSatish Balay jac->gridsweeps[2] = indx;
106616d9e3a6SLisandro Dalcin }
106716d9e3a6SLisandro Dalcin
10686a251517SEike Mueller /* Smooth type */
1069dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_smooth_type", "Enable more complex smoothers", "None", HYPREBoomerAMGSmoothType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGSmoothType), HYPREBoomerAMGSmoothType[0], &indx, &flg));
10706a251517SEike Mueller if (flg) {
10716a251517SEike Mueller jac->smoothtype = indx;
1072f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetSmoothType(jac->hsolver, (HYPRE_Int)indx + 5));
10738131ecf7SEike Mueller jac->smoothnumlevels = 25;
1074a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetSmoothNumLevels(jac->hsolver, 25));
10758131ecf7SEike Mueller }
10768131ecf7SEike Mueller
10778131ecf7SEike Mueller /* Number of smoothing levels */
10789566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_smooth_num_levels", "Number of levels on which more complex smoothers are used", "None", 25, &indx, &flg));
10798131ecf7SEike Mueller if (flg && (jac->smoothtype != -1)) {
10808131ecf7SEike Mueller jac->smoothnumlevels = indx;
1081f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetSmoothNumLevels(jac->hsolver, (HYPRE_Int)indx));
10826a251517SEike Mueller }
10836a251517SEike Mueller
10843c61a47dSLukas /* Smooth num sweeps */
10853c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_smooth_num_sweeps", "Set number of smoother sweeps", "None", 1, &indx, &flg));
10863c61a47dSLukas if (flg && indx > 0) {
10873c61a47dSLukas jac->smoothsweeps = indx;
1088f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetSmoothNumSweeps(jac->hsolver, (HYPRE_Int)indx));
10893c61a47dSLukas }
10903c61a47dSLukas
10913c61a47dSLukas /* ILU: ILU Type */
10923c61a47dSLukas PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_ilu_type", "Choose ILU Type", "None", HYPREILUType, PETSC_STATIC_ARRAY_LENGTH(HYPREILUType), HYPREILUType[0], &indx, &flg));
1093f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetILUType(jac->hsolver, (HYPRE_Int)indx));
10943c61a47dSLukas
10953c61a47dSLukas /* ILU: ILU iterative setup type*/
10963c61a47dSLukas PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_ilu_iterative_setup_type", "Set ILU iterative setup type", "None", HYPREILUIterSetup, PETSC_STATIC_ARRAY_LENGTH(HYPREILUIterSetup), HYPREILUIterSetup[0], &indx, &flg));
1097f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetILUIterSetupType(jac->hsolver, (HYPRE_Int)indx));
10983c61a47dSLukas
10993c61a47dSLukas /* ILU: ILU iterative setup option*/
11003c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_iterative_setup_option", "Set ILU iterative setup option", "None", 0, &indx, &flg));
1101f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetILUIterSetupOption(jac->hsolver, (HYPRE_Int)indx));
11023c61a47dSLukas
11033c61a47dSLukas /* ILU: ILU iterative setup maxiter */
11043c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_iterative_setup_maxiter", "Set ILU iterative setup maximum iteration count", "None", 0, &indx, &flg));
1105f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetILUIterSetupMaxIter(jac->hsolver, (HYPRE_Int)indx));
11063c61a47dSLukas
11073c61a47dSLukas /* ILU: ILU iterative setup tolerance */
11083c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_ilu_iterative_setup_tolerance", "Set ILU iterative setup tolerance", "None", 0, &tmpdbl, &flg));
1109a333fa2bSZach Atkins if (flg) PetscCallHYPRE(hypre_BoomerAMGSetILUIterSetupTolerance(jac->hsolver, tmpdbl));
11103c61a47dSLukas
11113c61a47dSLukas /* ILU: ILU Print Level */
11123c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_print_level", "Set ILU print level", "None", 0, &indx, &flg));
1113f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetPrintLevel(jac->hsolver, (HYPRE_Int)indx));
11143c61a47dSLukas
11153c61a47dSLukas /* ILU: Logging */
11163c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_logging", "Set ILU logging level", "None", 0, &indx, &flg));
1117f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetLogging(jac->hsolver, (HYPRE_Int)indx));
11183c61a47dSLukas
11193c61a47dSLukas /* ILU: ILU Level */
11203c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_level", "Set ILU level", "None", 0, &indx, &flg));
1121f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetILULevel(jac->hsolver, (HYPRE_Int)indx));
11223c61a47dSLukas
11233c61a47dSLukas /* ILU: ILU Max NNZ per row */
11243c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_max_nnz_per_row", "Set maximum NNZ per row", "None", 0, &indx, &flg));
1125f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetILUMaxRowNnz(jac->hsolver, (HYPRE_Int)indx));
11263c61a47dSLukas
11273c61a47dSLukas /* ILU: maximum iteration count */
11283c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_maxiter", "Set ILU max iterations", "None", 0, &indx, &flg));
1129f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetILUMaxIter(jac->hsolver, (HYPRE_Int)indx));
11303c61a47dSLukas
11313c61a47dSLukas /* ILU: drop threshold */
11323c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_ilu_drop_tol", "Drop tolerance for ILU", "None", 0, &tmpdbl, &flg));
1133a333fa2bSZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetILUDroptol(jac->hsolver, tmpdbl));
11343c61a47dSLukas
11353c61a47dSLukas /* ILU: Triangular Solve */
11363c61a47dSLukas PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_ilu_tri_solve", "Enable triangular solve", "None", PETSC_FALSE, &tmp_truth, &flg));
1137a333fa2bSZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetILUTriSolve(jac->hsolver, tmp_truth));
11383c61a47dSLukas
11393c61a47dSLukas /* ILU: Lower Jacobi iteration */
11403c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_lower_jacobi_iters", "Set lower Jacobi iteration count", "None", 0, &indx, &flg));
1141f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetILULowerJacobiIters(jac->hsolver, (HYPRE_Int)indx));
11423c61a47dSLukas
11433c61a47dSLukas /* ILU: Upper Jacobi iteration */
11443c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_upper_jacobi_iters", "Set upper Jacobi iteration count", "None", 0, &indx, &flg));
1145f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetILUUpperJacobiIters(jac->hsolver, (HYPRE_Int)indx));
11463c61a47dSLukas
11473c61a47dSLukas /* ILU: local reordering */
11483c61a47dSLukas PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_ilu_local_reordering", "Enable local reordering", "None", PETSC_FALSE, &tmp_truth, &flg));
1149a333fa2bSZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetILULocalReordering(jac->hsolver, tmp_truth));
11503c61a47dSLukas
11511810e44eSEike Mueller /* Number of levels for ILU(k) for Euclid */
11529566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_eu_level", "Number of levels for ILU(k) in Euclid smoother", "None", 0, &indx, &flg));
11533c61a47dSLukas if (flg && (jac->smoothtype == 4)) {
11541810e44eSEike Mueller jac->eu_level = indx;
1155f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetEuLevel(jac->hsolver, (HYPRE_Int)indx));
11561810e44eSEike Mueller }
11571810e44eSEike Mueller
11581810e44eSEike Mueller /* Filter for ILU(k) for Euclid */
115973dcfd97SStefano Zampini PetscReal droptolerance;
11609566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_eu_droptolerance", "Drop tolerance for ILU(k) in Euclid smoother", "None", 0, &droptolerance, &flg));
11613c61a47dSLukas if (flg && (jac->smoothtype == 4)) {
11621810e44eSEike Mueller jac->eu_droptolerance = droptolerance;
1163a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetEuLevel(jac->hsolver, droptolerance));
11641810e44eSEike Mueller }
11651810e44eSEike Mueller
11661810e44eSEike Mueller /* Use Block Jacobi ILUT for Euclid */
11679566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg));
11683c61a47dSLukas if (flg && (jac->smoothtype == 4)) {
11691810e44eSEike Mueller jac->eu_bj = tmp_truth;
1170f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetEuBJ(jac->hsolver, (HYPRE_Int)jac->eu_bj));
11711810e44eSEike Mueller }
11721810e44eSEike Mueller
117316d9e3a6SLisandro Dalcin /* Relax type */
1174abf5c9d9SBarry Smith PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_relax_type_all", "Relax type for the up and down cycles", "None", HYPREBoomerAMGRelaxType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGRelaxType),
1175abf5c9d9SBarry Smith jac->relaxtype[0] < 0 ? "not yet set" : HYPREBoomerAMGRelaxType[jac->relaxtype[0]], &indx, &flg));
1176abf5c9d9SBarry Smith if (flg) jac->relaxtype[0] = jac->relaxtype[1] = indx;
1177abf5c9d9SBarry Smith PetscCall(
1178abf5c9d9SBarry Smith PetscOptionsEList("-pc_hypre_boomeramg_relax_type_down", "Relax type for the down cycles", "None", HYPREBoomerAMGRelaxType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGRelaxType), jac->relaxtype[0] < 0 ? "not yet set" : HYPREBoomerAMGRelaxType[jac->relaxtype[0]], &indx, &flg));
1179abf5c9d9SBarry Smith if (flg) jac->relaxtype[0] = indx;
1180abf5c9d9SBarry Smith PetscCall(
1181abf5c9d9SBarry Smith PetscOptionsEList("-pc_hypre_boomeramg_relax_type_up", "Relax type for the up cycles", "None", HYPREBoomerAMGRelaxType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGRelaxType), jac->relaxtype[1] < 0 ? "not yet set" : HYPREBoomerAMGRelaxType[jac->relaxtype[1]], &indx, &flg));
1182abf5c9d9SBarry Smith if (flg) jac->relaxtype[1] = indx;
1183abf5c9d9SBarry Smith PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse", "Relax type on coarse grid", "None", HYPREBoomerAMGRelaxType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGRelaxType), HYPREBoomerAMGRelaxType[jac->relaxtype[2]], &indx, &flg));
1184abf5c9d9SBarry Smith if (flg) jac->relaxtype[2] = indx;
118516d9e3a6SLisandro Dalcin
118616d9e3a6SLisandro Dalcin /* Relaxation Weight */
11879566063dSJacob Faibussowitsch PetscCall(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));
118816d9e3a6SLisandro Dalcin if (flg) {
1189a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetRelaxWt(jac->hsolver, tmpdbl));
119016d9e3a6SLisandro Dalcin jac->relaxweight = tmpdbl;
119116d9e3a6SLisandro Dalcin }
119216d9e3a6SLisandro Dalcin
119316d9e3a6SLisandro Dalcin n = 2;
119416d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0;
11959566063dSJacob Faibussowitsch PetscCall(PetscOptionsRealArray("-pc_hypre_boomeramg_relax_weight_level", "Set the relaxation weight for a particular level (weight,level)", "None", twodbl, &n, &flg));
119616d9e3a6SLisandro Dalcin if (flg) {
11970fdf79fbSJacob Faibussowitsch PetscCheck(n == 2, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Relax weight level: you must provide 2 values separated by a comma (and no space), you provided %" PetscInt_FMT, n);
119816d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]);
1199f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetLevelRelaxWt(jac->hsolver, twodbl[0], (HYPRE_Int)indx));
120016d9e3a6SLisandro Dalcin }
120116d9e3a6SLisandro Dalcin
120216d9e3a6SLisandro Dalcin /* Outer relaxation Weight */
12039566063dSJacob Faibussowitsch PetscCall(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));
120416d9e3a6SLisandro Dalcin if (flg) {
1205a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetOuterWt(jac->hsolver, tmpdbl));
120616d9e3a6SLisandro Dalcin jac->outerrelaxweight = tmpdbl;
120716d9e3a6SLisandro Dalcin }
120816d9e3a6SLisandro Dalcin
120916d9e3a6SLisandro Dalcin n = 2;
121016d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0;
12119566063dSJacob Faibussowitsch PetscCall(PetscOptionsRealArray("-pc_hypre_boomeramg_outer_relax_weight_level", "Set the outer relaxation weight for a particular level (weight,level)", "None", twodbl, &n, &flg));
121216d9e3a6SLisandro Dalcin if (flg) {
12130fdf79fbSJacob Faibussowitsch PetscCheck(n == 2, 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 %" PetscInt_FMT, n);
121416d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]);
1215f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetLevelOuterWt(jac->hsolver, twodbl[0], (HYPRE_Int)indx));
121616d9e3a6SLisandro Dalcin }
121716d9e3a6SLisandro Dalcin
121816d9e3a6SLisandro Dalcin /* the Relax Order */
12199566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg));
1220ec342aa2SAlex Lindsay if (flg) jac->relaxorder = !tmp_truth;
1221dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_measure_type", "Measure type", "None", HYPREBoomerAMGMeasureType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGMeasureType), HYPREBoomerAMGMeasureType[0], &indx, &flg));
122216d9e3a6SLisandro Dalcin if (flg) {
122316d9e3a6SLisandro Dalcin jac->measuretype = indx;
1224f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetMeasureType(jac->hsolver, (HYPRE_Int)jac->measuretype));
122516d9e3a6SLisandro Dalcin }
1226abf5c9d9SBarry Smith PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type", "Coarsen type", "None", HYPREBoomerAMGCoarsenType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGCoarsenType), jac->coarsentype < 0 ? "unknown" : HYPREBoomerAMGCoarsenType[jac->coarsentype], &indx, &flg));
1227abf5c9d9SBarry Smith if (flg) jac->coarsentype = indx;
12280f1074feSSatish Balay
12299566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_max_coarse_size", "Maximum size of coarsest grid", "None", jac->maxc, &jac->maxc, &flg));
1230f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetMaxCoarseSize(jac->hsolver, (HYPRE_Int)jac->maxc));
12319566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_min_coarse_size", "Minimum size of coarsest grid", "None", jac->minc, &jac->minc, &flg));
1232f2f41e48SZach Atkins if (flg) PetscCallHYPRE(HYPRE_BoomerAMGSetMinCoarseSize(jac->hsolver, (HYPRE_Int)jac->minc));
1233db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0)
1234db6f9c32SMark Adams // global parameter but is closely associated with BoomerAMG
1235abf5c9d9SBarry Smith PetscCall(PetscOptionsEList("-pc_mg_galerkin_mat_product_algorithm", "Type of SpGEMM to use in hypre (only for now)", "PCMGGalerkinSetMatProductAlgorithm", HYPRESpgemmTypes, PETSC_STATIC_ARRAY_LENGTH(HYPRESpgemmTypes), jac->spgemm_type, &indx, &flg));
1236d7185485SAlex Lindsay if (flg) PetscCall(PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(pc, HYPRESpgemmTypes[indx]));
1237db6f9c32SMark Adams #endif
1238589dcaf0SStefano Zampini /* AIR */
1239589dcaf0SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0)
12409566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_restriction_type", "Type of AIR method (distance 1 or 2, 0 means no AIR)", "None", jac->Rtype, &jac->Rtype, NULL));
1241f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetRestriction(jac->hsolver, (HYPRE_Int)jac->Rtype));
1242589dcaf0SStefano Zampini if (jac->Rtype) {
124319be502cSAlexander HYPRE_Int **grid_relax_points = hypre_TAlloc(HYPRE_Int *, 4, HYPRE_MEMORY_HOST);
124419be502cSAlexander char *prerelax[256];
124519be502cSAlexander char *postrelax[256];
124619be502cSAlexander char stringF[2] = "F", stringC[2] = "C", stringA[2] = "A";
124719be502cSAlexander PetscInt ns_down = 256, ns_up = 256;
124819be502cSAlexander PetscBool matchF, matchC, matchA;
124919be502cSAlexander
1250589dcaf0SStefano Zampini jac->interptype = 100; /* no way we can pass this with strings... Set it as default as in MFEM, then users can still customize it back to a different one */
1251589dcaf0SStefano Zampini
12529566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_strongthresholdR", "Threshold for R", "None", jac->Rstrongthreshold, &jac->Rstrongthreshold, NULL));
1253a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetStrongThresholdR(jac->hsolver, jac->Rstrongthreshold));
1254589dcaf0SStefano Zampini
12559566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_filterthresholdR", "Filter threshold for R", "None", jac->Rfilterthreshold, &jac->Rfilterthreshold, NULL));
1256a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetFilterThresholdR(jac->hsolver, jac->Rfilterthreshold));
1257589dcaf0SStefano Zampini
12589566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_Adroptol", "Defines the drop tolerance for the A-matrices from the 2nd level of AMG", "None", jac->Adroptol, &jac->Adroptol, NULL));
1259f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetADropTol(jac->hsolver, (HYPRE_Int)jac->Adroptol));
1260589dcaf0SStefano Zampini
12619566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_Adroptype", "Drops the entries that are not on the diagonal and smaller than its row norm: type 1: 1-norm, 2: 2-norm, -1: infinity norm", "None", jac->Adroptype, &jac->Adroptype, NULL));
1262f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetADropType(jac->hsolver, (HYPRE_Int)jac->Adroptype));
126319be502cSAlexander PetscCall(PetscOptionsStringArray("-pc_hypre_boomeramg_prerelax", "Defines prerelax scheme", "None", prerelax, &ns_down, NULL));
126419be502cSAlexander PetscCall(PetscOptionsStringArray("-pc_hypre_boomeramg_postrelax", "Defines postrelax scheme", "None", postrelax, &ns_up, NULL));
126519be502cSAlexander PetscCheck(ns_down == jac->gridsweeps[0], PetscObjectComm((PetscObject)jac), PETSC_ERR_ARG_SIZ, "The number of arguments passed to -pc_hypre_boomeramg_prerelax must match the number passed to -pc_hypre_bomeramg_grid_sweeps_down");
126619be502cSAlexander PetscCheck(ns_up == jac->gridsweeps[1], PetscObjectComm((PetscObject)jac), PETSC_ERR_ARG_SIZ, "The number of arguments passed to -pc_hypre_boomeramg_postrelax must match the number passed to -pc_hypre_bomeramg_grid_sweeps_up");
126719be502cSAlexander
126819be502cSAlexander grid_relax_points[0] = NULL;
126919be502cSAlexander grid_relax_points[1] = hypre_TAlloc(HYPRE_Int, ns_down, HYPRE_MEMORY_HOST);
127019be502cSAlexander grid_relax_points[2] = hypre_TAlloc(HYPRE_Int, ns_up, HYPRE_MEMORY_HOST);
127119be502cSAlexander grid_relax_points[3] = hypre_TAlloc(HYPRE_Int, jac->gridsweeps[2], HYPRE_MEMORY_HOST);
127219be502cSAlexander grid_relax_points[3][0] = 0;
127319be502cSAlexander
127419be502cSAlexander // set down relax scheme
127519be502cSAlexander for (PetscInt i = 0; i < ns_down; i++) {
127619be502cSAlexander PetscCall(PetscStrcasecmp(prerelax[i], stringF, &matchF));
127719be502cSAlexander PetscCall(PetscStrcasecmp(prerelax[i], stringC, &matchC));
127819be502cSAlexander PetscCall(PetscStrcasecmp(prerelax[i], stringA, &matchA));
127919be502cSAlexander PetscCheck(matchF || matchC || matchA, PetscObjectComm((PetscObject)jac), PETSC_ERR_ARG_WRONG, "Valid argument options for -pc_hypre_boomeramg_prerelax are C, F, and A");
128019be502cSAlexander if (matchF) grid_relax_points[1][i] = -1;
128119be502cSAlexander else if (matchC) grid_relax_points[1][i] = 1;
128219be502cSAlexander else if (matchA) grid_relax_points[1][i] = 0;
128319be502cSAlexander }
128419be502cSAlexander
128519be502cSAlexander // set up relax scheme
128619be502cSAlexander for (PetscInt i = 0; i < ns_up; i++) {
128719be502cSAlexander PetscCall(PetscStrcasecmp(postrelax[i], stringF, &matchF));
128819be502cSAlexander PetscCall(PetscStrcasecmp(postrelax[i], stringC, &matchC));
128919be502cSAlexander PetscCall(PetscStrcasecmp(postrelax[i], stringA, &matchA));
129019be502cSAlexander PetscCheck(matchF || matchC || matchA, PetscObjectComm((PetscObject)jac), PETSC_ERR_ARG_WRONG, "Valid argument options for -pc_hypre_boomeramg_postrelax are C, F, and A");
129119be502cSAlexander if (matchF) grid_relax_points[2][i] = -1;
129219be502cSAlexander else if (matchC) grid_relax_points[2][i] = 1;
129319be502cSAlexander else if (matchA) grid_relax_points[2][i] = 0;
129419be502cSAlexander }
129519be502cSAlexander
129619be502cSAlexander // set coarse relax scheme
129719be502cSAlexander for (PetscInt i = 0; i < jac->gridsweeps[2]; i++) grid_relax_points[3][i] = 0;
129819be502cSAlexander
129919be502cSAlexander // Pass relax schemes to hypre
1300a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetGridRelaxPoints(jac->hsolver, grid_relax_points));
130119be502cSAlexander
130219be502cSAlexander // cleanup memory
130319be502cSAlexander for (PetscInt i = 0; i < ns_down; i++) PetscCall(PetscFree(prerelax[i]));
130419be502cSAlexander for (PetscInt i = 0; i < ns_up; i++) PetscCall(PetscFree(postrelax[i]));
1305589dcaf0SStefano Zampini }
1306589dcaf0SStefano Zampini #endif
1307589dcaf0SStefano Zampini
1308ecae95adSPierre Jolivet #if PETSC_PKG_HYPRE_VERSION_LE(9, 9, 9)
130963a3b9bcSJacob Faibussowitsch PetscCheck(!jac->Rtype || !jac->agg_nl, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "-pc_hypre_boomeramg_restriction_type (%" PetscInt_FMT ") and -pc_hypre_boomeramg_agg_nl (%" PetscInt_FMT ")", jac->Rtype, jac->agg_nl);
1310ecae95adSPierre Jolivet #endif
1311ecae95adSPierre Jolivet
1312abf5c9d9SBarry Smith PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_interp_type", "Interpolation type", "None", HYPREBoomerAMGInterpType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGInterpType), jac->interptype < 0 ? "unknown" : HYPREBoomerAMGInterpType[jac->interptype], &indx, &flg));
1313589dcaf0SStefano Zampini if (flg) jac->interptype = indx;
13140f1074feSSatish Balay
13159566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-pc_hypre_boomeramg_print_statistics", "Print statistics", "None", &flg));
131616d9e3a6SLisandro Dalcin if (flg) {
1317b96a4a96SBarry Smith level = 3;
13189566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_print_statistics", "Print statistics", "None", level, &level, NULL));
13192fa5cd67SKarl Rupp
1320b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE;
1321f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetPrintLevel(jac->hsolver, (HYPRE_Int)level));
13222ae77aedSBarry Smith }
13232ae77aedSBarry Smith
13249566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-pc_hypre_boomeramg_print_debug", "Print debug information", "None", &flg));
13252ae77aedSBarry Smith if (flg) {
1326b96a4a96SBarry Smith level = 3;
13279566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_print_debug", "Print debug information", "None", level, &level, NULL));
13282fa5cd67SKarl Rupp
1329b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE;
1330f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetDebugFlag(jac->hsolver, (HYPRE_Int)level));
133116d9e3a6SLisandro Dalcin }
13328f87f92bSBarry Smith
13339566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg));
13348f87f92bSBarry Smith if (flg && tmp_truth) {
13358f87f92bSBarry Smith PetscInt tmp_int;
1336f2f41e48SZach Atkins PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", (HYPRE_Int)jac->nodal_relax_levels, &tmp_int, &flg));
13378f87f92bSBarry Smith if (flg) jac->nodal_relax_levels = tmp_int;
1338a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetSmoothType(jac->hsolver, 6));
1339a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetDomainType(jac->hsolver, 1));
1340a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetOverlap(jac->hsolver, 0));
1341f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetSmoothNumLevels(jac->hsolver, (HYPRE_Int)jac->nodal_relax_levels));
13428f87f92bSBarry Smith }
13438f87f92bSBarry Smith
1344abf5c9d9SBarry Smith PetscCall(PetscOptionsBool3("-pc_hypre_boomeramg_keeptranspose", "Avoid transpose matvecs in preconditioner application", "None", jac->keeptranspose, &jac->keeptranspose, NULL));
1345589dcaf0SStefano Zampini
1346589dcaf0SStefano Zampini /* options for ParaSails solvers */
1347dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_parasails_sym", "Symmetry of matrix and preconditioner", "None", symtlist, PETSC_STATIC_ARRAY_LENGTH(symtlist), symtlist[0], &indx, &flg));
1348589dcaf0SStefano Zampini if (flg) {
1349589dcaf0SStefano Zampini jac->symt = indx;
1350f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetSym(jac->hsolver, (HYPRE_Int)jac->symt));
1351589dcaf0SStefano Zampini }
1352589dcaf0SStefano Zampini
1353d0609cedSBarry Smith PetscOptionsHeadEnd();
13543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
135516d9e3a6SLisandro Dalcin }
135616d9e3a6SLisandro Dalcin
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)1357d71ae5a4SJacob Faibussowitsch 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)
1358d71ae5a4SJacob Faibussowitsch {
135916d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data;
13602cf14000SStefano Zampini HYPRE_Int oits;
136116d9e3a6SLisandro Dalcin
136216d9e3a6SLisandro Dalcin PetscFunctionBegin;
13639566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite));
1364f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetMaxIter(jac->hsolver, (HYPRE_Int)(its * jac->maxiter)));
1365a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetTol(jac->hsolver, rtol));
136616d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_TRUE;
13679566063dSJacob Faibussowitsch PetscCall(PCApply_HYPRE(pc, b, y));
136816d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE;
1369a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGGetNumIterations(jac->hsolver, &oits));
13704d0a8057SBarry Smith *outits = oits;
13714d0a8057SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
13724d0a8057SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL;
1373a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetTol(jac->hsolver, jac->tol));
1374f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGSetMaxIter(jac->hsolver, (HYPRE_Int)jac->maxiter));
13753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
137616d9e3a6SLisandro Dalcin }
137716d9e3a6SLisandro Dalcin
PCView_HYPRE_BoomerAMG(PC pc,PetscViewer viewer)1378d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc, PetscViewer viewer)
1379d71ae5a4SJacob Faibussowitsch {
138016d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data;
13813c61a47dSLukas hypre_ParAMGData *amg_data = (hypre_ParAMGData *)jac->hsolver;
13829f196a02SMartin Diehl PetscBool isascii;
13833c61a47dSLukas PetscInt indx;
13843c61a47dSLukas PetscReal val;
138516d9e3a6SLisandro Dalcin
138616d9e3a6SLisandro Dalcin PetscFunctionBegin;
13879f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
13889f196a02SMartin Diehl if (isascii) {
13899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE BoomerAMG preconditioning\n"));
13909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Cycle type %s\n", HYPREBoomerAMGCycleType[jac->cycletype]));
139163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum number of levels %" PetscInt_FMT "\n", jac->maxlevels));
139263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum number of iterations PER hypre call %" PetscInt_FMT "\n", jac->maxiter));
13939566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Convergence tolerance PER hypre call %g\n", (double)jac->tol));
13949566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Threshold for strong coupling %g\n", (double)jac->strongthreshold));
13959566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation truncation factor %g\n", (double)jac->truncfactor));
139663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation: max elements per row %" PetscInt_FMT "\n", jac->pmax));
139748a46eb9SPierre Jolivet if (jac->interp_refine) PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation: number of steps of weighted refinement %" PetscInt_FMT "\n", jac->interp_refine));
139863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Number of levels of aggressive coarsening %" PetscInt_FMT "\n", jac->agg_nl));
139963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Number of paths for aggressive coarsening %" PetscInt_FMT "\n", jac->agg_num_paths));
14000f1074feSSatish Balay
14019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum row sums %g\n", (double)jac->maxrowsum));
140216d9e3a6SLisandro Dalcin
140363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Sweeps down %" PetscInt_FMT "\n", jac->gridsweeps[0]));
140463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Sweeps up %" PetscInt_FMT "\n", jac->gridsweeps[1]));
140563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Sweeps on coarse %" PetscInt_FMT "\n", jac->gridsweeps[2]));
140616d9e3a6SLisandro Dalcin
1407abf5c9d9SBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, " Relax down %s\n", jac->relaxtype[0] < 0 ? "not yet set" : HYPREBoomerAMGRelaxType[jac->relaxtype[0]]));
1408abf5c9d9SBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, " Relax up %s\n", jac->relaxtype[1] < 0 ? "not yet set" : HYPREBoomerAMGRelaxType[jac->relaxtype[1]]));
14099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax on coarse %s\n", HYPREBoomerAMGRelaxType[jac->relaxtype[2]]));
141016d9e3a6SLisandro Dalcin
14119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax weight (all) %g\n", (double)jac->relaxweight));
14129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Outer relax weight (all) %g\n", (double)jac->outerrelaxweight));
141316d9e3a6SLisandro Dalcin
141419be502cSAlexander PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum size of coarsest grid %" PetscInt_FMT "\n", jac->maxc));
141519be502cSAlexander PetscCall(PetscViewerASCIIPrintf(viewer, " Minimum size of coarsest grid %" PetscInt_FMT "\n", jac->minc));
141619be502cSAlexander
1417abf5c9d9SBarry Smith if (jac->relaxorder == PETSC_DECIDE) {
1418abf5c9d9SBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, " CF-relaxation option not yet determined\n"));
1419abf5c9d9SBarry Smith } else if (jac->relaxorder) {
14209566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Using CF-relaxation\n"));
142116d9e3a6SLisandro Dalcin } else {
14229566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Not using CF-relaxation\n"));
142316d9e3a6SLisandro Dalcin }
14246a251517SEike Mueller if (jac->smoothtype != -1) {
14259566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Smooth type %s\n", HYPREBoomerAMGSmoothType[jac->smoothtype]));
142663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Smooth num levels %" PetscInt_FMT "\n", jac->smoothnumlevels));
14273c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " Smooth num sweeps %" PetscInt_FMT "\n", jac->smoothsweeps));
14283c61a47dSLukas if (jac->smoothtype == 0) {
14293c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUType", indx = hypre_ParAMGDataILUType(amg_data));
14303c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU type %s (%" PetscInt_FMT ")\n", HYPREILUType[indx], indx));
14313c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILULevel", indx = hypre_ParAMGDataILULevel(amg_data));
14323c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU level %" PetscInt_FMT "\n", indx));
14333c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUMaxIter", indx = hypre_ParAMGDataILUMaxIter(amg_data));
14343c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU max iterations %" PetscInt_FMT "\n", indx));
14353c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUMaxRowNnz", indx = hypre_ParAMGDataILUMaxRowNnz(amg_data));
14363c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU max NNZ per row %" PetscInt_FMT "\n", indx));
14373c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUTriSolve", indx = hypre_ParAMGDataILUTriSolve(amg_data));
14383c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU triangular solve %" PetscInt_FMT "\n", indx));
14393c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataTol", val = hypre_ParAMGDataTol(amg_data));
14403c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU tolerance %e\n", val));
14413c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUDroptol", val = hypre_ParAMGDataILUDroptol(amg_data));
14423c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU drop tolerance %e\n", val));
14433c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILULocalReordering", indx = hypre_ParAMGDataILULocalReordering(amg_data));
14443c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU local reordering %" PetscInt_FMT "\n", indx));
14453c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILULowerJacobiIters", indx = hypre_ParAMGDataILULowerJacobiIters(amg_data));
14463c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU lower Jacobi iterations %" PetscInt_FMT "\n", indx));
14473c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUUpperJacobiIters", indx = hypre_ParAMGDataILUUpperJacobiIters(amg_data));
14483c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU upper Jacobi iterations %" PetscInt_FMT "\n", indx));
14493c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataPrintLevel", indx = hypre_ParAMGDataPrintLevel(amg_data));
14503c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU print level %" PetscInt_FMT "\n", indx));
14513c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataLogging", indx = hypre_ParAMGDataLogging(amg_data));
14523c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU logging level %" PetscInt_FMT "\n", indx));
14533c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUIterSetupType", indx = hypre_ParAMGDataILUIterSetupType(amg_data));
14543c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup type %s (%" PetscInt_FMT ")\n", HYPREILUIterSetup[indx], indx));
14553c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUIterSetupOption", indx = hypre_ParAMGDataILUIterSetupOption(amg_data));
14563c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup option %" PetscInt_FMT "\n", indx));
14573c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUIterSetupMaxIter", indx = hypre_ParAMGDataILUIterSetupMaxIter(amg_data));
14583c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup max iterations %" PetscInt_FMT "\n", indx));
14593c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUIterSetupTolerance", val = hypre_ParAMGDataILUIterSetupTolerance(amg_data));
14603c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup tolerance %e\n", val));
14613c61a47dSLukas }
14627e352d70SEike Mueller } else {
14639566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Not using more complex smoothers.\n"));
14641810e44eSEike Mueller }
14651810e44eSEike Mueller if (jac->smoothtype == 3) {
146663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Euclid ILU(k) levels %" PetscInt_FMT "\n", jac->eu_level));
14679566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Euclid ILU(k) drop tolerance %g\n", (double)jac->eu_droptolerance));
146863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Euclid ILU use Block-Jacobi? %" PetscInt_FMT "\n", jac->eu_bj));
14696a251517SEike Mueller }
14709566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Measure type %s\n", HYPREBoomerAMGMeasureType[jac->measuretype]));
1471abf5c9d9SBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, " Coarsen type %s\n", jac->coarsentype < 0 ? "not yet set" : HYPREBoomerAMGCoarsenType[jac->coarsentype]));
1472abf5c9d9SBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation type %s\n", jac->interptype != 100 ? (jac->interptype < 0 ? "not yet set" : HYPREBoomerAMGInterpType[jac->interptype]) : "1pt"));
147348a46eb9SPierre Jolivet if (jac->nodal_coarsening) PetscCall(PetscViewerASCIIPrintf(viewer, " Using nodal coarsening with HYPRE_BOOMERAMGSetNodal() %" PetscInt_FMT "\n", jac->nodal_coarsening));
14745272c319SBarry Smith if (jac->vec_interp_variant) {
147563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE_BoomerAMGSetInterpVecVariant() %" PetscInt_FMT "\n", jac->vec_interp_variant));
147663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE_BoomerAMGSetInterpVecQMax() %" PetscInt_FMT "\n", jac->vec_interp_qmax));
14779566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n", jac->vec_interp_smooth));
14788f87f92bSBarry Smith }
147948a46eb9SPierre Jolivet if (jac->nodal_relax) PetscCall(PetscViewerASCIIPrintf(viewer, " Using nodal relaxation via Schwarz smoothing on levels %" PetscInt_FMT "\n", jac->nodal_relax_levels));
1480db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0)
14819566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " SpGEMM type %s\n", jac->spgemm_type));
14822d6c3ceeSStefano Zampini #else
14832d6c3ceeSStefano Zampini PetscCall(PetscViewerASCIIPrintf(viewer, " SpGEMM type %s\n", "hypre"));
1484db6f9c32SMark Adams #endif
1485589dcaf0SStefano Zampini /* AIR */
1486589dcaf0SStefano Zampini if (jac->Rtype) {
148763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Using approximate ideal restriction type %" PetscInt_FMT "\n", jac->Rtype));
14889566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Threshold for R %g\n", (double)jac->Rstrongthreshold));
14899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Filter for R %g\n", (double)jac->Rfilterthreshold));
14909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " A drop tolerance %g\n", (double)jac->Adroptol));
149163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " A drop type %" PetscInt_FMT "\n", jac->Adroptype));
1492589dcaf0SStefano Zampini }
149316d9e3a6SLisandro Dalcin }
14943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
149516d9e3a6SLisandro Dalcin }
149616d9e3a6SLisandro Dalcin
PCSetFromOptions_HYPRE_ParaSails(PC pc,PetscOptionItems PetscOptionsObject)1497ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PC pc, PetscOptionItems PetscOptionsObject)
1498d71ae5a4SJacob Faibussowitsch {
149916d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data;
15004ddd07fcSJed Brown PetscInt indx;
1501ace3abfcSBarry Smith PetscBool flag;
150216d9e3a6SLisandro Dalcin const char *symtlist[] = {"nonsymmetric", "SPD", "nonsymmetric,SPD"};
150316d9e3a6SLisandro Dalcin
150416d9e3a6SLisandro Dalcin PetscFunctionBegin;
1505d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE ParaSails Options");
15069566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_parasails_nlevels", "Number of number of levels", "None", jac->nlevels, &jac->nlevels, 0));
15079566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_thresh", "Threshold", "None", jac->threshold, &jac->threshold, &flag));
1508f2f41e48SZach Atkins if (flag) PetscCallHYPRE(HYPRE_ParaSailsSetParams(jac->hsolver, jac->threshold, (HYPRE_Int)jac->nlevels));
150916d9e3a6SLisandro Dalcin
15109566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_filter", "filter", "None", jac->filter, &jac->filter, &flag));
1511a333fa2bSZach Atkins if (flag) PetscCallHYPRE(HYPRE_ParaSailsSetFilter(jac->hsolver, jac->filter));
151216d9e3a6SLisandro Dalcin
15139566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_loadbal", "Load balance", "None", jac->loadbal, &jac->loadbal, &flag));
1514f2f41e48SZach Atkins if (flag) PetscCallHYPRE(HYPRE_ParaSailsSetLoadbal(jac->hsolver, (HYPRE_Int)jac->loadbal));
151516d9e3a6SLisandro Dalcin
15169566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_parasails_logging", "Print info to screen", "None", (PetscBool)jac->logging, (PetscBool *)&jac->logging, &flag));
1517f2f41e48SZach Atkins if (flag) PetscCallHYPRE(HYPRE_ParaSailsSetLogging(jac->hsolver, (HYPRE_Int)jac->logging));
151816d9e3a6SLisandro Dalcin
15199566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_parasails_reuse", "Reuse nonzero pattern in preconditioner", "None", (PetscBool)jac->ruse, (PetscBool *)&jac->ruse, &flag));
1520f2f41e48SZach Atkins if (flag) PetscCallHYPRE(HYPRE_ParaSailsSetReuse(jac->hsolver, (HYPRE_Int)jac->ruse));
152116d9e3a6SLisandro Dalcin
1522dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_parasails_sym", "Symmetry of matrix and preconditioner", "None", symtlist, PETSC_STATIC_ARRAY_LENGTH(symtlist), symtlist[0], &indx, &flag));
152316d9e3a6SLisandro Dalcin if (flag) {
152416d9e3a6SLisandro Dalcin jac->symt = indx;
1525f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_ParaSailsSetSym(jac->hsolver, (HYPRE_Int)jac->symt));
152616d9e3a6SLisandro Dalcin }
152716d9e3a6SLisandro Dalcin
1528d0609cedSBarry Smith PetscOptionsHeadEnd();
15293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
153016d9e3a6SLisandro Dalcin }
153116d9e3a6SLisandro Dalcin
PCView_HYPRE_ParaSails(PC pc,PetscViewer viewer)1532d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_ParaSails(PC pc, PetscViewer viewer)
1533d71ae5a4SJacob Faibussowitsch {
153416d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data;
15359f196a02SMartin Diehl PetscBool isascii;
1536feb237baSPierre Jolivet const char *symt = 0;
153716d9e3a6SLisandro Dalcin
153816d9e3a6SLisandro Dalcin PetscFunctionBegin;
15399f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
15409f196a02SMartin Diehl if (isascii) {
15419566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE ParaSails preconditioning\n"));
154263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " nlevels %" PetscInt_FMT "\n", jac->nlevels));
15439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " threshold %g\n", (double)jac->threshold));
15449566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " filter %g\n", (double)jac->filter));
15459566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " load balance %g\n", (double)jac->loadbal));
15469566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " reuse nonzero structure %s\n", PetscBools[jac->ruse]));
15479566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " print info to screen %s\n", PetscBools[jac->logging]));
15482fa5cd67SKarl Rupp if (!jac->symt) symt = "nonsymmetric matrix and preconditioner";
15492fa5cd67SKarl Rupp else if (jac->symt == 1) symt = "SPD matrix and preconditioner";
15502fa5cd67SKarl Rupp else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner";
155163a3b9bcSJacob Faibussowitsch else SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONG, "Unknown HYPRE ParaSails symmetric option %" PetscInt_FMT, jac->symt);
15529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %s\n", symt));
155316d9e3a6SLisandro Dalcin }
15543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
155516d9e3a6SLisandro Dalcin }
1556f1580f4eSBarry Smith
PCSetFromOptions_HYPRE_AMS(PC pc,PetscOptionItems PetscOptionsObject)1557ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PC pc, PetscOptionItems PetscOptionsObject)
1558d71ae5a4SJacob Faibussowitsch {
15594cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data;
15604cb006feSStefano Zampini PetscInt n;
15614cb006feSStefano Zampini PetscBool flag, flag2, flag3, flag4;
15624cb006feSStefano Zampini
15634cb006feSStefano Zampini PetscFunctionBegin;
1564d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE AMS Options");
15659566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_print_level", "Debugging output level for AMS", "None", jac->as_print, &jac->as_print, &flag));
1566f2f41e48SZach Atkins if (flag) PetscCallHYPRE(HYPRE_AMSSetPrintLevel(jac->hsolver, (HYPRE_Int)jac->as_print));
15679566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_max_iter", "Maximum number of AMS multigrid iterations within PCApply", "None", jac->as_max_iter, &jac->as_max_iter, &flag));
1568f2f41e48SZach Atkins if (flag) PetscCallHYPRE(HYPRE_AMSSetMaxIter(jac->hsolver, (HYPRE_Int)jac->as_max_iter));
15699566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_cycle_type", "Cycle type for AMS multigrid", "None", jac->ams_cycle_type, &jac->ams_cycle_type, &flag));
1570f2f41e48SZach Atkins if (flag) PetscCallHYPRE(HYPRE_AMSSetCycleType(jac->hsolver, (HYPRE_Int)jac->ams_cycle_type));
15719566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_tol", "Error tolerance for AMS multigrid", "None", jac->as_tol, &jac->as_tol, &flag));
1572a333fa2bSZach Atkins if (flag) PetscCallHYPRE(HYPRE_AMSSetTol(jac->hsolver, jac->as_tol));
15739566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_relax_type", "Relaxation type for AMS smoother", "None", jac->as_relax_type, &jac->as_relax_type, &flag));
15749566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_relax_times", "Number of relaxation steps for AMS smoother", "None", jac->as_relax_times, &jac->as_relax_times, &flag2));
15759566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_relax_weight", "Relaxation weight for AMS smoother", "None", jac->as_relax_weight, &jac->as_relax_weight, &flag3));
15769566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_omega", "SSOR coefficient for AMS smoother", "None", jac->as_omega, &jac->as_omega, &flag4));
1577f2f41e48SZach Atkins if (flag || flag2 || flag3 || flag4) PetscCallHYPRE(HYPRE_AMSSetSmoothingOptions(jac->hsolver, (HYPRE_Int)jac->as_relax_type, (HYPRE_Int)jac->as_relax_times, jac->as_relax_weight, jac->as_omega));
15789566063dSJacob Faibussowitsch PetscCall(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));
15794cb006feSStefano Zampini n = 5;
15809566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options", "AMG options for vector Poisson", "None", jac->as_amg_alpha_opts, &n, &flag2));
15814cb006feSStefano Zampini if (flag || flag2) {
1582f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_AMSSetAlphaAMGOptions(jac->hsolver, (HYPRE_Int)jac->as_amg_alpha_opts[0], /* AMG coarsen type */
1583f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_alpha_opts[1], /* AMG agg_levels */
1584f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_alpha_opts[2], /* AMG relax_type */
1585f2f41e48SZach Atkins jac->as_amg_alpha_theta, (HYPRE_Int)jac->as_amg_alpha_opts[3], /* AMG interp_type */
1586f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_alpha_opts[4])); /* AMG Pmax */
15874cb006feSStefano Zampini }
15889566063dSJacob Faibussowitsch PetscCall(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));
15894cb006feSStefano Zampini n = 5;
15909566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ams_amg_beta_options", "AMG options for scalar Poisson solver", "None", jac->as_amg_beta_opts, &n, &flag2));
15914cb006feSStefano Zampini if (flag || flag2) {
1592f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_AMSSetBetaAMGOptions(jac->hsolver, (HYPRE_Int)jac->as_amg_beta_opts[0], /* AMG coarsen type */
1593f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_beta_opts[1], /* AMG agg_levels */
1594f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_beta_opts[2], /* AMG relax_type */
1595f2f41e48SZach Atkins jac->as_amg_beta_theta, (HYPRE_Int)jac->as_amg_beta_opts[3], /* AMG interp_type */
1596f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_beta_opts[4])); /* AMG Pmax */
15974cb006feSStefano Zampini }
15989566063dSJacob Faibussowitsch PetscCall(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));
159923df4f25SStefano Zampini if (flag) { /* override HYPRE's default only if the options is used */
1600f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_AMSSetProjectionFrequency(jac->hsolver, (HYPRE_Int)jac->ams_proj_freq));
160123df4f25SStefano Zampini }
1602d0609cedSBarry Smith PetscOptionsHeadEnd();
16033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
16044cb006feSStefano Zampini }
16054cb006feSStefano Zampini
PCView_HYPRE_AMS(PC pc,PetscViewer viewer)1606d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_AMS(PC pc, PetscViewer viewer)
1607d71ae5a4SJacob Faibussowitsch {
16084cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data;
16099f196a02SMartin Diehl PetscBool isascii;
16104cb006feSStefano Zampini
16114cb006feSStefano Zampini PetscFunctionBegin;
16129f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
16139f196a02SMartin Diehl if (isascii) {
16149566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE AMS preconditioning\n"));
161563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iterations per application %" PetscInt_FMT "\n", jac->as_max_iter));
161663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace cycle type %" PetscInt_FMT "\n", jac->ams_cycle_type));
161763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iteration tolerance %g\n", (double)jac->as_tol));
161863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother type %" PetscInt_FMT "\n", jac->as_relax_type));
161963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number of smoothing steps %" PetscInt_FMT "\n", jac->as_relax_times));
162063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother weight %g\n", (double)jac->as_relax_weight));
162163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother omega %g\n", (double)jac->as_omega));
16224cb006feSStefano Zampini if (jac->alpha_Poisson) {
16239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " vector Poisson solver (passed in by user)\n"));
16244cb006feSStefano Zampini } else {
16259566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " vector Poisson solver (computed) \n"));
16264cb006feSStefano Zampini }
162763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG coarsening type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[0]));
162863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[1]));
162963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG relaxation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[2]));
163063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG interpolation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[3]));
163163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[4]));
163263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG strength threshold %g\n", (double)jac->as_amg_alpha_theta));
16334cb006feSStefano Zampini if (!jac->ams_beta_is_zero) {
16344cb006feSStefano Zampini if (jac->beta_Poisson) {
16359566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " scalar Poisson solver (passed in by user)\n"));
16364cb006feSStefano Zampini } else {
16379566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " scalar Poisson solver (computed) \n"));
16384cb006feSStefano Zampini }
163963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG coarsening type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[0]));
164063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_beta_opts[1]));
164163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG relaxation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[2]));
164263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG interpolation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[3]));
164363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_beta_opts[4]));
164463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG strength threshold %g\n", (double)jac->as_amg_beta_theta));
164548a46eb9SPierre Jolivet if (jac->ams_beta_is_zero_part) PetscCall(PetscViewerASCIIPrintf(viewer, " compatible subspace projection frequency %" PetscInt_FMT " (-1 HYPRE uses default)\n", jac->ams_proj_freq));
164623df4f25SStefano Zampini } else {
16479566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " scalar Poisson solver not used (zero-conductivity everywhere) \n"));
16484cb006feSStefano Zampini }
16494cb006feSStefano Zampini }
16503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
16514cb006feSStefano Zampini }
16524cb006feSStefano Zampini
PCSetFromOptions_HYPRE_ADS(PC pc,PetscOptionItems PetscOptionsObject)1653ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PC pc, PetscOptionItems PetscOptionsObject)
1654d71ae5a4SJacob Faibussowitsch {
1655863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data;
1656863406b8SStefano Zampini PetscInt n;
1657863406b8SStefano Zampini PetscBool flag, flag2, flag3, flag4;
1658863406b8SStefano Zampini
1659863406b8SStefano Zampini PetscFunctionBegin;
1660d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE ADS Options");
16619566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_print_level", "Debugging output level for ADS", "None", jac->as_print, &jac->as_print, &flag));
1662f2f41e48SZach Atkins if (flag) PetscCallHYPRE(HYPRE_ADSSetPrintLevel(jac->hsolver, (HYPRE_Int)jac->as_print));
16639566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_max_iter", "Maximum number of ADS multigrid iterations within PCApply", "None", jac->as_max_iter, &jac->as_max_iter, &flag));
1664f2f41e48SZach Atkins if (flag) PetscCallHYPRE(HYPRE_ADSSetMaxIter(jac->hsolver, (HYPRE_Int)jac->as_max_iter));
16659566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_cycle_type", "Cycle type for ADS multigrid", "None", jac->ads_cycle_type, &jac->ads_cycle_type, &flag));
1666f2f41e48SZach Atkins if (flag) PetscCallHYPRE(HYPRE_ADSSetCycleType(jac->hsolver, (HYPRE_Int)jac->ads_cycle_type));
16679566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_tol", "Error tolerance for ADS multigrid", "None", jac->as_tol, &jac->as_tol, &flag));
1668a333fa2bSZach Atkins if (flag) PetscCallHYPRE(HYPRE_ADSSetTol(jac->hsolver, jac->as_tol));
16699566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_relax_type", "Relaxation type for ADS smoother", "None", jac->as_relax_type, &jac->as_relax_type, &flag));
16709566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_relax_times", "Number of relaxation steps for ADS smoother", "None", jac->as_relax_times, &jac->as_relax_times, &flag2));
16719566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_relax_weight", "Relaxation weight for ADS smoother", "None", jac->as_relax_weight, &jac->as_relax_weight, &flag3));
16729566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_omega", "SSOR coefficient for ADS smoother", "None", jac->as_omega, &jac->as_omega, &flag4));
1673f2f41e48SZach Atkins if (flag || flag2 || flag3 || flag4) PetscCallHYPRE(HYPRE_ADSSetSmoothingOptions(jac->hsolver, (HYPRE_Int)jac->as_relax_type, (HYPRE_Int)jac->as_relax_times, jac->as_relax_weight, jac->as_omega));
16749566063dSJacob Faibussowitsch PetscCall(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));
1675863406b8SStefano Zampini n = 5;
16769566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ads_ams_options", "AMG options for AMS solver inside ADS", "None", jac->as_amg_alpha_opts, &n, &flag2));
16779566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_ams_cycle_type", "Cycle type for AMS solver inside ADS", "None", jac->ams_cycle_type, &jac->ams_cycle_type, &flag3));
1678863406b8SStefano Zampini if (flag || flag2 || flag3) {
1679f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_ADSSetAMSOptions(jac->hsolver, (HYPRE_Int)jac->ams_cycle_type, /* AMS cycle type */
1680f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_alpha_opts[0], /* AMG coarsen type */
1681f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_alpha_opts[1], /* AMG agg_levels */
1682f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_alpha_opts[2], /* AMG relax_type */
1683f2f41e48SZach Atkins jac->as_amg_alpha_theta, (HYPRE_Int)jac->as_amg_alpha_opts[3], /* AMG interp_type */
1684f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_alpha_opts[4])); /* AMG Pmax */
1685863406b8SStefano Zampini }
16869566063dSJacob Faibussowitsch PetscCall(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));
1687863406b8SStefano Zampini n = 5;
16889566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ads_amg_options", "AMG options for vector AMG solver inside ADS", "None", jac->as_amg_beta_opts, &n, &flag2));
1689863406b8SStefano Zampini if (flag || flag2) {
1690f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_ADSSetAMGOptions(jac->hsolver, (HYPRE_Int)jac->as_amg_beta_opts[0], /* AMG coarsen type */
1691f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_beta_opts[1], /* AMG agg_levels */
1692f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_beta_opts[2], /* AMG relax_type */
1693f2f41e48SZach Atkins jac->as_amg_beta_theta, (HYPRE_Int)jac->as_amg_beta_opts[3], /* AMG interp_type */
1694f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_beta_opts[4])); /* AMG Pmax */
1695863406b8SStefano Zampini }
1696d0609cedSBarry Smith PetscOptionsHeadEnd();
16973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1698863406b8SStefano Zampini }
1699863406b8SStefano Zampini
PCView_HYPRE_ADS(PC pc,PetscViewer viewer)1700d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_ADS(PC pc, PetscViewer viewer)
1701d71ae5a4SJacob Faibussowitsch {
1702863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data;
17039f196a02SMartin Diehl PetscBool isascii;
1704863406b8SStefano Zampini
1705863406b8SStefano Zampini PetscFunctionBegin;
17069f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
17079f196a02SMartin Diehl if (isascii) {
17089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE ADS preconditioning\n"));
170963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iterations per application %" PetscInt_FMT "\n", jac->as_max_iter));
171063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace cycle type %" PetscInt_FMT "\n", jac->ads_cycle_type));
171163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iteration tolerance %g\n", (double)jac->as_tol));
171263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother type %" PetscInt_FMT "\n", jac->as_relax_type));
171363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number of smoothing steps %" PetscInt_FMT "\n", jac->as_relax_times));
171463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother weight %g\n", (double)jac->as_relax_weight));
171563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother omega %g\n", (double)jac->as_omega));
17169566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " AMS solver using boomerAMG\n"));
171763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace cycle type %" PetscInt_FMT "\n", jac->ams_cycle_type));
171863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " coarsening type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[0]));
171963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[1]));
172063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relaxation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[2]));
172163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " interpolation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[3]));
172263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[4]));
172363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " strength threshold %g\n", (double)jac->as_amg_alpha_theta));
17249566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " vector Poisson solver using boomerAMG\n"));
172563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " coarsening type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[0]));
172663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_beta_opts[1]));
172763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relaxation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[2]));
172863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " interpolation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[3]));
172963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_beta_opts[4]));
173063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " strength threshold %g\n", (double)jac->as_amg_beta_theta));
1731863406b8SStefano Zampini }
17323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1733863406b8SStefano Zampini }
1734863406b8SStefano Zampini
PCHYPRESetDiscreteGradient_HYPRE(PC pc,Mat G)1735d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G)
1736d71ae5a4SJacob Faibussowitsch {
17374cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data;
17385ac14e1cSStefano Zampini PetscBool ishypre;
17394cb006feSStefano Zampini
17404cb006feSStefano Zampini PetscFunctionBegin;
17419566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)G, MATHYPRE, &ishypre));
17425ac14e1cSStefano Zampini if (ishypre) {
17439566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)G));
17449566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G));
17455ac14e1cSStefano Zampini jac->G = G;
17465ac14e1cSStefano Zampini } else {
17479566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G));
17489566063dSJacob Faibussowitsch PetscCall(MatConvert(G, MATHYPRE, MAT_INITIAL_MATRIX, &jac->G));
17495ac14e1cSStefano Zampini }
17503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
17514cb006feSStefano Zampini }
17524cb006feSStefano Zampini
17534cb006feSStefano Zampini /*@
1754c3466c22SBarry Smith PCHYPRESetDiscreteGradient - Set the discrete gradient matrix for `PCHYPRE` type of AMS or ADS
17554cb006feSStefano Zampini
1756c3339decSBarry Smith Collective
17574cb006feSStefano Zampini
17584cb006feSStefano Zampini Input Parameters:
17594cb006feSStefano Zampini + pc - the preconditioning context
17604cb006feSStefano Zampini - G - the discrete gradient
17614cb006feSStefano Zampini
17624cb006feSStefano Zampini Level: intermediate
17634cb006feSStefano Zampini
176495452b02SPatrick Sanan Notes:
1765c3466c22SBarry Smith `G` should have as many rows as the number of edges and as many columns as the number of vertices in the mesh
1766147403d9SBarry Smith
1767c3466c22SBarry Smith 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
17684cb006feSStefano Zampini
1769c3466c22SBarry Smith Developer Note:
1770f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type
1771f1580f4eSBarry Smith
1772562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteCurl()`
17734cb006feSStefano Zampini @*/
PCHYPRESetDiscreteGradient(PC pc,Mat G)1774d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G)
1775d71ae5a4SJacob Faibussowitsch {
17764cb006feSStefano Zampini PetscFunctionBegin;
17774cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
17784cb006feSStefano Zampini PetscValidHeaderSpecific(G, MAT_CLASSID, 2);
17794cb006feSStefano Zampini PetscCheckSameComm(pc, 1, G, 2);
1780cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetDiscreteGradient_C", (PC, Mat), (pc, G));
17813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
17824cb006feSStefano Zampini }
17834cb006feSStefano Zampini
PCHYPRESetDiscreteCurl_HYPRE(PC pc,Mat C)1784d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C)
1785d71ae5a4SJacob Faibussowitsch {
1786863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data;
17875ac14e1cSStefano Zampini PetscBool ishypre;
1788863406b8SStefano Zampini
1789863406b8SStefano Zampini PetscFunctionBegin;
17909566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)C, MATHYPRE, &ishypre));
17915ac14e1cSStefano Zampini if (ishypre) {
17929566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)C));
17939566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C));
17945ac14e1cSStefano Zampini jac->C = C;
17955ac14e1cSStefano Zampini } else {
17969566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C));
17979566063dSJacob Faibussowitsch PetscCall(MatConvert(C, MATHYPRE, MAT_INITIAL_MATRIX, &jac->C));
17985ac14e1cSStefano Zampini }
17993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1800863406b8SStefano Zampini }
1801863406b8SStefano Zampini
1802863406b8SStefano Zampini /*@
1803c3466c22SBarry Smith PCHYPRESetDiscreteCurl - Set the discrete curl matrix for `PCHYPRE` type of ADS
1804863406b8SStefano Zampini
1805c3339decSBarry Smith Collective
1806863406b8SStefano Zampini
1807863406b8SStefano Zampini Input Parameters:
1808863406b8SStefano Zampini + pc - the preconditioning context
1809863406b8SStefano Zampini - C - the discrete curl
1810863406b8SStefano Zampini
1811863406b8SStefano Zampini Level: intermediate
1812863406b8SStefano Zampini
181395452b02SPatrick Sanan Notes:
1814c3466c22SBarry Smith `C` should have as many rows as the number of faces and as many columns as the number of edges in the mesh
1815147403d9SBarry Smith
1816c3466c22SBarry Smith Each row of `C` has as many nonzeros as the number of edges of a face, with column indexes being the global indexes of the corresponding edge.
1817c3466c22SBarry Smith Matrix entries are +1 and -1 depending on edge orientation with respect to the face orientation
1818863406b8SStefano Zampini
1819feefa0e1SJacob Faibussowitsch Developer Notes:
1820f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type
1821f1580f4eSBarry Smith
1822c3466c22SBarry Smith If this is only for `PCHYPRE` type of ADS it should be called `PCHYPREADSSetDiscreteCurl()`
1823f1580f4eSBarry Smith
1824562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`
1825863406b8SStefano Zampini @*/
PCHYPRESetDiscreteCurl(PC pc,Mat C)1826d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C)
1827d71ae5a4SJacob Faibussowitsch {
1828863406b8SStefano Zampini PetscFunctionBegin;
1829863406b8SStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
1830863406b8SStefano Zampini PetscValidHeaderSpecific(C, MAT_CLASSID, 2);
1831863406b8SStefano Zampini PetscCheckSameComm(pc, 1, C, 2);
1832cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetDiscreteCurl_C", (PC, Mat), (pc, C));
18333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1834863406b8SStefano Zampini }
1835863406b8SStefano Zampini
PCHYPRESetInterpolations_HYPRE(PC pc,PetscInt dim,Mat RT_PiFull,Mat RT_Pi[],Mat ND_PiFull,Mat ND_Pi[])1836d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
1837d71ae5a4SJacob Faibussowitsch {
18386bf688a0SCe Qin PC_HYPRE *jac = (PC_HYPRE *)pc->data;
18396bf688a0SCe Qin PetscBool ishypre;
18406bf688a0SCe Qin PetscInt i;
18416bf688a0SCe Qin
18424d86920dSPierre Jolivet PetscFunctionBegin;
18439566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_PiFull));
18449566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_PiFull));
18456bf688a0SCe Qin for (i = 0; i < 3; ++i) {
18469566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[i]));
18479566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[i]));
18486bf688a0SCe Qin }
18496bf688a0SCe Qin
18506bf688a0SCe Qin jac->dim = dim;
18516bf688a0SCe Qin if (RT_PiFull) {
18529566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)RT_PiFull, MATHYPRE, &ishypre));
18536bf688a0SCe Qin if (ishypre) {
18549566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)RT_PiFull));
18556bf688a0SCe Qin jac->RT_PiFull = RT_PiFull;
18566bf688a0SCe Qin } else {
18579566063dSJacob Faibussowitsch PetscCall(MatConvert(RT_PiFull, MATHYPRE, MAT_INITIAL_MATRIX, &jac->RT_PiFull));
18586bf688a0SCe Qin }
18596bf688a0SCe Qin }
18606bf688a0SCe Qin if (RT_Pi) {
18616bf688a0SCe Qin for (i = 0; i < dim; ++i) {
18626bf688a0SCe Qin if (RT_Pi[i]) {
18639566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)RT_Pi[i], MATHYPRE, &ishypre));
18646bf688a0SCe Qin if (ishypre) {
18659566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)RT_Pi[i]));
18666bf688a0SCe Qin jac->RT_Pi[i] = RT_Pi[i];
18676bf688a0SCe Qin } else {
18689566063dSJacob Faibussowitsch PetscCall(MatConvert(RT_Pi[i], MATHYPRE, MAT_INITIAL_MATRIX, &jac->RT_Pi[i]));
18696bf688a0SCe Qin }
18706bf688a0SCe Qin }
18716bf688a0SCe Qin }
18726bf688a0SCe Qin }
18736bf688a0SCe Qin if (ND_PiFull) {
18749566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)ND_PiFull, MATHYPRE, &ishypre));
18756bf688a0SCe Qin if (ishypre) {
18769566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ND_PiFull));
18776bf688a0SCe Qin jac->ND_PiFull = ND_PiFull;
18786bf688a0SCe Qin } else {
18799566063dSJacob Faibussowitsch PetscCall(MatConvert(ND_PiFull, MATHYPRE, MAT_INITIAL_MATRIX, &jac->ND_PiFull));
18806bf688a0SCe Qin }
18816bf688a0SCe Qin }
18826bf688a0SCe Qin if (ND_Pi) {
18836bf688a0SCe Qin for (i = 0; i < dim; ++i) {
18846bf688a0SCe Qin if (ND_Pi[i]) {
18859566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)ND_Pi[i], MATHYPRE, &ishypre));
18866bf688a0SCe Qin if (ishypre) {
18879566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ND_Pi[i]));
18886bf688a0SCe Qin jac->ND_Pi[i] = ND_Pi[i];
18896bf688a0SCe Qin } else {
18909566063dSJacob Faibussowitsch PetscCall(MatConvert(ND_Pi[i], MATHYPRE, MAT_INITIAL_MATRIX, &jac->ND_Pi[i]));
18916bf688a0SCe Qin }
18926bf688a0SCe Qin }
18936bf688a0SCe Qin }
18946bf688a0SCe Qin }
18953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
18966bf688a0SCe Qin }
18976bf688a0SCe Qin
18986bf688a0SCe Qin /*@
1899c3466c22SBarry Smith PCHYPRESetInterpolations - Set the interpolation matrices for `PCHYPRE` type of AMS or ADS
19006bf688a0SCe Qin
1901c3339decSBarry Smith Collective
19026bf688a0SCe Qin
19036bf688a0SCe Qin Input Parameters:
19046bf688a0SCe Qin + pc - the preconditioning context
19052fe279fdSBarry Smith . dim - the dimension of the problem, only used in AMS
19062fe279fdSBarry Smith . RT_PiFull - Raviart-Thomas interpolation matrix
19072fe279fdSBarry Smith . RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix
19082fe279fdSBarry Smith . ND_PiFull - Nedelec interpolation matrix
19096bf688a0SCe Qin - ND_Pi - x/y/z component of Nedelec interpolation matrix
19106bf688a0SCe Qin
1911f1580f4eSBarry Smith Level: intermediate
1912f1580f4eSBarry Smith
191395452b02SPatrick Sanan Notes:
1914c3466c22SBarry Smith For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to `NULL`.
1915147403d9SBarry Smith
19166bf688a0SCe Qin For ADS, both type of interpolation matrices are needed.
1917147403d9SBarry Smith
1918c3466c22SBarry Smith Developer Note:
1919f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type
19206bf688a0SCe Qin
1921562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`
19226bf688a0SCe Qin @*/
PCHYPRESetInterpolations(PC pc,PetscInt dim,Mat RT_PiFull,Mat RT_Pi[],Mat ND_PiFull,Mat ND_Pi[])1923d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[])
1924d71ae5a4SJacob Faibussowitsch {
19256bf688a0SCe Qin PetscInt i;
19266bf688a0SCe Qin
19276bf688a0SCe Qin PetscFunctionBegin;
19286bf688a0SCe Qin PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
19296bf688a0SCe Qin if (RT_PiFull) {
19306bf688a0SCe Qin PetscValidHeaderSpecific(RT_PiFull, MAT_CLASSID, 3);
19316bf688a0SCe Qin PetscCheckSameComm(pc, 1, RT_PiFull, 3);
19326bf688a0SCe Qin }
19336bf688a0SCe Qin if (RT_Pi) {
19344f572ea9SToby Isaac PetscAssertPointer(RT_Pi, 4);
19356bf688a0SCe Qin for (i = 0; i < dim; ++i) {
19366bf688a0SCe Qin if (RT_Pi[i]) {
19376bf688a0SCe Qin PetscValidHeaderSpecific(RT_Pi[i], MAT_CLASSID, 4);
19386bf688a0SCe Qin PetscCheckSameComm(pc, 1, RT_Pi[i], 4);
19396bf688a0SCe Qin }
19406bf688a0SCe Qin }
19416bf688a0SCe Qin }
19426bf688a0SCe Qin if (ND_PiFull) {
19436bf688a0SCe Qin PetscValidHeaderSpecific(ND_PiFull, MAT_CLASSID, 5);
19446bf688a0SCe Qin PetscCheckSameComm(pc, 1, ND_PiFull, 5);
19456bf688a0SCe Qin }
19466bf688a0SCe Qin if (ND_Pi) {
19474f572ea9SToby Isaac PetscAssertPointer(ND_Pi, 6);
19486bf688a0SCe Qin for (i = 0; i < dim; ++i) {
19496bf688a0SCe Qin if (ND_Pi[i]) {
19506bf688a0SCe Qin PetscValidHeaderSpecific(ND_Pi[i], MAT_CLASSID, 6);
19516bf688a0SCe Qin PetscCheckSameComm(pc, 1, ND_Pi[i], 6);
19526bf688a0SCe Qin }
19536bf688a0SCe Qin }
19546bf688a0SCe Qin }
1955cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetInterpolations_C", (PC, PetscInt, Mat, Mat[], Mat, Mat[]), (pc, dim, RT_PiFull, RT_Pi, ND_PiFull, ND_Pi));
19563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
19576bf688a0SCe Qin }
19586bf688a0SCe Qin
PCHYPRESetPoissonMatrix_HYPRE(PC pc,Mat A,PetscBool isalpha)1959d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha)
1960d71ae5a4SJacob Faibussowitsch {
19614cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data;
19625ac14e1cSStefano Zampini PetscBool ishypre;
19634cb006feSStefano Zampini
19644cb006feSStefano Zampini PetscFunctionBegin;
19659566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATHYPRE, &ishypre));
19665ac14e1cSStefano Zampini if (ishypre) {
19675ac14e1cSStefano Zampini if (isalpha) {
19689566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A));
19699566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson));
19705ac14e1cSStefano Zampini jac->alpha_Poisson = A;
19715ac14e1cSStefano Zampini } else {
19725ac14e1cSStefano Zampini if (A) {
19739566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A));
19745ac14e1cSStefano Zampini } else {
19755ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_TRUE;
19765ac14e1cSStefano Zampini }
19779566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson));
19785ac14e1cSStefano Zampini jac->beta_Poisson = A;
19795ac14e1cSStefano Zampini }
19805ac14e1cSStefano Zampini } else {
19815ac14e1cSStefano Zampini if (isalpha) {
19829566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson));
19839566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &jac->alpha_Poisson));
19845ac14e1cSStefano Zampini } else {
19855ac14e1cSStefano Zampini if (A) {
19869566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson));
19879566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &jac->beta_Poisson));
19885ac14e1cSStefano Zampini } else {
19899566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson));
19905ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_TRUE;
19915ac14e1cSStefano Zampini }
19925ac14e1cSStefano Zampini }
19935ac14e1cSStefano Zampini }
19943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
19954cb006feSStefano Zampini }
19964cb006feSStefano Zampini
19974cb006feSStefano Zampini /*@
1998c3466c22SBarry Smith PCHYPRESetAlphaPoissonMatrix - Set the vector Poisson matrix for `PCHYPRE` of type AMS
19994cb006feSStefano Zampini
2000c3339decSBarry Smith Collective
20014cb006feSStefano Zampini
20024cb006feSStefano Zampini Input Parameters:
20034cb006feSStefano Zampini + pc - the preconditioning context
20044cb006feSStefano Zampini - A - the matrix
20054cb006feSStefano Zampini
20064cb006feSStefano Zampini Level: intermediate
20074cb006feSStefano Zampini
2008f1580f4eSBarry Smith Note:
2009c3466c22SBarry Smith `A` should be obtained by discretizing the vector valued Poisson problem with linear finite elements
20104cb006feSStefano Zampini
2011feefa0e1SJacob Faibussowitsch Developer Notes:
2012f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type
2013f1580f4eSBarry Smith
2014c3466c22SBarry Smith If this is only for `PCHYPRE` type of AMS it should be called `PCHYPREAMSSetAlphaPoissonMatrix()`
2015f1580f4eSBarry Smith
2016562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetBetaPoissonMatrix()`
20174cb006feSStefano Zampini @*/
PCHYPRESetAlphaPoissonMatrix(PC pc,Mat A)2018d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A)
2019d71ae5a4SJacob Faibussowitsch {
20204cb006feSStefano Zampini PetscFunctionBegin;
20214cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
20224cb006feSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 2);
20234cb006feSStefano Zampini PetscCheckSameComm(pc, 1, A, 2);
2024cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetPoissonMatrix_C", (PC, Mat, PetscBool), (pc, A, PETSC_TRUE));
20253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
20264cb006feSStefano Zampini }
20274cb006feSStefano Zampini
20284cb006feSStefano Zampini /*@
2029c3466c22SBarry Smith PCHYPRESetBetaPoissonMatrix - Set the Poisson matrix for `PCHYPRE` of type AMS
20304cb006feSStefano Zampini
2031c3339decSBarry Smith Collective
20324cb006feSStefano Zampini
20334cb006feSStefano Zampini Input Parameters:
20344cb006feSStefano Zampini + pc - the preconditioning context
2035c3466c22SBarry Smith - A - the matrix, or `NULL` to turn it off
20364cb006feSStefano Zampini
20374cb006feSStefano Zampini Level: intermediate
20384cb006feSStefano Zampini
2039f1580f4eSBarry Smith Note:
2040c3466c22SBarry Smith `A` should be obtained by discretizing the Poisson problem with linear finite elements.
20414cb006feSStefano Zampini
2042feefa0e1SJacob Faibussowitsch Developer Notes:
2043f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type
2044f1580f4eSBarry Smith
2045c3466c22SBarry Smith If this is only for `PCHYPRE` type of AMS it should be called `PCHYPREAMSPCHYPRESetBetaPoissonMatrix()`
2046f1580f4eSBarry Smith
2047562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()`
20484cb006feSStefano Zampini @*/
PCHYPRESetBetaPoissonMatrix(PC pc,Mat A)2049d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A)
2050d71ae5a4SJacob Faibussowitsch {
20514cb006feSStefano Zampini PetscFunctionBegin;
20524cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
20534cb006feSStefano Zampini if (A) {
20544cb006feSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 2);
20554cb006feSStefano Zampini PetscCheckSameComm(pc, 1, A, 2);
20564cb006feSStefano Zampini }
2057cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetPoissonMatrix_C", (PC, Mat, PetscBool), (pc, A, PETSC_FALSE));
20583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
20594cb006feSStefano Zampini }
20604cb006feSStefano Zampini
PCHYPRESetEdgeConstantVectors_HYPRE(PC pc,Vec ozz,Vec zoz,Vec zzo)2061d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc, Vec ozz, Vec zoz, Vec zzo)
2062d71ae5a4SJacob Faibussowitsch {
20634cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data;
20644cb006feSStefano Zampini
20654cb006feSStefano Zampini PetscFunctionBegin;
20664cb006feSStefano Zampini /* throw away any vector if already set */
20679566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[0]));
20689566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[1]));
20699566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[2]));
20709566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(ozz->map, &jac->constants[0]));
20719566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(ozz, jac->constants[0]));
20729566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(zoz->map, &jac->constants[1]));
20739566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(zoz, jac->constants[1]));
20745ac14e1cSStefano Zampini jac->dim = 2;
20754cb006feSStefano Zampini if (zzo) {
20769566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(zzo->map, &jac->constants[2]));
20779566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(zzo, jac->constants[2]));
20785ac14e1cSStefano Zampini jac->dim++;
20794cb006feSStefano Zampini }
20803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
20814cb006feSStefano Zampini }
20824cb006feSStefano Zampini
20834cb006feSStefano Zampini /*@
2084c3466c22SBarry Smith PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in the edge element basis for `PCHYPRE` of type AMS
20854cb006feSStefano Zampini
2086c3339decSBarry Smith Collective
20874cb006feSStefano Zampini
20884cb006feSStefano Zampini Input Parameters:
20894cb006feSStefano Zampini + pc - the preconditioning context
20902fe279fdSBarry Smith . ozz - vector representing (1,0,0) (or (1,0) in 2D)
20912fe279fdSBarry Smith . zoz - vector representing (0,1,0) (or (0,1) in 2D)
20924cb006feSStefano Zampini - zzo - vector representing (0,0,1) (use NULL in 2D)
20934cb006feSStefano Zampini
20944cb006feSStefano Zampini Level: intermediate
20954cb006feSStefano Zampini
2096c3466c22SBarry Smith Developer Note:
2097c3466c22SBarry Smith If this is only for `PCHYPRE` type of AMS it should be called `PCHYPREAMSSetEdgeConstantVectors()`
2098f1580f4eSBarry Smith
2099562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()`
21004cb006feSStefano Zampini @*/
PCHYPRESetEdgeConstantVectors(PC pc,Vec ozz,Vec zoz,Vec zzo)2101d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo)
2102d71ae5a4SJacob Faibussowitsch {
21034cb006feSStefano Zampini PetscFunctionBegin;
21044cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
21054cb006feSStefano Zampini PetscValidHeaderSpecific(ozz, VEC_CLASSID, 2);
21064cb006feSStefano Zampini PetscValidHeaderSpecific(zoz, VEC_CLASSID, 3);
21074cb006feSStefano Zampini if (zzo) PetscValidHeaderSpecific(zzo, VEC_CLASSID, 4);
21084cb006feSStefano Zampini PetscCheckSameComm(pc, 1, ozz, 2);
21094cb006feSStefano Zampini PetscCheckSameComm(pc, 1, zoz, 3);
21104cb006feSStefano Zampini if (zzo) PetscCheckSameComm(pc, 1, zzo, 4);
2111cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetEdgeConstantVectors_C", (PC, Vec, Vec, Vec), (pc, ozz, zoz, zzo));
21123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
21134cb006feSStefano Zampini }
21144cb006feSStefano Zampini
PCHYPREAMSSetInteriorNodes_HYPRE(PC pc,Vec interior)2115d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPREAMSSetInteriorNodes_HYPRE(PC pc, Vec interior)
2116d71ae5a4SJacob Faibussowitsch {
2117be14dc20SKerry Key PC_HYPRE *jac = (PC_HYPRE *)pc->data;
2118be14dc20SKerry Key
2119be14dc20SKerry Key PetscFunctionBegin;
2120be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorDestroy(&jac->interior));
2121be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorCreate(interior->map, &jac->interior));
2122be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorCopy(interior, jac->interior));
2123be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_TRUE;
21243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2125be14dc20SKerry Key }
2126be14dc20SKerry Key
2127be14dc20SKerry Key /*@
2128c3466c22SBarry Smith PCHYPREAMSSetInteriorNodes - Set the list of interior nodes to a zero-conductivity region for `PCHYPRE` of type AMS
2129be14dc20SKerry Key
2130c3339decSBarry Smith Collective
2131be14dc20SKerry Key
2132be14dc20SKerry Key Input Parameters:
2133be14dc20SKerry Key + pc - the preconditioning context
2134be14dc20SKerry Key - interior - vector. node is interior if its entry in the array is 1.0.
2135be14dc20SKerry Key
2136be14dc20SKerry Key Level: intermediate
2137be14dc20SKerry Key
2138be14dc20SKerry Key Note:
2139f1580f4eSBarry Smith This calls `HYPRE_AMSSetInteriorNodes()`
2140f1580f4eSBarry Smith
2141562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()`
2142be14dc20SKerry Key @*/
PCHYPREAMSSetInteriorNodes(PC pc,Vec interior)2143d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPREAMSSetInteriorNodes(PC pc, Vec interior)
2144d71ae5a4SJacob Faibussowitsch {
2145be14dc20SKerry Key PetscFunctionBegin;
2146be14dc20SKerry Key PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
2147be14dc20SKerry Key PetscValidHeaderSpecific(interior, VEC_CLASSID, 2);
2148be14dc20SKerry Key PetscCheckSameComm(pc, 1, interior, 2);
2149be14dc20SKerry Key PetscTryMethod(pc, "PCHYPREAMSSetInteriorNodes_C", (PC, Vec), (pc, interior));
21503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2151be14dc20SKerry Key }
2152be14dc20SKerry Key
PCSetCoordinates_HYPRE(PC pc,PetscInt dim,PetscInt nloc,PetscReal * coords)2153d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords)
2154d71ae5a4SJacob Faibussowitsch {
21554cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data;
21564cb006feSStefano Zampini Vec tv;
21574cb006feSStefano Zampini PetscInt i;
21584cb006feSStefano Zampini
21594cb006feSStefano Zampini PetscFunctionBegin;
21604cb006feSStefano Zampini /* throw away any coordinate vector if already set */
21619566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[0]));
21629566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[1]));
21639566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[2]));
21645ac14e1cSStefano Zampini jac->dim = dim;
21655ac14e1cSStefano Zampini
21664cb006feSStefano Zampini /* compute IJ vector for coordinates */
21679566063dSJacob Faibussowitsch PetscCall(VecCreate(PetscObjectComm((PetscObject)pc), &tv));
21689566063dSJacob Faibussowitsch PetscCall(VecSetType(tv, VECSTANDARD));
21699566063dSJacob Faibussowitsch PetscCall(VecSetSizes(tv, nloc, PETSC_DECIDE));
21704cb006feSStefano Zampini for (i = 0; i < dim; i++) {
21714cb006feSStefano Zampini PetscScalar *array;
21724cb006feSStefano Zampini PetscInt j;
21734cb006feSStefano Zampini
21749566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(tv->map, &jac->coords[i]));
21759566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(tv, &array));
21766ea7df73SStefano Zampini for (j = 0; j < nloc; j++) array[j] = coords[j * dim + i];
21779566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(tv, &array));
21789566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(tv, jac->coords[i]));
21794cb006feSStefano Zampini }
21809566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tv));
21813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
21824cb006feSStefano Zampini }
21834cb006feSStefano Zampini
PCHYPREGetType_HYPRE(PC pc,const char * name[])2184d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPREGetType_HYPRE(PC pc, const char *name[])
2185d71ae5a4SJacob Faibussowitsch {
218616d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data;
218716d9e3a6SLisandro Dalcin
218816d9e3a6SLisandro Dalcin PetscFunctionBegin;
218916d9e3a6SLisandro Dalcin *name = jac->hypre_type;
21903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
219116d9e3a6SLisandro Dalcin }
219216d9e3a6SLisandro Dalcin
PCHYPRESetType_HYPRE(PC pc,const char name[])2193d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetType_HYPRE(PC pc, const char name[])
2194d71ae5a4SJacob Faibussowitsch {
219516d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data;
2196ace3abfcSBarry Smith PetscBool flag;
219716d9e3a6SLisandro Dalcin
219816d9e3a6SLisandro Dalcin PetscFunctionBegin;
219916d9e3a6SLisandro Dalcin if (jac->hypre_type) {
22009566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type, name, &flag));
2201d7185485SAlex Lindsay if (flag) PetscFunctionReturn(PETSC_SUCCESS);
220216d9e3a6SLisandro Dalcin }
220316d9e3a6SLisandro Dalcin
2204d7185485SAlex Lindsay PetscCall(PCReset_HYPRE(pc));
2205d7185485SAlex Lindsay PetscCall(PetscFree(jac->hypre_type));
2206d7185485SAlex Lindsay PetscCall(PetscStrallocpy(name, &jac->hypre_type));
2207d7185485SAlex Lindsay
220816d9e3a6SLisandro Dalcin jac->maxiter = PETSC_DEFAULT;
220916d9e3a6SLisandro Dalcin jac->tol = PETSC_DEFAULT;
221016d9e3a6SLisandro Dalcin jac->printstatistics = PetscLogPrintInfo;
221116d9e3a6SLisandro Dalcin
22123c61a47dSLukas PetscCall(PetscStrcmp("ilu", jac->hypre_type, &flag));
22133c61a47dSLukas if (flag) {
22143c61a47dSLukas PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre));
2215a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_ILUCreate(&jac->hsolver));
22163c61a47dSLukas pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ILU;
22173c61a47dSLukas pc->ops->view = PCView_HYPRE_ILU;
22183c61a47dSLukas jac->destroy = HYPRE_ILUDestroy;
22193c61a47dSLukas jac->setup = HYPRE_ILUSetup;
22203c61a47dSLukas jac->solve = HYPRE_ILUSolve;
22213c61a47dSLukas jac->factorrowsize = PETSC_DEFAULT;
22223c61a47dSLukas PetscFunctionReturn(PETSC_SUCCESS);
22233c61a47dSLukas }
22243c61a47dSLukas
22259566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("pilut", jac->hypre_type, &flag));
222616d9e3a6SLisandro Dalcin if (flag) {
22279566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre));
2228a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_ParCSRPilutCreate(jac->comm_hypre, &jac->hsolver));
222916d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut;
223016d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_Pilut;
223116d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParCSRPilutDestroy;
223216d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParCSRPilutSetup;
223316d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParCSRPilutSolve;
223416d9e3a6SLisandro Dalcin jac->factorrowsize = PETSC_DEFAULT;
22353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
223616d9e3a6SLisandro Dalcin }
22379566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("euclid", jac->hypre_type, &flag));
2238db966c6cSHong Zhang if (flag) {
22394e3c431bSBarry Smith #if defined(PETSC_USE_64BIT_INDICES)
22407de69702SBarry Smith SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "Hypre Euclid does not support 64-bit indices");
22418bf83915SBarry Smith #endif
22429566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre));
2243a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_EuclidCreate(jac->comm_hypre, &jac->hsolver));
2244db966c6cSHong Zhang pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid;
2245db966c6cSHong Zhang pc->ops->view = PCView_HYPRE_Euclid;
2246db966c6cSHong Zhang jac->destroy = HYPRE_EuclidDestroy;
2247db966c6cSHong Zhang jac->setup = HYPRE_EuclidSetup;
2248db966c6cSHong Zhang jac->solve = HYPRE_EuclidSolve;
2249db966c6cSHong Zhang jac->factorrowsize = PETSC_DEFAULT;
2250db966c6cSHong Zhang jac->eu_level = PETSC_DEFAULT; /* default */
22513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2252db966c6cSHong Zhang }
22539566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("parasails", jac->hypre_type, &flag));
225416d9e3a6SLisandro Dalcin if (flag) {
22559566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre));
2256a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_ParaSailsCreate(jac->comm_hypre, &jac->hsolver));
225716d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails;
225816d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_ParaSails;
225916d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParaSailsDestroy;
226016d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParaSailsSetup;
226116d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParaSailsSolve;
226216d9e3a6SLisandro Dalcin /* initialize */
226316d9e3a6SLisandro Dalcin jac->nlevels = 1;
22648966356dSPierre Jolivet jac->threshold = .1;
226516d9e3a6SLisandro Dalcin jac->filter = .1;
226616d9e3a6SLisandro Dalcin jac->loadbal = 0;
22672fa5cd67SKarl Rupp if (PetscLogPrintInfo) jac->logging = (int)PETSC_TRUE;
22682fa5cd67SKarl Rupp else jac->logging = (int)PETSC_FALSE;
22692fa5cd67SKarl Rupp
227016d9e3a6SLisandro Dalcin jac->ruse = (int)PETSC_FALSE;
227116d9e3a6SLisandro Dalcin jac->symt = 0;
2272f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_ParaSailsSetParams(jac->hsolver, jac->threshold, (HYPRE_Int)jac->nlevels));
2273a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_ParaSailsSetFilter(jac->hsolver, jac->filter));
2274f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_ParaSailsSetLoadbal(jac->hsolver, (HYPRE_Int)jac->loadbal));
2275f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_ParaSailsSetLogging(jac->hsolver, (HYPRE_Int)jac->logging));
2276f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_ParaSailsSetReuse(jac->hsolver, (HYPRE_Int)jac->ruse));
2277f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_ParaSailsSetSym(jac->hsolver, (HYPRE_Int)jac->symt));
22783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
227916d9e3a6SLisandro Dalcin }
22809566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("boomeramg", jac->hypre_type, &flag));
228116d9e3a6SLisandro Dalcin if (flag) {
2282a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_BoomerAMGCreate(&jac->hsolver));
228316d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_BoomerAMG;
228416d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_BoomerAMG;
228516d9e3a6SLisandro Dalcin pc->ops->applytranspose = PCApplyTranspose_HYPRE_BoomerAMG;
228616d9e3a6SLisandro Dalcin pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG;
228785245615SPierre Jolivet pc->ops->matapply = PCMatApply_HYPRE_BoomerAMG;
22889566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetInterpolations_C", PCGetInterpolations_BoomerAMG));
22899566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetCoarseOperators_C", PCGetCoarseOperators_BoomerAMG));
229042e5ec60SJeff-Hadley PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREGetCFMarkers_C", PCHYPREGetCFMarkers_BoomerAMG));
229116d9e3a6SLisandro Dalcin jac->destroy = HYPRE_BoomerAMGDestroy;
229216d9e3a6SLisandro Dalcin jac->setup = HYPRE_BoomerAMGSetup;
229316d9e3a6SLisandro Dalcin jac->solve = HYPRE_BoomerAMGSolve;
229416d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE;
229516d9e3a6SLisandro Dalcin /* these defaults match the hypre defaults */
229616d9e3a6SLisandro Dalcin jac->cycletype = 1;
229716d9e3a6SLisandro Dalcin jac->maxlevels = 25;
229816d9e3a6SLisandro Dalcin jac->maxiter = 1;
22998f87f92bSBarry Smith jac->tol = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */
230016d9e3a6SLisandro Dalcin jac->truncfactor = 0.0;
230116d9e3a6SLisandro Dalcin jac->strongthreshold = .25;
230216d9e3a6SLisandro Dalcin jac->maxrowsum = .9;
230316d9e3a6SLisandro Dalcin jac->measuretype = 0;
23040f1074feSSatish Balay jac->gridsweeps[0] = jac->gridsweeps[1] = jac->gridsweeps[2] = 1;
23056a251517SEike Mueller jac->smoothtype = -1; /* Not set by default */
2306b9eb5777SEike Mueller jac->smoothnumlevels = 25;
23071810e44eSEike Mueller jac->eu_level = 0;
23081810e44eSEike Mueller jac->eu_droptolerance = 0;
23091810e44eSEike Mueller jac->eu_bj = 0;
231016d9e3a6SLisandro Dalcin jac->relaxweight = 1.0;
231116d9e3a6SLisandro Dalcin jac->outerrelaxweight = 1.0;
2312589dcaf0SStefano Zampini jac->Rtype = 0;
2313589dcaf0SStefano Zampini jac->Rstrongthreshold = 0.25;
2314589dcaf0SStefano Zampini jac->Rfilterthreshold = 0.0;
2315589dcaf0SStefano Zampini jac->Adroptype = -1;
2316589dcaf0SStefano Zampini jac->Adroptol = 0.0;
23170f1074feSSatish Balay jac->agg_nl = 0;
23180f1074feSSatish Balay jac->pmax = 0;
23190f1074feSSatish Balay jac->truncfactor = 0.0;
23200f1074feSSatish Balay jac->agg_num_paths = 1;
2321589dcaf0SStefano Zampini jac->maxc = 9;
2322589dcaf0SStefano Zampini jac->minc = 1;
232322e51d31SStefano Zampini jac->nodal_coarsening = 0;
232422e51d31SStefano Zampini jac->nodal_coarsening_diag = 0;
232522e51d31SStefano Zampini jac->vec_interp_variant = 0;
232622e51d31SStefano Zampini jac->vec_interp_qmax = 0;
232722e51d31SStefano Zampini jac->vec_interp_smooth = PETSC_FALSE;
232822e51d31SStefano Zampini jac->interp_refine = 0;
23298f87f92bSBarry Smith jac->nodal_relax = PETSC_FALSE;
23308f87f92bSBarry Smith jac->nodal_relax_levels = 1;
23316ea7df73SStefano Zampini jac->rap2 = 0;
2332abf5c9d9SBarry Smith PetscObjectParameterSetDefault(jac, relaxtype[2], 9); /* G.E. */
2333abf5c9d9SBarry Smith
2334abf5c9d9SBarry Smith /*
2335abf5c9d9SBarry Smith Initialize the following parameters with invalid value so we can recognize user input that sets the parameter.
2336abf5c9d9SBarry Smith If there is no user input they are overwritten in PCSetUp_HYPRE() depending on if the matrix is on the CPU or the GPU
2337abf5c9d9SBarry Smith */
2338abf5c9d9SBarry Smith PetscObjectParameterSetDefault(jac, relaxorder, PETSC_DECIDE);
2339abf5c9d9SBarry Smith PetscObjectParameterSetDefault(jac, coarsentype, PETSC_DECIDE);
2340abf5c9d9SBarry Smith PetscObjectParameterSetDefault(jac, interptype, PETSC_DECIDE);
2341abf5c9d9SBarry Smith PetscObjectParameterSetDefault(jac, relaxtype[0], PETSC_DECIDE);
2342abf5c9d9SBarry Smith PetscObjectParameterSetDefault(jac, relaxtype[1], PETSC_DECIDE);
2343abf5c9d9SBarry Smith #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0)
2344abf5c9d9SBarry Smith PetscObjectParameterSetDefault(jac, spgemm_type, "not yet set");
2345abf5c9d9SBarry Smith #endif
2346abf5c9d9SBarry Smith #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0)
2347abf5c9d9SBarry Smith PetscObjectParameterSetDefault(jac, keeptranspose, PETSC_BOOL3_UNKNOWN);
2348abf5c9d9SBarry Smith PetscObjectParameterSetDefault(jac, mod_rap2, PETSC_DECIDE);
2349abf5c9d9SBarry Smith #endif
2350abf5c9d9SBarry Smith PetscObjectParameterSetDefault(jac, agg_interptype, PETSC_DECIDE);
23513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
235216d9e3a6SLisandro Dalcin }
23539566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("ams", jac->hypre_type, &flag));
23544cb006feSStefano Zampini if (flag) {
2355a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_AMSCreate(&jac->hsolver));
23564cb006feSStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_HYPRE_AMS;
23574cb006feSStefano Zampini pc->ops->view = PCView_HYPRE_AMS;
23584cb006feSStefano Zampini jac->destroy = HYPRE_AMSDestroy;
23594cb006feSStefano Zampini jac->setup = HYPRE_AMSSetup;
23604cb006feSStefano Zampini jac->solve = HYPRE_AMSSolve;
23614cb006feSStefano Zampini jac->coords[0] = NULL;
23624cb006feSStefano Zampini jac->coords[1] = NULL;
23634cb006feSStefano Zampini jac->coords[2] = NULL;
2364be14dc20SKerry Key jac->interior = NULL;
23654cb006feSStefano Zampini /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */
2366863406b8SStefano Zampini jac->as_print = 0;
2367863406b8SStefano Zampini jac->as_max_iter = 1; /* used as a preconditioner */
2368863406b8SStefano Zampini jac->as_tol = 0.; /* used as a preconditioner */
23694cb006feSStefano Zampini jac->ams_cycle_type = 13;
23704cb006feSStefano Zampini /* Smoothing options */
2371863406b8SStefano Zampini jac->as_relax_type = 2;
2372863406b8SStefano Zampini jac->as_relax_times = 1;
2373863406b8SStefano Zampini jac->as_relax_weight = 1.0;
2374863406b8SStefano Zampini jac->as_omega = 1.0;
23754cb006feSStefano Zampini /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
2376863406b8SStefano Zampini jac->as_amg_alpha_opts[0] = 10;
2377863406b8SStefano Zampini jac->as_amg_alpha_opts[1] = 1;
23780bdd8552SBarry Smith jac->as_amg_alpha_opts[2] = 6;
2379863406b8SStefano Zampini jac->as_amg_alpha_opts[3] = 6;
2380863406b8SStefano Zampini jac->as_amg_alpha_opts[4] = 4;
2381863406b8SStefano Zampini jac->as_amg_alpha_theta = 0.25;
23824cb006feSStefano Zampini /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
2383863406b8SStefano Zampini jac->as_amg_beta_opts[0] = 10;
2384863406b8SStefano Zampini jac->as_amg_beta_opts[1] = 1;
23850bdd8552SBarry Smith jac->as_amg_beta_opts[2] = 6;
2386863406b8SStefano Zampini jac->as_amg_beta_opts[3] = 6;
2387863406b8SStefano Zampini jac->as_amg_beta_opts[4] = 4;
2388863406b8SStefano Zampini jac->as_amg_beta_theta = 0.25;
2389f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_AMSSetPrintLevel(jac->hsolver, (HYPRE_Int)jac->as_print));
2390f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_AMSSetMaxIter(jac->hsolver, (HYPRE_Int)jac->as_max_iter));
2391f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_AMSSetCycleType(jac->hsolver, (HYPRE_Int)jac->ams_cycle_type));
2392a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_AMSSetTol(jac->hsolver, jac->as_tol));
2393f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_AMSSetSmoothingOptions(jac->hsolver, (HYPRE_Int)jac->as_relax_type, (HYPRE_Int)jac->as_relax_times, jac->as_relax_weight, jac->as_omega));
2394f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_AMSSetAlphaAMGOptions(jac->hsolver, (HYPRE_Int)jac->as_amg_alpha_opts[0], /* AMG coarsen type */
2395f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_alpha_opts[1], /* AMG agg_levels */
2396f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_alpha_opts[2], /* AMG relax_type */
2397f2f41e48SZach Atkins jac->as_amg_alpha_theta, (HYPRE_Int)jac->as_amg_alpha_opts[3], /* AMG interp_type */
2398f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_alpha_opts[4])); /* AMG Pmax */
2399f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_AMSSetBetaAMGOptions(jac->hsolver, (HYPRE_Int)jac->as_amg_beta_opts[0], /* AMG coarsen type */
2400f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_beta_opts[1], /* AMG agg_levels */
2401f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_beta_opts[2], /* AMG relax_type */
2402f2f41e48SZach Atkins jac->as_amg_beta_theta, (HYPRE_Int)jac->as_amg_beta_opts[3], /* AMG interp_type */
2403f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_beta_opts[4])); /* AMG Pmax */
240423df4f25SStefano Zampini /* Zero conductivity */
240523df4f25SStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE;
240623df4f25SStefano Zampini jac->ams_beta_is_zero_part = PETSC_FALSE;
24073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
24084cb006feSStefano Zampini }
24099566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("ads", jac->hypre_type, &flag));
2410863406b8SStefano Zampini if (flag) {
2411a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_ADSCreate(&jac->hsolver));
2412863406b8SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ADS;
2413863406b8SStefano Zampini pc->ops->view = PCView_HYPRE_ADS;
2414863406b8SStefano Zampini jac->destroy = HYPRE_ADSDestroy;
2415863406b8SStefano Zampini jac->setup = HYPRE_ADSSetup;
2416863406b8SStefano Zampini jac->solve = HYPRE_ADSSolve;
2417863406b8SStefano Zampini jac->coords[0] = NULL;
2418863406b8SStefano Zampini jac->coords[1] = NULL;
2419863406b8SStefano Zampini jac->coords[2] = NULL;
2420863406b8SStefano Zampini /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */
2421863406b8SStefano Zampini jac->as_print = 0;
2422863406b8SStefano Zampini jac->as_max_iter = 1; /* used as a preconditioner */
2423863406b8SStefano Zampini jac->as_tol = 0.; /* used as a preconditioner */
2424863406b8SStefano Zampini jac->ads_cycle_type = 13;
2425863406b8SStefano Zampini /* Smoothing options */
2426863406b8SStefano Zampini jac->as_relax_type = 2;
2427863406b8SStefano Zampini jac->as_relax_times = 1;
2428863406b8SStefano Zampini jac->as_relax_weight = 1.0;
2429863406b8SStefano Zampini jac->as_omega = 1.0;
2430863406b8SStefano Zampini /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */
2431863406b8SStefano Zampini jac->ams_cycle_type = 14;
2432863406b8SStefano Zampini jac->as_amg_alpha_opts[0] = 10;
2433863406b8SStefano Zampini jac->as_amg_alpha_opts[1] = 1;
2434863406b8SStefano Zampini jac->as_amg_alpha_opts[2] = 6;
2435863406b8SStefano Zampini jac->as_amg_alpha_opts[3] = 6;
2436863406b8SStefano Zampini jac->as_amg_alpha_opts[4] = 4;
2437863406b8SStefano Zampini jac->as_amg_alpha_theta = 0.25;
2438863406b8SStefano Zampini /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */
2439863406b8SStefano Zampini jac->as_amg_beta_opts[0] = 10;
2440863406b8SStefano Zampini jac->as_amg_beta_opts[1] = 1;
2441863406b8SStefano Zampini jac->as_amg_beta_opts[2] = 6;
2442863406b8SStefano Zampini jac->as_amg_beta_opts[3] = 6;
2443863406b8SStefano Zampini jac->as_amg_beta_opts[4] = 4;
2444863406b8SStefano Zampini jac->as_amg_beta_theta = 0.25;
2445f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_ADSSetPrintLevel(jac->hsolver, (HYPRE_Int)jac->as_print));
2446f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_ADSSetMaxIter(jac->hsolver, (HYPRE_Int)jac->as_max_iter));
2447f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_ADSSetCycleType(jac->hsolver, (HYPRE_Int)jac->ams_cycle_type));
2448a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_ADSSetTol(jac->hsolver, jac->as_tol));
2449f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_ADSSetSmoothingOptions(jac->hsolver, (HYPRE_Int)jac->as_relax_type, (HYPRE_Int)jac->as_relax_times, jac->as_relax_weight, jac->as_omega));
2450f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_ADSSetAMSOptions(jac->hsolver, (HYPRE_Int)jac->ams_cycle_type, /* AMG coarsen type */
2451f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_alpha_opts[0], /* AMG coarsen type */
2452f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_alpha_opts[1], /* AMG agg_levels */
2453f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_alpha_opts[2], /* AMG relax_type */
2454f2f41e48SZach Atkins jac->as_amg_alpha_theta, (HYPRE_Int)jac->as_amg_alpha_opts[3], /* AMG interp_type */
2455f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_alpha_opts[4])); /* AMG Pmax */
2456f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_ADSSetAMGOptions(jac->hsolver, (HYPRE_Int)jac->as_amg_beta_opts[0], /* AMG coarsen type */
2457f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_beta_opts[1], /* AMG agg_levels */
2458f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_beta_opts[2], /* AMG relax_type */
2459f2f41e48SZach Atkins jac->as_amg_beta_theta, (HYPRE_Int)jac->as_amg_beta_opts[3], /* AMG interp_type */
2460f2f41e48SZach Atkins (HYPRE_Int)jac->as_amg_beta_opts[4])); /* AMG Pmax */
24613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2462863406b8SStefano Zampini }
24639566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hypre_type));
24642fa5cd67SKarl Rupp
24650298fd71SBarry Smith jac->hypre_type = NULL;
2466b06c524fSNuno Nobre SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown HYPRE preconditioner %s; Choices are euclid, ilu, pilut, parasails, boomeramg, ams, ads", name);
246716d9e3a6SLisandro Dalcin }
246816d9e3a6SLisandro Dalcin
246916d9e3a6SLisandro Dalcin /*
247016d9e3a6SLisandro Dalcin It only gets here if the HYPRE type has not been set before the call to
247116d9e3a6SLisandro Dalcin ...SetFromOptions() which actually is most of the time
247216d9e3a6SLisandro Dalcin */
PCSetFromOptions_HYPRE(PC pc,PetscOptionItems PetscOptionsObject)2473ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PC pc, PetscOptionItems PetscOptionsObject)
2474d71ae5a4SJacob Faibussowitsch {
24754ddd07fcSJed Brown PetscInt indx;
24763c61a47dSLukas const char *type[] = {"ilu", "euclid", "pilut", "parasails", "boomeramg", "ams", "ads"};
2477ace3abfcSBarry Smith PetscBool flg;
2478d7185485SAlex Lindsay PC_HYPRE *jac = (PC_HYPRE *)pc->data;
247916d9e3a6SLisandro Dalcin
248016d9e3a6SLisandro Dalcin PetscFunctionBegin;
2481d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE preconditioner options");
2482dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_type", "HYPRE preconditioner type", "PCHYPRESetType", type, PETSC_STATIC_ARRAY_LENGTH(type), "boomeramg", &indx, &flg));
2483d7185485SAlex Lindsay if (flg) PetscCall(PCHYPRESetType_HYPRE(pc, type[indx]));
2484d7185485SAlex Lindsay /*
2485d7185485SAlex Lindsay Set the type if it was never set.
2486d7185485SAlex Lindsay */
2487d7185485SAlex Lindsay if (!jac->hypre_type) PetscCall(PCHYPRESetType_HYPRE(pc, "boomeramg"));
2488dbbe0bcdSBarry Smith PetscTryTypeMethod(pc, setfromoptions, PetscOptionsObject);
2489d0609cedSBarry Smith PetscOptionsHeadEnd();
24903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
249116d9e3a6SLisandro Dalcin }
249216d9e3a6SLisandro Dalcin
2493cc4c1da9SBarry Smith /*@
249416d9e3a6SLisandro Dalcin PCHYPRESetType - Sets which hypre preconditioner you wish to use
249516d9e3a6SLisandro Dalcin
249616d9e3a6SLisandro Dalcin Input Parameters:
249716d9e3a6SLisandro Dalcin + pc - the preconditioner context
2498c3466c22SBarry Smith - name - either euclid, ilu, pilut, parasails, boomeramg, ams, or ads
249916d9e3a6SLisandro Dalcin
2500f1580f4eSBarry Smith Options Database Key:
2501c3466c22SBarry Smith . pc_hypre_type - One of euclid, ilu, pilut, parasails, boomeramg, ams, or ads
250216d9e3a6SLisandro Dalcin
250316d9e3a6SLisandro Dalcin Level: intermediate
250416d9e3a6SLisandro Dalcin
2505562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCreate()`, `PCSetType()`, `PCType`, `PC`, `PCHYPRE`
250616d9e3a6SLisandro Dalcin @*/
PCHYPRESetType(PC pc,const char name[])2507d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetType(PC pc, const char name[])
2508d71ae5a4SJacob Faibussowitsch {
250916d9e3a6SLisandro Dalcin PetscFunctionBegin;
25100700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
25114f572ea9SToby Isaac PetscAssertPointer(name, 2);
2512cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetType_C", (PC, const char[]), (pc, name));
25133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
251416d9e3a6SLisandro Dalcin }
251516d9e3a6SLisandro Dalcin
251642e5ec60SJeff-Hadley /*@C
251742e5ec60SJeff-Hadley PCHYPREGetCFMarkers - Gets CF marker arrays for all levels (except the finest level)
251842e5ec60SJeff-Hadley
251942e5ec60SJeff-Hadley Logically Collective
252042e5ec60SJeff-Hadley
252142e5ec60SJeff-Hadley Input Parameter:
252242e5ec60SJeff-Hadley . pc - the preconditioner context
252342e5ec60SJeff-Hadley
252442e5ec60SJeff-Hadley Output Parameters:
252542e5ec60SJeff-Hadley + n_per_level - the number of nodes per level (size of `num_levels`)
252642e5ec60SJeff-Hadley - CFMarkers - the Coarse/Fine Boolean arrays (size of `num_levels` - 1)
252742e5ec60SJeff-Hadley
2528c3466c22SBarry Smith Level: advanced
2529c3466c22SBarry Smith
253042e5ec60SJeff-Hadley Note:
253142e5ec60SJeff-Hadley Caller is responsible for memory management of `n_per_level` and `CFMarkers` pointers. That is they should free them with `PetscFree()` when no longer needed.
253242e5ec60SJeff-Hadley
253342e5ec60SJeff-Hadley .seealso: [](ch_ksp), `PC`, `PCMG`, `PCMGGetRestriction()`, `PCMGSetInterpolation()`, `PCMGGetRScale()`, `PCMGGetInterpolation()`, `PCGetInterpolations()`
253442e5ec60SJeff-Hadley @*/
PCHYPREGetCFMarkers(PC pc,PetscInt * n_per_level[],PetscBT * CFMarkers[])253542e5ec60SJeff-Hadley PetscErrorCode PCHYPREGetCFMarkers(PC pc, PetscInt *n_per_level[], PetscBT *CFMarkers[])
253642e5ec60SJeff-Hadley {
253742e5ec60SJeff-Hadley PetscFunctionBegin;
253842e5ec60SJeff-Hadley PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
253942e5ec60SJeff-Hadley PetscAssertPointer(n_per_level, 2);
254042e5ec60SJeff-Hadley PetscAssertPointer(CFMarkers, 3);
254142e5ec60SJeff-Hadley PetscUseMethod(pc, "PCHYPREGetCFMarkers_C", (PC, PetscInt *[], PetscBT *[]), (pc, n_per_level, CFMarkers));
254242e5ec60SJeff-Hadley PetscFunctionReturn(PETSC_SUCCESS);
254342e5ec60SJeff-Hadley }
254442e5ec60SJeff-Hadley
2545cc4c1da9SBarry Smith /*@
254616d9e3a6SLisandro Dalcin PCHYPREGetType - Gets which hypre preconditioner you are using
254716d9e3a6SLisandro Dalcin
254816d9e3a6SLisandro Dalcin Input Parameter:
254916d9e3a6SLisandro Dalcin . pc - the preconditioner context
255016d9e3a6SLisandro Dalcin
255116d9e3a6SLisandro Dalcin Output Parameter:
2552c3466c22SBarry Smith . name - either euclid, ilu, pilut, parasails, boomeramg, ams, or ads
255316d9e3a6SLisandro Dalcin
255416d9e3a6SLisandro Dalcin Level: intermediate
255516d9e3a6SLisandro Dalcin
2556562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCreate()`, `PCHYPRESetType()`, `PCType`, `PC`, `PCHYPRE`
255716d9e3a6SLisandro Dalcin @*/
PCHYPREGetType(PC pc,const char * name[])2558d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPREGetType(PC pc, const char *name[])
2559d71ae5a4SJacob Faibussowitsch {
256016d9e3a6SLisandro Dalcin PetscFunctionBegin;
25610700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
25624f572ea9SToby Isaac PetscAssertPointer(name, 2);
2563cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPREGetType_C", (PC, const char *[]), (pc, name));
25643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
256516d9e3a6SLisandro Dalcin }
256616d9e3a6SLisandro Dalcin
2567cc4c1da9SBarry Smith /*@
2568c3466c22SBarry Smith PCMGGalerkinSetMatProductAlgorithm - Set type of sparse matrix-matrix product for hypre's BoomerAMG to use on GPUs
2569db6f9c32SMark Adams
2570c3339decSBarry Smith Logically Collective
2571db6f9c32SMark Adams
2572db6f9c32SMark Adams Input Parameters:
2573db6f9c32SMark Adams + pc - the hypre context
2574feefa0e1SJacob Faibussowitsch - name - one of 'cusparse', 'hypre'
2575db6f9c32SMark Adams
2576db6f9c32SMark Adams Options Database Key:
2577c3466c22SBarry Smith . -pc_mg_galerkin_mat_product_algorithm <cusparse,hypre> - Type of sparse matrix-matrix product to use in hypre
2578db6f9c32SMark Adams
2579db6f9c32SMark Adams Level: intermediate
2580db6f9c32SMark Adams
2581c3466c22SBarry Smith Developer Note:
2582f1580f4eSBarry Smith How the name starts with `PCMG`, should it not be `PCHYPREBoomerAMG`?
2583db6f9c32SMark Adams
2584562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCMGGalerkinGetMatProductAlgorithm()`
2585db6f9c32SMark Adams @*/
PCMGGalerkinSetMatProductAlgorithm(PC pc,const char name[])2586d71ae5a4SJacob Faibussowitsch PetscErrorCode PCMGGalerkinSetMatProductAlgorithm(PC pc, const char name[])
2587d71ae5a4SJacob Faibussowitsch {
2588db6f9c32SMark Adams PetscFunctionBegin;
2589db6f9c32SMark Adams PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
2590cac4c232SBarry Smith PetscTryMethod(pc, "PCMGGalerkinSetMatProductAlgorithm_C", (PC, const char[]), (pc, name));
25913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2592db6f9c32SMark Adams }
2593db6f9c32SMark Adams
2594cc4c1da9SBarry Smith /*@
2595c3466c22SBarry Smith PCMGGalerkinGetMatProductAlgorithm - Get type of sparse matrix-matrix product for hypre's BoomerAMG to use on GPUs
2596db6f9c32SMark Adams
2597db6f9c32SMark Adams Not Collective
2598db6f9c32SMark Adams
2599db6f9c32SMark Adams Input Parameter:
2600db6f9c32SMark Adams . pc - the multigrid context
2601db6f9c32SMark Adams
2602db6f9c32SMark Adams Output Parameter:
2603db6f9c32SMark Adams . name - one of 'cusparse', 'hypre'
2604db6f9c32SMark Adams
2605db6f9c32SMark Adams Level: intermediate
2606db6f9c32SMark Adams
2607a94f484eSPierre Jolivet .seealso: [](ch_ksp), `PCHYPRE`, `PCMGGalerkinSetMatProductAlgorithm()`
2608db6f9c32SMark Adams @*/
PCMGGalerkinGetMatProductAlgorithm(PC pc,const char * name[])2609d71ae5a4SJacob Faibussowitsch PetscErrorCode PCMGGalerkinGetMatProductAlgorithm(PC pc, const char *name[])
2610d71ae5a4SJacob Faibussowitsch {
2611db6f9c32SMark Adams PetscFunctionBegin;
2612db6f9c32SMark Adams PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
2613cac4c232SBarry Smith PetscTryMethod(pc, "PCMGGalerkinGetMatProductAlgorithm_C", (PC, const char *[]), (pc, name));
26143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2615db6f9c32SMark Adams }
2616db6f9c32SMark Adams
261716d9e3a6SLisandro Dalcin /*MC
2618f1580f4eSBarry Smith PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre as PETSc `PC`
261916d9e3a6SLisandro Dalcin
262016d9e3a6SLisandro Dalcin Options Database Keys:
2621b5a865d8SNuno Nobre + -pc_hypre_type - One of `euclid`, `ilu`, `pilut`, `parasails`, `boomeramg`, `ams`, or `ads`
2622c3466c22SBarry Smith . -pc_hypre_boomeramg_nodal_coarsen <n> - where `n` is from 1 to 6 (see `HYPRE_BoomerAMGSetNodal()`)
2623c3466c22SBarry Smith . -pc_hypre_boomeramg_vec_interp_variant <v> - where `v` is from 1 to 3 (see `HYPRE_BoomerAMGSetInterpVecVariant()`)
26247cbeddf0SNuno Nobre - Many others - run with `-pc_type hypre` `-pc_hypre_type XXX` `-help` to see options for the XXX preconditioner
262516d9e3a6SLisandro Dalcin
262616d9e3a6SLisandro Dalcin Level: intermediate
262716d9e3a6SLisandro Dalcin
262895452b02SPatrick Sanan Notes:
2629e1ded407SBarry Smith Apart from `-pc_hypre_type` (for which there is `PCHYPRESetType()`),
263016d9e3a6SLisandro Dalcin the many hypre options can ONLY be set via the options database (e.g. the command line
263149567fc5SPierre Jolivet or with `PetscOptionsSetValue()`, there are no functions to set them)
263216d9e3a6SLisandro Dalcin
2633e1ded407SBarry Smith The options `-pc_hypre_boomeramg_max_iter` and `-pc_hypre_boomeramg_tol` refer to the number of iterations
2634e1ded407SBarry Smith (V-cycles) and tolerance that boomerAMG does EACH time it is called. So for example, if
2635e1ded407SBarry Smith `-pc_hypre_boomeramg_max_iter` is set to 2 then 2-V-cycles are being used to define the preconditioner
2636e1ded407SBarry Smith (`-pc_hypre_boomeramg_tol` should be set to 0.0 - the default - to strictly use a fixed number of
2637e1ded407SBarry Smith iterations per hypre call). `-ksp_max_it` and `-ksp_rtol` STILL determine the total number of iterations
2638e1ded407SBarry Smith and tolerance for the Krylov solver. For example, if `-pc_hypre_boomeramg_max_iter` is 2 and `-ksp_max_it` is 10
2639c3466c22SBarry Smith then AT MOST twenty V-cycles of BoomerAMG will be used.
264016d9e3a6SLisandro Dalcin
2641e1ded407SBarry Smith Note that the option `-pc_hypre_boomeramg_relax_type_all` defaults to symmetric relaxation
26420f1074feSSatish Balay (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry.
2643e1ded407SBarry Smith Otherwise, you may want to use `-pc_hypre_boomeramg_relax_type_all SOR/Jacobi`.
264416d9e3a6SLisandro Dalcin
2645c3466c22SBarry Smith If you provide a near null space to your matrix with `MatSetNearNullSpace()` it is ignored by hypre's BoomerAMG UNLESS you also use
2646e1ded407SBarry Smith the following two options: `-pc_hypre_boomeramg_nodal_coarsen <n> -pc_hypre_boomeramg_vec_interp_variant <v>`
26470b1a5bd9SEric Chamberland
2648f1580f4eSBarry Smith See `PCPFMG`, `PCSMG`, and `PCSYSPFMG` for access to hypre's other (nonalgebraic) multigrid solvers
2649f1580f4eSBarry Smith
2650e1ded407SBarry Smith For `PCHYPRE` type of `ams` or `ads` auxiliary data must be provided to the preconditioner with `PCHYPRESetDiscreteGradient()`,
2651f1580f4eSBarry Smith `PCHYPRESetDiscreteCurl()`, `PCHYPRESetInterpolations()`, `PCHYPRESetAlphaPoissonMatrix()`, `PCHYPRESetBetaPoissonMatrix()`, `PCHYPRESetEdgeConstantVectors()`,
265249567fc5SPierre Jolivet `PCHYPREAMSSetInteriorNodes()`
2653f1580f4eSBarry Smith
2654e1ded407SBarry Smith Sometimes people want to try algebraic multigrid as a "standalone" solver, that is not accelerating it with a Krylov method. Though we generally do not recommend this
2655e1ded407SBarry Smith since it is usually slower, one should use a `KSPType` of `KSPRICHARDSON`
2656e1ded407SBarry Smith (or equivalently `-ksp_type richardson`) to achieve this. Using `KSPPREONLY` will not work since it only applies a single cycle of multigrid.
2657e1ded407SBarry Smith
26588fc55d51SJunchao Zhang PETSc provides its own geometric and algebraic multigrid solvers `PCMG` and `PCGAMG`, also see `PCHMG` which is useful for certain multicomponent problems.
26598fc55d51SJunchao Zhang
26608fc55d51SJunchao Zhang hypre supports performance logging via the `Caliper` library. With `--download-hypre --download-caliper`, hypre will be automatically configured with the support.
26618fc55d51SJunchao Zhang
26628fc55d51SJunchao Zhang Enabling Caliper logging requires setting the `CALI_CONFIG` environment variable before running your hypre code. For example,
26638fc55d51SJunchao Zhang
26648fc55d51SJunchao Zhang .vb
26658fc55d51SJunchao Zhang export CALI_CONFIG=runtime-report,max_column_width=200,calc.inclusive,mpi-report,output=stdout
26668fc55d51SJunchao Zhang .ve
26678fc55d51SJunchao Zhang
26688fc55d51SJunchao Zhang Then run a hypre code, and you will see profiling results on stdout. See https://software.llnl.gov/Caliper/#guides for more options.
26699e5bc791SBarry Smith
2670ead8c081SBarry Smith GPU Notes:
2671ead8c081SBarry Smith To configure hypre BoomerAMG so that it can utilize NVIDIA GPUs run ./configure --download-hypre --with-cuda
2672f1580f4eSBarry Smith Then pass `VECCUDA` vectors and `MATAIJCUSPARSE` matrices to the solvers and PETSc will automatically utilize hypre's GPU solvers.
2673ead8c081SBarry Smith
2674ead8c081SBarry Smith To configure hypre BoomerAMG so that it can utilize AMD GPUs run ./configure --download-hypre --with-hip
2675f1580f4eSBarry Smith Then pass `VECHIP` vectors to the solvers and PETSc will automatically utilize hypre's GPU solvers.
2676ead8c081SBarry Smith
2677562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCreate()`, `PCSetType()`, `PCType`, `PC`, `PCHYPRESetType()`, `PCPFMG`, `PCGAMG`, `PCSYSPFMG`, `PCSMG`, `PCHYPRESetDiscreteGradient()`,
2678f1580f4eSBarry Smith `PCHYPRESetDiscreteCurl()`, `PCHYPRESetInterpolations()`, `PCHYPRESetAlphaPoissonMatrix()`, `PCHYPRESetBetaPoissonMatrix()`, `PCHYPRESetEdgeConstantVectors()`,
2679f1580f4eSBarry Smith PCHYPREAMSSetInteriorNodes()
268016d9e3a6SLisandro Dalcin M*/
268116d9e3a6SLisandro Dalcin
PCCreate_HYPRE(PC pc)2682d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc)
2683d71ae5a4SJacob Faibussowitsch {
268416d9e3a6SLisandro Dalcin PC_HYPRE *jac;
268516d9e3a6SLisandro Dalcin
268616d9e3a6SLisandro Dalcin PetscFunctionBegin;
26874dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&jac));
26882fa5cd67SKarl Rupp
268916d9e3a6SLisandro Dalcin pc->data = jac;
26908695de01SBarry Smith pc->ops->reset = PCReset_HYPRE;
269116d9e3a6SLisandro Dalcin pc->ops->destroy = PCDestroy_HYPRE;
269216d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE;
269316d9e3a6SLisandro Dalcin pc->ops->setup = PCSetUp_HYPRE;
269416d9e3a6SLisandro Dalcin pc->ops->apply = PCApply_HYPRE;
2695d7185485SAlex Lindsay jac->hypre_type = NULL;
269616d9e3a6SLisandro Dalcin jac->comm_hypre = MPI_COMM_NULL;
26979566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetType_C", PCHYPRESetType_HYPRE));
26989566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREGetType_C", PCHYPREGetType_HYPRE));
26999566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSetCoordinates_C", PCSetCoordinates_HYPRE));
27009566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteGradient_C", PCHYPRESetDiscreteGradient_HYPRE));
27019566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteCurl_C", PCHYPRESetDiscreteCurl_HYPRE));
27029566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetInterpolations_C", PCHYPRESetInterpolations_HYPRE));
27039566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetEdgeConstantVectors_C", PCHYPRESetEdgeConstantVectors_HYPRE));
2704be14dc20SKerry Key PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREAMSSetInteriorNodes_C", PCHYPREAMSSetInteriorNodes_HYPRE));
27059566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetPoissonMatrix_C", PCHYPRESetPoissonMatrix_HYPRE));
27069566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinSetMatProductAlgorithm_C", PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG));
27079566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinGetMatProductAlgorithm_C", PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG));
27086ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE)
27096ea7df73SStefano Zampini #if defined(HYPRE_USING_HIP)
27109566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_HIP));
27116ea7df73SStefano Zampini #endif
27126ea7df73SStefano Zampini #if defined(HYPRE_USING_CUDA)
27139566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_CUDA));
27146ea7df73SStefano Zampini #endif
27156ea7df73SStefano Zampini #endif
2716*5482091fSJunchao Zhang PetscCall(PetscHYPREInitialize());
27173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
271816d9e3a6SLisandro Dalcin }
2719ebc551c0SBarry Smith
2720ebc551c0SBarry Smith typedef struct {
272168326731SBarry Smith MPI_Comm hcomm; /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
2722f91d8e95SBarry Smith HYPRE_StructSolver hsolver;
27239e5bc791SBarry Smith
27249e5bc791SBarry Smith /* keep copy of PFMG options used so may view them */
27254ddd07fcSJed Brown PetscInt its;
272673dcfd97SStefano Zampini PetscReal tol;
27274ddd07fcSJed Brown PetscInt relax_type;
27284ddd07fcSJed Brown PetscInt rap_type;
27294ddd07fcSJed Brown PetscInt num_pre_relax, num_post_relax;
27304ddd07fcSJed Brown PetscInt max_levels;
27310be8cd64Sftrigaux PetscInt skip_relax;
27320be8cd64Sftrigaux PetscBool print_statistics;
2733ebc551c0SBarry Smith } PC_PFMG;
2734ebc551c0SBarry Smith
PCDestroy_PFMG(PC pc)2735ba38deedSJacob Faibussowitsch static PetscErrorCode PCDestroy_PFMG(PC pc)
2736d71ae5a4SJacob Faibussowitsch {
2737f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data;
2738ebc551c0SBarry Smith
2739ebc551c0SBarry Smith PetscFunctionBegin;
2740a333fa2bSZach Atkins if (ex->hsolver) PetscCallHYPRE(HYPRE_StructPFMGDestroy(ex->hsolver));
27419566063dSJacob Faibussowitsch PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &ex->hcomm));
27429566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data));
27433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2744ebc551c0SBarry Smith }
2745ebc551c0SBarry Smith
27469e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi", "Weighted-Jacobi", "symmetric-Red/Black-Gauss-Seidel", "Red/Black-Gauss-Seidel"};
27479e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin", "non-Galerkin"};
27489e5bc791SBarry Smith
PCView_PFMG(PC pc,PetscViewer viewer)2749ba38deedSJacob Faibussowitsch static PetscErrorCode PCView_PFMG(PC pc, PetscViewer viewer)
2750d71ae5a4SJacob Faibussowitsch {
27519f196a02SMartin Diehl PetscBool isascii;
2752f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data;
2753ebc551c0SBarry Smith
2754ebc551c0SBarry Smith PetscFunctionBegin;
27559f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
27569f196a02SMartin Diehl if (isascii) {
27579566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE PFMG preconditioning\n"));
275863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max iterations %" PetscInt_FMT "\n", ex->its));
27599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " tolerance %g\n", ex->tol));
27609566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relax type %s\n", PFMGRelaxType[ex->relax_type]));
27619566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " RAP type %s\n", PFMGRAPType[ex->rap_type]));
276263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n", ex->num_pre_relax, ex->num_post_relax));
276363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max levels %" PetscInt_FMT "\n", ex->max_levels));
27640be8cd64Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " skip relax %" PetscInt_FMT "\n", ex->skip_relax));
27659e5bc791SBarry Smith }
27663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2767ebc551c0SBarry Smith }
2768ebc551c0SBarry Smith
PCSetFromOptions_PFMG(PC pc,PetscOptionItems PetscOptionsObject)2769ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_PFMG(PC pc, PetscOptionItems PetscOptionsObject)
2770d71ae5a4SJacob Faibussowitsch {
2771f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data;
2772ebc551c0SBarry Smith
2773ebc551c0SBarry Smith PetscFunctionBegin;
2774d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "PFMG options");
27750be8cd64Sftrigaux PetscCall(PetscOptionsBool("-pc_pfmg_print_statistics", "Print statistics", "HYPRE_StructPFMGSetPrintLevel", ex->print_statistics, &ex->print_statistics, NULL));
27769566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_pfmg_its", "Number of iterations of PFMG to use as preconditioner", "HYPRE_StructPFMGSetMaxIter", ex->its, &ex->its, NULL));
2777f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetMaxIter(ex->hsolver, (HYPRE_Int)ex->its));
27789566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_pfmg_num_pre_relax", "Number of smoothing steps before coarse grid", "HYPRE_StructPFMGSetNumPreRelax", ex->num_pre_relax, &ex->num_pre_relax, NULL));
2779f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetNumPreRelax(ex->hsolver, (HYPRE_Int)ex->num_pre_relax));
27809566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_pfmg_num_post_relax", "Number of smoothing steps after coarse grid", "HYPRE_StructPFMGSetNumPostRelax", ex->num_post_relax, &ex->num_post_relax, NULL));
2781f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetNumPostRelax(ex->hsolver, (HYPRE_Int)ex->num_post_relax));
27829e5bc791SBarry Smith
27839566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_pfmg_max_levels", "Max Levels for MG hierarchy", "HYPRE_StructPFMGSetMaxLevels", ex->max_levels, &ex->max_levels, NULL));
2784f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetMaxLevels(ex->hsolver, (HYPRE_Int)ex->max_levels));
27853b46a515SGlenn Hammond
27869566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_pfmg_tol", "Tolerance of PFMG", "HYPRE_StructPFMGSetTol", ex->tol, &ex->tol, NULL));
2787a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetTol(ex->hsolver, ex->tol));
2788dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_pfmg_relax_type", "Relax type for the up and down cycles", "HYPRE_StructPFMGSetRelaxType", PFMGRelaxType, PETSC_STATIC_ARRAY_LENGTH(PFMGRelaxType), PFMGRelaxType[ex->relax_type], &ex->relax_type, NULL));
2789f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetRelaxType(ex->hsolver, (HYPRE_Int)ex->relax_type));
2790dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_pfmg_rap_type", "RAP type", "HYPRE_StructPFMGSetRAPType", PFMGRAPType, PETSC_STATIC_ARRAY_LENGTH(PFMGRAPType), PFMGRAPType[ex->rap_type], &ex->rap_type, NULL));
2791f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetRAPType(ex->hsolver, (HYPRE_Int)ex->rap_type));
27920be8cd64Sftrigaux PetscCall(PetscOptionsInt("-pc_pfmg_skip_relax", "Skip relaxation on certain grids for isotropic problems. This can greatly improve efficiency by eliminating unnecessary relaxations when the underlying problem is isotropic", "HYPRE_StructPFMGSetSkipRelax", ex->skip_relax, &ex->skip_relax, NULL));
2793f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetSkipRelax(ex->hsolver, (HYPRE_Int)ex->skip_relax));
2794d0609cedSBarry Smith PetscOptionsHeadEnd();
27953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2796ebc551c0SBarry Smith }
2797ebc551c0SBarry Smith
PCApply_PFMG(PC pc,Vec x,Vec y)2798ba38deedSJacob Faibussowitsch static PetscErrorCode PCApply_PFMG(PC pc, Vec x, Vec y)
2799d71ae5a4SJacob Faibussowitsch {
2800f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data;
2801d9ca1df4SBarry Smith PetscScalar *yy;
2802d9ca1df4SBarry Smith const PetscScalar *xx;
28034ddd07fcSJed Brown PetscInt ilower[3], iupper[3];
28042cf14000SStefano Zampini HYPRE_Int hlower[3], hupper[3];
2805f4f49eeaSPierre Jolivet Mat_HYPREStruct *mx = (Mat_HYPREStruct *)pc->pmat->data;
2806f91d8e95SBarry Smith
2807f91d8e95SBarry Smith PetscFunctionBegin;
28089566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite));
28099566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(mx->da, &ilower[0], &ilower[1], &ilower[2], &iupper[0], &iupper[1], &iupper[2]));
28102cf14000SStefano Zampini /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
2811f91d8e95SBarry Smith iupper[0] += ilower[0] - 1;
2812f91d8e95SBarry Smith iupper[1] += ilower[1] - 1;
2813f91d8e95SBarry Smith iupper[2] += ilower[2] - 1;
28142cf14000SStefano Zampini hlower[0] = (HYPRE_Int)ilower[0];
28152cf14000SStefano Zampini hlower[1] = (HYPRE_Int)ilower[1];
28162cf14000SStefano Zampini hlower[2] = (HYPRE_Int)ilower[2];
28172cf14000SStefano Zampini hupper[0] = (HYPRE_Int)iupper[0];
28182cf14000SStefano Zampini hupper[1] = (HYPRE_Int)iupper[1];
28192cf14000SStefano Zampini hupper[2] = (HYPRE_Int)iupper[2];
2820f91d8e95SBarry Smith
2821f91d8e95SBarry Smith /* copy x values over to hypre */
2822a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructVectorSetConstantValues(mx->hb, 0.0));
28239566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx));
2824a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructVectorSetBoxValues(mx->hb, hlower, hupper, (HYPRE_Complex *)xx));
28259566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx));
2826a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructVectorAssemble(mx->hb));
2827a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSolve(ex->hsolver, mx->hmat, mx->hb, mx->hx));
2828f91d8e95SBarry Smith
2829f91d8e95SBarry Smith /* copy solution values back to PETSc */
28309566063dSJacob Faibussowitsch PetscCall(VecGetArray(y, &yy));
2831a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructVectorGetBoxValues(mx->hx, hlower, hupper, (HYPRE_Complex *)yy));
28329566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y, &yy));
28333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2834f91d8e95SBarry Smith }
2835f91d8e95SBarry Smith
PCApplyRichardson_PFMG(PC pc,Vec b,Vec y,Vec w,PetscReal rtol,PetscReal abstol,PetscReal dtol,PetscInt its,PetscBool guesszero,PetscInt * outits,PCRichardsonConvergedReason * reason)2836d71ae5a4SJacob Faibussowitsch 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)
2837d71ae5a4SJacob Faibussowitsch {
28389e5bc791SBarry Smith PC_PFMG *jac = (PC_PFMG *)pc->data;
28392cf14000SStefano Zampini HYPRE_Int oits;
28409e5bc791SBarry Smith
28419e5bc791SBarry Smith PetscFunctionBegin;
28429566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite));
2843f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetMaxIter(jac->hsolver, (HYPRE_Int)(its * jac->its)));
2844a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetTol(jac->hsolver, rtol));
28459e5bc791SBarry Smith
28469566063dSJacob Faibussowitsch PetscCall(PCApply_PFMG(pc, b, y));
2847a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructPFMGGetNumIterations(jac->hsolver, &oits));
28489e5bc791SBarry Smith *outits = oits;
28499e5bc791SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
28509e5bc791SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL;
2851a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetTol(jac->hsolver, jac->tol));
2852f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetMaxIter(jac->hsolver, (HYPRE_Int)jac->its));
28533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
28549e5bc791SBarry Smith }
28559e5bc791SBarry Smith
PCSetUp_PFMG(PC pc)2856ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetUp_PFMG(PC pc)
2857d71ae5a4SJacob Faibussowitsch {
28583a32d3dbSGlenn Hammond PC_PFMG *ex = (PC_PFMG *)pc->data;
2859f4f49eeaSPierre Jolivet Mat_HYPREStruct *mx = (Mat_HYPREStruct *)pc->pmat->data;
2860ace3abfcSBarry Smith PetscBool flg;
28613a32d3dbSGlenn Hammond
28623a32d3dbSGlenn Hammond PetscFunctionBegin;
28639566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRESTRUCT, &flg));
286428b400f6SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Must use MATHYPRESTRUCT with this preconditioner");
28653a32d3dbSGlenn Hammond
28663a32d3dbSGlenn Hammond /* create the hypre solver object and set its information */
2867a333fa2bSZach Atkins if (ex->hsolver) PetscCallHYPRE(HYPRE_StructPFMGDestroy(ex->hsolver));
2868a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructPFMGCreate(ex->hcomm, &ex->hsolver));
28690be8cd64Sftrigaux
28700be8cd64Sftrigaux // Print Hypre statistics about the solve process
2871a333fa2bSZach Atkins if (ex->print_statistics) PetscCallHYPRE(HYPRE_StructPFMGSetPrintLevel(ex->hsolver, 3));
28720be8cd64Sftrigaux
28730be8cd64Sftrigaux // The hypre options must be repeated here because the StructPFMG was destroyed and recreated
2874f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetMaxIter(ex->hsolver, (HYPRE_Int)ex->its));
2875f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetNumPreRelax(ex->hsolver, (HYPRE_Int)ex->num_pre_relax));
2876f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetNumPostRelax(ex->hsolver, (HYPRE_Int)ex->num_post_relax));
2877f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetMaxLevels(ex->hsolver, (HYPRE_Int)ex->max_levels));
2878a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetTol(ex->hsolver, ex->tol));
2879f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetRelaxType(ex->hsolver, (HYPRE_Int)ex->relax_type));
2880f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetRAPType(ex->hsolver, (HYPRE_Int)ex->rap_type));
28810be8cd64Sftrigaux
2882a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetup(ex->hsolver, mx->hmat, mx->hb, mx->hx));
2883a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructPFMGSetZeroGuess(ex->hsolver));
28843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
28853a32d3dbSGlenn Hammond }
28863a32d3dbSGlenn Hammond
2887ebc551c0SBarry Smith /*MC
2888ebc551c0SBarry Smith PCPFMG - the hypre PFMG multigrid solver
2889ebc551c0SBarry Smith
2890f1580f4eSBarry Smith Options Database Keys:
289167b8a455SSatish Balay + -pc_pfmg_its <its> - number of iterations of PFMG to use as preconditioner
289267b8a455SSatish Balay . -pc_pfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid solve
289367b8a455SSatish Balay . -pc_pfmg_num_post_relax <steps> - number of smoothing steps after coarse grid solve
289467b8a455SSatish Balay . -pc_pfmg_tol <tol> - tolerance of PFMG
28959e5bc791SBarry 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
28960be8cd64Sftrigaux . -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin
2897f1580f4eSBarry Smith - -pc_pfmg_skip_relax - skip relaxation on certain grids for isotropic problems. This can greatly improve efficiency by eliminating unnecessary relaxations
2898f1580f4eSBarry Smith when the underlying problem is isotropic, one of 0,1
2899f1580f4eSBarry Smith
2900f1580f4eSBarry Smith Level: advanced
2901f91d8e95SBarry Smith
290295452b02SPatrick Sanan Notes:
290395452b02SPatrick Sanan This is for CELL-centered descretizations
29049e5bc791SBarry Smith
2905f1580f4eSBarry Smith See `PCSYSPFMG` for a version suitable for systems of PDEs, and `PCSMG`
29069e5bc791SBarry Smith
2907f1580f4eSBarry Smith See `PCHYPRE` for hypre's BoomerAMG algebraic multigrid solver
2908f1580f4eSBarry Smith
2909f1580f4eSBarry Smith This must be used with the `MATHYPRESTRUCT` matrix type.
2910f1580f4eSBarry Smith
2911f1580f4eSBarry Smith This provides only some of the functionality of PFMG, it supports only one block per process defined by a PETSc `DMDA`.
2912f1580f4eSBarry Smith
2913562efe2eSBarry Smith .seealso: [](ch_ksp), `PCMG`, `MATHYPRESTRUCT`, `PCHYPRE`, `PCGAMG`, `PCSYSPFMG`, `PCSMG`
2914ebc551c0SBarry Smith M*/
2915ebc551c0SBarry Smith
PCCreate_PFMG(PC pc)2916d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc)
2917d71ae5a4SJacob Faibussowitsch {
2918ebc551c0SBarry Smith PC_PFMG *ex;
2919ebc551c0SBarry Smith
2920ebc551c0SBarry Smith PetscFunctionBegin;
29219371c9d4SSatish Balay PetscCall(PetscNew(&ex));
292268326731SBarry Smith pc->data = ex;
2923ebc551c0SBarry Smith
29249e5bc791SBarry Smith ex->its = 1;
29259e5bc791SBarry Smith ex->tol = 1.e-8;
29269e5bc791SBarry Smith ex->relax_type = 1;
29279e5bc791SBarry Smith ex->rap_type = 0;
29289e5bc791SBarry Smith ex->num_pre_relax = 1;
29299e5bc791SBarry Smith ex->num_post_relax = 1;
29303b46a515SGlenn Hammond ex->max_levels = 0;
29310be8cd64Sftrigaux ex->skip_relax = 0;
29320be8cd64Sftrigaux ex->print_statistics = PETSC_FALSE;
29339e5bc791SBarry Smith
2934ebc551c0SBarry Smith pc->ops->setfromoptions = PCSetFromOptions_PFMG;
2935ebc551c0SBarry Smith pc->ops->view = PCView_PFMG;
2936ebc551c0SBarry Smith pc->ops->destroy = PCDestroy_PFMG;
2937f91d8e95SBarry Smith pc->ops->apply = PCApply_PFMG;
29389e5bc791SBarry Smith pc->ops->applyrichardson = PCApplyRichardson_PFMG;
293968326731SBarry Smith pc->ops->setup = PCSetUp_PFMG;
29402fa5cd67SKarl Rupp
29419566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &ex->hcomm));
2942*5482091fSJunchao Zhang PetscCall(PetscHYPREInitialize());
2943a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructPFMGCreate(ex->hcomm, &ex->hsolver));
29443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2945ebc551c0SBarry Smith }
2946d851a50bSGlenn Hammond
2947d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */
2948d851a50bSGlenn Hammond typedef struct {
2949d851a50bSGlenn Hammond MPI_Comm hcomm; /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */
2950d851a50bSGlenn Hammond HYPRE_SStructSolver ss_solver;
2951d851a50bSGlenn Hammond
2952d851a50bSGlenn Hammond /* keep copy of SYSPFMG options used so may view them */
29534ddd07fcSJed Brown PetscInt its;
295473dcfd97SStefano Zampini PetscReal tol;
29554ddd07fcSJed Brown PetscInt relax_type;
29564ddd07fcSJed Brown PetscInt num_pre_relax, num_post_relax;
2957d851a50bSGlenn Hammond } PC_SysPFMG;
2958d851a50bSGlenn Hammond
PCDestroy_SysPFMG(PC pc)2959ba38deedSJacob Faibussowitsch static PetscErrorCode PCDestroy_SysPFMG(PC pc)
2960d71ae5a4SJacob Faibussowitsch {
2961d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data;
2962d851a50bSGlenn Hammond
2963d851a50bSGlenn Hammond PetscFunctionBegin;
2964a333fa2bSZach Atkins if (ex->ss_solver) PetscCallHYPRE(HYPRE_SStructSysPFMGDestroy(ex->ss_solver));
29659566063dSJacob Faibussowitsch PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &ex->hcomm));
29669566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data));
29673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2968d851a50bSGlenn Hammond }
2969d851a50bSGlenn Hammond
2970d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi", "Red/Black-Gauss-Seidel"};
2971d851a50bSGlenn Hammond
PCView_SysPFMG(PC pc,PetscViewer viewer)2972ba38deedSJacob Faibussowitsch static PetscErrorCode PCView_SysPFMG(PC pc, PetscViewer viewer)
2973d71ae5a4SJacob Faibussowitsch {
29749f196a02SMartin Diehl PetscBool isascii;
2975d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data;
2976d851a50bSGlenn Hammond
2977d851a50bSGlenn Hammond PetscFunctionBegin;
29789f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
29799f196a02SMartin Diehl if (isascii) {
29809566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE SysPFMG preconditioning\n"));
298163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max iterations %" PetscInt_FMT "\n", ex->its));
29829566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " tolerance %g\n", ex->tol));
29839566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relax type %s\n", PFMGRelaxType[ex->relax_type]));
298463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n", ex->num_pre_relax, ex->num_post_relax));
2985d851a50bSGlenn Hammond }
29863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2987d851a50bSGlenn Hammond }
2988d851a50bSGlenn Hammond
PCSetFromOptions_SysPFMG(PC pc,PetscOptionItems PetscOptionsObject)2989ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_SysPFMG(PC pc, PetscOptionItems PetscOptionsObject)
2990d71ae5a4SJacob Faibussowitsch {
2991d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data;
2992ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE;
2993d851a50bSGlenn Hammond
2994d851a50bSGlenn Hammond PetscFunctionBegin;
2995d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "SysPFMG options");
29969566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_syspfmg_print_statistics", "Print statistics", "HYPRE_SStructSysPFMGSetPrintLevel", flg, &flg, NULL));
2997a333fa2bSZach Atkins if (flg) PetscCallHYPRE(HYPRE_SStructSysPFMGSetPrintLevel(ex->ss_solver, 3));
29989566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_syspfmg_its", "Number of iterations of SysPFMG to use as preconditioner", "HYPRE_SStructSysPFMGSetMaxIter", ex->its, &ex->its, NULL));
2999f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_SStructSysPFMGSetMaxIter(ex->ss_solver, (HYPRE_Int)ex->its));
30009566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_syspfmg_num_pre_relax", "Number of smoothing steps before coarse grid", "HYPRE_SStructSysPFMGSetNumPreRelax", ex->num_pre_relax, &ex->num_pre_relax, NULL));
3001f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_SStructSysPFMGSetNumPreRelax(ex->ss_solver, (HYPRE_Int)ex->num_pre_relax));
30029566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_syspfmg_num_post_relax", "Number of smoothing steps after coarse grid", "HYPRE_SStructSysPFMGSetNumPostRelax", ex->num_post_relax, &ex->num_post_relax, NULL));
3003f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_SStructSysPFMGSetNumPostRelax(ex->ss_solver, (HYPRE_Int)ex->num_post_relax));
3004d851a50bSGlenn Hammond
30059566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_syspfmg_tol", "Tolerance of SysPFMG", "HYPRE_SStructSysPFMGSetTol", ex->tol, &ex->tol, NULL));
3006a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_SStructSysPFMGSetTol(ex->ss_solver, ex->tol));
3007dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_syspfmg_relax_type", "Relax type for the up and down cycles", "HYPRE_SStructSysPFMGSetRelaxType", SysPFMGRelaxType, PETSC_STATIC_ARRAY_LENGTH(SysPFMGRelaxType), SysPFMGRelaxType[ex->relax_type], &ex->relax_type, NULL));
3008f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_SStructSysPFMGSetRelaxType(ex->ss_solver, (HYPRE_Int)ex->relax_type));
3009d0609cedSBarry Smith PetscOptionsHeadEnd();
30103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3011d851a50bSGlenn Hammond }
3012d851a50bSGlenn Hammond
PCApply_SysPFMG(PC pc,Vec x,Vec y)3013ba38deedSJacob Faibussowitsch static PetscErrorCode PCApply_SysPFMG(PC pc, Vec x, Vec y)
3014d71ae5a4SJacob Faibussowitsch {
3015d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data;
3016d9ca1df4SBarry Smith PetscScalar *yy;
3017d9ca1df4SBarry Smith const PetscScalar *xx;
30184ddd07fcSJed Brown PetscInt ilower[3], iupper[3];
30192cf14000SStefano Zampini HYPRE_Int hlower[3], hupper[3];
3020f4f49eeaSPierre Jolivet Mat_HYPRESStruct *mx = (Mat_HYPRESStruct *)pc->pmat->data;
30214ddd07fcSJed Brown PetscInt ordering = mx->dofs_order;
30224ddd07fcSJed Brown PetscInt nvars = mx->nvars;
3023f2f41e48SZach Atkins HYPRE_Int part = 0;
30244ddd07fcSJed Brown PetscInt size;
30254ddd07fcSJed Brown PetscInt i;
3026d851a50bSGlenn Hammond
3027d851a50bSGlenn Hammond PetscFunctionBegin;
30289566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite));
30299566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(mx->da, &ilower[0], &ilower[1], &ilower[2], &iupper[0], &iupper[1], &iupper[2]));
30302cf14000SStefano Zampini /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
3031d851a50bSGlenn Hammond iupper[0] += ilower[0] - 1;
3032d851a50bSGlenn Hammond iupper[1] += ilower[1] - 1;
3033d851a50bSGlenn Hammond iupper[2] += ilower[2] - 1;
30342cf14000SStefano Zampini hlower[0] = (HYPRE_Int)ilower[0];
30352cf14000SStefano Zampini hlower[1] = (HYPRE_Int)ilower[1];
30362cf14000SStefano Zampini hlower[2] = (HYPRE_Int)ilower[2];
30372cf14000SStefano Zampini hupper[0] = (HYPRE_Int)iupper[0];
30382cf14000SStefano Zampini hupper[1] = (HYPRE_Int)iupper[1];
30392cf14000SStefano Zampini hupper[2] = (HYPRE_Int)iupper[2];
3040d851a50bSGlenn Hammond
3041d851a50bSGlenn Hammond size = 1;
30422fa5cd67SKarl Rupp for (i = 0; i < 3; i++) size *= (iupper[i] - ilower[i] + 1);
30432fa5cd67SKarl Rupp
3044d851a50bSGlenn Hammond /* copy x values over to hypre for variable ordering */
3045d851a50bSGlenn Hammond if (ordering) {
3046a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_SStructVectorSetConstantValues(mx->ss_b, 0.0));
30479566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx));
3048f2f41e48SZach Atkins for (i = 0; i < nvars; i++) PetscCallHYPRE(HYPRE_SStructVectorSetBoxValues(mx->ss_b, part, hlower, hupper, (HYPRE_Int)i, (HYPRE_Complex *)(xx + (size * i))));
30499566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx));
3050a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_SStructVectorAssemble(mx->ss_b));
3051a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_SStructMatrixMatvec(1.0, mx->ss_mat, mx->ss_b, 0.0, mx->ss_x));
3052a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_SStructSysPFMGSolve(ex->ss_solver, mx->ss_mat, mx->ss_b, mx->ss_x));
3053d851a50bSGlenn Hammond
3054d851a50bSGlenn Hammond /* copy solution values back to PETSc */
30559566063dSJacob Faibussowitsch PetscCall(VecGetArray(y, &yy));
3056f2f41e48SZach Atkins for (i = 0; i < nvars; i++) PetscCallHYPRE(HYPRE_SStructVectorGetBoxValues(mx->ss_x, part, hlower, hupper, (HYPRE_Int)i, (HYPRE_Complex *)(yy + (size * i))));
30579566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y, &yy));
3058a65764d7SBarry Smith } else { /* nodal ordering must be mapped to variable ordering for sys_pfmg */
3059d851a50bSGlenn Hammond PetscScalar *z;
30604ddd07fcSJed Brown PetscInt j, k;
3061d851a50bSGlenn Hammond
30629566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvars * size, &z));
3063a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_SStructVectorSetConstantValues(mx->ss_b, 0.0));
30649566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx));
3065d851a50bSGlenn Hammond
3066d851a50bSGlenn Hammond /* transform nodal to hypre's variable ordering for sys_pfmg */
3067d851a50bSGlenn Hammond for (i = 0; i < size; i++) {
3068d851a50bSGlenn Hammond k = i * nvars;
30692fa5cd67SKarl Rupp for (j = 0; j < nvars; j++) z[j * size + i] = xx[k + j];
3070d851a50bSGlenn Hammond }
3071f2f41e48SZach Atkins for (i = 0; i < nvars; i++) PetscCallHYPRE(HYPRE_SStructVectorSetBoxValues(mx->ss_b, part, hlower, hupper, (HYPRE_Int)i, (HYPRE_Complex *)(z + (size * i))));
30729566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx));
3073a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_SStructVectorAssemble(mx->ss_b));
3074a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_SStructSysPFMGSolve(ex->ss_solver, mx->ss_mat, mx->ss_b, mx->ss_x));
3075d851a50bSGlenn Hammond
3076d851a50bSGlenn Hammond /* copy solution values back to PETSc */
30779566063dSJacob Faibussowitsch PetscCall(VecGetArray(y, &yy));
3078f2f41e48SZach Atkins for (i = 0; i < nvars; i++) PetscCallHYPRE(HYPRE_SStructVectorGetBoxValues(mx->ss_x, part, hlower, hupper, (HYPRE_Int)i, (HYPRE_Complex *)(z + (size * i))));
3079d851a50bSGlenn Hammond /* transform hypre's variable ordering for sys_pfmg to nodal ordering */
3080d851a50bSGlenn Hammond for (i = 0; i < size; i++) {
3081d851a50bSGlenn Hammond k = i * nvars;
30822fa5cd67SKarl Rupp for (j = 0; j < nvars; j++) yy[k + j] = z[j * size + i];
3083d851a50bSGlenn Hammond }
30849566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y, &yy));
30859566063dSJacob Faibussowitsch PetscCall(PetscFree(z));
3086d851a50bSGlenn Hammond }
30873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3088d851a50bSGlenn Hammond }
3089d851a50bSGlenn Hammond
PCApplyRichardson_SysPFMG(PC pc,Vec b,Vec y,Vec w,PetscReal rtol,PetscReal abstol,PetscReal dtol,PetscInt its,PetscBool guesszero,PetscInt * outits,PCRichardsonConvergedReason * reason)3090d71ae5a4SJacob Faibussowitsch 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)
3091d71ae5a4SJacob Faibussowitsch {
3092d851a50bSGlenn Hammond PC_SysPFMG *jac = (PC_SysPFMG *)pc->data;
30932cf14000SStefano Zampini HYPRE_Int oits;
3094d851a50bSGlenn Hammond
3095d851a50bSGlenn Hammond PetscFunctionBegin;
30969566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite));
3097f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_SStructSysPFMGSetMaxIter(jac->ss_solver, (HYPRE_Int)(its * jac->its)));
3098a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_SStructSysPFMGSetTol(jac->ss_solver, rtol));
30999566063dSJacob Faibussowitsch PetscCall(PCApply_SysPFMG(pc, b, y));
3100a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_SStructSysPFMGGetNumIterations(jac->ss_solver, &oits));
3101d851a50bSGlenn Hammond *outits = oits;
3102d851a50bSGlenn Hammond if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
3103d851a50bSGlenn Hammond else *reason = PCRICHARDSON_CONVERGED_RTOL;
3104a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_SStructSysPFMGSetTol(jac->ss_solver, jac->tol));
3105f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_SStructSysPFMGSetMaxIter(jac->ss_solver, (HYPRE_Int)jac->its));
31063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3107d851a50bSGlenn Hammond }
3108d851a50bSGlenn Hammond
PCSetUp_SysPFMG(PC pc)3109ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetUp_SysPFMG(PC pc)
3110d71ae5a4SJacob Faibussowitsch {
3111d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data;
3112f4f49eeaSPierre Jolivet Mat_HYPRESStruct *mx = (Mat_HYPRESStruct *)pc->pmat->data;
3113ace3abfcSBarry Smith PetscBool flg;
3114d851a50bSGlenn Hammond
3115d851a50bSGlenn Hammond PetscFunctionBegin;
31169566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRESSTRUCT, &flg));
311728b400f6SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Must use MATHYPRESSTRUCT with this preconditioner");
3118d851a50bSGlenn Hammond
3119d851a50bSGlenn Hammond /* create the hypre sstruct solver object and set its information */
3120a333fa2bSZach Atkins if (ex->ss_solver) PetscCallHYPRE(HYPRE_SStructSysPFMGDestroy(ex->ss_solver));
3121a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_SStructSysPFMGCreate(ex->hcomm, &ex->ss_solver));
3122a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_SStructSysPFMGSetZeroGuess(ex->ss_solver));
3123a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_SStructSysPFMGSetup(ex->ss_solver, mx->ss_mat, mx->ss_b, mx->ss_x));
31243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3125d851a50bSGlenn Hammond }
3126d851a50bSGlenn Hammond
3127d851a50bSGlenn Hammond /*MC
3128f1580f4eSBarry Smith PCSYSPFMG - the hypre SysPFMG multigrid solver
3129d851a50bSGlenn Hammond
3130d851a50bSGlenn Hammond Level: advanced
3131d851a50bSGlenn Hammond
3132f1580f4eSBarry Smith Options Database Keys:
313367b8a455SSatish Balay + -pc_syspfmg_its <its> - number of iterations of SysPFMG to use as preconditioner
313467b8a455SSatish Balay . -pc_syspfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid
313567b8a455SSatish Balay . -pc_syspfmg_num_post_relax <steps> - number of smoothing steps after coarse grid
313667b8a455SSatish Balay . -pc_syspfmg_tol <tol> - tolerance of SysPFMG
313767b8a455SSatish Balay - -pc_syspfmg_relax_type <Weighted-Jacobi,Red/Black-Gauss-Seidel> - relaxation type for the up and down cycles
3138d851a50bSGlenn Hammond
313995452b02SPatrick Sanan Notes:
3140f1580f4eSBarry Smith See `PCPFMG` for hypre's PFMG that works for a scalar PDE and `PCSMG`
3141f1580f4eSBarry Smith
3142f1580f4eSBarry Smith See `PCHYPRE` for hypre's BoomerAMG algebraic multigrid solver
3143f1580f4eSBarry Smith
314495452b02SPatrick Sanan This is for CELL-centered descretizations
3145d851a50bSGlenn Hammond
3146f1580f4eSBarry Smith This must be used with the `MATHYPRESSTRUCT` matrix type.
3147d851a50bSGlenn Hammond
3148f1580f4eSBarry Smith This does not give access to all the functionality of hypres SysPFMG, it supports only one part, and one block per process defined by a PETSc `DMDA`.
3149f1580f4eSBarry Smith
3150562efe2eSBarry Smith .seealso: [](ch_ksp), `PCMG`, `MATHYPRESSTRUCT`, `PCPFMG`, `PCHYPRE`, `PCGAMG`, `PCSMG`
3151d851a50bSGlenn Hammond M*/
3152d851a50bSGlenn Hammond
PCCreate_SysPFMG(PC pc)3153d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc)
3154d71ae5a4SJacob Faibussowitsch {
3155d851a50bSGlenn Hammond PC_SysPFMG *ex;
3156d851a50bSGlenn Hammond
3157d851a50bSGlenn Hammond PetscFunctionBegin;
31589371c9d4SSatish Balay PetscCall(PetscNew(&ex));
3159d851a50bSGlenn Hammond pc->data = ex;
3160d851a50bSGlenn Hammond
3161d851a50bSGlenn Hammond ex->its = 1;
3162d851a50bSGlenn Hammond ex->tol = 1.e-8;
3163d851a50bSGlenn Hammond ex->relax_type = 1;
3164d851a50bSGlenn Hammond ex->num_pre_relax = 1;
3165d851a50bSGlenn Hammond ex->num_post_relax = 1;
3166d851a50bSGlenn Hammond
3167d851a50bSGlenn Hammond pc->ops->setfromoptions = PCSetFromOptions_SysPFMG;
3168d851a50bSGlenn Hammond pc->ops->view = PCView_SysPFMG;
3169d851a50bSGlenn Hammond pc->ops->destroy = PCDestroy_SysPFMG;
3170d851a50bSGlenn Hammond pc->ops->apply = PCApply_SysPFMG;
3171d851a50bSGlenn Hammond pc->ops->applyrichardson = PCApplyRichardson_SysPFMG;
3172d851a50bSGlenn Hammond pc->ops->setup = PCSetUp_SysPFMG;
31732fa5cd67SKarl Rupp
31749566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &ex->hcomm));
3175*5482091fSJunchao Zhang PetscCall(PetscHYPREInitialize());
3176a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_SStructSysPFMGCreate(ex->hcomm, &ex->ss_solver));
31773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3178d851a50bSGlenn Hammond }
31791c188c59Sftrigaux
3180f1580f4eSBarry Smith /* PC SMG */
31811c188c59Sftrigaux typedef struct {
31821c188c59Sftrigaux MPI_Comm hcomm; /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */
31831c188c59Sftrigaux HYPRE_StructSolver hsolver;
31841c188c59Sftrigaux PetscInt its; /* keep copy of SMG options used so may view them */
318573dcfd97SStefano Zampini PetscReal tol;
31861c188c59Sftrigaux PetscBool print_statistics;
31871c188c59Sftrigaux PetscInt num_pre_relax, num_post_relax;
31881c188c59Sftrigaux } PC_SMG;
31891c188c59Sftrigaux
PCDestroy_SMG(PC pc)3190ba38deedSJacob Faibussowitsch static PetscErrorCode PCDestroy_SMG(PC pc)
3191d71ae5a4SJacob Faibussowitsch {
31921c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data;
31931c188c59Sftrigaux
31941c188c59Sftrigaux PetscFunctionBegin;
3195a333fa2bSZach Atkins if (ex->hsolver) PetscCallHYPRE(HYPRE_StructSMGDestroy(ex->hsolver));
31961c188c59Sftrigaux PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &ex->hcomm));
31971c188c59Sftrigaux PetscCall(PetscFree(pc->data));
31983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
31991c188c59Sftrigaux }
32001c188c59Sftrigaux
PCView_SMG(PC pc,PetscViewer viewer)3201ba38deedSJacob Faibussowitsch static PetscErrorCode PCView_SMG(PC pc, PetscViewer viewer)
3202d71ae5a4SJacob Faibussowitsch {
32039f196a02SMartin Diehl PetscBool isascii;
32041c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data;
32051c188c59Sftrigaux
32061c188c59Sftrigaux PetscFunctionBegin;
32079f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
32089f196a02SMartin Diehl if (isascii) {
32091c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE SMG preconditioning\n"));
32101c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " max iterations %" PetscInt_FMT "\n", ex->its));
32111c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " tolerance %g\n", ex->tol));
32121c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n", ex->num_pre_relax, ex->num_post_relax));
32131c188c59Sftrigaux }
32143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
32151c188c59Sftrigaux }
32161c188c59Sftrigaux
PCSetFromOptions_SMG(PC pc,PetscOptionItems PetscOptionsObject)3217ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_SMG(PC pc, PetscOptionItems PetscOptionsObject)
3218d71ae5a4SJacob Faibussowitsch {
32191c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data;
32201c188c59Sftrigaux
32211c188c59Sftrigaux PetscFunctionBegin;
32221c188c59Sftrigaux PetscOptionsHeadBegin(PetscOptionsObject, "SMG options");
32231c188c59Sftrigaux
32241c188c59Sftrigaux PetscCall(PetscOptionsInt("-pc_smg_its", "Number of iterations of SMG to use as preconditioner", "HYPRE_StructSMGSetMaxIter", ex->its, &ex->its, NULL));
32251c188c59Sftrigaux PetscCall(PetscOptionsInt("-pc_smg_num_pre_relax", "Number of smoothing steps before coarse grid", "HYPRE_StructSMGSetNumPreRelax", ex->num_pre_relax, &ex->num_pre_relax, NULL));
32261c188c59Sftrigaux PetscCall(PetscOptionsInt("-pc_smg_num_post_relax", "Number of smoothing steps after coarse grid", "HYPRE_StructSMGSetNumPostRelax", ex->num_post_relax, &ex->num_post_relax, NULL));
32271c188c59Sftrigaux PetscCall(PetscOptionsReal("-pc_smg_tol", "Tolerance of SMG", "HYPRE_StructSMGSetTol", ex->tol, &ex->tol, NULL));
32281c188c59Sftrigaux
32291c188c59Sftrigaux PetscOptionsHeadEnd();
32303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
32311c188c59Sftrigaux }
32321c188c59Sftrigaux
PCApply_SMG(PC pc,Vec x,Vec y)3233ba38deedSJacob Faibussowitsch static PetscErrorCode PCApply_SMG(PC pc, Vec x, Vec y)
3234d71ae5a4SJacob Faibussowitsch {
32351c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data;
32361c188c59Sftrigaux PetscScalar *yy;
32371c188c59Sftrigaux const PetscScalar *xx;
32381c188c59Sftrigaux PetscInt ilower[3], iupper[3];
32391c188c59Sftrigaux HYPRE_Int hlower[3], hupper[3];
3240f4f49eeaSPierre Jolivet Mat_HYPREStruct *mx = (Mat_HYPREStruct *)pc->pmat->data;
32411c188c59Sftrigaux
32421c188c59Sftrigaux PetscFunctionBegin;
32431c188c59Sftrigaux PetscCall(PetscCitationsRegister(hypreCitation, &cite));
32441c188c59Sftrigaux PetscCall(DMDAGetCorners(mx->da, &ilower[0], &ilower[1], &ilower[2], &iupper[0], &iupper[1], &iupper[2]));
32451c188c59Sftrigaux /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */
32461c188c59Sftrigaux iupper[0] += ilower[0] - 1;
32471c188c59Sftrigaux iupper[1] += ilower[1] - 1;
32481c188c59Sftrigaux iupper[2] += ilower[2] - 1;
32491c188c59Sftrigaux hlower[0] = (HYPRE_Int)ilower[0];
32501c188c59Sftrigaux hlower[1] = (HYPRE_Int)ilower[1];
32511c188c59Sftrigaux hlower[2] = (HYPRE_Int)ilower[2];
32521c188c59Sftrigaux hupper[0] = (HYPRE_Int)iupper[0];
32531c188c59Sftrigaux hupper[1] = (HYPRE_Int)iupper[1];
32541c188c59Sftrigaux hupper[2] = (HYPRE_Int)iupper[2];
32551c188c59Sftrigaux
32561c188c59Sftrigaux /* copy x values over to hypre */
3257a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructVectorSetConstantValues(mx->hb, 0.0));
32581c188c59Sftrigaux PetscCall(VecGetArrayRead(x, &xx));
3259a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructVectorSetBoxValues(mx->hb, hlower, hupper, (HYPRE_Complex *)xx));
32601c188c59Sftrigaux PetscCall(VecRestoreArrayRead(x, &xx));
3261a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructVectorAssemble(mx->hb));
3262a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructSMGSolve(ex->hsolver, mx->hmat, mx->hb, mx->hx));
32631c188c59Sftrigaux
32641c188c59Sftrigaux /* copy solution values back to PETSc */
32651c188c59Sftrigaux PetscCall(VecGetArray(y, &yy));
3266a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructVectorGetBoxValues(mx->hx, hlower, hupper, (HYPRE_Complex *)yy));
32671c188c59Sftrigaux PetscCall(VecRestoreArray(y, &yy));
32683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
32691c188c59Sftrigaux }
32701c188c59Sftrigaux
PCApplyRichardson_SMG(PC pc,Vec b,Vec y,Vec w,PetscReal rtol,PetscReal abstol,PetscReal dtol,PetscInt its,PetscBool guesszero,PetscInt * outits,PCRichardsonConvergedReason * reason)3271d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApplyRichardson_SMG(PC pc, Vec b, Vec y, Vec w, PetscReal rtol, PetscReal abstol, PetscReal dtol, PetscInt its, PetscBool guesszero, PetscInt *outits, PCRichardsonConvergedReason *reason)
3272d71ae5a4SJacob Faibussowitsch {
32731c188c59Sftrigaux PC_SMG *jac = (PC_SMG *)pc->data;
32741c188c59Sftrigaux HYPRE_Int oits;
32751c188c59Sftrigaux
32761c188c59Sftrigaux PetscFunctionBegin;
32771c188c59Sftrigaux PetscCall(PetscCitationsRegister(hypreCitation, &cite));
3278f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructSMGSetMaxIter(jac->hsolver, (HYPRE_Int)(its * jac->its)));
3279a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructSMGSetTol(jac->hsolver, rtol));
32801c188c59Sftrigaux
32811c188c59Sftrigaux PetscCall(PCApply_SMG(pc, b, y));
3282a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructSMGGetNumIterations(jac->hsolver, &oits));
32831c188c59Sftrigaux *outits = oits;
32841c188c59Sftrigaux if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS;
32851c188c59Sftrigaux else *reason = PCRICHARDSON_CONVERGED_RTOL;
3286a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructSMGSetTol(jac->hsolver, jac->tol));
3287f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructSMGSetMaxIter(jac->hsolver, (HYPRE_Int)jac->its));
32883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
32891c188c59Sftrigaux }
32901c188c59Sftrigaux
PCSetUp_SMG(PC pc)3291ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetUp_SMG(PC pc)
3292d71ae5a4SJacob Faibussowitsch {
32931c188c59Sftrigaux PetscInt i, dim;
32941c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data;
3295f4f49eeaSPierre Jolivet Mat_HYPREStruct *mx = (Mat_HYPREStruct *)pc->pmat->data;
32961c188c59Sftrigaux PetscBool flg;
32971c188c59Sftrigaux DMBoundaryType p[3];
32981c188c59Sftrigaux PetscInt M[3];
32991c188c59Sftrigaux
33001c188c59Sftrigaux PetscFunctionBegin;
33011c188c59Sftrigaux PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRESTRUCT, &flg));
33021c188c59Sftrigaux PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Must use MATHYPRESTRUCT with this preconditioner");
33031c188c59Sftrigaux
33041c188c59Sftrigaux PetscCall(DMDAGetInfo(mx->da, &dim, &M[0], &M[1], &M[2], 0, 0, 0, 0, 0, &p[0], &p[1], &p[2], 0));
33051c188c59Sftrigaux // Check if power of 2 in periodic directions
33061c188c59Sftrigaux for (i = 0; i < dim; i++) {
3307966bd95aSPierre Jolivet PetscCheck((M[i] & (M[i] - 1)) == 0 || p[i] != DM_BOUNDARY_PERIODIC, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "With SMG, the number of points in a periodic direction must be a power of 2, but is here %" PetscInt_FMT ".", M[i]);
33081c188c59Sftrigaux }
33091c188c59Sftrigaux
33101c188c59Sftrigaux /* create the hypre solver object and set its information */
3311a333fa2bSZach Atkins if (ex->hsolver) PetscCallHYPRE(HYPRE_StructSMGDestroy(ex->hsolver));
3312a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructSMGCreate(ex->hcomm, &ex->hsolver));
33131c188c59Sftrigaux // The hypre options must be set here and not in SetFromOptions because it is created here!
3314f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructSMGSetMaxIter(ex->hsolver, (HYPRE_Int)ex->its));
3315f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructSMGSetNumPreRelax(ex->hsolver, (HYPRE_Int)ex->num_pre_relax));
3316f2f41e48SZach Atkins PetscCallHYPRE(HYPRE_StructSMGSetNumPostRelax(ex->hsolver, (HYPRE_Int)ex->num_post_relax));
3317a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructSMGSetTol(ex->hsolver, ex->tol));
33181c188c59Sftrigaux
3319a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructSMGSetup(ex->hsolver, mx->hmat, mx->hb, mx->hx));
3320a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructSMGSetZeroGuess(ex->hsolver));
33213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
33221c188c59Sftrigaux }
33231c188c59Sftrigaux
33241c188c59Sftrigaux /*MC
33255cb80ecdSBarry Smith PCSMG - the hypre (structured grid) SMG multigrid solver
33261c188c59Sftrigaux
33271c188c59Sftrigaux Level: advanced
33281c188c59Sftrigaux
3329f1580f4eSBarry Smith Options Database Keys:
33305cb80ecdSBarry Smith + -pc_smg_its <its> - number of iterations of SMG to use as preconditioner
33315cb80ecdSBarry Smith . -pc_smg_num_pre_relax <steps> - number of smoothing steps before coarse grid
33325cb80ecdSBarry Smith . -pc_smg_num_post_relax <steps> - number of smoothing steps after coarse grid
33335cb80ecdSBarry Smith - -pc_smg_tol <tol> - tolerance of SMG
33341c188c59Sftrigaux
33351c188c59Sftrigaux Notes:
33361c188c59Sftrigaux This is for CELL-centered descretizations
33371c188c59Sftrigaux
33385cb80ecdSBarry Smith This must be used with the `MATHYPRESTRUCT` `MatType`.
33391c188c59Sftrigaux
3340f1580f4eSBarry Smith This does not provide all the functionality of hypre's SMG solver, it supports only one block per process defined by a PETSc `DMDA`.
3341f1580f4eSBarry Smith
3342f1580f4eSBarry Smith See `PCSYSPFMG`, `PCSMG`, `PCPFMG`, and `PCHYPRE` for access to hypre's other preconditioners
3343f1580f4eSBarry Smith
3344f1580f4eSBarry Smith .seealso: `PCMG`, `MATHYPRESTRUCT`, `PCPFMG`, `PCSYSPFMG`, `PCHYPRE`, `PCGAMG`
33451c188c59Sftrigaux M*/
33461c188c59Sftrigaux
PCCreate_SMG(PC pc)3347d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_SMG(PC pc)
3348d71ae5a4SJacob Faibussowitsch {
33491c188c59Sftrigaux PC_SMG *ex;
33501c188c59Sftrigaux
33511c188c59Sftrigaux PetscFunctionBegin;
33529371c9d4SSatish Balay PetscCall(PetscNew(&ex));
33531c188c59Sftrigaux pc->data = ex;
33541c188c59Sftrigaux
33551c188c59Sftrigaux ex->its = 1;
33561c188c59Sftrigaux ex->tol = 1.e-8;
33571c188c59Sftrigaux ex->num_pre_relax = 1;
33581c188c59Sftrigaux ex->num_post_relax = 1;
33591c188c59Sftrigaux
33601c188c59Sftrigaux pc->ops->setfromoptions = PCSetFromOptions_SMG;
33611c188c59Sftrigaux pc->ops->view = PCView_SMG;
33621c188c59Sftrigaux pc->ops->destroy = PCDestroy_SMG;
33631c188c59Sftrigaux pc->ops->apply = PCApply_SMG;
33641c188c59Sftrigaux pc->ops->applyrichardson = PCApplyRichardson_SMG;
33651c188c59Sftrigaux pc->ops->setup = PCSetUp_SMG;
33661c188c59Sftrigaux
33671c188c59Sftrigaux PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &ex->hcomm));
3368*5482091fSJunchao Zhang PetscCall(PetscHYPREInitialize());
3369a333fa2bSZach Atkins PetscCallHYPRE(HYPRE_StructSMGCreate(ex->hcomm, &ex->hsolver));
33703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
33711c188c59Sftrigaux }
3372