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