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 */ 85d7185485SAlex Lindsay PetscObjectParameterDeclare(PetscBool, 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 */ 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 */ 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 */ 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 */ 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"}; 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 PetscBool flag; 263d7185485SAlex Lindsay 264d7185485SAlex Lindsay #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 265d7185485SAlex Lindsay PetscFunctionBegin; 266d7185485SAlex Lindsay if (jac->spgemm_type) { 267d7185485SAlex Lindsay PetscCall(PetscStrcmp(jac->spgemm_type, name, &flag)); 268d7185485SAlex Lindsay PetscCheck(flag, PetscObjectComm((PetscObject)pc), PETSC_ERR_ORDER, "PETSc support for resetting the HYPRE SpGEMM is not implemented"); 269d7185485SAlex Lindsay PetscFunctionReturn(PETSC_SUCCESS); 270d7185485SAlex Lindsay } else jac->spgemm_type = name; 271d7185485SAlex Lindsay 272d7185485SAlex Lindsay PetscCall(PetscStrcmp("cusparse", jac->spgemm_type, &flag)); 273d7185485SAlex Lindsay if (flag) { 274d7185485SAlex Lindsay PetscCallExternal(HYPRE_SetSpGemmUseCusparse, 1); 275d7185485SAlex Lindsay PetscFunctionReturn(PETSC_SUCCESS); 276d7185485SAlex Lindsay } 277d7185485SAlex Lindsay PetscCall(PetscStrcmp("hypre", jac->spgemm_type, &flag)); 278d7185485SAlex Lindsay if (flag) { 279d7185485SAlex Lindsay PetscCallExternal(HYPRE_SetSpGemmUseCusparse, 0); 280d7185485SAlex Lindsay PetscFunctionReturn(PETSC_SUCCESS); 281d7185485SAlex Lindsay } 282d7185485SAlex Lindsay jac->spgemm_type = NULL; 283d7185485SAlex Lindsay SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown HYPRE SpGEMM type %s; Choices are cusparse, hypre", name); 284d7185485SAlex Lindsay #endif 285d7185485SAlex Lindsay } 286d7185485SAlex Lindsay 287d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetUp_HYPRE(PC pc) 288d71ae5a4SJacob Faibussowitsch { 28916d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 29049a781f5SStefano Zampini Mat_HYPRE *hjac; 29116d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 29216d9e3a6SLisandro Dalcin HYPRE_ParVector bv, xv; 29349a781f5SStefano Zampini PetscBool ishypre; 29416d9e3a6SLisandro Dalcin 29516d9e3a6SLisandro Dalcin PetscFunctionBegin; 2960df1829cSStefano Zampini /* default type is boomerAMG */ 29748a46eb9SPierre Jolivet if (!jac->hypre_type) PetscCall(PCHYPRESetType(pc, "boomeramg")); 2985f5c5b43SBarry Smith 2990df1829cSStefano Zampini /* get hypre matrix */ 3000df1829cSStefano Zampini if (pc->flag == DIFFERENT_NONZERO_PATTERN) PetscCall(MatDestroy(&jac->hpmat)); 3019566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRE, &ishypre)); 30249a781f5SStefano Zampini if (!ishypre) { 303e6519f9fSJunchao Zhang #if defined(PETSC_HAVE_HYPRE_DEVICE) && PETSC_PKG_HYPRE_VERSION_LE(2, 30, 0) 3040df1829cSStefano Zampini /* Temporary fix since we do not support MAT_REUSE_MATRIX with HYPRE device */ 3050df1829cSStefano Zampini PetscBool iscuda, iship, iskokkos; 3060df1829cSStefano Zampini 3070df1829cSStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)pc->pmat, &iscuda, MATSEQAIJCUSPARSE, MATMPIAIJCUSPARSE, "")); 3080df1829cSStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)pc->pmat, &iship, MATSEQAIJHIPSPARSE, MATMPIAIJHIPSPARSE, "")); 3090df1829cSStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)pc->pmat, &iskokkos, MATSEQAIJKOKKOS, MATMPIAIJKOKKOS, "")); 3100df1829cSStefano Zampini if (iscuda || iship || iskokkos) PetscCall(MatDestroy(&jac->hpmat)); 3110df1829cSStefano Zampini #endif 3120df1829cSStefano Zampini PetscCall(MatConvert(pc->pmat, MATHYPRE, jac->hpmat ? MAT_REUSE_MATRIX : MAT_INITIAL_MATRIX, &jac->hpmat)); 31349a781f5SStefano Zampini } else { 3149566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)pc->pmat)); 3159566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->hpmat)); 31649a781f5SStefano Zampini jac->hpmat = pc->pmat; 31716d9e3a6SLisandro Dalcin } 3180df1829cSStefano Zampini 3196ea7df73SStefano Zampini /* allow debug */ 3209566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(jac->hpmat, NULL, "-pc_hypre_mat_view")); 321f4f49eeaSPierre Jolivet hjac = (Mat_HYPRE *)jac->hpmat->data; 3225f5c5b43SBarry Smith 32316d9e3a6SLisandro Dalcin /* special case for BoomerAMG */ 32416d9e3a6SLisandro Dalcin if (jac->setup == HYPRE_BoomerAMGSetup) { 3255272c319SBarry Smith MatNullSpace mnull; 3265272c319SBarry Smith PetscBool has_const; 32749a781f5SStefano Zampini PetscInt bs, nvec, i; 328d7185485SAlex Lindsay PetscMemType memtype; 3295272c319SBarry Smith const Vec *vecs; 3305272c319SBarry Smith 331d7185485SAlex Lindsay PetscCall(MatGetCurrentMemType(jac->hpmat, &memtype)); 332d7185485SAlex Lindsay if (PetscMemTypeDevice(memtype)) { 333d7185485SAlex Lindsay /* GPU defaults 334d7185485SAlex Lindsay From https://hypre.readthedocs.io/en/latest/solvers-boomeramg.html#gpu-supported-options 335d7185485SAlex Lindsay and /src/parcsr_ls/par_amg.c 336d7185485SAlex Lindsay First handle options which users have interfaces for changing */ 337d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, coarsentype, 8); 338d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, relaxorder, 0); 339d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, interptype, 6); 340d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, relaxtype[0], 18); 341d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, relaxtype[1], 18); 342d7185485SAlex Lindsay #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 343d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, spgemm_type, HYPRESpgemmTypes[0]); 344d7185485SAlex Lindsay #endif 345d7185485SAlex Lindsay #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0) 346d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, keeptranspose, PETSC_TRUE); 347d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, mod_rap2, 1); 348d7185485SAlex Lindsay #endif 349d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, agg_interptype, 7); 350d7185485SAlex Lindsay } else { 351d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, coarsentype, 6); 352d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, relaxorder, 1); 353d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, interptype, 0); 354d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, relaxtype[0], 6); 355d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, relaxtype[1], 6); /* Defaults to SYMMETRIC since in PETSc we are using a PC - most likely with CG */ 356d7185485SAlex Lindsay #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 357d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, spgemm_type, "hypre"); 358d7185485SAlex Lindsay #endif 359d7185485SAlex Lindsay #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0) 360d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, keeptranspose, PETSC_FALSE); 361d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, mod_rap2, 0); 362d7185485SAlex Lindsay #endif 363d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, agg_interptype, 4); 364d7185485SAlex Lindsay } 365d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, relaxtype[2], 9); /*G.E. */ 366d7185485SAlex Lindsay 367d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetCycleType, jac->hsolver, jac->cycletype); 368d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetMaxLevels, jac->hsolver, jac->maxlevels); 369d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, jac->maxiter); 370d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, jac->tol); 371d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetTruncFactor, jac->hsolver, jac->truncfactor); 372d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetStrongThreshold, jac->hsolver, jac->strongthreshold); 373d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetMaxRowSum, jac->hsolver, jac->maxrowsum); 374d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetMeasureType, jac->hsolver, jac->measuretype); 375d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetAggNumLevels, jac->hsolver, jac->agg_nl); 376d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetPMaxElmts, jac->hsolver, jac->pmax); 377d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetNumPaths, jac->hsolver, jac->agg_num_paths); 378d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps, jac->hsolver, jac->gridsweeps[0], 1); 379d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps, jac->hsolver, jac->gridsweeps[1], 2); 380d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps, jac->hsolver, jac->gridsweeps[2], 3); 381d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetMaxCoarseSize, jac->hsolver, jac->maxc); 382d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetMinCoarseSize, jac->hsolver, jac->minc); 383d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetCoarsenType, jac->hsolver, jac->coarsentype); 384d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetRelaxOrder, jac->hsolver, jac->relaxorder); 385d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetInterpType, jac->hsolver, jac->interptype); 386d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetRelaxType, jac->hsolver, jac->relaxtype[0]); 387d7185485SAlex Lindsay /* GPU */ 388d7185485SAlex Lindsay #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 389d7185485SAlex Lindsay PetscCall(PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(pc, jac->spgemm_type)); 390d7185485SAlex Lindsay #endif 391d7185485SAlex Lindsay #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0) 392d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetKeepTranspose, jac->hsolver, jac->keeptranspose ? 1 : 0); 393d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetRAP2, jac->hsolver, jac->rap2); 394d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetModuleRAP2, jac->hsolver, jac->mod_rap2); 395d7185485SAlex Lindsay #endif 396d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetAggInterpType, jac->hsolver, jac->agg_interptype); 397d7185485SAlex Lindsay 398d7185485SAlex Lindsay /* AIR */ 399d7185485SAlex Lindsay #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0) 400d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetRestriction, jac->hsolver, jac->Rtype); 401d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetStrongThresholdR, jac->hsolver, jac->Rstrongthreshold); 402d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetFilterThresholdR, jac->hsolver, jac->Rfilterthreshold); 403d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetADropTol, jac->hsolver, jac->Adroptol); 404d7185485SAlex Lindsay PetscCallExternal(HYPRE_BoomerAMGSetADropType, jac->hsolver, jac->Adroptype); 405d7185485SAlex Lindsay #endif 406d7185485SAlex Lindsay 4079566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(pc->pmat, &bs)); 408792fecdfSBarry Smith if (bs > 1) PetscCallExternal(HYPRE_BoomerAMGSetNumFunctions, jac->hsolver, bs); 4099566063dSJacob Faibussowitsch PetscCall(MatGetNearNullSpace(pc->mat, &mnull)); 4105272c319SBarry Smith if (mnull) { 4119566063dSJacob Faibussowitsch PetscCall(PCHYPREResetNearNullSpace_Private(pc)); 4129566063dSJacob Faibussowitsch PetscCall(MatNullSpaceGetVecs(mnull, &has_const, &nvec, &vecs)); 4139566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvec + 1, &jac->hmnull)); 4149566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvec + 1, &jac->phmnull)); 4155272c319SBarry Smith for (i = 0; i < nvec; i++) { 4169566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(vecs[i]->map, &jac->hmnull[i])); 4179566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(vecs[i], jac->hmnull[i])); 418792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->hmnull[i]->ij, (void **)&jac->phmnull[i]); 4195272c319SBarry Smith } 4205272c319SBarry Smith if (has_const) { 4219566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(pc->pmat, &jac->hmnull_constant, NULL)); 4229566063dSJacob Faibussowitsch PetscCall(VecSet(jac->hmnull_constant, 1)); 4239566063dSJacob Faibussowitsch PetscCall(VecNormalize(jac->hmnull_constant, NULL)); 4249566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(jac->hmnull_constant->map, &jac->hmnull[nvec])); 4259566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(jac->hmnull_constant, jac->hmnull[nvec])); 426792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->hmnull[nvec]->ij, (void **)&jac->phmnull[nvec]); 4275272c319SBarry Smith nvec++; 4285272c319SBarry Smith } 429792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpVectors, jac->hsolver, nvec, jac->phmnull); 4305272c319SBarry Smith jac->n_hmnull = nvec; 4315272c319SBarry Smith } 4324cb006feSStefano Zampini } 433863406b8SStefano Zampini 4344cb006feSStefano Zampini /* special case for AMS */ 4354cb006feSStefano Zampini if (jac->setup == HYPRE_AMSSetup) { 4365ac14e1cSStefano Zampini Mat_HYPRE *hm; 4375ac14e1cSStefano Zampini HYPRE_ParCSRMatrix parcsr; 438*966bd95aSPierre 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()"); 43948a46eb9SPierre Jolivet if (jac->dim) PetscCallExternal(HYPRE_AMSSetDimension, jac->hsolver, jac->dim); 4405ac14e1cSStefano Zampini if (jac->constants[0]) { 4415ac14e1cSStefano Zampini HYPRE_ParVector ozz, zoz, zzo = NULL; 442792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->constants[0]->ij, (void **)(&ozz)); 443792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, jac->constants[1]->ij, (void **)(&zoz)); 44448a46eb9SPierre Jolivet if (jac->constants[2]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->constants[2]->ij, (void **)(&zzo)); 445792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetEdgeConstantVectors, jac->hsolver, ozz, zoz, zzo); 4465ac14e1cSStefano Zampini } 4475ac14e1cSStefano Zampini if (jac->coords[0]) { 4485ac14e1cSStefano Zampini HYPRE_ParVector coords[3]; 4495ac14e1cSStefano Zampini coords[0] = NULL; 4505ac14e1cSStefano Zampini coords[1] = NULL; 4515ac14e1cSStefano Zampini coords[2] = NULL; 452792fecdfSBarry Smith if (jac->coords[0]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[0]->ij, (void **)(&coords[0])); 453792fecdfSBarry Smith if (jac->coords[1]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[1]->ij, (void **)(&coords[1])); 454792fecdfSBarry Smith if (jac->coords[2]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[2]->ij, (void **)(&coords[2])); 455792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetCoordinateVectors, jac->hsolver, coords[0], coords[1], coords[2]); 4565ac14e1cSStefano Zampini } 4575f80ce2aSJacob Faibussowitsch PetscCheck(jac->G, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE AMS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient"); 458f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->G->data; 459792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 460792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetDiscreteGradient, jac->hsolver, parcsr); 4615ac14e1cSStefano Zampini if (jac->alpha_Poisson) { 462f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->alpha_Poisson->data; 463792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 464792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaPoissonMatrix, jac->hsolver, parcsr); 4655ac14e1cSStefano Zampini } 4665ac14e1cSStefano Zampini if (jac->ams_beta_is_zero) { 467792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaPoissonMatrix, jac->hsolver, NULL); 4685ac14e1cSStefano Zampini } else if (jac->beta_Poisson) { 469f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->beta_Poisson->data; 470792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 471792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaPoissonMatrix, jac->hsolver, parcsr); 472be14dc20SKerry Key } else if (jac->ams_beta_is_zero_part) { 473be14dc20SKerry Key if (jac->interior) { 474be14dc20SKerry Key HYPRE_ParVector interior = NULL; 475be14dc20SKerry Key PetscCallExternal(HYPRE_IJVectorGetObject, jac->interior->ij, (void **)(&interior)); 476be14dc20SKerry Key PetscCallExternal(HYPRE_AMSSetInteriorNodes, jac->hsolver, interior); 477be14dc20SKerry Key } else { 478be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_FALSE; 479be14dc20SKerry Key } 4805ac14e1cSStefano Zampini } 4816bf688a0SCe Qin if (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1])) { 4826bf688a0SCe Qin PetscInt i; 4836bf688a0SCe Qin HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3]; 4846bf688a0SCe Qin if (jac->ND_PiFull) { 485f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->ND_PiFull->data; 486792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsrfull)); 4876bf688a0SCe Qin } else { 4886bf688a0SCe Qin nd_parcsrfull = NULL; 4896bf688a0SCe Qin } 4906bf688a0SCe Qin for (i = 0; i < 3; ++i) { 4916bf688a0SCe Qin if (jac->ND_Pi[i]) { 492f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->ND_Pi[i]->data; 493792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsr[i])); 4946bf688a0SCe Qin } else { 4956bf688a0SCe Qin nd_parcsr[i] = NULL; 4966bf688a0SCe Qin } 4976bf688a0SCe Qin } 498792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetInterpolations, jac->hsolver, nd_parcsrfull, nd_parcsr[0], nd_parcsr[1], nd_parcsr[2]); 4996bf688a0SCe Qin } 5004cb006feSStefano Zampini } 501863406b8SStefano Zampini /* special case for ADS */ 502863406b8SStefano Zampini if (jac->setup == HYPRE_ADSSetup) { 5035ac14e1cSStefano Zampini Mat_HYPRE *hm; 5045ac14e1cSStefano Zampini HYPRE_ParCSRMatrix parcsr; 5056bf688a0SCe 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])))) { 5066bf688a0SCe Qin SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE ADS preconditioner needs either the coordinate vectors via PCSetCoordinates() or the interpolation matrices via PCHYPRESetInterpolations"); 5079371c9d4SSatish 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"); 5085f80ce2aSJacob Faibussowitsch PetscCheck(jac->G, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE ADS preconditioner needs the discrete gradient operator via PCHYPRESetDiscreteGradient"); 5095f80ce2aSJacob Faibussowitsch PetscCheck(jac->C, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "HYPRE ADS preconditioner needs the discrete curl operator via PCHYPRESetDiscreteGradient"); 5105ac14e1cSStefano Zampini if (jac->coords[0]) { 5115ac14e1cSStefano Zampini HYPRE_ParVector coords[3]; 5125ac14e1cSStefano Zampini coords[0] = NULL; 5135ac14e1cSStefano Zampini coords[1] = NULL; 5145ac14e1cSStefano Zampini coords[2] = NULL; 515792fecdfSBarry Smith if (jac->coords[0]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[0]->ij, (void **)(&coords[0])); 516792fecdfSBarry Smith if (jac->coords[1]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[1]->ij, (void **)(&coords[1])); 517792fecdfSBarry Smith if (jac->coords[2]) PetscCallExternal(HYPRE_IJVectorGetObject, jac->coords[2]->ij, (void **)(&coords[2])); 518792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetCoordinateVectors, jac->hsolver, coords[0], coords[1], coords[2]); 5195ac14e1cSStefano Zampini } 520f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->G->data; 521792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 522792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetDiscreteGradient, jac->hsolver, parcsr); 523f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->C->data; 524792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&parcsr)); 525792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetDiscreteCurl, jac->hsolver, parcsr); 5266bf688a0SCe Qin if ((jac->RT_PiFull || (jac->RT_Pi[0] && jac->RT_Pi[1])) && (jac->ND_PiFull || (jac->ND_Pi[0] && jac->ND_Pi[1]))) { 5276bf688a0SCe Qin PetscInt i; 5286bf688a0SCe Qin HYPRE_ParCSRMatrix rt_parcsrfull, rt_parcsr[3]; 5296bf688a0SCe Qin HYPRE_ParCSRMatrix nd_parcsrfull, nd_parcsr[3]; 5306bf688a0SCe Qin if (jac->RT_PiFull) { 531f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->RT_PiFull->data; 532792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&rt_parcsrfull)); 5336bf688a0SCe Qin } else { 5346bf688a0SCe Qin rt_parcsrfull = NULL; 5356bf688a0SCe Qin } 5366bf688a0SCe Qin for (i = 0; i < 3; ++i) { 5376bf688a0SCe Qin if (jac->RT_Pi[i]) { 538f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->RT_Pi[i]->data; 539792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&rt_parcsr[i])); 5406bf688a0SCe Qin } else { 5416bf688a0SCe Qin rt_parcsr[i] = NULL; 5426bf688a0SCe Qin } 5436bf688a0SCe Qin } 5446bf688a0SCe Qin if (jac->ND_PiFull) { 545f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->ND_PiFull->data; 546792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsrfull)); 5476bf688a0SCe Qin } else { 5486bf688a0SCe Qin nd_parcsrfull = NULL; 5496bf688a0SCe Qin } 5506bf688a0SCe Qin for (i = 0; i < 3; ++i) { 5516bf688a0SCe Qin if (jac->ND_Pi[i]) { 552f4f49eeaSPierre Jolivet hm = (Mat_HYPRE *)jac->ND_Pi[i]->data; 553792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hm->ij, (void **)(&nd_parcsr[i])); 5546bf688a0SCe Qin } else { 5556bf688a0SCe Qin nd_parcsr[i] = NULL; 5566bf688a0SCe Qin } 5576bf688a0SCe Qin } 558792fecdfSBarry Smith PetscCallExternal(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]); 5596bf688a0SCe Qin } 560863406b8SStefano Zampini } 561792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&hmat); 562792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->b->ij, (void **)&bv); 563792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->x->ij, (void **)&xv); 56497c1e3cbSStefano Zampini PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 565792fecdfSBarry Smith PetscCallExternal(jac->setup, jac->hsolver, hmat, bv, xv); 56697c1e3cbSStefano Zampini PetscCall(PetscFPTrapPop()); 5673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 56816d9e3a6SLisandro Dalcin } 56916d9e3a6SLisandro Dalcin 570d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApply_HYPRE(PC pc, Vec b, Vec x) 571d71ae5a4SJacob Faibussowitsch { 57216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 573f4f49eeaSPierre Jolivet Mat_HYPRE *hjac = (Mat_HYPRE *)jac->hpmat->data; 57416d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 57516d9e3a6SLisandro Dalcin HYPRE_ParVector jbv, jxv; 57616d9e3a6SLisandro Dalcin 57716d9e3a6SLisandro Dalcin PetscFunctionBegin; 5789566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 5799566063dSJacob Faibussowitsch if (!jac->applyrichardson) PetscCall(VecSet(x, 0.0)); 5809566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hjac->b, b)); 5819566063dSJacob Faibussowitsch if (jac->applyrichardson) PetscCall(VecHYPRE_IJVectorPushVec(hjac->x, x)); 5829566063dSJacob Faibussowitsch else PetscCall(VecHYPRE_IJVectorPushVecWrite(hjac->x, x)); 583792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&hmat); 584792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->b->ij, (void **)&jbv); 585792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->x->ij, (void **)&jxv); 5869371c9d4SSatish Balay PetscStackCallExternalVoid( 5879371c9d4SSatish Balay "Hypre solve", do { 5885f80ce2aSJacob Faibussowitsch HYPRE_Int hierr = (*jac->solve)(jac->hsolver, hmat, jbv, jxv); 5895f80ce2aSJacob Faibussowitsch if (hierr) { 5905f80ce2aSJacob Faibussowitsch PetscCheck(hierr == HYPRE_ERROR_CONV, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in HYPRE solver, error code %d", (int)hierr); 59185245615SPierre Jolivet HYPRE_ClearAllErrors(); 5925f80ce2aSJacob Faibussowitsch } 5935f80ce2aSJacob Faibussowitsch } while (0)); 59416d9e3a6SLisandro Dalcin 59548a46eb9SPierre Jolivet if (jac->setup == HYPRE_AMSSetup && jac->ams_beta_is_zero_part) PetscCallExternal(HYPRE_AMSProjectOutGradients, jac->hsolver, jxv); 5969566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->x)); 5979566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->b)); 5983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 59916d9e3a6SLisandro Dalcin } 60016d9e3a6SLisandro Dalcin 60185245615SPierre Jolivet static PetscErrorCode PCMatApply_HYPRE_BoomerAMG(PC pc, Mat B, Mat X) 60285245615SPierre Jolivet { 60385245615SPierre Jolivet PC_HYPRE *jac = (PC_HYPRE *)pc->data; 604f4f49eeaSPierre Jolivet Mat_HYPRE *hjac = (Mat_HYPRE *)jac->hpmat->data; 60585245615SPierre Jolivet hypre_ParCSRMatrix *par_matrix; 60685245615SPierre Jolivet HYPRE_ParVector hb, hx; 60785245615SPierre Jolivet const PetscScalar *b; 60885245615SPierre Jolivet PetscScalar *x; 60985245615SPierre Jolivet PetscInt m, N, lda; 61085245615SPierre Jolivet hypre_Vector *x_local; 61185245615SPierre Jolivet PetscMemType type; 61285245615SPierre Jolivet 61385245615SPierre Jolivet PetscFunctionBegin; 61485245615SPierre Jolivet PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 61585245615SPierre Jolivet PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&par_matrix); 61685245615SPierre Jolivet PetscCall(MatGetLocalSize(B, &m, NULL)); 61785245615SPierre Jolivet PetscCall(MatGetSize(B, NULL, &N)); 61885245615SPierre Jolivet PetscCallExternal(HYPRE_ParMultiVectorCreate, hypre_ParCSRMatrixComm(par_matrix), hypre_ParCSRMatrixGlobalNumRows(par_matrix), hypre_ParCSRMatrixRowStarts(par_matrix), N, &hb); 61985245615SPierre Jolivet PetscCallExternal(HYPRE_ParMultiVectorCreate, hypre_ParCSRMatrixComm(par_matrix), hypre_ParCSRMatrixGlobalNumRows(par_matrix), hypre_ParCSRMatrixRowStarts(par_matrix), N, &hx); 62085245615SPierre Jolivet PetscCall(MatZeroEntries(X)); 62185245615SPierre Jolivet PetscCall(MatDenseGetArrayReadAndMemType(B, &b, &type)); 62285245615SPierre Jolivet PetscCall(MatDenseGetLDA(B, &lda)); 62385245615SPierre 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); 62485245615SPierre Jolivet PetscCall(MatDenseGetLDA(X, &lda)); 62585245615SPierre 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); 62685245615SPierre Jolivet x_local = hypre_ParVectorLocalVector(hb); 62785245615SPierre Jolivet PetscCallExternal(hypre_SeqVectorSetDataOwner, x_local, 0); 62885245615SPierre Jolivet hypre_VectorData(x_local) = (HYPRE_Complex *)b; 62985245615SPierre Jolivet PetscCall(MatDenseGetArrayWriteAndMemType(X, &x, NULL)); 63085245615SPierre Jolivet x_local = hypre_ParVectorLocalVector(hx); 63185245615SPierre Jolivet PetscCallExternal(hypre_SeqVectorSetDataOwner, x_local, 0); 63285245615SPierre Jolivet hypre_VectorData(x_local) = (HYPRE_Complex *)x; 63385245615SPierre Jolivet PetscCallExternal(hypre_ParVectorInitialize_v2, hb, type == PETSC_MEMTYPE_HOST ? HYPRE_MEMORY_HOST : HYPRE_MEMORY_DEVICE); 63485245615SPierre Jolivet PetscCallExternal(hypre_ParVectorInitialize_v2, hx, type == PETSC_MEMTYPE_HOST ? HYPRE_MEMORY_HOST : HYPRE_MEMORY_DEVICE); 63585245615SPierre Jolivet PetscStackCallExternalVoid( 63685245615SPierre Jolivet "Hypre solve", do { 63785245615SPierre Jolivet HYPRE_Int hierr = (*jac->solve)(jac->hsolver, par_matrix, hb, hx); 63885245615SPierre Jolivet if (hierr) { 63985245615SPierre Jolivet PetscCheck(hierr == HYPRE_ERROR_CONV, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in HYPRE solver, error code %d", (int)hierr); 64085245615SPierre Jolivet HYPRE_ClearAllErrors(); 64185245615SPierre Jolivet } 64285245615SPierre Jolivet } while (0)); 64385245615SPierre Jolivet PetscCallExternal(HYPRE_ParVectorDestroy, hb); 64485245615SPierre Jolivet PetscCallExternal(HYPRE_ParVectorDestroy, hx); 64585245615SPierre Jolivet PetscCall(MatDenseRestoreArrayReadAndMemType(B, &b)); 64685245615SPierre Jolivet PetscCall(MatDenseRestoreArrayWriteAndMemType(X, &x)); 64785245615SPierre Jolivet PetscFunctionReturn(PETSC_SUCCESS); 64885245615SPierre Jolivet } 64985245615SPierre Jolivet 650d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCReset_HYPRE(PC pc) 651d71ae5a4SJacob Faibussowitsch { 6528695de01SBarry Smith PC_HYPRE *jac = (PC_HYPRE *)pc->data; 6538695de01SBarry Smith 6548695de01SBarry Smith PetscFunctionBegin; 6559566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->hpmat)); 6569566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 6579566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 6589566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 6599566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 6609566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_PiFull)); 6619566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[0])); 6629566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[1])); 6639566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[2])); 6649566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_PiFull)); 6659566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[0])); 6669566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[1])); 6679566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[2])); 6689566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[0])); 6699566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[1])); 6709566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[2])); 6719566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[0])); 6729566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[1])); 6739566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[2])); 674be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorDestroy(&jac->interior)); 6759566063dSJacob Faibussowitsch PetscCall(PCHYPREResetNearNullSpace_Private(pc)); 6765ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 677be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_FALSE; 6785ac14e1cSStefano Zampini jac->dim = 0; 6793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6808695de01SBarry Smith } 6818695de01SBarry Smith 682d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCDestroy_HYPRE(PC pc) 683d71ae5a4SJacob Faibussowitsch { 68416d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 68516d9e3a6SLisandro Dalcin 68616d9e3a6SLisandro Dalcin PetscFunctionBegin; 6879566063dSJacob Faibussowitsch PetscCall(PCReset_HYPRE(pc)); 688792fecdfSBarry Smith if (jac->destroy) PetscCallExternal(jac->destroy, jac->hsolver); 6899566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hypre_type)); 6909566063dSJacob Faibussowitsch if (jac->comm_hypre != MPI_COMM_NULL) PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 6919566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 69216d9e3a6SLisandro Dalcin 6939566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)pc, 0)); 6949566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetType_C", NULL)); 6959566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREGetType_C", NULL)); 6969566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteGradient_C", NULL)); 6979566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteCurl_C", NULL)); 6989566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetInterpolations_C", NULL)); 6999566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetConstantEdgeVectors_C", NULL)); 7009566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetPoissonMatrix_C", NULL)); 7012e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetEdgeConstantVectors_C", NULL)); 702be14dc20SKerry Key PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREAMSSetInteriorNodes_C", NULL)); 7039566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetInterpolations_C", NULL)); 7049566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetCoarseOperators_C", NULL)); 70542e5ec60SJeff-Hadley PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREGetCFMarkers_C", NULL)); 7069566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinSetMatProductAlgorithm_C", NULL)); 7079566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinGetMatProductAlgorithm_C", NULL)); 7082e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSetCoordinates_C", NULL)); 7093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 71016d9e3a6SLisandro Dalcin } 71116d9e3a6SLisandro Dalcin 712ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Pilut(PC pc, PetscOptionItems PetscOptionsObject) 713d71ae5a4SJacob Faibussowitsch { 71416d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 715ace3abfcSBarry Smith PetscBool flag; 71616d9e3a6SLisandro Dalcin 71716d9e3a6SLisandro Dalcin PetscFunctionBegin; 718d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE Pilut Options"); 7199566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_pilut_maxiter", "Number of iterations", "None", jac->maxiter, &jac->maxiter, &flag)); 720792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetMaxIter, jac->hsolver, jac->maxiter); 7219566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_pilut_tol", "Drop tolerance", "None", jac->tol, &jac->tol, &flag)); 722792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetDropTolerance, jac->hsolver, jac->tol); 7239566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_pilut_factorrowsize", "FactorRowSize", "None", jac->factorrowsize, &jac->factorrowsize, &flag)); 724792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParCSRPilutSetFactorRowSize, jac->hsolver, jac->factorrowsize); 725d0609cedSBarry Smith PetscOptionsHeadEnd(); 7263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 72716d9e3a6SLisandro Dalcin } 72816d9e3a6SLisandro Dalcin 729d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_Pilut(PC pc, PetscViewer viewer) 730d71ae5a4SJacob Faibussowitsch { 73116d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 7329f196a02SMartin Diehl PetscBool isascii; 73316d9e3a6SLisandro Dalcin 73416d9e3a6SLisandro Dalcin PetscFunctionBegin; 7359f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 7369f196a02SMartin Diehl if (isascii) { 7379566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE Pilut preconditioning\n")); 73816d9e3a6SLisandro Dalcin if (jac->maxiter != PETSC_DEFAULT) { 73963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " maximum number of iterations %" PetscInt_FMT "\n", jac->maxiter)); 74016d9e3a6SLisandro Dalcin } else { 7419566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default maximum number of iterations \n")); 74216d9e3a6SLisandro Dalcin } 74316d9e3a6SLisandro Dalcin if (jac->tol != PETSC_DEFAULT) { 7449566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " drop tolerance %g\n", (double)jac->tol)); 74516d9e3a6SLisandro Dalcin } else { 7469566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default drop tolerance \n")); 74716d9e3a6SLisandro Dalcin } 74816d9e3a6SLisandro Dalcin if (jac->factorrowsize != PETSC_DEFAULT) { 74963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " factor row size %" PetscInt_FMT "\n", jac->factorrowsize)); 75016d9e3a6SLisandro Dalcin } else { 7519566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default factor row size \n")); 75216d9e3a6SLisandro Dalcin } 75316d9e3a6SLisandro Dalcin } 7543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 75516d9e3a6SLisandro Dalcin } 75616d9e3a6SLisandro Dalcin 7573c61a47dSLukas static const char *HYPREILUType[] = { 7583c61a47dSLukas "Block-Jacobi-ILUk", "Block-Jacobi-ILUT", "", "", "", "", "", "", "", "", /* 0-9 */ 7593c61a47dSLukas "GMRES-ILUk", "GMRES-ILUT", "", "", "", "", "", "", "", "", /* 10-19 */ 7603c61a47dSLukas "NSH-ILUk", "NSH-ILUT", "", "", "", "", "", "", "", "", /* 20-29 */ 7613c61a47dSLukas "RAS-ILUk", "RAS-ILUT", "", "", "", "", "", "", "", "", /* 30-39 */ 7623c61a47dSLukas "ddPQ-GMRES-ILUk", "ddPQ-GMRES-ILUT", "", "", "", "", "", "", "", "", /* 40-49 */ 7633c61a47dSLukas "GMRES-ILU0" /* 50 */ 7643c61a47dSLukas }; 7653c61a47dSLukas 7663c61a47dSLukas static const char *HYPREILUIterSetup[] = {"default", "async-in-place", "async-explicit", "sync-explicit", "semisync-explicit"}; 7673c61a47dSLukas 768ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ILU(PC pc, PetscOptionItems PetscOptionsObject) 7693c61a47dSLukas { 7703c61a47dSLukas PC_HYPRE *jac = (PC_HYPRE *)pc->data; 7713c61a47dSLukas PetscBool flg; 7723c61a47dSLukas PetscInt indx; 7733c61a47dSLukas PetscReal tmpdbl; 7743c61a47dSLukas PetscBool tmp_truth; 7753c61a47dSLukas 7763c61a47dSLukas PetscFunctionBegin; 7773c61a47dSLukas PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE ILU Options"); 7783c61a47dSLukas 7793c61a47dSLukas /* ILU: ILU Type */ 7803c61a47dSLukas PetscCall(PetscOptionsEList("-pc_hypre_ilu_type", "Choose ILU Type", "None", HYPREILUType, PETSC_STATIC_ARRAY_LENGTH(HYPREILUType), HYPREILUType[0], &indx, &flg)); 7813a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_ILUSetType, jac->hsolver, indx); 7823c61a47dSLukas 7833c61a47dSLukas /* ILU: ILU iterative setup type*/ 7843c61a47dSLukas PetscCall(PetscOptionsEList("-pc_hypre_ilu_iterative_setup_type", "Set ILU iterative setup type", "None", HYPREILUIterSetup, PETSC_STATIC_ARRAY_LENGTH(HYPREILUIterSetup), HYPREILUIterSetup[0], &indx, &flg)); 7853a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_ILUSetIterativeSetupType, jac->hsolver, indx); 7863c61a47dSLukas 7873c61a47dSLukas /* ILU: ILU iterative setup option*/ 7883c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_iterative_setup_option", "Set ILU iterative setup option", "None", 0, &indx, &flg)); 7893a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_ILUSetIterativeSetupOption, jac->hsolver, indx); 7903c61a47dSLukas 7913c61a47dSLukas /* ILU: ILU iterative setup maxiter */ 7923c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_iterative_setup_maxiter", "Set ILU iterative setup maximum iteration count", "None", 0, &indx, &flg)); 7933a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_ILUSetIterativeSetupMaxIter, jac->hsolver, indx); 7943c61a47dSLukas 7953c61a47dSLukas /* ILU: ILU iterative setup tolerance */ 7963c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_ilu_iterative_setup_tolerance", "Set ILU iterative setup tolerance", "None", 0, &tmpdbl, &flg)); 7973a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_ILUSetIterativeSetupTolerance, jac->hsolver, tmpdbl); 7983c61a47dSLukas 7993c61a47dSLukas /* ILU: ILU Print Level */ 8003c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_print_level", "Set ILU print level", "None", 0, &indx, &flg)); 8013a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_ILUSetPrintLevel, jac->hsolver, indx); 8023c61a47dSLukas 8033c61a47dSLukas /* ILU: Logging */ 8043c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_logging", "Set ILU logging level", "None", 0, &indx, &flg)); 8053a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_ILUSetLogging, jac->hsolver, indx); 8063c61a47dSLukas 8073c61a47dSLukas /* ILU: ILU Level */ 8083c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_level", "Set ILU level", "None", 0, &indx, &flg)); 8093a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_ILUSetLevelOfFill, jac->hsolver, indx); 8103c61a47dSLukas 8113c61a47dSLukas /* ILU: ILU Max NNZ per row */ 8123c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_max_nnz_per_row", "Set maximum NNZ per row", "None", 0, &indx, &flg)); 8133a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_ILUSetMaxNnzPerRow, jac->hsolver, indx); 8143c61a47dSLukas 8153c61a47dSLukas /* ILU: tolerance */ 8163c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_ilu_tol", "Tolerance for ILU", "None", 0, &tmpdbl, &flg)); 8173a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_ILUSetTol, jac->hsolver, tmpdbl); 8183c61a47dSLukas 8193c61a47dSLukas /* ILU: maximum iteration count */ 8203c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_maxiter", "Set ILU max iterations", "None", 0, &indx, &flg)); 8213a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_ILUSetMaxIter, jac->hsolver, indx); 8223c61a47dSLukas 8233c61a47dSLukas /* ILU: drop threshold */ 8243c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_ilu_drop_threshold", "Drop threshold for ILU", "None", 0, &tmpdbl, &flg)); 8253a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_ILUSetDropThreshold, jac->hsolver, tmpdbl); 8263c61a47dSLukas 8273c61a47dSLukas /* ILU: Triangular Solve */ 8283c61a47dSLukas PetscCall(PetscOptionsBool("-pc_hypre_ilu_tri_solve", "Enable triangular solve", "None", PETSC_FALSE, &tmp_truth, &flg)); 8293a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_ILUSetTriSolve, jac->hsolver, tmp_truth); 8303c61a47dSLukas 8313c61a47dSLukas /* ILU: Lower Jacobi iteration */ 8323c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_lower_jacobi_iters", "Set lower Jacobi iteration count", "None", 0, &indx, &flg)); 8333a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_ILUSetLowerJacobiIters, jac->hsolver, indx); 8343c61a47dSLukas 8353c61a47dSLukas /* ILU: Upper Jacobi iteration */ 8363c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_ilu_upper_jacobi_iters", "Set upper Jacobi iteration count", "None", 0, &indx, &flg)); 8373a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_ILUSetUpperJacobiIters, jac->hsolver, indx); 8383c61a47dSLukas 8393c61a47dSLukas /* ILU: local reordering */ 8403c61a47dSLukas PetscCall(PetscOptionsBool("-pc_hypre_ilu_local_reordering", "Enable local reordering", "None", PETSC_FALSE, &tmp_truth, &flg)); 8413a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_ILUSetLocalReordering, jac->hsolver, tmp_truth); 8423c61a47dSLukas 8433c61a47dSLukas PetscOptionsHeadEnd(); 8443c61a47dSLukas PetscFunctionReturn(PETSC_SUCCESS); 8453c61a47dSLukas } 8463c61a47dSLukas 8473c61a47dSLukas static PetscErrorCode PCView_HYPRE_ILU(PC pc, PetscViewer viewer) 8483c61a47dSLukas { 8493c61a47dSLukas PC_HYPRE *jac = (PC_HYPRE *)pc->data; 8503c61a47dSLukas hypre_ParILUData *ilu_data = (hypre_ParILUData *)jac->hsolver; 8519f196a02SMartin Diehl PetscBool isascii; 8523c61a47dSLukas PetscInt indx; 8533c61a47dSLukas PetscReal tmpdbl; 8543c61a47dSLukas PetscReal *tmpdbl3; 8553c61a47dSLukas 8563c61a47dSLukas PetscFunctionBegin; 8579f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 8589f196a02SMartin Diehl if (isascii) { 8593c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE ILU preconditioning\n")); 8603c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIluType", indx = hypre_ParILUDataIluType(ilu_data)); 8613c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU type %s (%" PetscInt_FMT ")\n", HYPREILUType[indx], indx)); 8623c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataLfil", indx = hypre_ParILUDataLfil(ilu_data)); 8633c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU level %" PetscInt_FMT "\n", indx)); 8643c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataMaxIter", indx = hypre_ParILUDataMaxIter(ilu_data)); 8653c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU max iterations %" PetscInt_FMT "\n", indx)); 8663c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataMaxRowNnz", indx = hypre_ParILUDataMaxRowNnz(ilu_data)); 8673c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU max NNZ per row %" PetscInt_FMT "\n", indx)); 8683c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataTriSolve", indx = hypre_ParILUDataTriSolve(ilu_data)); 8693c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU triangular solve %" PetscInt_FMT "\n", indx)); 8703c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataTol", tmpdbl = hypre_ParILUDataTol(ilu_data)); 8713c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU tolerance %e\n", tmpdbl)); 8723c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataDroptol", tmpdbl3 = hypre_ParILUDataDroptol(ilu_data)); 8733c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU drop tolerance %e / %e / %e\n", tmpdbl3[0], tmpdbl3[1], tmpdbl3[2])); 8743c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataReorderingType", indx = hypre_ParILUDataReorderingType(ilu_data)); 8753c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU local reordering %" PetscInt_FMT "\n", indx)); 8763c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataLowerJacobiIters", indx = hypre_ParILUDataLowerJacobiIters(ilu_data)); 8773c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU lower Jacobi iterations %" PetscInt_FMT "\n", indx)); 8783c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataUpperJacobiIters", indx = hypre_ParILUDataUpperJacobiIters(ilu_data)); 8793c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU upper Jacobi iterations %" PetscInt_FMT "\n", indx)); 8803c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataPrintLevel", indx = hypre_ParILUDataPrintLevel(ilu_data)); 8813c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU print level %" PetscInt_FMT "\n", indx)); 8823c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataLogging", indx = hypre_ParILUDataLogging(ilu_data)); 8833c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU logging level %" PetscInt_FMT "\n", indx)); 8843c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIterativeSetupType", indx = hypre_ParILUDataIterativeSetupType(ilu_data)); 8853c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup type %s (%" PetscInt_FMT ")\n", HYPREILUIterSetup[indx], indx)); 8863c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIterativeSetupOption", indx = hypre_ParILUDataIterativeSetupOption(ilu_data)); 8873c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup option %" PetscInt_FMT "\n", indx)); 8883c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIterativeSetupMaxIter", indx = hypre_ParILUDataIterativeSetupMaxIter(ilu_data)); 8893c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup max iterations %" PetscInt_FMT "\n", indx)); 8903c61a47dSLukas PetscStackCallExternalVoid("hypre_ParILUDataIterativeSetupTolerance", tmpdbl = hypre_ParILUDataIterativeSetupTolerance(ilu_data)); 8913c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup tolerance %e\n", tmpdbl)); 8923c61a47dSLukas } 8933c61a47dSLukas PetscFunctionReturn(PETSC_SUCCESS); 8943c61a47dSLukas } 8953c61a47dSLukas 896ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_Euclid(PC pc, PetscOptionItems PetscOptionsObject) 897d71ae5a4SJacob Faibussowitsch { 898db966c6cSHong Zhang PC_HYPRE *jac = (PC_HYPRE *)pc->data; 8998bf83915SBarry Smith PetscBool flag, eu_bj = jac->eu_bj ? PETSC_TRUE : PETSC_FALSE; 900db966c6cSHong Zhang 901db966c6cSHong Zhang PetscFunctionBegin; 902d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE Euclid Options"); 9039566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_euclid_level", "Factorization levels", "None", jac->eu_level, &jac->eu_level, &flag)); 904792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_EuclidSetLevel, jac->hsolver, jac->eu_level); 9058bf83915SBarry Smith 9069566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_euclid_droptolerance", "Drop tolerance for ILU(k) in Euclid", "None", jac->eu_droptolerance, &jac->eu_droptolerance, &flag)); 9078bf83915SBarry Smith if (flag) { 9088bf83915SBarry Smith PetscMPIInt size; 9098bf83915SBarry Smith 9109566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pc), &size)); 9117827d75bSBarry Smith PetscCheck(size == 1, PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "hypre's Euclid does not support a parallel drop tolerance"); 912792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidSetILUT, jac->hsolver, jac->eu_droptolerance); 9138bf83915SBarry Smith } 9148bf83915SBarry Smith 9159566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_euclid_bj", "Use Block Jacobi for ILU in Euclid", "None", eu_bj, &eu_bj, &flag)); 9168bf83915SBarry Smith if (flag) { 9178bf83915SBarry Smith jac->eu_bj = eu_bj ? 1 : 0; 918792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidSetBJ, jac->hsolver, jac->eu_bj); 9198bf83915SBarry Smith } 920d0609cedSBarry Smith PetscOptionsHeadEnd(); 9213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 922db966c6cSHong Zhang } 923db966c6cSHong Zhang 924d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_Euclid(PC pc, PetscViewer viewer) 925d71ae5a4SJacob Faibussowitsch { 926db966c6cSHong Zhang PC_HYPRE *jac = (PC_HYPRE *)pc->data; 9279f196a02SMartin Diehl PetscBool isascii; 928db966c6cSHong Zhang 929db966c6cSHong Zhang PetscFunctionBegin; 9309f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 9319f196a02SMartin Diehl if (isascii) { 9329566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE Euclid preconditioning\n")); 933db966c6cSHong Zhang if (jac->eu_level != PETSC_DEFAULT) { 93463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " factorization levels %" PetscInt_FMT "\n", jac->eu_level)); 935db966c6cSHong Zhang } else { 9369566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " default factorization levels \n")); 937db966c6cSHong Zhang } 9389566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " drop tolerance %g\n", (double)jac->eu_droptolerance)); 93963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " use Block-Jacobi? %" PetscInt_FMT "\n", jac->eu_bj)); 940db966c6cSHong Zhang } 9413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 942db966c6cSHong Zhang } 943db966c6cSHong Zhang 944d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApplyTranspose_HYPRE_BoomerAMG(PC pc, Vec b, Vec x) 945d71ae5a4SJacob Faibussowitsch { 94616d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 947f4f49eeaSPierre Jolivet Mat_HYPRE *hjac = (Mat_HYPRE *)jac->hpmat->data; 94816d9e3a6SLisandro Dalcin HYPRE_ParCSRMatrix hmat; 94916d9e3a6SLisandro Dalcin HYPRE_ParVector jbv, jxv; 95016d9e3a6SLisandro Dalcin 95116d9e3a6SLisandro Dalcin PetscFunctionBegin; 9529566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 9539566063dSJacob Faibussowitsch PetscCall(VecSet(x, 0.0)); 954af221044SPierre Jolivet PetscCall(VecHYPRE_IJVectorPushVecRead(hjac->b, b)); 955af221044SPierre Jolivet PetscCall(VecHYPRE_IJVectorPushVecWrite(hjac->x, x)); 95616d9e3a6SLisandro Dalcin 957792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hjac->ij, (void **)&hmat); 958792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->b->ij, (void **)&jbv); 959792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hjac->x->ij, (void **)&jxv); 96016d9e3a6SLisandro Dalcin 9619371c9d4SSatish Balay PetscStackCallExternalVoid( 9629371c9d4SSatish Balay "Hypre Transpose solve", do { 9635f80ce2aSJacob Faibussowitsch HYPRE_Int hierr = HYPRE_BoomerAMGSolveT(jac->hsolver, hmat, jbv, jxv); 9645f80ce2aSJacob Faibussowitsch if (hierr) { 96516d9e3a6SLisandro Dalcin /* error code of 1 in BoomerAMG merely means convergence not achieved */ 9665f80ce2aSJacob Faibussowitsch PetscCheck(hierr == 1, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in HYPRE solver, error code %d", (int)hierr); 96785245615SPierre Jolivet HYPRE_ClearAllErrors(); 9685f80ce2aSJacob Faibussowitsch } 9695f80ce2aSJacob Faibussowitsch } while (0)); 97016d9e3a6SLisandro Dalcin 9719566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->x)); 9729566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hjac->b)); 9733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 97416d9e3a6SLisandro Dalcin } 97516d9e3a6SLisandro Dalcin 976d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG(PC pc, const char *spgemm[]) 977d71ae5a4SJacob Faibussowitsch { 978db6f9c32SMark Adams PC_HYPRE *jac = (PC_HYPRE *)pc->data; 979db6f9c32SMark Adams 980db6f9c32SMark Adams PetscFunctionBegin; 981db6f9c32SMark Adams PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 982db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 983db6f9c32SMark Adams *spgemm = jac->spgemm_type; 984db6f9c32SMark Adams #endif 9853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 986db6f9c32SMark Adams } 987db6f9c32SMark Adams 98816d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGCycleType[] = {"", "V", "W"}; 9890f1074feSSatish Balay static const char *HYPREBoomerAMGCoarsenType[] = {"CLJP", "Ruge-Stueben", "", "modifiedRuge-Stueben", "", "", "Falgout", "", "PMIS", "", "HMIS"}; 99016d9e3a6SLisandro Dalcin static const char *HYPREBoomerAMGMeasureType[] = {"local", "global"}; 99165de4495SJed Brown /* The following corresponds to HYPRE_BoomerAMGSetRelaxType which has many missing numbers in the enum */ 9923c61a47dSLukas static const char *HYPREBoomerAMGSmoothType[] = {"ILU", "Schwarz-smoothers", "Pilut", "ParaSails", "Euclid"}; 9939371c9d4SSatish 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"}; 9949371c9d4SSatish 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"}; 995d7185485SAlex Lindsay 996ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_BoomerAMG(PC pc, PetscOptionItems PetscOptionsObject) 997d71ae5a4SJacob Faibussowitsch { 99816d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 99922e51d31SStefano Zampini PetscInt bs, n, indx, level; 1000ace3abfcSBarry Smith PetscBool flg, tmp_truth; 100173dcfd97SStefano Zampini PetscReal tmpdbl, twodbl[2]; 1002589dcaf0SStefano Zampini const char *symtlist[] = {"nonsymmetric", "SPD", "nonsymmetric,SPD"}; 100316d9e3a6SLisandro Dalcin 100416d9e3a6SLisandro Dalcin PetscFunctionBegin; 1005d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE BoomerAMG Options"); 10069566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_cycle_type", "Cycle type", "None", HYPREBoomerAMGCycleType + 1, 2, HYPREBoomerAMGCycleType[jac->cycletype], &indx, &flg)); 100716d9e3a6SLisandro Dalcin if (flg) { 10084336a9eeSBarry Smith jac->cycletype = indx + 1; 1009792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleType, jac->hsolver, jac->cycletype); 101016d9e3a6SLisandro Dalcin } 101152ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedInt("-pc_hypre_boomeramg_max_levels", "Number of levels (of grids) allowed", "None", jac->maxlevels, &jac->maxlevels, &flg, 2)); 101252ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMaxLevels, jac->hsolver, jac->maxlevels); 101352ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedInt("-pc_hypre_boomeramg_max_iter", "Maximum iterations used PER hypre call", "None", jac->maxiter, &jac->maxiter, &flg, 1)); 101452ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, jac->maxiter); 101552ce0ab5SPierre 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)); 101652ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, jac->tol); 101722e51d31SStefano Zampini bs = 1; 101848a46eb9SPierre Jolivet if (pc->pmat) PetscCall(MatGetBlockSize(pc->pmat, &bs)); 10199566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_numfunctions", "Number of functions", "HYPRE_BoomerAMGSetNumFunctions", bs, &bs, &flg)); 102048a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetNumFunctions, jac->hsolver, bs); 102116d9e3a6SLisandro Dalcin 102252ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedReal("-pc_hypre_boomeramg_truncfactor", "Truncation factor for interpolation (0=no truncation)", "None", jac->truncfactor, &jac->truncfactor, &flg, 0.0)); 102352ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetTruncFactor, jac->hsolver, jac->truncfactor); 102416d9e3a6SLisandro Dalcin 102552ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedInt("-pc_hypre_boomeramg_P_max", "Max elements per row for interpolation operator (0=unlimited)", "None", jac->pmax, &jac->pmax, &flg, 0)); 102652ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetPMaxElmts, jac->hsolver, jac->pmax); 10270f1074feSSatish Balay 10289566063dSJacob 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)); 1029792fecdfSBarry Smith if (flg) PetscCallExternal(HYPRE_BoomerAMGSetAggNumLevels, jac->hsolver, jac->agg_nl); 10300f1074feSSatish Balay 103152ce0ab5SPierre 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)); 103252ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetNumPaths, jac->hsolver, jac->agg_num_paths); 10330f1074feSSatish Balay 103452ce0ab5SPierre Jolivet PetscCall(PetscOptionsBoundedReal("-pc_hypre_boomeramg_strong_threshold", "Threshold for being strongly connected", "None", jac->strongthreshold, &jac->strongthreshold, &flg, 0.0)); 103552ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetStrongThreshold, jac->hsolver, jac->strongthreshold); 103652ce0ab5SPierre Jolivet PetscCall(PetscOptionsRangeReal("-pc_hypre_boomeramg_max_row_sum", "Maximum row sum", "None", jac->maxrowsum, &jac->maxrowsum, &flg, 0.0, 1.0)); 103752ce0ab5SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMaxRowSum, jac->hsolver, jac->maxrowsum); 103816d9e3a6SLisandro Dalcin 103916d9e3a6SLisandro Dalcin /* Grid sweeps */ 10409566063dSJacob 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)); 104116d9e3a6SLisandro Dalcin if (flg) { 104216d9e3a6SLisandro Dalcin /* modify the jac structure so we can view the updated options with PC_View */ 104316d9e3a6SLisandro Dalcin jac->gridsweeps[0] = indx; 10440f1074feSSatish Balay jac->gridsweeps[1] = indx; 10450f1074feSSatish Balay /*defaults coarse to 1 */ 10460f1074feSSatish Balay jac->gridsweeps[2] = 1; 104716d9e3a6SLisandro Dalcin } 10489566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_nodal_coarsen", "Use a nodal based coarsening 1-6", "HYPRE_BoomerAMGSetNodal", jac->nodal_coarsening, &jac->nodal_coarsening, &flg)); 104948a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetNodal, jac->hsolver, jac->nodal_coarsening); 10509566063dSJacob 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)); 105148a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetNodalDiag, jac->hsolver, jac->nodal_coarsening_diag); 10529566063dSJacob 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)); 105348a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetInterpVecVariant, jac->hsolver, jac->vec_interp_variant); 10549566063dSJacob 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)); 105548a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetInterpVecQMax, jac->hsolver, jac->vec_interp_qmax); 10569566063dSJacob 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)); 105748a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetSmoothInterpVectors, jac->hsolver, jac->vec_interp_smooth); 10589566063dSJacob 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)); 105948a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetInterpRefine, jac->hsolver, jac->interp_refine); 10609566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_down", "Number of sweeps for the down cycles", "None", jac->gridsweeps[0], &indx, &flg)); 106116d9e3a6SLisandro Dalcin if (flg) { 1062792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps, jac->hsolver, indx, 1); 10630f1074feSSatish Balay jac->gridsweeps[0] = indx; 106416d9e3a6SLisandro Dalcin } 10659566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_up", "Number of sweeps for the up cycles", "None", jac->gridsweeps[1], &indx, &flg)); 106616d9e3a6SLisandro Dalcin if (flg) { 1067792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps, jac->hsolver, indx, 2); 10680f1074feSSatish Balay jac->gridsweeps[1] = indx; 106916d9e3a6SLisandro Dalcin } 10709566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_grid_sweeps_coarse", "Number of sweeps for the coarse level", "None", jac->gridsweeps[2], &indx, &flg)); 107116d9e3a6SLisandro Dalcin if (flg) { 1072792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleNumSweeps, jac->hsolver, indx, 3); 10730f1074feSSatish Balay jac->gridsweeps[2] = indx; 107416d9e3a6SLisandro Dalcin } 107516d9e3a6SLisandro Dalcin 10766a251517SEike Mueller /* Smooth type */ 1077dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_smooth_type", "Enable more complex smoothers", "None", HYPREBoomerAMGSmoothType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGSmoothType), HYPREBoomerAMGSmoothType[0], &indx, &flg)); 10786a251517SEike Mueller if (flg) { 10796a251517SEike Mueller jac->smoothtype = indx; 10803c61a47dSLukas PetscCallExternal(HYPRE_BoomerAMGSetSmoothType, jac->hsolver, indx + 5); 10818131ecf7SEike Mueller jac->smoothnumlevels = 25; 1082792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels, jac->hsolver, 25); 10838131ecf7SEike Mueller } 10848131ecf7SEike Mueller 10858131ecf7SEike Mueller /* Number of smoothing levels */ 10869566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_smooth_num_levels", "Number of levels on which more complex smoothers are used", "None", 25, &indx, &flg)); 10878131ecf7SEike Mueller if (flg && (jac->smoothtype != -1)) { 10888131ecf7SEike Mueller jac->smoothnumlevels = indx; 1089792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels, jac->hsolver, indx); 10906a251517SEike Mueller } 10916a251517SEike Mueller 10923c61a47dSLukas /* Smooth num sweeps */ 10933c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_smooth_num_sweeps", "Set number of smoother sweeps", "None", 1, &indx, &flg)); 10943c61a47dSLukas if (flg && indx > 0) { 10953c61a47dSLukas jac->smoothsweeps = indx; 10963c61a47dSLukas PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumSweeps, jac->hsolver, indx); 10973c61a47dSLukas } 10983c61a47dSLukas 10993c61a47dSLukas /* ILU: ILU Type */ 11003c61a47dSLukas PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_ilu_type", "Choose ILU Type", "None", HYPREILUType, PETSC_STATIC_ARRAY_LENGTH(HYPREILUType), HYPREILUType[0], &indx, &flg)); 11013a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetILUType, jac->hsolver, indx); 11023c61a47dSLukas 11033c61a47dSLukas /* ILU: ILU iterative setup type*/ 11043c61a47dSLukas 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)); 11053a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetILUIterSetupType, jac->hsolver, indx); 11063c61a47dSLukas 11073c61a47dSLukas /* ILU: ILU iterative setup option*/ 11083c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_iterative_setup_option", "Set ILU iterative setup option", "None", 0, &indx, &flg)); 11093a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetILUIterSetupOption, jac->hsolver, indx); 11103c61a47dSLukas 11113c61a47dSLukas /* ILU: ILU iterative setup maxiter */ 11123c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_iterative_setup_maxiter", "Set ILU iterative setup maximum iteration count", "None", 0, &indx, &flg)); 11133a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetILUIterSetupMaxIter, jac->hsolver, indx); 11143c61a47dSLukas 11153c61a47dSLukas /* ILU: ILU iterative setup tolerance */ 11163c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_ilu_iterative_setup_tolerance", "Set ILU iterative setup tolerance", "None", 0, &tmpdbl, &flg)); 11173a7d0413SPierre Jolivet if (flg) PetscCallExternal(hypre_BoomerAMGSetILUIterSetupTolerance, jac->hsolver, tmpdbl); 11183c61a47dSLukas 11193c61a47dSLukas /* ILU: ILU Print Level */ 11203c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_print_level", "Set ILU print level", "None", 0, &indx, &flg)); 11213a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetPrintLevel, jac->hsolver, indx); 11223c61a47dSLukas 11233c61a47dSLukas /* ILU: Logging */ 11243c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_logging", "Set ILU logging level", "None", 0, &indx, &flg)); 11253a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetLogging, jac->hsolver, indx); 11263c61a47dSLukas 11273c61a47dSLukas /* ILU: ILU Level */ 11283c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_level", "Set ILU level", "None", 0, &indx, &flg)); 11293a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetILULevel, jac->hsolver, indx); 11303c61a47dSLukas 11313c61a47dSLukas /* ILU: ILU Max NNZ per row */ 11323c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_max_nnz_per_row", "Set maximum NNZ per row", "None", 0, &indx, &flg)); 11333a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetILUMaxRowNnz, jac->hsolver, indx); 11343c61a47dSLukas 11353c61a47dSLukas /* ILU: maximum iteration count */ 11363c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_maxiter", "Set ILU max iterations", "None", 0, &indx, &flg)); 11373a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetILUMaxIter, jac->hsolver, indx); 11383c61a47dSLukas 11393c61a47dSLukas /* ILU: drop threshold */ 11403c61a47dSLukas PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_ilu_drop_tol", "Drop tolerance for ILU", "None", 0, &tmpdbl, &flg)); 11413a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetILUDroptol, jac->hsolver, tmpdbl); 11423c61a47dSLukas 11433c61a47dSLukas /* ILU: Triangular Solve */ 11443c61a47dSLukas PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_ilu_tri_solve", "Enable triangular solve", "None", PETSC_FALSE, &tmp_truth, &flg)); 11453a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetILUTriSolve, jac->hsolver, tmp_truth); 11463c61a47dSLukas 11473c61a47dSLukas /* ILU: Lower Jacobi iteration */ 11483c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_lower_jacobi_iters", "Set lower Jacobi iteration count", "None", 0, &indx, &flg)); 11493a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetILULowerJacobiIters, jac->hsolver, indx); 11503c61a47dSLukas 11513c61a47dSLukas /* ILU: Upper Jacobi iteration */ 11523c61a47dSLukas PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_ilu_upper_jacobi_iters", "Set upper Jacobi iteration count", "None", 0, &indx, &flg)); 11533a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetILUUpperJacobiIters, jac->hsolver, indx); 11543c61a47dSLukas 11553c61a47dSLukas /* ILU: local reordering */ 11563c61a47dSLukas PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_ilu_local_reordering", "Enable local reordering", "None", PETSC_FALSE, &tmp_truth, &flg)); 11573a7d0413SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetILULocalReordering, jac->hsolver, tmp_truth); 11583c61a47dSLukas 11591810e44eSEike Mueller /* Number of levels for ILU(k) for Euclid */ 11609566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_eu_level", "Number of levels for ILU(k) in Euclid smoother", "None", 0, &indx, &flg)); 11613c61a47dSLukas if (flg && (jac->smoothtype == 4)) { 11621810e44eSEike Mueller jac->eu_level = indx; 1163792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuLevel, jac->hsolver, indx); 11641810e44eSEike Mueller } 11651810e44eSEike Mueller 11661810e44eSEike Mueller /* Filter for ILU(k) for Euclid */ 116773dcfd97SStefano Zampini PetscReal droptolerance; 11689566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_eu_droptolerance", "Drop tolerance for ILU(k) in Euclid smoother", "None", 0, &droptolerance, &flg)); 11693c61a47dSLukas if (flg && (jac->smoothtype == 4)) { 11701810e44eSEike Mueller jac->eu_droptolerance = droptolerance; 1171792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuLevel, jac->hsolver, droptolerance); 11721810e44eSEike Mueller } 11731810e44eSEike Mueller 11741810e44eSEike Mueller /* Use Block Jacobi ILUT for Euclid */ 11759566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_eu_bj", "Use Block Jacobi for ILU in Euclid smoother?", "None", PETSC_FALSE, &tmp_truth, &flg)); 11763c61a47dSLukas if (flg && (jac->smoothtype == 4)) { 11771810e44eSEike Mueller jac->eu_bj = tmp_truth; 1178792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetEuBJ, jac->hsolver, jac->eu_bj); 11791810e44eSEike Mueller } 11801810e44eSEike Mueller 118116d9e3a6SLisandro Dalcin /* Relax type */ 1182dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_relax_type_all", "Relax type for the up and down cycles", "None", HYPREBoomerAMGRelaxType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGRelaxType), HYPREBoomerAMGRelaxType[6], &indx, &flg)); 118316d9e3a6SLisandro Dalcin if (flg) { 11840f1074feSSatish Balay jac->relaxtype[0] = jac->relaxtype[1] = indx; 1185792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxType, jac->hsolver, indx); 11860f1074feSSatish Balay /* by default, coarse type set to 9 */ 11870f1074feSSatish Balay jac->relaxtype[2] = 9; 1188792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, 9, 3); 118916d9e3a6SLisandro Dalcin } 1190dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_relax_type_down", "Relax type for the down cycles", "None", HYPREBoomerAMGRelaxType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGRelaxType), HYPREBoomerAMGRelaxType[6], &indx, &flg)); 119116d9e3a6SLisandro Dalcin if (flg) { 119216d9e3a6SLisandro Dalcin jac->relaxtype[0] = indx; 1193792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, indx, 1); 119416d9e3a6SLisandro Dalcin } 1195dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_relax_type_up", "Relax type for the up cycles", "None", HYPREBoomerAMGRelaxType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGRelaxType), HYPREBoomerAMGRelaxType[6], &indx, &flg)); 119616d9e3a6SLisandro Dalcin if (flg) { 11970f1074feSSatish Balay jac->relaxtype[1] = indx; 1198792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, indx, 2); 119916d9e3a6SLisandro Dalcin } 1200dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_relax_type_coarse", "Relax type on coarse grid", "None", HYPREBoomerAMGRelaxType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGRelaxType), HYPREBoomerAMGRelaxType[9], &indx, &flg)); 120116d9e3a6SLisandro Dalcin if (flg) { 12020f1074feSSatish Balay jac->relaxtype[2] = indx; 1203792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCycleRelaxType, jac->hsolver, indx, 3); 120416d9e3a6SLisandro Dalcin } 120516d9e3a6SLisandro Dalcin 120616d9e3a6SLisandro Dalcin /* Relaxation Weight */ 12079566063dSJacob 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)); 120816d9e3a6SLisandro Dalcin if (flg) { 1209792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxWt, jac->hsolver, tmpdbl); 121016d9e3a6SLisandro Dalcin jac->relaxweight = tmpdbl; 121116d9e3a6SLisandro Dalcin } 121216d9e3a6SLisandro Dalcin 121316d9e3a6SLisandro Dalcin n = 2; 121416d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 12159566063dSJacob Faibussowitsch PetscCall(PetscOptionsRealArray("-pc_hypre_boomeramg_relax_weight_level", "Set the relaxation weight for a particular level (weight,level)", "None", twodbl, &n, &flg)); 121616d9e3a6SLisandro Dalcin if (flg) { 12170fdf79fbSJacob 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); 121816d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 1219792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetLevelRelaxWt, jac->hsolver, twodbl[0], indx); 122016d9e3a6SLisandro Dalcin } 122116d9e3a6SLisandro Dalcin 122216d9e3a6SLisandro Dalcin /* Outer relaxation Weight */ 12239566063dSJacob 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)); 122416d9e3a6SLisandro Dalcin if (flg) { 1225792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetOuterWt, jac->hsolver, tmpdbl); 122616d9e3a6SLisandro Dalcin jac->outerrelaxweight = tmpdbl; 122716d9e3a6SLisandro Dalcin } 122816d9e3a6SLisandro Dalcin 122916d9e3a6SLisandro Dalcin n = 2; 123016d9e3a6SLisandro Dalcin twodbl[0] = twodbl[1] = 1.0; 12319566063dSJacob 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)); 123216d9e3a6SLisandro Dalcin if (flg) { 12330fdf79fbSJacob 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); 123416d9e3a6SLisandro Dalcin indx = (int)PetscAbsReal(twodbl[1]); 1235792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetLevelOuterWt, jac->hsolver, twodbl[0], indx); 123616d9e3a6SLisandro Dalcin } 123716d9e3a6SLisandro Dalcin 123816d9e3a6SLisandro Dalcin /* the Relax Order */ 12399566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_no_CF", "Do not use CF-relaxation", "None", PETSC_FALSE, &tmp_truth, &flg)); 124016d9e3a6SLisandro Dalcin 12418afaa268SBarry Smith if (flg && tmp_truth) { 124216d9e3a6SLisandro Dalcin jac->relaxorder = 0; 1243792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRelaxOrder, jac->hsolver, jac->relaxorder); 124416d9e3a6SLisandro Dalcin } 1245dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_measure_type", "Measure type", "None", HYPREBoomerAMGMeasureType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGMeasureType), HYPREBoomerAMGMeasureType[0], &indx, &flg)); 124616d9e3a6SLisandro Dalcin if (flg) { 124716d9e3a6SLisandro Dalcin jac->measuretype = indx; 1248792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMeasureType, jac->hsolver, jac->measuretype); 124916d9e3a6SLisandro Dalcin } 12500f1074feSSatish Balay /* update list length 3/07 */ 1251dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_coarsen_type", "Coarsen type", "None", HYPREBoomerAMGCoarsenType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGCoarsenType), HYPREBoomerAMGCoarsenType[6], &indx, &flg)); 125216d9e3a6SLisandro Dalcin if (flg) { 125316d9e3a6SLisandro Dalcin jac->coarsentype = indx; 1254792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetCoarsenType, jac->hsolver, jac->coarsentype); 125516d9e3a6SLisandro Dalcin } 12560f1074feSSatish Balay 12579566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_max_coarse_size", "Maximum size of coarsest grid", "None", jac->maxc, &jac->maxc, &flg)); 125848a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMaxCoarseSize, jac->hsolver, jac->maxc); 12599566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_min_coarse_size", "Minimum size of coarsest grid", "None", jac->minc, &jac->minc, &flg)); 126048a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_BoomerAMGSetMinCoarseSize, jac->hsolver, jac->minc); 1261db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 1262db6f9c32SMark Adams // global parameter but is closely associated with BoomerAMG 1263d7185485SAlex Lindsay 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), HYPRESpgemmTypes[0], &indx, &flg)); 1264d7185485SAlex Lindsay if (flg) PetscCall(PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG(pc, HYPRESpgemmTypes[indx])); 1265db6f9c32SMark Adams #endif 1266589dcaf0SStefano Zampini /* AIR */ 1267589dcaf0SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 18, 0) 12689566063dSJacob 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)); 1269792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetRestriction, jac->hsolver, jac->Rtype); 1270589dcaf0SStefano Zampini if (jac->Rtype) { 127119be502cSAlexander HYPRE_Int **grid_relax_points = hypre_TAlloc(HYPRE_Int *, 4, HYPRE_MEMORY_HOST); 127219be502cSAlexander char *prerelax[256]; 127319be502cSAlexander char *postrelax[256]; 127419be502cSAlexander char stringF[2] = "F", stringC[2] = "C", stringA[2] = "A"; 127519be502cSAlexander PetscInt ns_down = 256, ns_up = 256; 127619be502cSAlexander PetscBool matchF, matchC, matchA; 127719be502cSAlexander 1278589dcaf0SStefano 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 */ 1279589dcaf0SStefano Zampini 12809566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_strongthresholdR", "Threshold for R", "None", jac->Rstrongthreshold, &jac->Rstrongthreshold, NULL)); 1281792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetStrongThresholdR, jac->hsolver, jac->Rstrongthreshold); 1282589dcaf0SStefano Zampini 12839566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_boomeramg_filterthresholdR", "Filter threshold for R", "None", jac->Rfilterthreshold, &jac->Rfilterthreshold, NULL)); 1284792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetFilterThresholdR, jac->hsolver, jac->Rfilterthreshold); 1285589dcaf0SStefano Zampini 12869566063dSJacob 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)); 1287792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropTol, jac->hsolver, jac->Adroptol); 1288589dcaf0SStefano Zampini 12899566063dSJacob 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)); 1290792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetADropType, jac->hsolver, jac->Adroptype); 129119be502cSAlexander PetscCall(PetscOptionsStringArray("-pc_hypre_boomeramg_prerelax", "Defines prerelax scheme", "None", prerelax, &ns_down, NULL)); 129219be502cSAlexander PetscCall(PetscOptionsStringArray("-pc_hypre_boomeramg_postrelax", "Defines postrelax scheme", "None", postrelax, &ns_up, NULL)); 129319be502cSAlexander 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"); 129419be502cSAlexander 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"); 129519be502cSAlexander 129619be502cSAlexander grid_relax_points[0] = NULL; 129719be502cSAlexander grid_relax_points[1] = hypre_TAlloc(HYPRE_Int, ns_down, HYPRE_MEMORY_HOST); 129819be502cSAlexander grid_relax_points[2] = hypre_TAlloc(HYPRE_Int, ns_up, HYPRE_MEMORY_HOST); 129919be502cSAlexander grid_relax_points[3] = hypre_TAlloc(HYPRE_Int, jac->gridsweeps[2], HYPRE_MEMORY_HOST); 130019be502cSAlexander grid_relax_points[3][0] = 0; 130119be502cSAlexander 130219be502cSAlexander // set down relax scheme 130319be502cSAlexander for (PetscInt i = 0; i < ns_down; i++) { 130419be502cSAlexander PetscCall(PetscStrcasecmp(prerelax[i], stringF, &matchF)); 130519be502cSAlexander PetscCall(PetscStrcasecmp(prerelax[i], stringC, &matchC)); 130619be502cSAlexander PetscCall(PetscStrcasecmp(prerelax[i], stringA, &matchA)); 130719be502cSAlexander PetscCheck(matchF || matchC || matchA, PetscObjectComm((PetscObject)jac), PETSC_ERR_ARG_WRONG, "Valid argument options for -pc_hypre_boomeramg_prerelax are C, F, and A"); 130819be502cSAlexander if (matchF) grid_relax_points[1][i] = -1; 130919be502cSAlexander else if (matchC) grid_relax_points[1][i] = 1; 131019be502cSAlexander else if (matchA) grid_relax_points[1][i] = 0; 131119be502cSAlexander } 131219be502cSAlexander 131319be502cSAlexander // set up relax scheme 131419be502cSAlexander for (PetscInt i = 0; i < ns_up; i++) { 131519be502cSAlexander PetscCall(PetscStrcasecmp(postrelax[i], stringF, &matchF)); 131619be502cSAlexander PetscCall(PetscStrcasecmp(postrelax[i], stringC, &matchC)); 131719be502cSAlexander PetscCall(PetscStrcasecmp(postrelax[i], stringA, &matchA)); 131819be502cSAlexander PetscCheck(matchF || matchC || matchA, PetscObjectComm((PetscObject)jac), PETSC_ERR_ARG_WRONG, "Valid argument options for -pc_hypre_boomeramg_postrelax are C, F, and A"); 131919be502cSAlexander if (matchF) grid_relax_points[2][i] = -1; 132019be502cSAlexander else if (matchC) grid_relax_points[2][i] = 1; 132119be502cSAlexander else if (matchA) grid_relax_points[2][i] = 0; 132219be502cSAlexander } 132319be502cSAlexander 132419be502cSAlexander // set coarse relax scheme 132519be502cSAlexander for (PetscInt i = 0; i < jac->gridsweeps[2]; i++) grid_relax_points[3][i] = 0; 132619be502cSAlexander 132719be502cSAlexander // Pass relax schemes to hypre 132819be502cSAlexander PetscCallExternal(HYPRE_BoomerAMGSetGridRelaxPoints, jac->hsolver, grid_relax_points); 132919be502cSAlexander 133019be502cSAlexander // cleanup memory 133119be502cSAlexander for (PetscInt i = 0; i < ns_down; i++) PetscCall(PetscFree(prerelax[i])); 133219be502cSAlexander for (PetscInt i = 0; i < ns_up; i++) PetscCall(PetscFree(postrelax[i])); 1333589dcaf0SStefano Zampini } 1334589dcaf0SStefano Zampini #endif 1335589dcaf0SStefano Zampini 1336ecae95adSPierre Jolivet #if PETSC_PKG_HYPRE_VERSION_LE(9, 9, 9) 133763a3b9bcSJacob 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); 1338ecae95adSPierre Jolivet #endif 1339ecae95adSPierre Jolivet 13400f1074feSSatish Balay /* new 3/07 */ 1341dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_interp_type", "Interpolation type", "None", HYPREBoomerAMGInterpType, PETSC_STATIC_ARRAY_LENGTH(HYPREBoomerAMGInterpType), HYPREBoomerAMGInterpType[0], &indx, &flg)); 1342589dcaf0SStefano Zampini if (flg || jac->Rtype) { 1343589dcaf0SStefano Zampini if (flg) jac->interptype = indx; 1344792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetInterpType, jac->hsolver, jac->interptype); 13450f1074feSSatish Balay } 13460f1074feSSatish Balay 13479566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-pc_hypre_boomeramg_print_statistics", "Print statistics", "None", &flg)); 134816d9e3a6SLisandro Dalcin if (flg) { 1349b96a4a96SBarry Smith level = 3; 13509566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_print_statistics", "Print statistics", "None", level, &level, NULL)); 13512fa5cd67SKarl Rupp 1352b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 1353792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetPrintLevel, jac->hsolver, level); 13542ae77aedSBarry Smith } 13552ae77aedSBarry Smith 13569566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-pc_hypre_boomeramg_print_debug", "Print debug information", "None", &flg)); 13572ae77aedSBarry Smith if (flg) { 1358b96a4a96SBarry Smith level = 3; 13599566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_print_debug", "Print debug information", "None", level, &level, NULL)); 13602fa5cd67SKarl Rupp 1361b96a4a96SBarry Smith jac->printstatistics = PETSC_TRUE; 1362792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetDebugFlag, jac->hsolver, level); 136316d9e3a6SLisandro Dalcin } 13648f87f92bSBarry Smith 13659566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", PETSC_FALSE, &tmp_truth, &flg)); 13668f87f92bSBarry Smith if (flg && tmp_truth) { 13678f87f92bSBarry Smith PetscInt tmp_int; 13689566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_boomeramg_nodal_relaxation", "Nodal relaxation via Schwarz", "None", jac->nodal_relax_levels, &tmp_int, &flg)); 13698f87f92bSBarry Smith if (flg) jac->nodal_relax_levels = tmp_int; 1370792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothType, jac->hsolver, 6); 1371792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetDomainType, jac->hsolver, 1); 1372792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetOverlap, jac->hsolver, 0); 1373792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSmoothNumLevels, jac->hsolver, jac->nodal_relax_levels); 13748f87f92bSBarry Smith } 13758f87f92bSBarry Smith 13769566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_boomeramg_keeptranspose", "Avoid transpose matvecs in preconditioner application", "None", jac->keeptranspose, &jac->keeptranspose, NULL)); 1377792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetKeepTranspose, jac->hsolver, jac->keeptranspose ? 1 : 0); 1378589dcaf0SStefano Zampini 1379589dcaf0SStefano Zampini /* options for ParaSails solvers */ 1380dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_boomeramg_parasails_sym", "Symmetry of matrix and preconditioner", "None", symtlist, PETSC_STATIC_ARRAY_LENGTH(symtlist), symtlist[0], &indx, &flg)); 1381589dcaf0SStefano Zampini if (flg) { 1382589dcaf0SStefano Zampini jac->symt = indx; 1383792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetSym, jac->hsolver, jac->symt); 1384589dcaf0SStefano Zampini } 1385589dcaf0SStefano Zampini 1386d0609cedSBarry Smith PetscOptionsHeadEnd(); 13873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 138816d9e3a6SLisandro Dalcin } 138916d9e3a6SLisandro Dalcin 1390d71ae5a4SJacob 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) 1391d71ae5a4SJacob Faibussowitsch { 139216d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 13932cf14000SStefano Zampini HYPRE_Int oits; 139416d9e3a6SLisandro Dalcin 139516d9e3a6SLisandro Dalcin PetscFunctionBegin; 13969566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 1397792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, its * jac->maxiter); 1398792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, rtol); 139916d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_TRUE; 14009566063dSJacob Faibussowitsch PetscCall(PCApply_HYPRE(pc, b, y)); 140116d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 1402792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGGetNumIterations, jac->hsolver, &oits); 14034d0a8057SBarry Smith *outits = oits; 14044d0a8057SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 14054d0a8057SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 1406792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetTol, jac->hsolver, jac->tol); 1407792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGSetMaxIter, jac->hsolver, jac->maxiter); 14083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 140916d9e3a6SLisandro Dalcin } 141016d9e3a6SLisandro Dalcin 1411d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_BoomerAMG(PC pc, PetscViewer viewer) 1412d71ae5a4SJacob Faibussowitsch { 141316d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 14143c61a47dSLukas hypre_ParAMGData *amg_data = (hypre_ParAMGData *)jac->hsolver; 14159f196a02SMartin Diehl PetscBool isascii; 14163c61a47dSLukas PetscInt indx; 14173c61a47dSLukas PetscReal val; 141816d9e3a6SLisandro Dalcin 141916d9e3a6SLisandro Dalcin PetscFunctionBegin; 14209f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 14219f196a02SMartin Diehl if (isascii) { 14229566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE BoomerAMG preconditioning\n")); 14239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Cycle type %s\n", HYPREBoomerAMGCycleType[jac->cycletype])); 142463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum number of levels %" PetscInt_FMT "\n", jac->maxlevels)); 142563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum number of iterations PER hypre call %" PetscInt_FMT "\n", jac->maxiter)); 14269566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Convergence tolerance PER hypre call %g\n", (double)jac->tol)); 14279566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Threshold for strong coupling %g\n", (double)jac->strongthreshold)); 14289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation truncation factor %g\n", (double)jac->truncfactor)); 142963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation: max elements per row %" PetscInt_FMT "\n", jac->pmax)); 143048a46eb9SPierre Jolivet if (jac->interp_refine) PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation: number of steps of weighted refinement %" PetscInt_FMT "\n", jac->interp_refine)); 143163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Number of levels of aggressive coarsening %" PetscInt_FMT "\n", jac->agg_nl)); 143263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Number of paths for aggressive coarsening %" PetscInt_FMT "\n", jac->agg_num_paths)); 14330f1074feSSatish Balay 14349566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum row sums %g\n", (double)jac->maxrowsum)); 143516d9e3a6SLisandro Dalcin 143663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Sweeps down %" PetscInt_FMT "\n", jac->gridsweeps[0])); 143763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Sweeps up %" PetscInt_FMT "\n", jac->gridsweeps[1])); 143863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Sweeps on coarse %" PetscInt_FMT "\n", jac->gridsweeps[2])); 143916d9e3a6SLisandro Dalcin 14409566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax down %s\n", HYPREBoomerAMGRelaxType[jac->relaxtype[0]])); 14419566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax up %s\n", HYPREBoomerAMGRelaxType[jac->relaxtype[1]])); 14429566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax on coarse %s\n", HYPREBoomerAMGRelaxType[jac->relaxtype[2]])); 144316d9e3a6SLisandro Dalcin 14449566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Relax weight (all) %g\n", (double)jac->relaxweight)); 14459566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Outer relax weight (all) %g\n", (double)jac->outerrelaxweight)); 144616d9e3a6SLisandro Dalcin 144719be502cSAlexander PetscCall(PetscViewerASCIIPrintf(viewer, " Maximum size of coarsest grid %" PetscInt_FMT "\n", jac->maxc)); 144819be502cSAlexander PetscCall(PetscViewerASCIIPrintf(viewer, " Minimum size of coarsest grid %" PetscInt_FMT "\n", jac->minc)); 144919be502cSAlexander 145016d9e3a6SLisandro Dalcin if (jac->relaxorder) { 14519566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Using CF-relaxation\n")); 145216d9e3a6SLisandro Dalcin } else { 14539566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Not using CF-relaxation\n")); 145416d9e3a6SLisandro Dalcin } 14556a251517SEike Mueller if (jac->smoothtype != -1) { 14569566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Smooth type %s\n", HYPREBoomerAMGSmoothType[jac->smoothtype])); 145763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Smooth num levels %" PetscInt_FMT "\n", jac->smoothnumlevels)); 14583c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " Smooth num sweeps %" PetscInt_FMT "\n", jac->smoothsweeps)); 14593c61a47dSLukas if (jac->smoothtype == 0) { 14603c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUType", indx = hypre_ParAMGDataILUType(amg_data)); 14613c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU type %s (%" PetscInt_FMT ")\n", HYPREILUType[indx], indx)); 14623c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILULevel", indx = hypre_ParAMGDataILULevel(amg_data)); 14633c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU level %" PetscInt_FMT "\n", indx)); 14643c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUMaxIter", indx = hypre_ParAMGDataILUMaxIter(amg_data)); 14653c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU max iterations %" PetscInt_FMT "\n", indx)); 14663c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUMaxRowNnz", indx = hypre_ParAMGDataILUMaxRowNnz(amg_data)); 14673c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU max NNZ per row %" PetscInt_FMT "\n", indx)); 14683c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUTriSolve", indx = hypre_ParAMGDataILUTriSolve(amg_data)); 14693c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU triangular solve %" PetscInt_FMT "\n", indx)); 14703c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataTol", val = hypre_ParAMGDataTol(amg_data)); 14713c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU tolerance %e\n", val)); 14723c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUDroptol", val = hypre_ParAMGDataILUDroptol(amg_data)); 14733c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU drop tolerance %e\n", val)); 14743c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILULocalReordering", indx = hypre_ParAMGDataILULocalReordering(amg_data)); 14753c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU local reordering %" PetscInt_FMT "\n", indx)); 14763c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILULowerJacobiIters", indx = hypre_ParAMGDataILULowerJacobiIters(amg_data)); 14773c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU lower Jacobi iterations %" PetscInt_FMT "\n", indx)); 14783c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUUpperJacobiIters", indx = hypre_ParAMGDataILUUpperJacobiIters(amg_data)); 14793c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU upper Jacobi iterations %" PetscInt_FMT "\n", indx)); 14803c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataPrintLevel", indx = hypre_ParAMGDataPrintLevel(amg_data)); 14813c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU print level %" PetscInt_FMT "\n", indx)); 14823c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataLogging", indx = hypre_ParAMGDataLogging(amg_data)); 14833c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU logging level %" PetscInt_FMT "\n", indx)); 14843c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUIterSetupType", indx = hypre_ParAMGDataILUIterSetupType(amg_data)); 14853c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup type %s (%" PetscInt_FMT ")\n", HYPREILUIterSetup[indx], indx)); 14863c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUIterSetupOption", indx = hypre_ParAMGDataILUIterSetupOption(amg_data)); 14873c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup option %" PetscInt_FMT "\n", indx)); 14883c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUIterSetupMaxIter", indx = hypre_ParAMGDataILUIterSetupMaxIter(amg_data)); 14893c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup max iterations %" PetscInt_FMT "\n", indx)); 14903c61a47dSLukas PetscStackCallExternalVoid("hypre_ParAMGDataILUIterSetupTolerance", val = hypre_ParAMGDataILUIterSetupTolerance(amg_data)); 14913c61a47dSLukas PetscCall(PetscViewerASCIIPrintf(viewer, " ILU iterative setup tolerance %e\n", val)); 14923c61a47dSLukas } 14937e352d70SEike Mueller } else { 14949566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Not using more complex smoothers.\n")); 14951810e44eSEike Mueller } 14961810e44eSEike Mueller if (jac->smoothtype == 3) { 149763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Euclid ILU(k) levels %" PetscInt_FMT "\n", jac->eu_level)); 14989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Euclid ILU(k) drop tolerance %g\n", (double)jac->eu_droptolerance)); 149963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Euclid ILU use Block-Jacobi? %" PetscInt_FMT "\n", jac->eu_bj)); 15006a251517SEike Mueller } 15019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Measure type %s\n", HYPREBoomerAMGMeasureType[jac->measuretype])); 15029566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Coarsen type %s\n", HYPREBoomerAMGCoarsenType[jac->coarsentype])); 15039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Interpolation type %s\n", jac->interptype != 100 ? HYPREBoomerAMGInterpType[jac->interptype] : "1pt")); 150448a46eb9SPierre Jolivet if (jac->nodal_coarsening) PetscCall(PetscViewerASCIIPrintf(viewer, " Using nodal coarsening with HYPRE_BOOMERAMGSetNodal() %" PetscInt_FMT "\n", jac->nodal_coarsening)); 15055272c319SBarry Smith if (jac->vec_interp_variant) { 150663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE_BoomerAMGSetInterpVecVariant() %" PetscInt_FMT "\n", jac->vec_interp_variant)); 150763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE_BoomerAMGSetInterpVecQMax() %" PetscInt_FMT "\n", jac->vec_interp_qmax)); 15089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE_BoomerAMGSetSmoothInterpVectors() %d\n", jac->vec_interp_smooth)); 15098f87f92bSBarry Smith } 151048a46eb9SPierre Jolivet if (jac->nodal_relax) PetscCall(PetscViewerASCIIPrintf(viewer, " Using nodal relaxation via Schwarz smoothing on levels %" PetscInt_FMT "\n", jac->nodal_relax_levels)); 1511db6f9c32SMark Adams #if PETSC_PKG_HYPRE_VERSION_GE(2, 23, 0) 15129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " SpGEMM type %s\n", jac->spgemm_type)); 15132d6c3ceeSStefano Zampini #else 15142d6c3ceeSStefano Zampini PetscCall(PetscViewerASCIIPrintf(viewer, " SpGEMM type %s\n", "hypre")); 1515db6f9c32SMark Adams #endif 1516589dcaf0SStefano Zampini /* AIR */ 1517589dcaf0SStefano Zampini if (jac->Rtype) { 151863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Using approximate ideal restriction type %" PetscInt_FMT "\n", jac->Rtype)); 15199566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Threshold for R %g\n", (double)jac->Rstrongthreshold)); 15209566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Filter for R %g\n", (double)jac->Rfilterthreshold)); 15219566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " A drop tolerance %g\n", (double)jac->Adroptol)); 152263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " A drop type %" PetscInt_FMT "\n", jac->Adroptype)); 1523589dcaf0SStefano Zampini } 152416d9e3a6SLisandro Dalcin } 15253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 152616d9e3a6SLisandro Dalcin } 152716d9e3a6SLisandro Dalcin 1528ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ParaSails(PC pc, PetscOptionItems PetscOptionsObject) 1529d71ae5a4SJacob Faibussowitsch { 153016d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 15314ddd07fcSJed Brown PetscInt indx; 1532ace3abfcSBarry Smith PetscBool flag; 153316d9e3a6SLisandro Dalcin const char *symtlist[] = {"nonsymmetric", "SPD", "nonsymmetric,SPD"}; 153416d9e3a6SLisandro Dalcin 153516d9e3a6SLisandro Dalcin PetscFunctionBegin; 1536d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE ParaSails Options"); 15379566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_parasails_nlevels", "Number of number of levels", "None", jac->nlevels, &jac->nlevels, 0)); 15389566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_thresh", "Threshold", "None", jac->threshold, &jac->threshold, &flag)); 1539792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetParams, jac->hsolver, jac->threshold, jac->nlevels); 154016d9e3a6SLisandro Dalcin 15419566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_filter", "filter", "None", jac->filter, &jac->filter, &flag)); 1542792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetFilter, jac->hsolver, jac->filter); 154316d9e3a6SLisandro Dalcin 15449566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_parasails_loadbal", "Load balance", "None", jac->loadbal, &jac->loadbal, &flag)); 1545792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetLoadbal, jac->hsolver, jac->loadbal); 154616d9e3a6SLisandro Dalcin 15479566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_parasails_logging", "Print info to screen", "None", (PetscBool)jac->logging, (PetscBool *)&jac->logging, &flag)); 1548792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetLogging, jac->hsolver, jac->logging); 154916d9e3a6SLisandro Dalcin 15509566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_hypre_parasails_reuse", "Reuse nonzero pattern in preconditioner", "None", (PetscBool)jac->ruse, (PetscBool *)&jac->ruse, &flag)); 1551792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ParaSailsSetReuse, jac->hsolver, jac->ruse); 155216d9e3a6SLisandro Dalcin 1553dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_parasails_sym", "Symmetry of matrix and preconditioner", "None", symtlist, PETSC_STATIC_ARRAY_LENGTH(symtlist), symtlist[0], &indx, &flag)); 155416d9e3a6SLisandro Dalcin if (flag) { 155516d9e3a6SLisandro Dalcin jac->symt = indx; 1556792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetSym, jac->hsolver, jac->symt); 155716d9e3a6SLisandro Dalcin } 155816d9e3a6SLisandro Dalcin 1559d0609cedSBarry Smith PetscOptionsHeadEnd(); 15603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 156116d9e3a6SLisandro Dalcin } 156216d9e3a6SLisandro Dalcin 1563d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_ParaSails(PC pc, PetscViewer viewer) 1564d71ae5a4SJacob Faibussowitsch { 156516d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 15669f196a02SMartin Diehl PetscBool isascii; 1567feb237baSPierre Jolivet const char *symt = 0; 156816d9e3a6SLisandro Dalcin 156916d9e3a6SLisandro Dalcin PetscFunctionBegin; 15709f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 15719f196a02SMartin Diehl if (isascii) { 15729566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE ParaSails preconditioning\n")); 157363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " nlevels %" PetscInt_FMT "\n", jac->nlevels)); 15749566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " threshold %g\n", (double)jac->threshold)); 15759566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " filter %g\n", (double)jac->filter)); 15769566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " load balance %g\n", (double)jac->loadbal)); 15779566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " reuse nonzero structure %s\n", PetscBools[jac->ruse])); 15789566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " print info to screen %s\n", PetscBools[jac->logging])); 15792fa5cd67SKarl Rupp if (!jac->symt) symt = "nonsymmetric matrix and preconditioner"; 15802fa5cd67SKarl Rupp else if (jac->symt == 1) symt = "SPD matrix and preconditioner"; 15812fa5cd67SKarl Rupp else if (jac->symt == 2) symt = "nonsymmetric matrix but SPD preconditioner"; 158263a3b9bcSJacob Faibussowitsch else SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_WRONG, "Unknown HYPRE ParaSails symmetric option %" PetscInt_FMT, jac->symt); 15839566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %s\n", symt)); 158416d9e3a6SLisandro Dalcin } 15853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 158616d9e3a6SLisandro Dalcin } 1587f1580f4eSBarry Smith 1588ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_AMS(PC pc, PetscOptionItems PetscOptionsObject) 1589d71ae5a4SJacob Faibussowitsch { 15904cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 15914cb006feSStefano Zampini PetscInt n; 15924cb006feSStefano Zampini PetscBool flag, flag2, flag3, flag4; 15934cb006feSStefano Zampini 15944cb006feSStefano Zampini PetscFunctionBegin; 1595d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE AMS Options"); 15969566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_print_level", "Debugging output level for AMS", "None", jac->as_print, &jac->as_print, &flag)); 1597792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetPrintLevel, jac->hsolver, jac->as_print); 15989566063dSJacob 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)); 1599792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetMaxIter, jac->hsolver, jac->as_max_iter); 16009566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_cycle_type", "Cycle type for AMS multigrid", "None", jac->ams_cycle_type, &jac->ams_cycle_type, &flag)); 1601792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetCycleType, jac->hsolver, jac->ams_cycle_type); 16029566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_tol", "Error tolerance for AMS multigrid", "None", jac->as_tol, &jac->as_tol, &flag)); 1603792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_AMSSetTol, jac->hsolver, jac->as_tol); 16049566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ams_relax_type", "Relaxation type for AMS smoother", "None", jac->as_relax_type, &jac->as_relax_type, &flag)); 16059566063dSJacob 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)); 16069566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_relax_weight", "Relaxation weight for AMS smoother", "None", jac->as_relax_weight, &jac->as_relax_weight, &flag3)); 16079566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ams_omega", "SSOR coefficient for AMS smoother", "None", jac->as_omega, &jac->as_omega, &flag4)); 160848a46eb9SPierre Jolivet if (flag || flag2 || flag3 || flag4) PetscCallExternal(HYPRE_AMSSetSmoothingOptions, jac->hsolver, jac->as_relax_type, jac->as_relax_times, jac->as_relax_weight, jac->as_omega); 16099566063dSJacob 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)); 16104cb006feSStefano Zampini n = 5; 16119566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ams_amg_alpha_options", "AMG options for vector Poisson", "None", jac->as_amg_alpha_opts, &n, &flag2)); 16124cb006feSStefano Zampini if (flag || flag2) { 1613792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaAMGOptions, jac->hsolver, jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 1614863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 1615863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 16169371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 1617a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 16184cb006feSStefano Zampini } 16199566063dSJacob 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)); 16204cb006feSStefano Zampini n = 5; 16219566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ams_amg_beta_options", "AMG options for scalar Poisson solver", "None", jac->as_amg_beta_opts, &n, &flag2)); 16224cb006feSStefano Zampini if (flag || flag2) { 1623792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 1624863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 1625863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 16269371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 1627a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 16284cb006feSStefano Zampini } 16299566063dSJacob 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)); 163023df4f25SStefano Zampini if (flag) { /* override HYPRE's default only if the options is used */ 1631792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetProjectionFrequency, jac->hsolver, jac->ams_proj_freq); 163223df4f25SStefano Zampini } 1633d0609cedSBarry Smith PetscOptionsHeadEnd(); 16343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16354cb006feSStefano Zampini } 16364cb006feSStefano Zampini 1637d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_AMS(PC pc, PetscViewer viewer) 1638d71ae5a4SJacob Faibussowitsch { 16394cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 16409f196a02SMartin Diehl PetscBool isascii; 16414cb006feSStefano Zampini 16424cb006feSStefano Zampini PetscFunctionBegin; 16439f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 16449f196a02SMartin Diehl if (isascii) { 16459566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE AMS preconditioning\n")); 164663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iterations per application %" PetscInt_FMT "\n", jac->as_max_iter)); 164763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace cycle type %" PetscInt_FMT "\n", jac->ams_cycle_type)); 164863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iteration tolerance %g\n", (double)jac->as_tol)); 164963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother type %" PetscInt_FMT "\n", jac->as_relax_type)); 165063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number of smoothing steps %" PetscInt_FMT "\n", jac->as_relax_times)); 165163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother weight %g\n", (double)jac->as_relax_weight)); 165263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother omega %g\n", (double)jac->as_omega)); 16534cb006feSStefano Zampini if (jac->alpha_Poisson) { 16549566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " vector Poisson solver (passed in by user)\n")); 16554cb006feSStefano Zampini } else { 16569566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " vector Poisson solver (computed) \n")); 16574cb006feSStefano Zampini } 165863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG coarsening type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[0])); 165963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[1])); 166063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG relaxation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[2])); 166163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG interpolation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[3])); 166263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[4])); 166363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG strength threshold %g\n", (double)jac->as_amg_alpha_theta)); 16644cb006feSStefano Zampini if (!jac->ams_beta_is_zero) { 16654cb006feSStefano Zampini if (jac->beta_Poisson) { 16669566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " scalar Poisson solver (passed in by user)\n")); 16674cb006feSStefano Zampini } else { 16689566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " scalar Poisson solver (computed) \n")); 16694cb006feSStefano Zampini } 167063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG coarsening type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[0])); 167163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_beta_opts[1])); 167263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG relaxation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[2])); 167363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG interpolation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[3])); 167463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_beta_opts[4])); 167563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " boomerAMG strength threshold %g\n", (double)jac->as_amg_beta_theta)); 167648a46eb9SPierre 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)); 167723df4f25SStefano Zampini } else { 16789566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " scalar Poisson solver not used (zero-conductivity everywhere) \n")); 16794cb006feSStefano Zampini } 16804cb006feSStefano Zampini } 16813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16824cb006feSStefano Zampini } 16834cb006feSStefano Zampini 1684ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE_ADS(PC pc, PetscOptionItems PetscOptionsObject) 1685d71ae5a4SJacob Faibussowitsch { 1686863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 1687863406b8SStefano Zampini PetscInt n; 1688863406b8SStefano Zampini PetscBool flag, flag2, flag3, flag4; 1689863406b8SStefano Zampini 1690863406b8SStefano Zampini PetscFunctionBegin; 1691d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE ADS Options"); 16929566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_print_level", "Debugging output level for ADS", "None", jac->as_print, &jac->as_print, &flag)); 1693792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetPrintLevel, jac->hsolver, jac->as_print); 16949566063dSJacob 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)); 1695792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetMaxIter, jac->hsolver, jac->as_max_iter); 16969566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_cycle_type", "Cycle type for ADS multigrid", "None", jac->ads_cycle_type, &jac->ads_cycle_type, &flag)); 1697792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetCycleType, jac->hsolver, jac->ads_cycle_type); 16989566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_tol", "Error tolerance for ADS multigrid", "None", jac->as_tol, &jac->as_tol, &flag)); 1699792fecdfSBarry Smith if (flag) PetscCallExternal(HYPRE_ADSSetTol, jac->hsolver, jac->as_tol); 17009566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_hypre_ads_relax_type", "Relaxation type for ADS smoother", "None", jac->as_relax_type, &jac->as_relax_type, &flag)); 17019566063dSJacob 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)); 17029566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_relax_weight", "Relaxation weight for ADS smoother", "None", jac->as_relax_weight, &jac->as_relax_weight, &flag3)); 17039566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_hypre_ads_omega", "SSOR coefficient for ADS smoother", "None", jac->as_omega, &jac->as_omega, &flag4)); 170448a46eb9SPierre Jolivet if (flag || flag2 || flag3 || flag4) PetscCallExternal(HYPRE_ADSSetSmoothingOptions, jac->hsolver, jac->as_relax_type, jac->as_relax_times, jac->as_relax_weight, jac->as_omega); 17059566063dSJacob 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)); 1706863406b8SStefano Zampini n = 5; 17079566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ads_ams_options", "AMG options for AMS solver inside ADS", "None", jac->as_amg_alpha_opts, &n, &flag2)); 17089566063dSJacob 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)); 1709863406b8SStefano Zampini if (flag || flag2 || flag3) { 1710792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMSOptions, jac->hsolver, jac->ams_cycle_type, /* AMS cycle type */ 1711863406b8SStefano Zampini jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 1712863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 1713863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 17149371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 1715a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 1716863406b8SStefano Zampini } 17179566063dSJacob 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)); 1718863406b8SStefano Zampini n = 5; 17199566063dSJacob Faibussowitsch PetscCall(PetscOptionsIntArray("-pc_hypre_ads_amg_options", "AMG options for vector AMG solver inside ADS", "None", jac->as_amg_beta_opts, &n, &flag2)); 1720863406b8SStefano Zampini if (flag || flag2) { 1721792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 1722863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 1723863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 17249371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 1725a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 1726863406b8SStefano Zampini } 1727d0609cedSBarry Smith PetscOptionsHeadEnd(); 17283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1729863406b8SStefano Zampini } 1730863406b8SStefano Zampini 1731d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCView_HYPRE_ADS(PC pc, PetscViewer viewer) 1732d71ae5a4SJacob Faibussowitsch { 1733863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 17349f196a02SMartin Diehl PetscBool isascii; 1735863406b8SStefano Zampini 1736863406b8SStefano Zampini PetscFunctionBegin; 17379f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 17389f196a02SMartin Diehl if (isascii) { 17399566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE ADS preconditioning\n")); 174063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iterations per application %" PetscInt_FMT "\n", jac->as_max_iter)); 174163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace cycle type %" PetscInt_FMT "\n", jac->ads_cycle_type)); 174263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace iteration tolerance %g\n", (double)jac->as_tol)); 174363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother type %" PetscInt_FMT "\n", jac->as_relax_type)); 174463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number of smoothing steps %" PetscInt_FMT "\n", jac->as_relax_times)); 174563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother weight %g\n", (double)jac->as_relax_weight)); 174663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " smoother omega %g\n", (double)jac->as_omega)); 17479566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " AMS solver using boomerAMG\n")); 174863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " subspace cycle type %" PetscInt_FMT "\n", jac->ams_cycle_type)); 174963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " coarsening type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[0])); 175063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[1])); 175163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relaxation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[2])); 175263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " interpolation type %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[3])); 175363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_alpha_opts[4])); 175463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " strength threshold %g\n", (double)jac->as_amg_alpha_theta)); 17559566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " vector Poisson solver using boomerAMG\n")); 175663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " coarsening type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[0])); 175763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " levels of aggressive coarsening %" PetscInt_FMT "\n", jac->as_amg_beta_opts[1])); 175863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relaxation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[2])); 175963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " interpolation type %" PetscInt_FMT "\n", jac->as_amg_beta_opts[3])); 176063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max nonzero elements in interpolation rows %" PetscInt_FMT "\n", jac->as_amg_beta_opts[4])); 176163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " strength threshold %g\n", (double)jac->as_amg_beta_theta)); 1762863406b8SStefano Zampini } 17633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1764863406b8SStefano Zampini } 1765863406b8SStefano Zampini 1766d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetDiscreteGradient_HYPRE(PC pc, Mat G) 1767d71ae5a4SJacob Faibussowitsch { 17684cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 17695ac14e1cSStefano Zampini PetscBool ishypre; 17704cb006feSStefano Zampini 17714cb006feSStefano Zampini PetscFunctionBegin; 17729566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)G, MATHYPRE, &ishypre)); 17735ac14e1cSStefano Zampini if (ishypre) { 17749566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)G)); 17759566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 17765ac14e1cSStefano Zampini jac->G = G; 17775ac14e1cSStefano Zampini } else { 17789566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->G)); 17799566063dSJacob Faibussowitsch PetscCall(MatConvert(G, MATHYPRE, MAT_INITIAL_MATRIX, &jac->G)); 17805ac14e1cSStefano Zampini } 17813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 17824cb006feSStefano Zampini } 17834cb006feSStefano Zampini 17844cb006feSStefano Zampini /*@ 1785f1580f4eSBarry Smith PCHYPRESetDiscreteGradient - Set discrete gradient matrix for `PCHYPRE` type of ams or ads 17864cb006feSStefano Zampini 1787c3339decSBarry Smith Collective 17884cb006feSStefano Zampini 17894cb006feSStefano Zampini Input Parameters: 17904cb006feSStefano Zampini + pc - the preconditioning context 17914cb006feSStefano Zampini - G - the discrete gradient 17924cb006feSStefano Zampini 17934cb006feSStefano Zampini Level: intermediate 17944cb006feSStefano Zampini 179595452b02SPatrick Sanan Notes: 179695452b02SPatrick Sanan G should have as many rows as the number of edges and as many columns as the number of vertices in the mesh 1797147403d9SBarry Smith 1798863406b8SStefano Zampini Each row of G has 2 nonzeros, with column indexes being the global indexes of edge's endpoints: matrix entries are +1 and -1 depending on edge orientation 17994cb006feSStefano Zampini 1800feefa0e1SJacob Faibussowitsch Developer Notes: 1801f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 1802f1580f4eSBarry Smith 1803562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteCurl()` 18044cb006feSStefano Zampini @*/ 1805d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetDiscreteGradient(PC pc, Mat G) 1806d71ae5a4SJacob Faibussowitsch { 18074cb006feSStefano Zampini PetscFunctionBegin; 18084cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 18094cb006feSStefano Zampini PetscValidHeaderSpecific(G, MAT_CLASSID, 2); 18104cb006feSStefano Zampini PetscCheckSameComm(pc, 1, G, 2); 1811cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetDiscreteGradient_C", (PC, Mat), (pc, G)); 18123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18134cb006feSStefano Zampini } 18144cb006feSStefano Zampini 1815d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetDiscreteCurl_HYPRE(PC pc, Mat C) 1816d71ae5a4SJacob Faibussowitsch { 1817863406b8SStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 18185ac14e1cSStefano Zampini PetscBool ishypre; 1819863406b8SStefano Zampini 1820863406b8SStefano Zampini PetscFunctionBegin; 18219566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)C, MATHYPRE, &ishypre)); 18225ac14e1cSStefano Zampini if (ishypre) { 18239566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)C)); 18249566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 18255ac14e1cSStefano Zampini jac->C = C; 18265ac14e1cSStefano Zampini } else { 18279566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->C)); 18289566063dSJacob Faibussowitsch PetscCall(MatConvert(C, MATHYPRE, MAT_INITIAL_MATRIX, &jac->C)); 18295ac14e1cSStefano Zampini } 18303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1831863406b8SStefano Zampini } 1832863406b8SStefano Zampini 1833863406b8SStefano Zampini /*@ 18346e415bd2SNuno Nobre PCHYPRESetDiscreteCurl - Set discrete curl matrix for `PCHYPRE` type of ads 1835863406b8SStefano Zampini 1836c3339decSBarry Smith Collective 1837863406b8SStefano Zampini 1838863406b8SStefano Zampini Input Parameters: 1839863406b8SStefano Zampini + pc - the preconditioning context 1840863406b8SStefano Zampini - C - the discrete curl 1841863406b8SStefano Zampini 1842863406b8SStefano Zampini Level: intermediate 1843863406b8SStefano Zampini 184495452b02SPatrick Sanan Notes: 184595452b02SPatrick Sanan C should have as many rows as the number of faces and as many columns as the number of edges in the mesh 1846147403d9SBarry Smith 18476e415bd2SNuno Nobre 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: matrix entries are +1 and -1 depending on edge orientation with respect to the face orientation 1848863406b8SStefano Zampini 1849feefa0e1SJacob Faibussowitsch Developer Notes: 1850f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 1851f1580f4eSBarry Smith 1852f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ads it should be called `PCHYPREADSSetDiscreteCurl()` 1853f1580f4eSBarry Smith 1854562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()` 1855863406b8SStefano Zampini @*/ 1856d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetDiscreteCurl(PC pc, Mat C) 1857d71ae5a4SJacob Faibussowitsch { 1858863406b8SStefano Zampini PetscFunctionBegin; 1859863406b8SStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 1860863406b8SStefano Zampini PetscValidHeaderSpecific(C, MAT_CLASSID, 2); 1861863406b8SStefano Zampini PetscCheckSameComm(pc, 1, C, 2); 1862cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetDiscreteCurl_C", (PC, Mat), (pc, C)); 18633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1864863406b8SStefano Zampini } 1865863406b8SStefano Zampini 1866d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetInterpolations_HYPRE(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[]) 1867d71ae5a4SJacob Faibussowitsch { 18686bf688a0SCe Qin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 18696bf688a0SCe Qin PetscBool ishypre; 18706bf688a0SCe Qin PetscInt i; 18716bf688a0SCe Qin 18724d86920dSPierre Jolivet PetscFunctionBegin; 18739566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_PiFull)); 18749566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_PiFull)); 18756bf688a0SCe Qin for (i = 0; i < 3; ++i) { 18769566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->RT_Pi[i])); 18779566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->ND_Pi[i])); 18786bf688a0SCe Qin } 18796bf688a0SCe Qin 18806bf688a0SCe Qin jac->dim = dim; 18816bf688a0SCe Qin if (RT_PiFull) { 18829566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)RT_PiFull, MATHYPRE, &ishypre)); 18836bf688a0SCe Qin if (ishypre) { 18849566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)RT_PiFull)); 18856bf688a0SCe Qin jac->RT_PiFull = RT_PiFull; 18866bf688a0SCe Qin } else { 18879566063dSJacob Faibussowitsch PetscCall(MatConvert(RT_PiFull, MATHYPRE, MAT_INITIAL_MATRIX, &jac->RT_PiFull)); 18886bf688a0SCe Qin } 18896bf688a0SCe Qin } 18906bf688a0SCe Qin if (RT_Pi) { 18916bf688a0SCe Qin for (i = 0; i < dim; ++i) { 18926bf688a0SCe Qin if (RT_Pi[i]) { 18939566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)RT_Pi[i], MATHYPRE, &ishypre)); 18946bf688a0SCe Qin if (ishypre) { 18959566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)RT_Pi[i])); 18966bf688a0SCe Qin jac->RT_Pi[i] = RT_Pi[i]; 18976bf688a0SCe Qin } else { 18989566063dSJacob Faibussowitsch PetscCall(MatConvert(RT_Pi[i], MATHYPRE, MAT_INITIAL_MATRIX, &jac->RT_Pi[i])); 18996bf688a0SCe Qin } 19006bf688a0SCe Qin } 19016bf688a0SCe Qin } 19026bf688a0SCe Qin } 19036bf688a0SCe Qin if (ND_PiFull) { 19049566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)ND_PiFull, MATHYPRE, &ishypre)); 19056bf688a0SCe Qin if (ishypre) { 19069566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ND_PiFull)); 19076bf688a0SCe Qin jac->ND_PiFull = ND_PiFull; 19086bf688a0SCe Qin } else { 19099566063dSJacob Faibussowitsch PetscCall(MatConvert(ND_PiFull, MATHYPRE, MAT_INITIAL_MATRIX, &jac->ND_PiFull)); 19106bf688a0SCe Qin } 19116bf688a0SCe Qin } 19126bf688a0SCe Qin if (ND_Pi) { 19136bf688a0SCe Qin for (i = 0; i < dim; ++i) { 19146bf688a0SCe Qin if (ND_Pi[i]) { 19159566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)ND_Pi[i], MATHYPRE, &ishypre)); 19166bf688a0SCe Qin if (ishypre) { 19179566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ND_Pi[i])); 19186bf688a0SCe Qin jac->ND_Pi[i] = ND_Pi[i]; 19196bf688a0SCe Qin } else { 19209566063dSJacob Faibussowitsch PetscCall(MatConvert(ND_Pi[i], MATHYPRE, MAT_INITIAL_MATRIX, &jac->ND_Pi[i])); 19216bf688a0SCe Qin } 19226bf688a0SCe Qin } 19236bf688a0SCe Qin } 19246bf688a0SCe Qin } 19253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 19266bf688a0SCe Qin } 19276bf688a0SCe Qin 19286bf688a0SCe Qin /*@ 1929f1580f4eSBarry Smith PCHYPRESetInterpolations - Set interpolation matrices for `PCHYPRE` type of ams or ads 19306bf688a0SCe Qin 1931c3339decSBarry Smith Collective 19326bf688a0SCe Qin 19336bf688a0SCe Qin Input Parameters: 19346bf688a0SCe Qin + pc - the preconditioning context 19352fe279fdSBarry Smith . dim - the dimension of the problem, only used in AMS 19362fe279fdSBarry Smith . RT_PiFull - Raviart-Thomas interpolation matrix 19372fe279fdSBarry Smith . RT_Pi - x/y/z component of Raviart-Thomas interpolation matrix 19382fe279fdSBarry Smith . ND_PiFull - Nedelec interpolation matrix 19396bf688a0SCe Qin - ND_Pi - x/y/z component of Nedelec interpolation matrix 19406bf688a0SCe Qin 1941f1580f4eSBarry Smith Level: intermediate 1942f1580f4eSBarry Smith 194395452b02SPatrick Sanan Notes: 194495452b02SPatrick Sanan For AMS, only Nedelec interpolation matrices are needed, the Raviart-Thomas interpolation matrices can be set to NULL. 1945147403d9SBarry Smith 19466bf688a0SCe Qin For ADS, both type of interpolation matrices are needed. 1947147403d9SBarry Smith 1948feefa0e1SJacob Faibussowitsch Developer Notes: 1949f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 19506bf688a0SCe Qin 1951562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE` 19526bf688a0SCe Qin @*/ 1953d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetInterpolations(PC pc, PetscInt dim, Mat RT_PiFull, Mat RT_Pi[], Mat ND_PiFull, Mat ND_Pi[]) 1954d71ae5a4SJacob Faibussowitsch { 19556bf688a0SCe Qin PetscInt i; 19566bf688a0SCe Qin 19576bf688a0SCe Qin PetscFunctionBegin; 19586bf688a0SCe Qin PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 19596bf688a0SCe Qin if (RT_PiFull) { 19606bf688a0SCe Qin PetscValidHeaderSpecific(RT_PiFull, MAT_CLASSID, 3); 19616bf688a0SCe Qin PetscCheckSameComm(pc, 1, RT_PiFull, 3); 19626bf688a0SCe Qin } 19636bf688a0SCe Qin if (RT_Pi) { 19644f572ea9SToby Isaac PetscAssertPointer(RT_Pi, 4); 19656bf688a0SCe Qin for (i = 0; i < dim; ++i) { 19666bf688a0SCe Qin if (RT_Pi[i]) { 19676bf688a0SCe Qin PetscValidHeaderSpecific(RT_Pi[i], MAT_CLASSID, 4); 19686bf688a0SCe Qin PetscCheckSameComm(pc, 1, RT_Pi[i], 4); 19696bf688a0SCe Qin } 19706bf688a0SCe Qin } 19716bf688a0SCe Qin } 19726bf688a0SCe Qin if (ND_PiFull) { 19736bf688a0SCe Qin PetscValidHeaderSpecific(ND_PiFull, MAT_CLASSID, 5); 19746bf688a0SCe Qin PetscCheckSameComm(pc, 1, ND_PiFull, 5); 19756bf688a0SCe Qin } 19766bf688a0SCe Qin if (ND_Pi) { 19774f572ea9SToby Isaac PetscAssertPointer(ND_Pi, 6); 19786bf688a0SCe Qin for (i = 0; i < dim; ++i) { 19796bf688a0SCe Qin if (ND_Pi[i]) { 19806bf688a0SCe Qin PetscValidHeaderSpecific(ND_Pi[i], MAT_CLASSID, 6); 19816bf688a0SCe Qin PetscCheckSameComm(pc, 1, ND_Pi[i], 6); 19826bf688a0SCe Qin } 19836bf688a0SCe Qin } 19846bf688a0SCe Qin } 1985cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetInterpolations_C", (PC, PetscInt, Mat, Mat[], Mat, Mat[]), (pc, dim, RT_PiFull, RT_Pi, ND_PiFull, ND_Pi)); 19863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 19876bf688a0SCe Qin } 19886bf688a0SCe Qin 1989d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetPoissonMatrix_HYPRE(PC pc, Mat A, PetscBool isalpha) 1990d71ae5a4SJacob Faibussowitsch { 19914cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 19925ac14e1cSStefano Zampini PetscBool ishypre; 19934cb006feSStefano Zampini 19944cb006feSStefano Zampini PetscFunctionBegin; 19959566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATHYPRE, &ishypre)); 19965ac14e1cSStefano Zampini if (ishypre) { 19975ac14e1cSStefano Zampini if (isalpha) { 19989566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 19999566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 20005ac14e1cSStefano Zampini jac->alpha_Poisson = A; 20015ac14e1cSStefano Zampini } else { 20025ac14e1cSStefano Zampini if (A) { 20039566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 20045ac14e1cSStefano Zampini } else { 20055ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_TRUE; 20065ac14e1cSStefano Zampini } 20079566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 20085ac14e1cSStefano Zampini jac->beta_Poisson = A; 20095ac14e1cSStefano Zampini } 20105ac14e1cSStefano Zampini } else { 20115ac14e1cSStefano Zampini if (isalpha) { 20129566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->alpha_Poisson)); 20139566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &jac->alpha_Poisson)); 20145ac14e1cSStefano Zampini } else { 20155ac14e1cSStefano Zampini if (A) { 20169566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 20179566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &jac->beta_Poisson)); 20185ac14e1cSStefano Zampini } else { 20199566063dSJacob Faibussowitsch PetscCall(MatDestroy(&jac->beta_Poisson)); 20205ac14e1cSStefano Zampini jac->ams_beta_is_zero = PETSC_TRUE; 20215ac14e1cSStefano Zampini } 20225ac14e1cSStefano Zampini } 20235ac14e1cSStefano Zampini } 20243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20254cb006feSStefano Zampini } 20264cb006feSStefano Zampini 20274cb006feSStefano Zampini /*@ 2028f1580f4eSBarry Smith PCHYPRESetAlphaPoissonMatrix - Set vector Poisson matrix for `PCHYPRE` of type ams 20294cb006feSStefano Zampini 2030c3339decSBarry Smith Collective 20314cb006feSStefano Zampini 20324cb006feSStefano Zampini Input Parameters: 20334cb006feSStefano Zampini + pc - the preconditioning context 20344cb006feSStefano Zampini - A - the matrix 20354cb006feSStefano Zampini 20364cb006feSStefano Zampini Level: intermediate 20374cb006feSStefano Zampini 2038f1580f4eSBarry Smith Note: 203995452b02SPatrick Sanan A should be obtained by discretizing the vector valued Poisson problem with linear finite elements 20404cb006feSStefano Zampini 2041feefa0e1SJacob Faibussowitsch Developer Notes: 2042f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 2043f1580f4eSBarry Smith 2044f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ams it should be called `PCHYPREAMSSetAlphaPoissonMatrix()` 2045f1580f4eSBarry Smith 2046562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetBetaPoissonMatrix()` 20474cb006feSStefano Zampini @*/ 2048d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PC pc, Mat A) 2049d71ae5a4SJacob Faibussowitsch { 20504cb006feSStefano Zampini PetscFunctionBegin; 20514cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 20524cb006feSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 2); 20534cb006feSStefano Zampini PetscCheckSameComm(pc, 1, A, 2); 2054cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetPoissonMatrix_C", (PC, Mat, PetscBool), (pc, A, PETSC_TRUE)); 20553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20564cb006feSStefano Zampini } 20574cb006feSStefano Zampini 20584cb006feSStefano Zampini /*@ 2059f1580f4eSBarry Smith PCHYPRESetBetaPoissonMatrix - Set Poisson matrix for `PCHYPRE` of type ams 20604cb006feSStefano Zampini 2061c3339decSBarry Smith Collective 20624cb006feSStefano Zampini 20634cb006feSStefano Zampini Input Parameters: 20644cb006feSStefano Zampini + pc - the preconditioning context 2065f1580f4eSBarry Smith - A - the matrix, or NULL to turn it off 20664cb006feSStefano Zampini 20674cb006feSStefano Zampini Level: intermediate 20684cb006feSStefano Zampini 2069f1580f4eSBarry Smith Note: 207095452b02SPatrick Sanan A should be obtained by discretizing the Poisson problem with linear finite elements. 20714cb006feSStefano Zampini 2072feefa0e1SJacob Faibussowitsch Developer Notes: 2073f1580f4eSBarry Smith This automatically converts the matrix to `MATHYPRE` if it is not already of that type 2074f1580f4eSBarry Smith 2075f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ams it should be called `PCHYPREAMSPCHYPRESetBetaPoissonMatrix()` 2076f1580f4eSBarry Smith 2077562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()` 20784cb006feSStefano Zampini @*/ 2079d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetBetaPoissonMatrix(PC pc, Mat A) 2080d71ae5a4SJacob Faibussowitsch { 20814cb006feSStefano Zampini PetscFunctionBegin; 20824cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 20834cb006feSStefano Zampini if (A) { 20844cb006feSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 2); 20854cb006feSStefano Zampini PetscCheckSameComm(pc, 1, A, 2); 20864cb006feSStefano Zampini } 2087cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetPoissonMatrix_C", (PC, Mat, PetscBool), (pc, A, PETSC_FALSE)); 20883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20894cb006feSStefano Zampini } 20904cb006feSStefano Zampini 2091d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetEdgeConstantVectors_HYPRE(PC pc, Vec ozz, Vec zoz, Vec zzo) 2092d71ae5a4SJacob Faibussowitsch { 20934cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 20944cb006feSStefano Zampini 20954cb006feSStefano Zampini PetscFunctionBegin; 20964cb006feSStefano Zampini /* throw away any vector if already set */ 20979566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[0])); 20989566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[1])); 20999566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->constants[2])); 21009566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(ozz->map, &jac->constants[0])); 21019566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(ozz, jac->constants[0])); 21029566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(zoz->map, &jac->constants[1])); 21039566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(zoz, jac->constants[1])); 21045ac14e1cSStefano Zampini jac->dim = 2; 21054cb006feSStefano Zampini if (zzo) { 21069566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(zzo->map, &jac->constants[2])); 21079566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(zzo, jac->constants[2])); 21085ac14e1cSStefano Zampini jac->dim++; 21094cb006feSStefano Zampini } 21103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21114cb006feSStefano Zampini } 21124cb006feSStefano Zampini 21134cb006feSStefano Zampini /*@ 2114f1580f4eSBarry Smith PCHYPRESetEdgeConstantVectors - Set the representation of the constant vector fields in the edge element basis for `PCHYPRE` of type ams 21154cb006feSStefano Zampini 2116c3339decSBarry Smith Collective 21174cb006feSStefano Zampini 21184cb006feSStefano Zampini Input Parameters: 21194cb006feSStefano Zampini + pc - the preconditioning context 21202fe279fdSBarry Smith . ozz - vector representing (1,0,0) (or (1,0) in 2D) 21212fe279fdSBarry Smith . zoz - vector representing (0,1,0) (or (0,1) in 2D) 21224cb006feSStefano Zampini - zzo - vector representing (0,0,1) (use NULL in 2D) 21234cb006feSStefano Zampini 21244cb006feSStefano Zampini Level: intermediate 21254cb006feSStefano Zampini 2126feefa0e1SJacob Faibussowitsch Developer Notes: 2127f1580f4eSBarry Smith If this is only for `PCHYPRE` type of ams it should be called `PCHYPREAMSSetEdgeConstantVectors()` 2128f1580f4eSBarry Smith 2129562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()` 21304cb006feSStefano Zampini @*/ 2131d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetEdgeConstantVectors(PC pc, Vec ozz, Vec zoz, Vec zzo) 2132d71ae5a4SJacob Faibussowitsch { 21334cb006feSStefano Zampini PetscFunctionBegin; 21344cb006feSStefano Zampini PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 21354cb006feSStefano Zampini PetscValidHeaderSpecific(ozz, VEC_CLASSID, 2); 21364cb006feSStefano Zampini PetscValidHeaderSpecific(zoz, VEC_CLASSID, 3); 21374cb006feSStefano Zampini if (zzo) PetscValidHeaderSpecific(zzo, VEC_CLASSID, 4); 21384cb006feSStefano Zampini PetscCheckSameComm(pc, 1, ozz, 2); 21394cb006feSStefano Zampini PetscCheckSameComm(pc, 1, zoz, 3); 21404cb006feSStefano Zampini if (zzo) PetscCheckSameComm(pc, 1, zzo, 4); 2141cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetEdgeConstantVectors_C", (PC, Vec, Vec, Vec), (pc, ozz, zoz, zzo)); 21423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21434cb006feSStefano Zampini } 21444cb006feSStefano Zampini 2145d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPREAMSSetInteriorNodes_HYPRE(PC pc, Vec interior) 2146d71ae5a4SJacob Faibussowitsch { 2147be14dc20SKerry Key PC_HYPRE *jac = (PC_HYPRE *)pc->data; 2148be14dc20SKerry Key 2149be14dc20SKerry Key PetscFunctionBegin; 2150be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorDestroy(&jac->interior)); 2151be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorCreate(interior->map, &jac->interior)); 2152be14dc20SKerry Key PetscCall(VecHYPRE_IJVectorCopy(interior, jac->interior)); 2153be14dc20SKerry Key jac->ams_beta_is_zero_part = PETSC_TRUE; 21543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2155be14dc20SKerry Key } 2156be14dc20SKerry Key 2157be14dc20SKerry Key /*@ 2158f1580f4eSBarry Smith PCHYPREAMSSetInteriorNodes - Set the list of interior nodes to a zero-conductivity region for `PCHYPRE` of type ams 2159be14dc20SKerry Key 2160c3339decSBarry Smith Collective 2161be14dc20SKerry Key 2162be14dc20SKerry Key Input Parameters: 2163be14dc20SKerry Key + pc - the preconditioning context 2164be14dc20SKerry Key - interior - vector. node is interior if its entry in the array is 1.0. 2165be14dc20SKerry Key 2166be14dc20SKerry Key Level: intermediate 2167be14dc20SKerry Key 2168be14dc20SKerry Key Note: 2169f1580f4eSBarry Smith This calls `HYPRE_AMSSetInteriorNodes()` 2170f1580f4eSBarry Smith 2171562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCHYPRESetDiscreteGradient()`, `PCHYPRESetDiscreteCurl()`, `PCHYPRESetAlphaPoissonMatrix()` 2172be14dc20SKerry Key @*/ 2173d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPREAMSSetInteriorNodes(PC pc, Vec interior) 2174d71ae5a4SJacob Faibussowitsch { 2175be14dc20SKerry Key PetscFunctionBegin; 2176be14dc20SKerry Key PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 2177be14dc20SKerry Key PetscValidHeaderSpecific(interior, VEC_CLASSID, 2); 2178be14dc20SKerry Key PetscCheckSameComm(pc, 1, interior, 2); 2179be14dc20SKerry Key PetscTryMethod(pc, "PCHYPREAMSSetInteriorNodes_C", (PC, Vec), (pc, interior)); 21803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2181be14dc20SKerry Key } 2182be14dc20SKerry Key 2183d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetCoordinates_HYPRE(PC pc, PetscInt dim, PetscInt nloc, PetscReal *coords) 2184d71ae5a4SJacob Faibussowitsch { 21854cb006feSStefano Zampini PC_HYPRE *jac = (PC_HYPRE *)pc->data; 21864cb006feSStefano Zampini Vec tv; 21874cb006feSStefano Zampini PetscInt i; 21884cb006feSStefano Zampini 21894cb006feSStefano Zampini PetscFunctionBegin; 21904cb006feSStefano Zampini /* throw away any coordinate vector if already set */ 21919566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[0])); 21929566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[1])); 21939566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&jac->coords[2])); 21945ac14e1cSStefano Zampini jac->dim = dim; 21955ac14e1cSStefano Zampini 21964cb006feSStefano Zampini /* compute IJ vector for coordinates */ 21979566063dSJacob Faibussowitsch PetscCall(VecCreate(PetscObjectComm((PetscObject)pc), &tv)); 21989566063dSJacob Faibussowitsch PetscCall(VecSetType(tv, VECSTANDARD)); 21999566063dSJacob Faibussowitsch PetscCall(VecSetSizes(tv, nloc, PETSC_DECIDE)); 22004cb006feSStefano Zampini for (i = 0; i < dim; i++) { 22014cb006feSStefano Zampini PetscScalar *array; 22024cb006feSStefano Zampini PetscInt j; 22034cb006feSStefano Zampini 22049566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCreate(tv->map, &jac->coords[i])); 22059566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(tv, &array)); 22066ea7df73SStefano Zampini for (j = 0; j < nloc; j++) array[j] = coords[j * dim + i]; 22079566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(tv, &array)); 22089566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorCopy(tv, jac->coords[i])); 22094cb006feSStefano Zampini } 22109566063dSJacob Faibussowitsch PetscCall(VecDestroy(&tv)); 22113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22124cb006feSStefano Zampini } 22134cb006feSStefano Zampini 2214d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPREGetType_HYPRE(PC pc, const char *name[]) 2215d71ae5a4SJacob Faibussowitsch { 221616d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 221716d9e3a6SLisandro Dalcin 221816d9e3a6SLisandro Dalcin PetscFunctionBegin; 221916d9e3a6SLisandro Dalcin *name = jac->hypre_type; 22203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 222116d9e3a6SLisandro Dalcin } 222216d9e3a6SLisandro Dalcin 2223d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCHYPRESetType_HYPRE(PC pc, const char name[]) 2224d71ae5a4SJacob Faibussowitsch { 222516d9e3a6SLisandro Dalcin PC_HYPRE *jac = (PC_HYPRE *)pc->data; 2226ace3abfcSBarry Smith PetscBool flag; 222716d9e3a6SLisandro Dalcin 222816d9e3a6SLisandro Dalcin PetscFunctionBegin; 222916d9e3a6SLisandro Dalcin if (jac->hypre_type) { 22309566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(jac->hypre_type, name, &flag)); 2231d7185485SAlex Lindsay if (flag) PetscFunctionReturn(PETSC_SUCCESS); 223216d9e3a6SLisandro Dalcin } 223316d9e3a6SLisandro Dalcin 2234d7185485SAlex Lindsay PetscCall(PCReset_HYPRE(pc)); 2235d7185485SAlex Lindsay PetscCall(PetscFree(jac->hypre_type)); 2236d7185485SAlex Lindsay PetscCall(PetscStrallocpy(name, &jac->hypre_type)); 2237d7185485SAlex Lindsay 223816d9e3a6SLisandro Dalcin jac->maxiter = PETSC_DEFAULT; 223916d9e3a6SLisandro Dalcin jac->tol = PETSC_DEFAULT; 224016d9e3a6SLisandro Dalcin jac->printstatistics = PetscLogPrintInfo; 224116d9e3a6SLisandro Dalcin 22423c61a47dSLukas PetscCall(PetscStrcmp("ilu", jac->hypre_type, &flag)); 22433c61a47dSLukas if (flag) { 22443c61a47dSLukas PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 22453c61a47dSLukas PetscCallExternal(HYPRE_ILUCreate, &jac->hsolver); 22463c61a47dSLukas pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ILU; 22473c61a47dSLukas pc->ops->view = PCView_HYPRE_ILU; 22483c61a47dSLukas jac->destroy = HYPRE_ILUDestroy; 22493c61a47dSLukas jac->setup = HYPRE_ILUSetup; 22503c61a47dSLukas jac->solve = HYPRE_ILUSolve; 22513c61a47dSLukas jac->factorrowsize = PETSC_DEFAULT; 22523c61a47dSLukas PetscFunctionReturn(PETSC_SUCCESS); 22533c61a47dSLukas } 22543c61a47dSLukas 22559566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("pilut", jac->hypre_type, &flag)); 225616d9e3a6SLisandro Dalcin if (flag) { 22579566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 2258792fecdfSBarry Smith PetscCallExternal(HYPRE_ParCSRPilutCreate, jac->comm_hypre, &jac->hsolver); 225916d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Pilut; 226016d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_Pilut; 226116d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParCSRPilutDestroy; 226216d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParCSRPilutSetup; 226316d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParCSRPilutSolve; 226416d9e3a6SLisandro Dalcin jac->factorrowsize = PETSC_DEFAULT; 22653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 226616d9e3a6SLisandro Dalcin } 22679566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("euclid", jac->hypre_type, &flag)); 2268db966c6cSHong Zhang if (flag) { 22694e3c431bSBarry Smith #if defined(PETSC_USE_64BIT_INDICES) 22707de69702SBarry Smith SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "Hypre Euclid does not support 64-bit indices"); 22718bf83915SBarry Smith #endif 22729566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 2273792fecdfSBarry Smith PetscCallExternal(HYPRE_EuclidCreate, jac->comm_hypre, &jac->hsolver); 2274db966c6cSHong Zhang pc->ops->setfromoptions = PCSetFromOptions_HYPRE_Euclid; 2275db966c6cSHong Zhang pc->ops->view = PCView_HYPRE_Euclid; 2276db966c6cSHong Zhang jac->destroy = HYPRE_EuclidDestroy; 2277db966c6cSHong Zhang jac->setup = HYPRE_EuclidSetup; 2278db966c6cSHong Zhang jac->solve = HYPRE_EuclidSolve; 2279db966c6cSHong Zhang jac->factorrowsize = PETSC_DEFAULT; 2280db966c6cSHong Zhang jac->eu_level = PETSC_DEFAULT; /* default */ 22813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2282db966c6cSHong Zhang } 22839566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("parasails", jac->hypre_type, &flag)); 228416d9e3a6SLisandro Dalcin if (flag) { 22859566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &jac->comm_hypre)); 2286792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsCreate, jac->comm_hypre, &jac->hsolver); 228716d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ParaSails; 228816d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_ParaSails; 228916d9e3a6SLisandro Dalcin jac->destroy = HYPRE_ParaSailsDestroy; 229016d9e3a6SLisandro Dalcin jac->setup = HYPRE_ParaSailsSetup; 229116d9e3a6SLisandro Dalcin jac->solve = HYPRE_ParaSailsSolve; 229216d9e3a6SLisandro Dalcin /* initialize */ 229316d9e3a6SLisandro Dalcin jac->nlevels = 1; 22948966356dSPierre Jolivet jac->threshold = .1; 229516d9e3a6SLisandro Dalcin jac->filter = .1; 229616d9e3a6SLisandro Dalcin jac->loadbal = 0; 22972fa5cd67SKarl Rupp if (PetscLogPrintInfo) jac->logging = (int)PETSC_TRUE; 22982fa5cd67SKarl Rupp else jac->logging = (int)PETSC_FALSE; 22992fa5cd67SKarl Rupp 230016d9e3a6SLisandro Dalcin jac->ruse = (int)PETSC_FALSE; 230116d9e3a6SLisandro Dalcin jac->symt = 0; 2302792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetParams, jac->hsolver, jac->threshold, jac->nlevels); 2303792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetFilter, jac->hsolver, jac->filter); 2304792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetLoadbal, jac->hsolver, jac->loadbal); 2305792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetLogging, jac->hsolver, jac->logging); 2306792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetReuse, jac->hsolver, jac->ruse); 2307792fecdfSBarry Smith PetscCallExternal(HYPRE_ParaSailsSetSym, jac->hsolver, jac->symt); 23083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 230916d9e3a6SLisandro Dalcin } 23109566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("boomeramg", jac->hypre_type, &flag)); 231116d9e3a6SLisandro Dalcin if (flag) { 2312792fecdfSBarry Smith PetscCallExternal(HYPRE_BoomerAMGCreate, &jac->hsolver); 231316d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE_BoomerAMG; 231416d9e3a6SLisandro Dalcin pc->ops->view = PCView_HYPRE_BoomerAMG; 231516d9e3a6SLisandro Dalcin pc->ops->applytranspose = PCApplyTranspose_HYPRE_BoomerAMG; 231616d9e3a6SLisandro Dalcin pc->ops->applyrichardson = PCApplyRichardson_HYPRE_BoomerAMG; 231785245615SPierre Jolivet pc->ops->matapply = PCMatApply_HYPRE_BoomerAMG; 23189566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetInterpolations_C", PCGetInterpolations_BoomerAMG)); 23199566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCGetCoarseOperators_C", PCGetCoarseOperators_BoomerAMG)); 232042e5ec60SJeff-Hadley PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREGetCFMarkers_C", PCHYPREGetCFMarkers_BoomerAMG)); 232116d9e3a6SLisandro Dalcin jac->destroy = HYPRE_BoomerAMGDestroy; 232216d9e3a6SLisandro Dalcin jac->setup = HYPRE_BoomerAMGSetup; 232316d9e3a6SLisandro Dalcin jac->solve = HYPRE_BoomerAMGSolve; 232416d9e3a6SLisandro Dalcin jac->applyrichardson = PETSC_FALSE; 232516d9e3a6SLisandro Dalcin /* these defaults match the hypre defaults */ 232616d9e3a6SLisandro Dalcin jac->cycletype = 1; 232716d9e3a6SLisandro Dalcin jac->maxlevels = 25; 232816d9e3a6SLisandro Dalcin jac->maxiter = 1; 23298f87f92bSBarry Smith jac->tol = 0.0; /* tolerance of zero indicates use as preconditioner (suppresses convergence errors) */ 233016d9e3a6SLisandro Dalcin jac->truncfactor = 0.0; 233116d9e3a6SLisandro Dalcin jac->strongthreshold = .25; 233216d9e3a6SLisandro Dalcin jac->maxrowsum = .9; 233316d9e3a6SLisandro Dalcin jac->measuretype = 0; 23340f1074feSSatish Balay jac->gridsweeps[0] = jac->gridsweeps[1] = jac->gridsweeps[2] = 1; 23356a251517SEike Mueller jac->smoothtype = -1; /* Not set by default */ 2336b9eb5777SEike Mueller jac->smoothnumlevels = 25; 23371810e44eSEike Mueller jac->eu_level = 0; 23381810e44eSEike Mueller jac->eu_droptolerance = 0; 23391810e44eSEike Mueller jac->eu_bj = 0; 234016d9e3a6SLisandro Dalcin jac->relaxweight = 1.0; 234116d9e3a6SLisandro Dalcin jac->outerrelaxweight = 1.0; 2342589dcaf0SStefano Zampini jac->Rtype = 0; 2343589dcaf0SStefano Zampini jac->Rstrongthreshold = 0.25; 2344589dcaf0SStefano Zampini jac->Rfilterthreshold = 0.0; 2345589dcaf0SStefano Zampini jac->Adroptype = -1; 2346589dcaf0SStefano Zampini jac->Adroptol = 0.0; 23470f1074feSSatish Balay jac->agg_nl = 0; 23480f1074feSSatish Balay jac->pmax = 0; 23490f1074feSSatish Balay jac->truncfactor = 0.0; 23500f1074feSSatish Balay jac->agg_num_paths = 1; 2351589dcaf0SStefano Zampini jac->maxc = 9; 2352589dcaf0SStefano Zampini jac->minc = 1; 235322e51d31SStefano Zampini jac->nodal_coarsening = 0; 235422e51d31SStefano Zampini jac->nodal_coarsening_diag = 0; 235522e51d31SStefano Zampini jac->vec_interp_variant = 0; 235622e51d31SStefano Zampini jac->vec_interp_qmax = 0; 235722e51d31SStefano Zampini jac->vec_interp_smooth = PETSC_FALSE; 235822e51d31SStefano Zampini jac->interp_refine = 0; 23598f87f92bSBarry Smith jac->nodal_relax = PETSC_FALSE; 23608f87f92bSBarry Smith jac->nodal_relax_levels = 1; 23616ea7df73SStefano Zampini jac->rap2 = 0; 2362d7185485SAlex Lindsay PetscObjectParameterSetDefault(jac, relaxorder, -1); /* Initialize with invalid value so we can recognize user input */ 23633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 236416d9e3a6SLisandro Dalcin } 23659566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("ams", jac->hypre_type, &flag)); 23664cb006feSStefano Zampini if (flag) { 23673ba16761SJacob Faibussowitsch PetscCallExternal(HYPRE_AMSCreate, &jac->hsolver); 23684cb006feSStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_HYPRE_AMS; 23694cb006feSStefano Zampini pc->ops->view = PCView_HYPRE_AMS; 23704cb006feSStefano Zampini jac->destroy = HYPRE_AMSDestroy; 23714cb006feSStefano Zampini jac->setup = HYPRE_AMSSetup; 23724cb006feSStefano Zampini jac->solve = HYPRE_AMSSolve; 23734cb006feSStefano Zampini jac->coords[0] = NULL; 23744cb006feSStefano Zampini jac->coords[1] = NULL; 23754cb006feSStefano Zampini jac->coords[2] = NULL; 2376be14dc20SKerry Key jac->interior = NULL; 23774cb006feSStefano Zampini /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE AMS */ 2378863406b8SStefano Zampini jac->as_print = 0; 2379863406b8SStefano Zampini jac->as_max_iter = 1; /* used as a preconditioner */ 2380863406b8SStefano Zampini jac->as_tol = 0.; /* used as a preconditioner */ 23814cb006feSStefano Zampini jac->ams_cycle_type = 13; 23824cb006feSStefano Zampini /* Smoothing options */ 2383863406b8SStefano Zampini jac->as_relax_type = 2; 2384863406b8SStefano Zampini jac->as_relax_times = 1; 2385863406b8SStefano Zampini jac->as_relax_weight = 1.0; 2386863406b8SStefano Zampini jac->as_omega = 1.0; 23874cb006feSStefano Zampini /* Vector valued Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2388863406b8SStefano Zampini jac->as_amg_alpha_opts[0] = 10; 2389863406b8SStefano Zampini jac->as_amg_alpha_opts[1] = 1; 23900bdd8552SBarry Smith jac->as_amg_alpha_opts[2] = 6; 2391863406b8SStefano Zampini jac->as_amg_alpha_opts[3] = 6; 2392863406b8SStefano Zampini jac->as_amg_alpha_opts[4] = 4; 2393863406b8SStefano Zampini jac->as_amg_alpha_theta = 0.25; 23944cb006feSStefano Zampini /* Scalar Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2395863406b8SStefano Zampini jac->as_amg_beta_opts[0] = 10; 2396863406b8SStefano Zampini jac->as_amg_beta_opts[1] = 1; 23970bdd8552SBarry Smith jac->as_amg_beta_opts[2] = 6; 2398863406b8SStefano Zampini jac->as_amg_beta_opts[3] = 6; 2399863406b8SStefano Zampini jac->as_amg_beta_opts[4] = 4; 2400863406b8SStefano Zampini jac->as_amg_beta_theta = 0.25; 2401792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetPrintLevel, jac->hsolver, jac->as_print); 2402792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetMaxIter, jac->hsolver, jac->as_max_iter); 2403792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetCycleType, jac->hsolver, jac->ams_cycle_type); 2404792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetTol, jac->hsolver, jac->as_tol); 24059371c9d4SSatish Balay PetscCallExternal(HYPRE_AMSSetSmoothingOptions, jac->hsolver, jac->as_relax_type, jac->as_relax_times, jac->as_relax_weight, jac->as_omega); 2406792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetAlphaAMGOptions, jac->hsolver, jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 2407863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 2408863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 24099371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 2410a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 2411792fecdfSBarry Smith PetscCallExternal(HYPRE_AMSSetBetaAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 2412863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 2413863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 24149371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 2415a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 241623df4f25SStefano Zampini /* Zero conductivity */ 241723df4f25SStefano Zampini jac->ams_beta_is_zero = PETSC_FALSE; 241823df4f25SStefano Zampini jac->ams_beta_is_zero_part = PETSC_FALSE; 24193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24204cb006feSStefano Zampini } 24219566063dSJacob Faibussowitsch PetscCall(PetscStrcmp("ads", jac->hypre_type, &flag)); 2422863406b8SStefano Zampini if (flag) { 24233ba16761SJacob Faibussowitsch PetscCallExternal(HYPRE_ADSCreate, &jac->hsolver); 2424863406b8SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_HYPRE_ADS; 2425863406b8SStefano Zampini pc->ops->view = PCView_HYPRE_ADS; 2426863406b8SStefano Zampini jac->destroy = HYPRE_ADSDestroy; 2427863406b8SStefano Zampini jac->setup = HYPRE_ADSSetup; 2428863406b8SStefano Zampini jac->solve = HYPRE_ADSSolve; 2429863406b8SStefano Zampini jac->coords[0] = NULL; 2430863406b8SStefano Zampini jac->coords[1] = NULL; 2431863406b8SStefano Zampini jac->coords[2] = NULL; 2432863406b8SStefano Zampini /* solver parameters: these are borrowed from mfem package, and they are not the default values from HYPRE ADS */ 2433863406b8SStefano Zampini jac->as_print = 0; 2434863406b8SStefano Zampini jac->as_max_iter = 1; /* used as a preconditioner */ 2435863406b8SStefano Zampini jac->as_tol = 0.; /* used as a preconditioner */ 2436863406b8SStefano Zampini jac->ads_cycle_type = 13; 2437863406b8SStefano Zampini /* Smoothing options */ 2438863406b8SStefano Zampini jac->as_relax_type = 2; 2439863406b8SStefano Zampini jac->as_relax_times = 1; 2440863406b8SStefano Zampini jac->as_relax_weight = 1.0; 2441863406b8SStefano Zampini jac->as_omega = 1.0; 2442863406b8SStefano Zampini /* AMS solver parameters: cycle_type, coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2443863406b8SStefano Zampini jac->ams_cycle_type = 14; 2444863406b8SStefano Zampini jac->as_amg_alpha_opts[0] = 10; 2445863406b8SStefano Zampini jac->as_amg_alpha_opts[1] = 1; 2446863406b8SStefano Zampini jac->as_amg_alpha_opts[2] = 6; 2447863406b8SStefano Zampini jac->as_amg_alpha_opts[3] = 6; 2448863406b8SStefano Zampini jac->as_amg_alpha_opts[4] = 4; 2449863406b8SStefano Zampini jac->as_amg_alpha_theta = 0.25; 2450863406b8SStefano Zampini /* Vector Poisson AMG solver parameters: coarsen type, agg_levels, relax_type, interp_type, Pmax */ 2451863406b8SStefano Zampini jac->as_amg_beta_opts[0] = 10; 2452863406b8SStefano Zampini jac->as_amg_beta_opts[1] = 1; 2453863406b8SStefano Zampini jac->as_amg_beta_opts[2] = 6; 2454863406b8SStefano Zampini jac->as_amg_beta_opts[3] = 6; 2455863406b8SStefano Zampini jac->as_amg_beta_opts[4] = 4; 2456863406b8SStefano Zampini jac->as_amg_beta_theta = 0.25; 2457792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetPrintLevel, jac->hsolver, jac->as_print); 2458792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetMaxIter, jac->hsolver, jac->as_max_iter); 2459792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetCycleType, jac->hsolver, jac->ams_cycle_type); 2460792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetTol, jac->hsolver, jac->as_tol); 24619371c9d4SSatish Balay PetscCallExternal(HYPRE_ADSSetSmoothingOptions, jac->hsolver, jac->as_relax_type, jac->as_relax_times, jac->as_relax_weight, jac->as_omega); 2462792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMSOptions, jac->hsolver, jac->ams_cycle_type, /* AMG coarsen type */ 2463863406b8SStefano Zampini jac->as_amg_alpha_opts[0], /* AMG coarsen type */ 2464863406b8SStefano Zampini jac->as_amg_alpha_opts[1], /* AMG agg_levels */ 2465863406b8SStefano Zampini jac->as_amg_alpha_opts[2], /* AMG relax_type */ 24669371c9d4SSatish Balay jac->as_amg_alpha_theta, jac->as_amg_alpha_opts[3], /* AMG interp_type */ 2467a74df02fSJacob Faibussowitsch jac->as_amg_alpha_opts[4]); /* AMG Pmax */ 2468792fecdfSBarry Smith PetscCallExternal(HYPRE_ADSSetAMGOptions, jac->hsolver, jac->as_amg_beta_opts[0], /* AMG coarsen type */ 2469863406b8SStefano Zampini jac->as_amg_beta_opts[1], /* AMG agg_levels */ 2470863406b8SStefano Zampini jac->as_amg_beta_opts[2], /* AMG relax_type */ 24719371c9d4SSatish Balay jac->as_amg_beta_theta, jac->as_amg_beta_opts[3], /* AMG interp_type */ 2472a74df02fSJacob Faibussowitsch jac->as_amg_beta_opts[4]); /* AMG Pmax */ 24733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2474863406b8SStefano Zampini } 24759566063dSJacob Faibussowitsch PetscCall(PetscFree(jac->hypre_type)); 24762fa5cd67SKarl Rupp 24770298fd71SBarry Smith jac->hypre_type = NULL; 2478b06c524fSNuno Nobre SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown HYPRE preconditioner %s; Choices are euclid, ilu, pilut, parasails, boomeramg, ams, ads", name); 247916d9e3a6SLisandro Dalcin } 248016d9e3a6SLisandro Dalcin 248116d9e3a6SLisandro Dalcin /* 248216d9e3a6SLisandro Dalcin It only gets here if the HYPRE type has not been set before the call to 248316d9e3a6SLisandro Dalcin ...SetFromOptions() which actually is most of the time 248416d9e3a6SLisandro Dalcin */ 2485ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_HYPRE(PC pc, PetscOptionItems PetscOptionsObject) 2486d71ae5a4SJacob Faibussowitsch { 24874ddd07fcSJed Brown PetscInt indx; 24883c61a47dSLukas const char *type[] = {"ilu", "euclid", "pilut", "parasails", "boomeramg", "ams", "ads"}; 2489ace3abfcSBarry Smith PetscBool flg; 2490d7185485SAlex Lindsay PC_HYPRE *jac = (PC_HYPRE *)pc->data; 249116d9e3a6SLisandro Dalcin 249216d9e3a6SLisandro Dalcin PetscFunctionBegin; 2493d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "HYPRE preconditioner options"); 2494dd39110bSPierre Jolivet PetscCall(PetscOptionsEList("-pc_hypre_type", "HYPRE preconditioner type", "PCHYPRESetType", type, PETSC_STATIC_ARRAY_LENGTH(type), "boomeramg", &indx, &flg)); 2495d7185485SAlex Lindsay if (flg) PetscCall(PCHYPRESetType_HYPRE(pc, type[indx])); 2496d7185485SAlex Lindsay /* 2497d7185485SAlex Lindsay Set the type if it was never set. 2498d7185485SAlex Lindsay */ 2499d7185485SAlex Lindsay if (!jac->hypre_type) PetscCall(PCHYPRESetType_HYPRE(pc, "boomeramg")); 2500dbbe0bcdSBarry Smith PetscTryTypeMethod(pc, setfromoptions, PetscOptionsObject); 2501d0609cedSBarry Smith PetscOptionsHeadEnd(); 25023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 250316d9e3a6SLisandro Dalcin } 250416d9e3a6SLisandro Dalcin 2505cc4c1da9SBarry Smith /*@ 250616d9e3a6SLisandro Dalcin PCHYPRESetType - Sets which hypre preconditioner you wish to use 250716d9e3a6SLisandro Dalcin 250816d9e3a6SLisandro Dalcin Input Parameters: 250916d9e3a6SLisandro Dalcin + pc - the preconditioner context 2510b06c524fSNuno Nobre - name - either euclid, ilu, pilut, parasails, boomeramg, ams, ads 251116d9e3a6SLisandro Dalcin 2512f1580f4eSBarry Smith Options Database Key: 2513b06c524fSNuno Nobre . pc_hypre_type - One of euclid, ilu, pilut, parasails, boomeramg, ams, ads 251416d9e3a6SLisandro Dalcin 251516d9e3a6SLisandro Dalcin Level: intermediate 251616d9e3a6SLisandro Dalcin 2517562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCreate()`, `PCSetType()`, `PCType`, `PC`, `PCHYPRE` 251816d9e3a6SLisandro Dalcin @*/ 2519d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPRESetType(PC pc, const char name[]) 2520d71ae5a4SJacob Faibussowitsch { 252116d9e3a6SLisandro Dalcin PetscFunctionBegin; 25220700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 25234f572ea9SToby Isaac PetscAssertPointer(name, 2); 2524cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPRESetType_C", (PC, const char[]), (pc, name)); 25253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 252616d9e3a6SLisandro Dalcin } 252716d9e3a6SLisandro Dalcin 252842e5ec60SJeff-Hadley /*@C 252942e5ec60SJeff-Hadley PCHYPREGetCFMarkers - Gets CF marker arrays for all levels (except the finest level) 253042e5ec60SJeff-Hadley 253142e5ec60SJeff-Hadley Logically Collective 253242e5ec60SJeff-Hadley 253342e5ec60SJeff-Hadley Input Parameter: 253442e5ec60SJeff-Hadley . pc - the preconditioner context 253542e5ec60SJeff-Hadley 253642e5ec60SJeff-Hadley Output Parameters: 253742e5ec60SJeff-Hadley + n_per_level - the number of nodes per level (size of `num_levels`) 253842e5ec60SJeff-Hadley - CFMarkers - the Coarse/Fine Boolean arrays (size of `num_levels` - 1) 253942e5ec60SJeff-Hadley 254042e5ec60SJeff-Hadley Note: 254142e5ec60SJeff-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. 254242e5ec60SJeff-Hadley 254342e5ec60SJeff-Hadley Level: advanced 254442e5ec60SJeff-Hadley 254542e5ec60SJeff-Hadley .seealso: [](ch_ksp), `PC`, `PCMG`, `PCMGGetRestriction()`, `PCMGSetInterpolation()`, `PCMGGetRScale()`, `PCMGGetInterpolation()`, `PCGetInterpolations()` 254642e5ec60SJeff-Hadley @*/ 254742e5ec60SJeff-Hadley PetscErrorCode PCHYPREGetCFMarkers(PC pc, PetscInt *n_per_level[], PetscBT *CFMarkers[]) 254842e5ec60SJeff-Hadley { 254942e5ec60SJeff-Hadley PetscFunctionBegin; 255042e5ec60SJeff-Hadley PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 255142e5ec60SJeff-Hadley PetscAssertPointer(n_per_level, 2); 255242e5ec60SJeff-Hadley PetscAssertPointer(CFMarkers, 3); 255342e5ec60SJeff-Hadley PetscUseMethod(pc, "PCHYPREGetCFMarkers_C", (PC, PetscInt *[], PetscBT *[]), (pc, n_per_level, CFMarkers)); 255442e5ec60SJeff-Hadley PetscFunctionReturn(PETSC_SUCCESS); 255542e5ec60SJeff-Hadley } 255642e5ec60SJeff-Hadley 2557cc4c1da9SBarry Smith /*@ 255816d9e3a6SLisandro Dalcin PCHYPREGetType - Gets which hypre preconditioner you are using 255916d9e3a6SLisandro Dalcin 256016d9e3a6SLisandro Dalcin Input Parameter: 256116d9e3a6SLisandro Dalcin . pc - the preconditioner context 256216d9e3a6SLisandro Dalcin 256316d9e3a6SLisandro Dalcin Output Parameter: 2564b06c524fSNuno Nobre . name - either euclid, ilu, pilut, parasails, boomeramg, ams, ads 256516d9e3a6SLisandro Dalcin 256616d9e3a6SLisandro Dalcin Level: intermediate 256716d9e3a6SLisandro Dalcin 2568562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCreate()`, `PCHYPRESetType()`, `PCType`, `PC`, `PCHYPRE` 256916d9e3a6SLisandro Dalcin @*/ 2570d71ae5a4SJacob Faibussowitsch PetscErrorCode PCHYPREGetType(PC pc, const char *name[]) 2571d71ae5a4SJacob Faibussowitsch { 257216d9e3a6SLisandro Dalcin PetscFunctionBegin; 25730700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 25744f572ea9SToby Isaac PetscAssertPointer(name, 2); 2575cac4c232SBarry Smith PetscTryMethod(pc, "PCHYPREGetType_C", (PC, const char *[]), (pc, name)); 25763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 257716d9e3a6SLisandro Dalcin } 257816d9e3a6SLisandro Dalcin 2579cc4c1da9SBarry Smith /*@ 2580f1580f4eSBarry Smith PCMGGalerkinSetMatProductAlgorithm - Set type of SpGEMM for hypre to use on GPUs 2581db6f9c32SMark Adams 2582c3339decSBarry Smith Logically Collective 2583db6f9c32SMark Adams 2584db6f9c32SMark Adams Input Parameters: 2585db6f9c32SMark Adams + pc - the hypre context 2586feefa0e1SJacob Faibussowitsch - name - one of 'cusparse', 'hypre' 2587db6f9c32SMark Adams 2588db6f9c32SMark Adams Options Database Key: 258967b8a455SSatish Balay . -pc_mg_galerkin_mat_product_algorithm <cusparse,hypre> - Type of SpGEMM to use in hypre 2590db6f9c32SMark Adams 2591db6f9c32SMark Adams Level: intermediate 2592db6f9c32SMark Adams 2593feefa0e1SJacob Faibussowitsch Developer Notes: 2594f1580f4eSBarry Smith How the name starts with `PCMG`, should it not be `PCHYPREBoomerAMG`? 2595db6f9c32SMark Adams 2596562efe2eSBarry Smith .seealso: [](ch_ksp), `PCHYPRE`, `PCMGGalerkinGetMatProductAlgorithm()` 2597db6f9c32SMark Adams @*/ 2598d71ae5a4SJacob Faibussowitsch PetscErrorCode PCMGGalerkinSetMatProductAlgorithm(PC pc, const char name[]) 2599d71ae5a4SJacob Faibussowitsch { 2600db6f9c32SMark Adams PetscFunctionBegin; 2601db6f9c32SMark Adams PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 2602cac4c232SBarry Smith PetscTryMethod(pc, "PCMGGalerkinSetMatProductAlgorithm_C", (PC, const char[]), (pc, name)); 26033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2604db6f9c32SMark Adams } 2605db6f9c32SMark Adams 2606cc4c1da9SBarry Smith /*@ 2607f1580f4eSBarry Smith PCMGGalerkinGetMatProductAlgorithm - Get type of SpGEMM for hypre to use on GPUs 2608db6f9c32SMark Adams 2609db6f9c32SMark Adams Not Collective 2610db6f9c32SMark Adams 2611db6f9c32SMark Adams Input Parameter: 2612db6f9c32SMark Adams . pc - the multigrid context 2613db6f9c32SMark Adams 2614db6f9c32SMark Adams Output Parameter: 2615db6f9c32SMark Adams . name - one of 'cusparse', 'hypre' 2616db6f9c32SMark Adams 2617db6f9c32SMark Adams Level: intermediate 2618db6f9c32SMark Adams 2619a94f484eSPierre Jolivet .seealso: [](ch_ksp), `PCHYPRE`, `PCMGGalerkinSetMatProductAlgorithm()` 2620db6f9c32SMark Adams @*/ 2621d71ae5a4SJacob Faibussowitsch PetscErrorCode PCMGGalerkinGetMatProductAlgorithm(PC pc, const char *name[]) 2622d71ae5a4SJacob Faibussowitsch { 2623db6f9c32SMark Adams PetscFunctionBegin; 2624db6f9c32SMark Adams PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 2625cac4c232SBarry Smith PetscTryMethod(pc, "PCMGGalerkinGetMatProductAlgorithm_C", (PC, const char *[]), (pc, name)); 26263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2627db6f9c32SMark Adams } 2628db6f9c32SMark Adams 262916d9e3a6SLisandro Dalcin /*MC 2630f1580f4eSBarry Smith PCHYPRE - Allows you to use the matrix element based preconditioners in the LLNL package hypre as PETSc `PC` 263116d9e3a6SLisandro Dalcin 263216d9e3a6SLisandro Dalcin Options Database Keys: 2633e1ded407SBarry Smith + -pc_hypre_type - One of `euclid`, `pilut`, `parasails`, `boomeramg`, `ams`, or `ads` 26347cbeddf0SNuno Nobre . -pc_hypre_boomeramg_nodal_coarsen <n> - where n is from 1 to 6 (see `HYPRE_BoomerAMGSetNodal()`) 2635f1580f4eSBarry Smith . -pc_hypre_boomeramg_vec_interp_variant <v> - where v is from 1 to 3 (see `HYPRE_BoomerAMGSetInterpVecVariant()`) 26367cbeddf0SNuno Nobre - Many others - run with `-pc_type hypre` `-pc_hypre_type XXX` `-help` to see options for the XXX preconditioner 263716d9e3a6SLisandro Dalcin 263816d9e3a6SLisandro Dalcin Level: intermediate 263916d9e3a6SLisandro Dalcin 264095452b02SPatrick Sanan Notes: 2641e1ded407SBarry Smith Apart from `-pc_hypre_type` (for which there is `PCHYPRESetType()`), 264216d9e3a6SLisandro Dalcin the many hypre options can ONLY be set via the options database (e.g. the command line 264349567fc5SPierre Jolivet or with `PetscOptionsSetValue()`, there are no functions to set them) 264416d9e3a6SLisandro Dalcin 2645e1ded407SBarry Smith The options `-pc_hypre_boomeramg_max_iter` and `-pc_hypre_boomeramg_tol` refer to the number of iterations 2646e1ded407SBarry Smith (V-cycles) and tolerance that boomerAMG does EACH time it is called. So for example, if 2647e1ded407SBarry Smith `-pc_hypre_boomeramg_max_iter` is set to 2 then 2-V-cycles are being used to define the preconditioner 2648e1ded407SBarry Smith (`-pc_hypre_boomeramg_tol` should be set to 0.0 - the default - to strictly use a fixed number of 2649e1ded407SBarry Smith iterations per hypre call). `-ksp_max_it` and `-ksp_rtol` STILL determine the total number of iterations 2650e1ded407SBarry Smith and tolerance for the Krylov solver. For example, if `-pc_hypre_boomeramg_max_iter` is 2 and `-ksp_max_it` is 10 2651e1ded407SBarry Smith then AT MOST twenty V-cycles of boomeramg will be used. 265216d9e3a6SLisandro Dalcin 2653e1ded407SBarry Smith Note that the option `-pc_hypre_boomeramg_relax_type_all` defaults to symmetric relaxation 26540f1074feSSatish Balay (symmetric-SOR/Jacobi), which is required for Krylov solvers like CG that expect symmetry. 2655e1ded407SBarry Smith Otherwise, you may want to use `-pc_hypre_boomeramg_relax_type_all SOR/Jacobi`. 265616d9e3a6SLisandro Dalcin 2657f1580f4eSBarry Smith `MatSetNearNullSpace()` - if you provide a near null space to your matrix it is ignored by hypre UNLESS you also use 2658e1ded407SBarry Smith the following two options: `-pc_hypre_boomeramg_nodal_coarsen <n> -pc_hypre_boomeramg_vec_interp_variant <v>` 26590b1a5bd9SEric Chamberland 2660f1580f4eSBarry Smith See `PCPFMG`, `PCSMG`, and `PCSYSPFMG` for access to hypre's other (nonalgebraic) multigrid solvers 2661f1580f4eSBarry Smith 2662e1ded407SBarry Smith For `PCHYPRE` type of `ams` or `ads` auxiliary data must be provided to the preconditioner with `PCHYPRESetDiscreteGradient()`, 2663f1580f4eSBarry Smith `PCHYPRESetDiscreteCurl()`, `PCHYPRESetInterpolations()`, `PCHYPRESetAlphaPoissonMatrix()`, `PCHYPRESetBetaPoissonMatrix()`, `PCHYPRESetEdgeConstantVectors()`, 266449567fc5SPierre Jolivet `PCHYPREAMSSetInteriorNodes()` 2665f1580f4eSBarry Smith 2666e1ded407SBarry 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 2667e1ded407SBarry Smith since it is usually slower, one should use a `KSPType` of `KSPRICHARDSON` 2668e1ded407SBarry Smith (or equivalently `-ksp_type richardson`) to achieve this. Using `KSPPREONLY` will not work since it only applies a single cycle of multigrid. 2669e1ded407SBarry Smith 2670f1580f4eSBarry Smith PETSc provides its own geometric and algebraic multigrid solvers `PCMG` and `PCGAMG`, also see `PCHMG` which is useful for certain multicomponent problems 26719e5bc791SBarry Smith 2672ead8c081SBarry Smith GPU Notes: 2673ead8c081SBarry Smith To configure hypre BoomerAMG so that it can utilize NVIDIA GPUs run ./configure --download-hypre --with-cuda 2674f1580f4eSBarry Smith Then pass `VECCUDA` vectors and `MATAIJCUSPARSE` matrices to the solvers and PETSc will automatically utilize hypre's GPU solvers. 2675ead8c081SBarry Smith 2676ead8c081SBarry Smith To configure hypre BoomerAMG so that it can utilize AMD GPUs run ./configure --download-hypre --with-hip 2677f1580f4eSBarry Smith Then pass `VECHIP` vectors to the solvers and PETSc will automatically utilize hypre's GPU solvers. 2678ead8c081SBarry Smith 2679562efe2eSBarry Smith .seealso: [](ch_ksp), `PCCreate()`, `PCSetType()`, `PCType`, `PC`, `PCHYPRESetType()`, `PCPFMG`, `PCGAMG`, `PCSYSPFMG`, `PCSMG`, `PCHYPRESetDiscreteGradient()`, 2680f1580f4eSBarry Smith `PCHYPRESetDiscreteCurl()`, `PCHYPRESetInterpolations()`, `PCHYPRESetAlphaPoissonMatrix()`, `PCHYPRESetBetaPoissonMatrix()`, `PCHYPRESetEdgeConstantVectors()`, 2681f1580f4eSBarry Smith PCHYPREAMSSetInteriorNodes() 268216d9e3a6SLisandro Dalcin M*/ 268316d9e3a6SLisandro Dalcin 2684d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_HYPRE(PC pc) 2685d71ae5a4SJacob Faibussowitsch { 268616d9e3a6SLisandro Dalcin PC_HYPRE *jac; 268716d9e3a6SLisandro Dalcin 268816d9e3a6SLisandro Dalcin PetscFunctionBegin; 26894dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&jac)); 26902fa5cd67SKarl Rupp 269116d9e3a6SLisandro Dalcin pc->data = jac; 26928695de01SBarry Smith pc->ops->reset = PCReset_HYPRE; 269316d9e3a6SLisandro Dalcin pc->ops->destroy = PCDestroy_HYPRE; 269416d9e3a6SLisandro Dalcin pc->ops->setfromoptions = PCSetFromOptions_HYPRE; 269516d9e3a6SLisandro Dalcin pc->ops->setup = PCSetUp_HYPRE; 269616d9e3a6SLisandro Dalcin pc->ops->apply = PCApply_HYPRE; 2697d7185485SAlex Lindsay jac->hypre_type = NULL; 269816d9e3a6SLisandro Dalcin jac->comm_hypre = MPI_COMM_NULL; 26999566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetType_C", PCHYPRESetType_HYPRE)); 27009566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREGetType_C", PCHYPREGetType_HYPRE)); 27019566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSetCoordinates_C", PCSetCoordinates_HYPRE)); 27029566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteGradient_C", PCHYPRESetDiscreteGradient_HYPRE)); 27039566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetDiscreteCurl_C", PCHYPRESetDiscreteCurl_HYPRE)); 27049566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetInterpolations_C", PCHYPRESetInterpolations_HYPRE)); 27059566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetEdgeConstantVectors_C", PCHYPRESetEdgeConstantVectors_HYPRE)); 2706be14dc20SKerry Key PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPREAMSSetInteriorNodes_C", PCHYPREAMSSetInteriorNodes_HYPRE)); 27079566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCHYPRESetPoissonMatrix_C", PCHYPRESetPoissonMatrix_HYPRE)); 27089566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinSetMatProductAlgorithm_C", PCMGGalerkinSetMatProductAlgorithm_HYPRE_BoomerAMG)); 27099566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCMGGalerkinGetMatProductAlgorithm_C", PCMGGalerkinGetMatProductAlgorithm_HYPRE_BoomerAMG)); 27106ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 27116ea7df73SStefano Zampini #if defined(HYPRE_USING_HIP) 27129566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_HIP)); 27136ea7df73SStefano Zampini #endif 27146ea7df73SStefano Zampini #if defined(HYPRE_USING_CUDA) 27159566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_CUDA)); 27166ea7df73SStefano Zampini #endif 27176ea7df73SStefano Zampini #endif 2718ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 27193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 272016d9e3a6SLisandro Dalcin } 2721ebc551c0SBarry Smith 2722ebc551c0SBarry Smith typedef struct { 272368326731SBarry Smith MPI_Comm hcomm; /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */ 2724f91d8e95SBarry Smith HYPRE_StructSolver hsolver; 27259e5bc791SBarry Smith 27269e5bc791SBarry Smith /* keep copy of PFMG options used so may view them */ 27274ddd07fcSJed Brown PetscInt its; 272873dcfd97SStefano Zampini PetscReal tol; 27294ddd07fcSJed Brown PetscInt relax_type; 27304ddd07fcSJed Brown PetscInt rap_type; 27314ddd07fcSJed Brown PetscInt num_pre_relax, num_post_relax; 27324ddd07fcSJed Brown PetscInt max_levels; 27330be8cd64Sftrigaux PetscInt skip_relax; 27340be8cd64Sftrigaux PetscBool print_statistics; 2735ebc551c0SBarry Smith } PC_PFMG; 2736ebc551c0SBarry Smith 2737ba38deedSJacob Faibussowitsch static PetscErrorCode PCDestroy_PFMG(PC pc) 2738d71ae5a4SJacob Faibussowitsch { 2739f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2740ebc551c0SBarry Smith 2741ebc551c0SBarry Smith PetscFunctionBegin; 2742792fecdfSBarry Smith if (ex->hsolver) PetscCallExternal(HYPRE_StructPFMGDestroy, ex->hsolver); 27439566063dSJacob Faibussowitsch PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 27449566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 27453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2746ebc551c0SBarry Smith } 2747ebc551c0SBarry Smith 27489e5bc791SBarry Smith static const char *PFMGRelaxType[] = {"Jacobi", "Weighted-Jacobi", "symmetric-Red/Black-Gauss-Seidel", "Red/Black-Gauss-Seidel"}; 27499e5bc791SBarry Smith static const char *PFMGRAPType[] = {"Galerkin", "non-Galerkin"}; 27509e5bc791SBarry Smith 2751ba38deedSJacob Faibussowitsch static PetscErrorCode PCView_PFMG(PC pc, PetscViewer viewer) 2752d71ae5a4SJacob Faibussowitsch { 27539f196a02SMartin Diehl PetscBool isascii; 2754f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2755ebc551c0SBarry Smith 2756ebc551c0SBarry Smith PetscFunctionBegin; 27579f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 27589f196a02SMartin Diehl if (isascii) { 27599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE PFMG preconditioning\n")); 276063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max iterations %" PetscInt_FMT "\n", ex->its)); 27619566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " tolerance %g\n", ex->tol)); 27629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relax type %s\n", PFMGRelaxType[ex->relax_type])); 27639566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " RAP type %s\n", PFMGRAPType[ex->rap_type])); 276463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n", ex->num_pre_relax, ex->num_post_relax)); 276563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max levels %" PetscInt_FMT "\n", ex->max_levels)); 27660be8cd64Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " skip relax %" PetscInt_FMT "\n", ex->skip_relax)); 27679e5bc791SBarry Smith } 27683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2769ebc551c0SBarry Smith } 2770ebc551c0SBarry Smith 2771ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_PFMG(PC pc, PetscOptionItems PetscOptionsObject) 2772d71ae5a4SJacob Faibussowitsch { 2773f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2774ebc551c0SBarry Smith 2775ebc551c0SBarry Smith PetscFunctionBegin; 2776d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "PFMG options"); 27770be8cd64Sftrigaux PetscCall(PetscOptionsBool("-pc_pfmg_print_statistics", "Print statistics", "HYPRE_StructPFMGSetPrintLevel", ex->print_statistics, &ex->print_statistics, NULL)); 27789566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_pfmg_its", "Number of iterations of PFMG to use as preconditioner", "HYPRE_StructPFMGSetMaxIter", ex->its, &ex->its, NULL)); 2779792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter, ex->hsolver, ex->its); 27809566063dSJacob 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)); 2781792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetNumPreRelax, ex->hsolver, ex->num_pre_relax); 27829566063dSJacob 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)); 2783792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetNumPostRelax, ex->hsolver, ex->num_post_relax); 27849e5bc791SBarry Smith 27859566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_pfmg_max_levels", "Max Levels for MG hierarchy", "HYPRE_StructPFMGSetMaxLevels", ex->max_levels, &ex->max_levels, NULL)); 2786792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxLevels, ex->hsolver, ex->max_levels); 27873b46a515SGlenn Hammond 27889566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_pfmg_tol", "Tolerance of PFMG", "HYPRE_StructPFMGSetTol", ex->tol, &ex->tol, NULL)); 2789792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol, ex->hsolver, ex->tol); 2790dd39110bSPierre 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)); 2791792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetRelaxType, ex->hsolver, ex->relax_type); 2792dd39110bSPierre 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)); 2793792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetRAPType, ex->hsolver, ex->rap_type); 27940be8cd64Sftrigaux 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)); 27950be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetSkipRelax, ex->hsolver, ex->skip_relax); 2796d0609cedSBarry Smith PetscOptionsHeadEnd(); 27973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2798ebc551c0SBarry Smith } 2799ebc551c0SBarry Smith 2800ba38deedSJacob Faibussowitsch static PetscErrorCode PCApply_PFMG(PC pc, Vec x, Vec y) 2801d71ae5a4SJacob Faibussowitsch { 2802f91d8e95SBarry Smith PC_PFMG *ex = (PC_PFMG *)pc->data; 2803d9ca1df4SBarry Smith PetscScalar *yy; 2804d9ca1df4SBarry Smith const PetscScalar *xx; 28054ddd07fcSJed Brown PetscInt ilower[3], iupper[3]; 28062cf14000SStefano Zampini HYPRE_Int hlower[3], hupper[3]; 2807f4f49eeaSPierre Jolivet Mat_HYPREStruct *mx = (Mat_HYPREStruct *)pc->pmat->data; 2808f91d8e95SBarry Smith 2809f91d8e95SBarry Smith PetscFunctionBegin; 28109566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 28119566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(mx->da, &ilower[0], &ilower[1], &ilower[2], &iupper[0], &iupper[1], &iupper[2])); 28122cf14000SStefano Zampini /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 2813f91d8e95SBarry Smith iupper[0] += ilower[0] - 1; 2814f91d8e95SBarry Smith iupper[1] += ilower[1] - 1; 2815f91d8e95SBarry Smith iupper[2] += ilower[2] - 1; 28162cf14000SStefano Zampini hlower[0] = (HYPRE_Int)ilower[0]; 28172cf14000SStefano Zampini hlower[1] = (HYPRE_Int)ilower[1]; 28182cf14000SStefano Zampini hlower[2] = (HYPRE_Int)ilower[2]; 28192cf14000SStefano Zampini hupper[0] = (HYPRE_Int)iupper[0]; 28202cf14000SStefano Zampini hupper[1] = (HYPRE_Int)iupper[1]; 28212cf14000SStefano Zampini hupper[2] = (HYPRE_Int)iupper[2]; 2822f91d8e95SBarry Smith 2823f91d8e95SBarry Smith /* copy x values over to hypre */ 2824792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorSetConstantValues, mx->hb, 0.0); 28259566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 2826792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorSetBoxValues, mx->hb, hlower, hupper, (HYPRE_Complex *)xx); 28279566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 2828792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorAssemble, mx->hb); 2829792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSolve, ex->hsolver, mx->hmat, mx->hb, mx->hx); 2830f91d8e95SBarry Smith 2831f91d8e95SBarry Smith /* copy solution values back to PETSc */ 28329566063dSJacob Faibussowitsch PetscCall(VecGetArray(y, &yy)); 2833792fecdfSBarry Smith PetscCallExternal(HYPRE_StructVectorGetBoxValues, mx->hx, hlower, hupper, (HYPRE_Complex *)yy); 28349566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y, &yy)); 28353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2836f91d8e95SBarry Smith } 2837f91d8e95SBarry Smith 2838d71ae5a4SJacob 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) 2839d71ae5a4SJacob Faibussowitsch { 28409e5bc791SBarry Smith PC_PFMG *jac = (PC_PFMG *)pc->data; 28412cf14000SStefano Zampini HYPRE_Int oits; 28429e5bc791SBarry Smith 28439e5bc791SBarry Smith PetscFunctionBegin; 28449566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 2845792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter, jac->hsolver, its * jac->its); 2846792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol, jac->hsolver, rtol); 28479e5bc791SBarry Smith 28489566063dSJacob Faibussowitsch PetscCall(PCApply_PFMG(pc, b, y)); 2849792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGGetNumIterations, jac->hsolver, &oits); 28509e5bc791SBarry Smith *outits = oits; 28519e5bc791SBarry Smith if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 28529e5bc791SBarry Smith else *reason = PCRICHARDSON_CONVERGED_RTOL; 2853792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetTol, jac->hsolver, jac->tol); 2854792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetMaxIter, jac->hsolver, jac->its); 28553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28569e5bc791SBarry Smith } 28579e5bc791SBarry Smith 2858ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetUp_PFMG(PC pc) 2859d71ae5a4SJacob Faibussowitsch { 28603a32d3dbSGlenn Hammond PC_PFMG *ex = (PC_PFMG *)pc->data; 2861f4f49eeaSPierre Jolivet Mat_HYPREStruct *mx = (Mat_HYPREStruct *)pc->pmat->data; 2862ace3abfcSBarry Smith PetscBool flg; 28633a32d3dbSGlenn Hammond 28643a32d3dbSGlenn Hammond PetscFunctionBegin; 28659566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRESTRUCT, &flg)); 286628b400f6SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Must use MATHYPRESTRUCT with this preconditioner"); 28673a32d3dbSGlenn Hammond 28683a32d3dbSGlenn Hammond /* create the hypre solver object and set its information */ 2869792fecdfSBarry Smith if (ex->hsolver) PetscCallExternal(HYPRE_StructPFMGDestroy, ex->hsolver); 2870792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGCreate, ex->hcomm, &ex->hsolver); 28710be8cd64Sftrigaux 28720be8cd64Sftrigaux // Print Hypre statistics about the solve process 28730be8cd64Sftrigaux if (ex->print_statistics) PetscCallExternal(HYPRE_StructPFMGSetPrintLevel, ex->hsolver, 3); 28740be8cd64Sftrigaux 28750be8cd64Sftrigaux // The hypre options must be repeated here because the StructPFMG was destroyed and recreated 28760be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetMaxIter, ex->hsolver, ex->its); 28770be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetNumPreRelax, ex->hsolver, ex->num_pre_relax); 28780be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetNumPostRelax, ex->hsolver, ex->num_post_relax); 28790be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetMaxLevels, ex->hsolver, ex->max_levels); 28800be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetTol, ex->hsolver, ex->tol); 28810be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetRelaxType, ex->hsolver, ex->relax_type); 28820be8cd64Sftrigaux PetscCallExternal(HYPRE_StructPFMGSetRAPType, ex->hsolver, ex->rap_type); 28830be8cd64Sftrigaux 2884792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetup, ex->hsolver, mx->hmat, mx->hb, mx->hx); 2885792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGSetZeroGuess, ex->hsolver); 28863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28873a32d3dbSGlenn Hammond } 28883a32d3dbSGlenn Hammond 2889ebc551c0SBarry Smith /*MC 2890ebc551c0SBarry Smith PCPFMG - the hypre PFMG multigrid solver 2891ebc551c0SBarry Smith 2892f1580f4eSBarry Smith Options Database Keys: 289367b8a455SSatish Balay + -pc_pfmg_its <its> - number of iterations of PFMG to use as preconditioner 289467b8a455SSatish Balay . -pc_pfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid solve 289567b8a455SSatish Balay . -pc_pfmg_num_post_relax <steps> - number of smoothing steps after coarse grid solve 289667b8a455SSatish Balay . -pc_pfmg_tol <tol> - tolerance of PFMG 28979e5bc791SBarry 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 28980be8cd64Sftrigaux . -pc_pfmg_rap_type - type of coarse matrix generation, one of Galerkin,non-Galerkin 2899f1580f4eSBarry Smith - -pc_pfmg_skip_relax - skip relaxation on certain grids for isotropic problems. This can greatly improve efficiency by eliminating unnecessary relaxations 2900f1580f4eSBarry Smith when the underlying problem is isotropic, one of 0,1 2901f1580f4eSBarry Smith 2902f1580f4eSBarry Smith Level: advanced 2903f91d8e95SBarry Smith 290495452b02SPatrick Sanan Notes: 290595452b02SPatrick Sanan This is for CELL-centered descretizations 29069e5bc791SBarry Smith 2907f1580f4eSBarry Smith See `PCSYSPFMG` for a version suitable for systems of PDEs, and `PCSMG` 29089e5bc791SBarry Smith 2909f1580f4eSBarry Smith See `PCHYPRE` for hypre's BoomerAMG algebraic multigrid solver 2910f1580f4eSBarry Smith 2911f1580f4eSBarry Smith This must be used with the `MATHYPRESTRUCT` matrix type. 2912f1580f4eSBarry Smith 2913f1580f4eSBarry Smith This provides only some of the functionality of PFMG, it supports only one block per process defined by a PETSc `DMDA`. 2914f1580f4eSBarry Smith 2915562efe2eSBarry Smith .seealso: [](ch_ksp), `PCMG`, `MATHYPRESTRUCT`, `PCHYPRE`, `PCGAMG`, `PCSYSPFMG`, `PCSMG` 2916ebc551c0SBarry Smith M*/ 2917ebc551c0SBarry Smith 2918d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_PFMG(PC pc) 2919d71ae5a4SJacob Faibussowitsch { 2920ebc551c0SBarry Smith PC_PFMG *ex; 2921ebc551c0SBarry Smith 2922ebc551c0SBarry Smith PetscFunctionBegin; 29239371c9d4SSatish Balay PetscCall(PetscNew(&ex)); 292468326731SBarry Smith pc->data = ex; 2925ebc551c0SBarry Smith 29269e5bc791SBarry Smith ex->its = 1; 29279e5bc791SBarry Smith ex->tol = 1.e-8; 29289e5bc791SBarry Smith ex->relax_type = 1; 29299e5bc791SBarry Smith ex->rap_type = 0; 29309e5bc791SBarry Smith ex->num_pre_relax = 1; 29319e5bc791SBarry Smith ex->num_post_relax = 1; 29323b46a515SGlenn Hammond ex->max_levels = 0; 29330be8cd64Sftrigaux ex->skip_relax = 0; 29340be8cd64Sftrigaux ex->print_statistics = PETSC_FALSE; 29359e5bc791SBarry Smith 2936ebc551c0SBarry Smith pc->ops->setfromoptions = PCSetFromOptions_PFMG; 2937ebc551c0SBarry Smith pc->ops->view = PCView_PFMG; 2938ebc551c0SBarry Smith pc->ops->destroy = PCDestroy_PFMG; 2939f91d8e95SBarry Smith pc->ops->apply = PCApply_PFMG; 29409e5bc791SBarry Smith pc->ops->applyrichardson = PCApplyRichardson_PFMG; 294168326731SBarry Smith pc->ops->setup = PCSetUp_PFMG; 29422fa5cd67SKarl Rupp 29439566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 2944ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 2945792fecdfSBarry Smith PetscCallExternal(HYPRE_StructPFMGCreate, ex->hcomm, &ex->hsolver); 29463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2947ebc551c0SBarry Smith } 2948d851a50bSGlenn Hammond 2949d851a50bSGlenn Hammond /* we know we are working with a HYPRE_SStructMatrix */ 2950d851a50bSGlenn Hammond typedef struct { 2951d851a50bSGlenn Hammond MPI_Comm hcomm; /* does not share comm with HYPRE_SStructMatrix because need to create solver before getting matrix */ 2952d851a50bSGlenn Hammond HYPRE_SStructSolver ss_solver; 2953d851a50bSGlenn Hammond 2954d851a50bSGlenn Hammond /* keep copy of SYSPFMG options used so may view them */ 29554ddd07fcSJed Brown PetscInt its; 295673dcfd97SStefano Zampini PetscReal tol; 29574ddd07fcSJed Brown PetscInt relax_type; 29584ddd07fcSJed Brown PetscInt num_pre_relax, num_post_relax; 2959d851a50bSGlenn Hammond } PC_SysPFMG; 2960d851a50bSGlenn Hammond 2961ba38deedSJacob Faibussowitsch static PetscErrorCode PCDestroy_SysPFMG(PC pc) 2962d71ae5a4SJacob Faibussowitsch { 2963d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2964d851a50bSGlenn Hammond 2965d851a50bSGlenn Hammond PetscFunctionBegin; 2966792fecdfSBarry Smith if (ex->ss_solver) PetscCallExternal(HYPRE_SStructSysPFMGDestroy, ex->ss_solver); 29679566063dSJacob Faibussowitsch PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 29689566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 29693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2970d851a50bSGlenn Hammond } 2971d851a50bSGlenn Hammond 2972d851a50bSGlenn Hammond static const char *SysPFMGRelaxType[] = {"Weighted-Jacobi", "Red/Black-Gauss-Seidel"}; 2973d851a50bSGlenn Hammond 2974ba38deedSJacob Faibussowitsch static PetscErrorCode PCView_SysPFMG(PC pc, PetscViewer viewer) 2975d71ae5a4SJacob Faibussowitsch { 29769f196a02SMartin Diehl PetscBool isascii; 2977d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2978d851a50bSGlenn Hammond 2979d851a50bSGlenn Hammond PetscFunctionBegin; 29809f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 29819f196a02SMartin Diehl if (isascii) { 29829566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE SysPFMG preconditioning\n")); 298363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " max iterations %" PetscInt_FMT "\n", ex->its)); 29849566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " tolerance %g\n", ex->tol)); 29859566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " relax type %s\n", PFMGRelaxType[ex->relax_type])); 298663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n", ex->num_pre_relax, ex->num_post_relax)); 2987d851a50bSGlenn Hammond } 29883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2989d851a50bSGlenn Hammond } 2990d851a50bSGlenn Hammond 2991ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_SysPFMG(PC pc, PetscOptionItems PetscOptionsObject) 2992d71ae5a4SJacob Faibussowitsch { 2993d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 2994ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 2995d851a50bSGlenn Hammond 2996d851a50bSGlenn Hammond PetscFunctionBegin; 2997d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "SysPFMG options"); 29989566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_syspfmg_print_statistics", "Print statistics", "HYPRE_SStructSysPFMGSetPrintLevel", flg, &flg, NULL)); 299948a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_SStructSysPFMGSetPrintLevel, ex->ss_solver, 3); 30009566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-pc_syspfmg_its", "Number of iterations of SysPFMG to use as preconditioner", "HYPRE_SStructSysPFMGSetMaxIter", ex->its, &ex->its, NULL)); 3001792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter, ex->ss_solver, ex->its); 30029566063dSJacob 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)); 3003792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetNumPreRelax, ex->ss_solver, ex->num_pre_relax); 30049566063dSJacob 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)); 3005792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetNumPostRelax, ex->ss_solver, ex->num_post_relax); 3006d851a50bSGlenn Hammond 30079566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_syspfmg_tol", "Tolerance of SysPFMG", "HYPRE_SStructSysPFMGSetTol", ex->tol, &ex->tol, NULL)); 3008792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol, ex->ss_solver, ex->tol); 3009dd39110bSPierre 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)); 3010792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetRelaxType, ex->ss_solver, ex->relax_type); 3011d0609cedSBarry Smith PetscOptionsHeadEnd(); 30123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3013d851a50bSGlenn Hammond } 3014d851a50bSGlenn Hammond 3015ba38deedSJacob Faibussowitsch static PetscErrorCode PCApply_SysPFMG(PC pc, Vec x, Vec y) 3016d71ae5a4SJacob Faibussowitsch { 3017d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 3018d9ca1df4SBarry Smith PetscScalar *yy; 3019d9ca1df4SBarry Smith const PetscScalar *xx; 30204ddd07fcSJed Brown PetscInt ilower[3], iupper[3]; 30212cf14000SStefano Zampini HYPRE_Int hlower[3], hupper[3]; 3022f4f49eeaSPierre Jolivet Mat_HYPRESStruct *mx = (Mat_HYPRESStruct *)pc->pmat->data; 30234ddd07fcSJed Brown PetscInt ordering = mx->dofs_order; 30244ddd07fcSJed Brown PetscInt nvars = mx->nvars; 30254ddd07fcSJed Brown PetscInt part = 0; 30264ddd07fcSJed Brown PetscInt size; 30274ddd07fcSJed Brown PetscInt i; 3028d851a50bSGlenn Hammond 3029d851a50bSGlenn Hammond PetscFunctionBegin; 30309566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 30319566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(mx->da, &ilower[0], &ilower[1], &ilower[2], &iupper[0], &iupper[1], &iupper[2])); 30322cf14000SStefano Zampini /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 3033d851a50bSGlenn Hammond iupper[0] += ilower[0] - 1; 3034d851a50bSGlenn Hammond iupper[1] += ilower[1] - 1; 3035d851a50bSGlenn Hammond iupper[2] += ilower[2] - 1; 30362cf14000SStefano Zampini hlower[0] = (HYPRE_Int)ilower[0]; 30372cf14000SStefano Zampini hlower[1] = (HYPRE_Int)ilower[1]; 30382cf14000SStefano Zampini hlower[2] = (HYPRE_Int)ilower[2]; 30392cf14000SStefano Zampini hupper[0] = (HYPRE_Int)iupper[0]; 30402cf14000SStefano Zampini hupper[1] = (HYPRE_Int)iupper[1]; 30412cf14000SStefano Zampini hupper[2] = (HYPRE_Int)iupper[2]; 3042d851a50bSGlenn Hammond 3043d851a50bSGlenn Hammond size = 1; 30442fa5cd67SKarl Rupp for (i = 0; i < 3; i++) size *= (iupper[i] - ilower[i] + 1); 30452fa5cd67SKarl Rupp 3046d851a50bSGlenn Hammond /* copy x values over to hypre for variable ordering */ 3047d851a50bSGlenn Hammond if (ordering) { 3048792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorSetConstantValues, mx->ss_b, 0.0); 30499566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 3050792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorSetBoxValues, mx->ss_b, part, hlower, hupper, i, (HYPRE_Complex *)(xx + (size * i))); 30519566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 3052792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorAssemble, mx->ss_b); 3053792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructMatrixMatvec, 1.0, mx->ss_mat, mx->ss_b, 0.0, mx->ss_x); 3054792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSolve, ex->ss_solver, mx->ss_mat, mx->ss_b, mx->ss_x); 3055d851a50bSGlenn Hammond 3056d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 30579566063dSJacob Faibussowitsch PetscCall(VecGetArray(y, &yy)); 3058792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorGetBoxValues, mx->ss_x, part, hlower, hupper, i, (HYPRE_Complex *)(yy + (size * i))); 30599566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y, &yy)); 3060a65764d7SBarry Smith } else { /* nodal ordering must be mapped to variable ordering for sys_pfmg */ 3061d851a50bSGlenn Hammond PetscScalar *z; 30624ddd07fcSJed Brown PetscInt j, k; 3063d851a50bSGlenn Hammond 30649566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nvars * size, &z)); 3065792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorSetConstantValues, mx->ss_b, 0.0); 30669566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 3067d851a50bSGlenn Hammond 3068d851a50bSGlenn Hammond /* transform nodal to hypre's variable ordering for sys_pfmg */ 3069d851a50bSGlenn Hammond for (i = 0; i < size; i++) { 3070d851a50bSGlenn Hammond k = i * nvars; 30712fa5cd67SKarl Rupp for (j = 0; j < nvars; j++) z[j * size + i] = xx[k + j]; 3072d851a50bSGlenn Hammond } 3073792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorSetBoxValues, mx->ss_b, part, hlower, hupper, i, (HYPRE_Complex *)(z + (size * i))); 30749566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 3075792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructVectorAssemble, mx->ss_b); 3076792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSolve, ex->ss_solver, mx->ss_mat, mx->ss_b, mx->ss_x); 3077d851a50bSGlenn Hammond 3078d851a50bSGlenn Hammond /* copy solution values back to PETSc */ 30799566063dSJacob Faibussowitsch PetscCall(VecGetArray(y, &yy)); 3080792fecdfSBarry Smith for (i = 0; i < nvars; i++) PetscCallExternal(HYPRE_SStructVectorGetBoxValues, mx->ss_x, part, hlower, hupper, i, (HYPRE_Complex *)(z + (size * i))); 3081d851a50bSGlenn Hammond /* transform hypre's variable ordering for sys_pfmg to nodal ordering */ 3082d851a50bSGlenn Hammond for (i = 0; i < size; i++) { 3083d851a50bSGlenn Hammond k = i * nvars; 30842fa5cd67SKarl Rupp for (j = 0; j < nvars; j++) yy[k + j] = z[j * size + i]; 3085d851a50bSGlenn Hammond } 30869566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y, &yy)); 30879566063dSJacob Faibussowitsch PetscCall(PetscFree(z)); 3088d851a50bSGlenn Hammond } 30893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3090d851a50bSGlenn Hammond } 3091d851a50bSGlenn Hammond 3092d71ae5a4SJacob 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) 3093d71ae5a4SJacob Faibussowitsch { 3094d851a50bSGlenn Hammond PC_SysPFMG *jac = (PC_SysPFMG *)pc->data; 30952cf14000SStefano Zampini HYPRE_Int oits; 3096d851a50bSGlenn Hammond 3097d851a50bSGlenn Hammond PetscFunctionBegin; 30989566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 3099792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter, jac->ss_solver, its * jac->its); 3100792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol, jac->ss_solver, rtol); 31019566063dSJacob Faibussowitsch PetscCall(PCApply_SysPFMG(pc, b, y)); 3102792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGGetNumIterations, jac->ss_solver, &oits); 3103d851a50bSGlenn Hammond *outits = oits; 3104d851a50bSGlenn Hammond if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 3105d851a50bSGlenn Hammond else *reason = PCRICHARDSON_CONVERGED_RTOL; 3106792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetTol, jac->ss_solver, jac->tol); 3107792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetMaxIter, jac->ss_solver, jac->its); 31083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3109d851a50bSGlenn Hammond } 3110d851a50bSGlenn Hammond 3111ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetUp_SysPFMG(PC pc) 3112d71ae5a4SJacob Faibussowitsch { 3113d851a50bSGlenn Hammond PC_SysPFMG *ex = (PC_SysPFMG *)pc->data; 3114f4f49eeaSPierre Jolivet Mat_HYPRESStruct *mx = (Mat_HYPRESStruct *)pc->pmat->data; 3115ace3abfcSBarry Smith PetscBool flg; 3116d851a50bSGlenn Hammond 3117d851a50bSGlenn Hammond PetscFunctionBegin; 31189566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRESSTRUCT, &flg)); 311928b400f6SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Must use MATHYPRESSTRUCT with this preconditioner"); 3120d851a50bSGlenn Hammond 3121d851a50bSGlenn Hammond /* create the hypre sstruct solver object and set its information */ 3122792fecdfSBarry Smith if (ex->ss_solver) PetscCallExternal(HYPRE_SStructSysPFMGDestroy, ex->ss_solver); 3123792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGCreate, ex->hcomm, &ex->ss_solver); 3124792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetZeroGuess, ex->ss_solver); 3125792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGSetup, ex->ss_solver, mx->ss_mat, mx->ss_b, mx->ss_x); 31263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3127d851a50bSGlenn Hammond } 3128d851a50bSGlenn Hammond 3129d851a50bSGlenn Hammond /*MC 3130f1580f4eSBarry Smith PCSYSPFMG - the hypre SysPFMG multigrid solver 3131d851a50bSGlenn Hammond 3132d851a50bSGlenn Hammond Level: advanced 3133d851a50bSGlenn Hammond 3134f1580f4eSBarry Smith Options Database Keys: 313567b8a455SSatish Balay + -pc_syspfmg_its <its> - number of iterations of SysPFMG to use as preconditioner 313667b8a455SSatish Balay . -pc_syspfmg_num_pre_relax <steps> - number of smoothing steps before coarse grid 313767b8a455SSatish Balay . -pc_syspfmg_num_post_relax <steps> - number of smoothing steps after coarse grid 313867b8a455SSatish Balay . -pc_syspfmg_tol <tol> - tolerance of SysPFMG 313967b8a455SSatish Balay - -pc_syspfmg_relax_type <Weighted-Jacobi,Red/Black-Gauss-Seidel> - relaxation type for the up and down cycles 3140d851a50bSGlenn Hammond 314195452b02SPatrick Sanan Notes: 3142f1580f4eSBarry Smith See `PCPFMG` for hypre's PFMG that works for a scalar PDE and `PCSMG` 3143f1580f4eSBarry Smith 3144f1580f4eSBarry Smith See `PCHYPRE` for hypre's BoomerAMG algebraic multigrid solver 3145f1580f4eSBarry Smith 314695452b02SPatrick Sanan This is for CELL-centered descretizations 3147d851a50bSGlenn Hammond 3148f1580f4eSBarry Smith This must be used with the `MATHYPRESSTRUCT` matrix type. 3149d851a50bSGlenn Hammond 3150f1580f4eSBarry 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`. 3151f1580f4eSBarry Smith 3152562efe2eSBarry Smith .seealso: [](ch_ksp), `PCMG`, `MATHYPRESSTRUCT`, `PCPFMG`, `PCHYPRE`, `PCGAMG`, `PCSMG` 3153d851a50bSGlenn Hammond M*/ 3154d851a50bSGlenn Hammond 3155d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_SysPFMG(PC pc) 3156d71ae5a4SJacob Faibussowitsch { 3157d851a50bSGlenn Hammond PC_SysPFMG *ex; 3158d851a50bSGlenn Hammond 3159d851a50bSGlenn Hammond PetscFunctionBegin; 31609371c9d4SSatish Balay PetscCall(PetscNew(&ex)); 3161d851a50bSGlenn Hammond pc->data = ex; 3162d851a50bSGlenn Hammond 3163d851a50bSGlenn Hammond ex->its = 1; 3164d851a50bSGlenn Hammond ex->tol = 1.e-8; 3165d851a50bSGlenn Hammond ex->relax_type = 1; 3166d851a50bSGlenn Hammond ex->num_pre_relax = 1; 3167d851a50bSGlenn Hammond ex->num_post_relax = 1; 3168d851a50bSGlenn Hammond 3169d851a50bSGlenn Hammond pc->ops->setfromoptions = PCSetFromOptions_SysPFMG; 3170d851a50bSGlenn Hammond pc->ops->view = PCView_SysPFMG; 3171d851a50bSGlenn Hammond pc->ops->destroy = PCDestroy_SysPFMG; 3172d851a50bSGlenn Hammond pc->ops->apply = PCApply_SysPFMG; 3173d851a50bSGlenn Hammond pc->ops->applyrichardson = PCApplyRichardson_SysPFMG; 3174d851a50bSGlenn Hammond pc->ops->setup = PCSetUp_SysPFMG; 31752fa5cd67SKarl Rupp 31769566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 3177ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 3178792fecdfSBarry Smith PetscCallExternal(HYPRE_SStructSysPFMGCreate, ex->hcomm, &ex->ss_solver); 31793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3180d851a50bSGlenn Hammond } 31811c188c59Sftrigaux 3182f1580f4eSBarry Smith /* PC SMG */ 31831c188c59Sftrigaux typedef struct { 31841c188c59Sftrigaux MPI_Comm hcomm; /* does not share comm with HYPRE_StructMatrix because need to create solver before getting matrix */ 31851c188c59Sftrigaux HYPRE_StructSolver hsolver; 31861c188c59Sftrigaux PetscInt its; /* keep copy of SMG options used so may view them */ 318773dcfd97SStefano Zampini PetscReal tol; 31881c188c59Sftrigaux PetscBool print_statistics; 31891c188c59Sftrigaux PetscInt num_pre_relax, num_post_relax; 31901c188c59Sftrigaux } PC_SMG; 31911c188c59Sftrigaux 3192ba38deedSJacob Faibussowitsch static PetscErrorCode PCDestroy_SMG(PC pc) 3193d71ae5a4SJacob Faibussowitsch { 31941c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 31951c188c59Sftrigaux 31961c188c59Sftrigaux PetscFunctionBegin; 31971c188c59Sftrigaux if (ex->hsolver) PetscCallExternal(HYPRE_StructSMGDestroy, ex->hsolver); 31981c188c59Sftrigaux PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 31991c188c59Sftrigaux PetscCall(PetscFree(pc->data)); 32003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 32011c188c59Sftrigaux } 32021c188c59Sftrigaux 3203ba38deedSJacob Faibussowitsch static PetscErrorCode PCView_SMG(PC pc, PetscViewer viewer) 3204d71ae5a4SJacob Faibussowitsch { 32059f196a02SMartin Diehl PetscBool isascii; 32061c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 32071c188c59Sftrigaux 32081c188c59Sftrigaux PetscFunctionBegin; 32099f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 32109f196a02SMartin Diehl if (isascii) { 32111c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " HYPRE SMG preconditioning\n")); 32121c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " max iterations %" PetscInt_FMT "\n", ex->its)); 32131c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " tolerance %g\n", ex->tol)); 32141c188c59Sftrigaux PetscCall(PetscViewerASCIIPrintf(viewer, " number pre-relax %" PetscInt_FMT " post-relax %" PetscInt_FMT "\n", ex->num_pre_relax, ex->num_post_relax)); 32151c188c59Sftrigaux } 32163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 32171c188c59Sftrigaux } 32181c188c59Sftrigaux 3219ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_SMG(PC pc, PetscOptionItems PetscOptionsObject) 3220d71ae5a4SJacob Faibussowitsch { 32211c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 32221c188c59Sftrigaux 32231c188c59Sftrigaux PetscFunctionBegin; 32241c188c59Sftrigaux PetscOptionsHeadBegin(PetscOptionsObject, "SMG options"); 32251c188c59Sftrigaux 32261c188c59Sftrigaux PetscCall(PetscOptionsInt("-pc_smg_its", "Number of iterations of SMG to use as preconditioner", "HYPRE_StructSMGSetMaxIter", ex->its, &ex->its, NULL)); 32271c188c59Sftrigaux 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)); 32281c188c59Sftrigaux 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)); 32291c188c59Sftrigaux PetscCall(PetscOptionsReal("-pc_smg_tol", "Tolerance of SMG", "HYPRE_StructSMGSetTol", ex->tol, &ex->tol, NULL)); 32301c188c59Sftrigaux 32311c188c59Sftrigaux PetscOptionsHeadEnd(); 32323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 32331c188c59Sftrigaux } 32341c188c59Sftrigaux 3235ba38deedSJacob Faibussowitsch static PetscErrorCode PCApply_SMG(PC pc, Vec x, Vec y) 3236d71ae5a4SJacob Faibussowitsch { 32371c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 32381c188c59Sftrigaux PetscScalar *yy; 32391c188c59Sftrigaux const PetscScalar *xx; 32401c188c59Sftrigaux PetscInt ilower[3], iupper[3]; 32411c188c59Sftrigaux HYPRE_Int hlower[3], hupper[3]; 3242f4f49eeaSPierre Jolivet Mat_HYPREStruct *mx = (Mat_HYPREStruct *)pc->pmat->data; 32431c188c59Sftrigaux 32441c188c59Sftrigaux PetscFunctionBegin; 32451c188c59Sftrigaux PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 32461c188c59Sftrigaux PetscCall(DMDAGetCorners(mx->da, &ilower[0], &ilower[1], &ilower[2], &iupper[0], &iupper[1], &iupper[2])); 32471c188c59Sftrigaux /* when HYPRE_MIXEDINT is defined, sizeof(HYPRE_Int) == 32 */ 32481c188c59Sftrigaux iupper[0] += ilower[0] - 1; 32491c188c59Sftrigaux iupper[1] += ilower[1] - 1; 32501c188c59Sftrigaux iupper[2] += ilower[2] - 1; 32511c188c59Sftrigaux hlower[0] = (HYPRE_Int)ilower[0]; 32521c188c59Sftrigaux hlower[1] = (HYPRE_Int)ilower[1]; 32531c188c59Sftrigaux hlower[2] = (HYPRE_Int)ilower[2]; 32541c188c59Sftrigaux hupper[0] = (HYPRE_Int)iupper[0]; 32551c188c59Sftrigaux hupper[1] = (HYPRE_Int)iupper[1]; 32561c188c59Sftrigaux hupper[2] = (HYPRE_Int)iupper[2]; 32571c188c59Sftrigaux 32581c188c59Sftrigaux /* copy x values over to hypre */ 32591c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorSetConstantValues, mx->hb, 0.0); 32601c188c59Sftrigaux PetscCall(VecGetArrayRead(x, &xx)); 32611c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorSetBoxValues, mx->hb, hlower, hupper, (HYPRE_Complex *)xx); 32621c188c59Sftrigaux PetscCall(VecRestoreArrayRead(x, &xx)); 32631c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorAssemble, mx->hb); 32641c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSolve, ex->hsolver, mx->hmat, mx->hb, mx->hx); 32651c188c59Sftrigaux 32661c188c59Sftrigaux /* copy solution values back to PETSc */ 32671c188c59Sftrigaux PetscCall(VecGetArray(y, &yy)); 32681c188c59Sftrigaux PetscCallExternal(HYPRE_StructVectorGetBoxValues, mx->hx, hlower, hupper, (HYPRE_Complex *)yy); 32691c188c59Sftrigaux PetscCall(VecRestoreArray(y, &yy)); 32703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 32711c188c59Sftrigaux } 32721c188c59Sftrigaux 3273d71ae5a4SJacob 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) 3274d71ae5a4SJacob Faibussowitsch { 32751c188c59Sftrigaux PC_SMG *jac = (PC_SMG *)pc->data; 32761c188c59Sftrigaux HYPRE_Int oits; 32771c188c59Sftrigaux 32781c188c59Sftrigaux PetscFunctionBegin; 32791c188c59Sftrigaux PetscCall(PetscCitationsRegister(hypreCitation, &cite)); 32801c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetMaxIter, jac->hsolver, its * jac->its); 32811c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetTol, jac->hsolver, rtol); 32821c188c59Sftrigaux 32831c188c59Sftrigaux PetscCall(PCApply_SMG(pc, b, y)); 32841c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGGetNumIterations, jac->hsolver, &oits); 32851c188c59Sftrigaux *outits = oits; 32861c188c59Sftrigaux if (oits == its) *reason = PCRICHARDSON_CONVERGED_ITS; 32871c188c59Sftrigaux else *reason = PCRICHARDSON_CONVERGED_RTOL; 32881c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetTol, jac->hsolver, jac->tol); 32891c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetMaxIter, jac->hsolver, jac->its); 32903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 32911c188c59Sftrigaux } 32921c188c59Sftrigaux 3293ba38deedSJacob Faibussowitsch static PetscErrorCode PCSetUp_SMG(PC pc) 3294d71ae5a4SJacob Faibussowitsch { 32951c188c59Sftrigaux PetscInt i, dim; 32961c188c59Sftrigaux PC_SMG *ex = (PC_SMG *)pc->data; 3297f4f49eeaSPierre Jolivet Mat_HYPREStruct *mx = (Mat_HYPREStruct *)pc->pmat->data; 32981c188c59Sftrigaux PetscBool flg; 32991c188c59Sftrigaux DMBoundaryType p[3]; 33001c188c59Sftrigaux PetscInt M[3]; 33011c188c59Sftrigaux 33021c188c59Sftrigaux PetscFunctionBegin; 33031c188c59Sftrigaux PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATHYPRESTRUCT, &flg)); 33041c188c59Sftrigaux PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_INCOMP, "Must use MATHYPRESTRUCT with this preconditioner"); 33051c188c59Sftrigaux 33061c188c59Sftrigaux PetscCall(DMDAGetInfo(mx->da, &dim, &M[0], &M[1], &M[2], 0, 0, 0, 0, 0, &p[0], &p[1], &p[2], 0)); 33071c188c59Sftrigaux // Check if power of 2 in periodic directions 33081c188c59Sftrigaux for (i = 0; i < dim; i++) { 3309*966bd95aSPierre 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]); 33101c188c59Sftrigaux } 33111c188c59Sftrigaux 33121c188c59Sftrigaux /* create the hypre solver object and set its information */ 331357508eceSPierre Jolivet if (ex->hsolver) PetscCallExternal(HYPRE_StructSMGDestroy, ex->hsolver); 33141c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGCreate, ex->hcomm, &ex->hsolver); 33151c188c59Sftrigaux // The hypre options must be set here and not in SetFromOptions because it is created here! 33161c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetMaxIter, ex->hsolver, ex->its); 33171c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetNumPreRelax, ex->hsolver, ex->num_pre_relax); 33181c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetNumPostRelax, ex->hsolver, ex->num_post_relax); 33191c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetTol, ex->hsolver, ex->tol); 33201c188c59Sftrigaux 33211c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetup, ex->hsolver, mx->hmat, mx->hb, mx->hx); 33221c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGSetZeroGuess, ex->hsolver); 33233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33241c188c59Sftrigaux } 33251c188c59Sftrigaux 33261c188c59Sftrigaux /*MC 33275cb80ecdSBarry Smith PCSMG - the hypre (structured grid) SMG multigrid solver 33281c188c59Sftrigaux 33291c188c59Sftrigaux Level: advanced 33301c188c59Sftrigaux 3331f1580f4eSBarry Smith Options Database Keys: 33325cb80ecdSBarry Smith + -pc_smg_its <its> - number of iterations of SMG to use as preconditioner 33335cb80ecdSBarry Smith . -pc_smg_num_pre_relax <steps> - number of smoothing steps before coarse grid 33345cb80ecdSBarry Smith . -pc_smg_num_post_relax <steps> - number of smoothing steps after coarse grid 33355cb80ecdSBarry Smith - -pc_smg_tol <tol> - tolerance of SMG 33361c188c59Sftrigaux 33371c188c59Sftrigaux Notes: 33381c188c59Sftrigaux This is for CELL-centered descretizations 33391c188c59Sftrigaux 33405cb80ecdSBarry Smith This must be used with the `MATHYPRESTRUCT` `MatType`. 33411c188c59Sftrigaux 3342f1580f4eSBarry 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`. 3343f1580f4eSBarry Smith 3344f1580f4eSBarry Smith See `PCSYSPFMG`, `PCSMG`, `PCPFMG`, and `PCHYPRE` for access to hypre's other preconditioners 3345f1580f4eSBarry Smith 3346f1580f4eSBarry Smith .seealso: `PCMG`, `MATHYPRESTRUCT`, `PCPFMG`, `PCSYSPFMG`, `PCHYPRE`, `PCGAMG` 33471c188c59Sftrigaux M*/ 33481c188c59Sftrigaux 3349d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_SMG(PC pc) 3350d71ae5a4SJacob Faibussowitsch { 33511c188c59Sftrigaux PC_SMG *ex; 33521c188c59Sftrigaux 33531c188c59Sftrigaux PetscFunctionBegin; 33549371c9d4SSatish Balay PetscCall(PetscNew(&ex)); 33551c188c59Sftrigaux pc->data = ex; 33561c188c59Sftrigaux 33571c188c59Sftrigaux ex->its = 1; 33581c188c59Sftrigaux ex->tol = 1.e-8; 33591c188c59Sftrigaux ex->num_pre_relax = 1; 33601c188c59Sftrigaux ex->num_post_relax = 1; 33611c188c59Sftrigaux 33621c188c59Sftrigaux pc->ops->setfromoptions = PCSetFromOptions_SMG; 33631c188c59Sftrigaux pc->ops->view = PCView_SMG; 33641c188c59Sftrigaux pc->ops->destroy = PCDestroy_SMG; 33651c188c59Sftrigaux pc->ops->apply = PCApply_SMG; 33661c188c59Sftrigaux pc->ops->applyrichardson = PCApplyRichardson_SMG; 33671c188c59Sftrigaux pc->ops->setup = PCSetUp_SMG; 33681c188c59Sftrigaux 33691c188c59Sftrigaux PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)pc), &ex->hcomm)); 3370ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 33711c188c59Sftrigaux PetscCallExternal(HYPRE_StructSMGCreate, ex->hcomm, &ex->hsolver); 33723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33731c188c59Sftrigaux } 3374